MySQL /PHP Database Applications Second Edition phần 7 docx

81 361 0
MySQL /PHP Database Applications Second Edition phần 7 docx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Chapter 13 Problem-Tracking System IN THIS CHAPTER ◆ Designing a problem-tracking system ◆ Protecting yourself from redundant data ◆ Using the IntegratedTemplate class from the PEAR class libraries ◆ Creating a site that has both public and private portions GOT PROBLEMS? Don’t worry, we’ve all got problems. Relationships falter, bosses make capricious demands, and family— oh, we all know about family. Sadly, in the crazy lives that we all live, PHP and MySQL can do nothing to make your girl/ boyfriend love you more or make your dealings with your parents or in-laws any easier. But no scripting language or relational database is better equipped in these areas. But if you’re working for a company that sells or otherwise dispenses goods, it is a virtual guarantee that someone somewhere is going to be unhappy with what he or she has received. When that person complains, you are going to want to have a place in which to record the problems and the steps required for resolution. The problem-tracking application in this chapter can be used for that purpose. What we have here is fairly generic, and depending on the goods involved with your business, it is likely that you are going to want some fields that apply to your specific products. Anyhow, this application should get you moving in the right direction. Determining the Scope and Goals of the Application This problem-tracking system should have aspects that are publicly available and others that only someone with the proper authorization can view. It makes sense to have a form that users can access over the Web in order to report their problems. Alternatively, someone on the support staff should be able to report problems — for example, while taking a phone call from a dissatisfied customer. Once the problem is entered, it should be tracked by the staff. Each action taken in the attempt to solve the problem should be noted. And the tracking should have 441 a public and a private realm — actions that you want the user to see must be differ- entiated from those that you do not want the user to see. Those with problems should be able to keep track of them in two ways. They should be emailed whenever a publicly viewable update is made to their case, and a Web page detailing their problem should be available. What do you need? The first thing you need is a form into which people can enter their complaints. What we present in Figure 13-1 is fairly generic; remember that for your own appli- cations you will probably want to add information regarding specific products. Figure 13-1: Problem entry form Once a problem is entered, there must be a place for the staff to work on the complaint. It should include all the information about the user, the history of the complaint, and a place to enter new information. This problem-update form would look something like the one in Figure 13-2. The support-staff members need a home, a place where they can log in and see both unassigned tasks and those that are assigned to them and are still open. The staff page would look something like the one in Figure 13-3. 442 Part IV: Not So Simple Applications Figure 13-2: Problem update form Figure 13-3: Staff page Chapter 13: Problem-Tracking System 443 If you want to see if any of your users are hypochondriacs, you can use the user- history page shown in Figure 13-4, which lists all problems associated with a user. Figure 13-4: User history page What do you need to prevent? In setting up this part of the application, you’re concerned with gathering informa- tion efficiently and in a way that’s pleasant for the user. Therefore, your worries are more of an interface-design nature, and thus more in the realm of Web design than application development. Developers, though, are concerned with making sure that the data collected is valid, and complies with database limitations. You might want to endow your forms with some client-side scripting that checks values for obvious problems before sending them in. Designing the Database As you can see from Figure 13-5, the problems table is at the center of the schema. 444 Part IV: Not So Simple Applications Figure 13-5: Tracking system schema admin username password problems problem_id customer_id status_id staff_id summary problem entered_by source_id entry_dt modify_dt last_public_entry last_entry_id history entry_id problem_id entry_type_id entered_by source_id entry_dt notes status status_id customers customer_id customer_code firstname lastname address address2 city state zip zip4 email day_area day_prefix day_suffix day_ext day_start day_end eve_area eve_prefix eve_suffix eve_ext eve_start eve_end staff staff_id username password staff_name active entry types entry_type_id entry_type sources source_id source Chapter 13: Problem-Tracking System 445 Here are some design considerations we had to keep in mind as we designed our database: ◆ Each customer can have one or many problems. The history table records the steps taken to remedy the problem or problems. ◆ The status table is a lookup table, containing the possible states of a problem, notably open, closed, in processing, and so on. ◆ The sources table is another lookup table, which records where the prob- lem was originally recorded. If a user enters a complaint over the Web, the sources table will record that; complaints received by the support staff might originate from a phone call, email, or flaming arrow. ◆ The entry_types table notes whether a specific item in the history table should be public or private. If it is private, it will not be available on the Web page when the user comes to view the progress of the problem, and an email will not be sent to the user when an update takes place. The pub- lic updates will be viewable and the user will receive email notification. Now for a couple of notes on this schema and the create statements that follow. Depending on how you plan on running your site, you may wish to add a table or change a column definition or two. Notice that we have a problem_code column in the problems table. However, if you will be emailing users regarding the status of problems, you may want some- thing a little less transparent than the following: http://yoursite.com/tracking/ problems.php?problem_id=7 . In Chapter 9 we take some precautions when we run into a similar situation. We didn’t want people to gain access to restricted parts of our data simply by guessing at variable names in the URL. Here we adopt the same technique we used there in the survey application, creating a random 8-character alphanumeric string from the md5() and uniqueid() functions. It’s true that we run a risk of the same random number coming up twice, and in fact this approach might not be right for a very large application. But it works here. Listing 13-1 shows the create statements for the tables we used in this applica- tion. In addition to the create statements, this listing includes some of the default data you will need to start the application. Note that if you install this application from the CD-ROM you will have a full set of dummy data you can play with. Listing 13-1: create Statements Used in the Problem-Tracking System drop table if exists status; create table status ( status_id tinyint not null auto_increment , status varchar(20) not null , primary key (status_id) 446 Part IV: Not So Simple Applications ) type=InnoDB ; insert into status (status) values (‘Opened’); insert into status (status) values (‘In Progress’); insert into status (status) values (‘Closed’); insert into status (status) values (‘Re-opened’); drop table if exists status_seq; create table status_seq ( id tinyint not null auto_increment , primary key (id) ) type=InnoDB ; insert into status_seq (id) select max(status_id)+1 from status; drop table if exists sources; create table sources ( source_id tinyint not null auto_increment , source varchar(10) not null , primary key (source_id) ) type=InnoDB ; insert into sources (source) values (‘web’); insert into sources (source) values (‘email’); insert into sources (source) values (‘phone’); insert into sources (source) values (‘in-store’); insert into sources (source) values (‘staff’); insert into sources (source) values (‘program’); drop table if exists source_seq; create table source_seq ( id int not null auto_increment , primary key (id) ) type=InnoDB ; insert into source_seq (id) select max(source_id)+1 from sources; drop table if exists entry_types; create table entry_types ( Continued Chapter 13: Problem-Tracking System 447 Listing 13-1 (Continued) entry_type_id tinyint not null auto_increment , entry_type varchar(10) not null , primary key (entry_type_id) ) type=InnoDB ; insert into entry_types (entry_type) values (‘private’); insert into entry_types (entry_type) values (‘public’); drop table if exists entry_type_seq; create table entry_type_seq ( id tinyint not null auto_increment , primary key (id) ) type=InnoDB ; insert into entry_type_seq (id) select max(entry_type_id)+1 from entry_types; drop table if exists staff; create table staff ( staff_id int not null auto_increment , username varchar(20) not null , password varchar(255) not null , staff_name varchar(50) not null , active tinyint default 1 , primary key (staff_id) , unique (username) ) type=InnoDB ; insert into staff (username,password,staff_name) values (‘fred’,password(‘fred’),’Fred Flintstone’) , (‘barney’,password(‘barney’),’Barney Rubble’) ; drop table if exists staff_seq; create table staff_seq ( id int not null auto_increment 448 Part IV: Not So Simple Applications , primary key (id) ) type=InnoDB ; insert into staff_seq (id) select max(staff_id)+1 from staff; drop table if exists customers; create table customers ( customer_id integer not null auto_increment , customer_code varchar(8) , firstname varchar(40) , lastname varchar(40) , address varchar(40) , address2 varchar(40) , city varchar(20) , state char(2) , zip char(5) , zip4 char(5) , email varchar(255) , day_area char(3) , day_prefix char(3) , day_suffix char(4) , day_ext char(5) , day_start char(8) , day_end char(8) , eve_area char(3) , eve_prefix char(3) , eve_suffix char(4) , eve_ext char(5) , eve_start char(8) , eve_end char(8) , primary key (customer_id) ) type=InnoDB ; drop table if exists customer_seq; create table customer_seq ( id int not null auto_increment , primary key (id) ) Continued Chapter 13: Problem-Tracking System 449 Listing 13-1 (Continued) type=InnoDB ; drop table if exists problems; create table problems ( problem_id integer not null auto_increment , customer_id integer not null , problem_code char(8) not null , status_id tinyint null , staff_id integer null , summary text , problem text , entered_by varchar(20) null , source_id tinyint null , entry_dt datetime , modify_dt timestamp , last_public_entry_id int null , last_entry_id int null , primary key (problem_id) , key (customer_id) , foreign key (customer_id) references customers (customer_id) on delete cascade , key (status_id) , foreign key (status_id) references status (status_id) on delete set null , key (source_id) , foreign key (source_id) references sources (source_id) on delete set null , key (staff_id) , foreign key (staff_id) references staff (staff_id) on delete set null , unique (problem_code) ) type=InnoDB ; drop table if exists problem_seq; create table problem_seq ( id int not null auto_increment , primary key (id) ) type=InnoDB 450 Part IV: Not So Simple Applications [...]... all the information in the current database // record should be overwritten by the values from // the form // set $action to indicate that we should update // the customer record using the information from 469 470 Part IV: Not So Simple Applications // the form $customer_code = $record[‘customer_code’]; $action = ‘update’; } else { // use the customer’s record from the database extract($record); $action... { $$field = trim($$field); } // for each column from the database record if ($value != $$field && empty($$field)) { // the value from the form ($$field // i.e the variable with the same name // as the column) is blank, and the // current value of the column // in the database is not blank // overwrite the form value with // the value from the database $$field = $value; } } // end parsing customer record... == ‘problems’) { $params[‘dup_results’] = $result; } } } if ($action == ‘problems’ || count($errors) > 0) { $params[‘error_messages’] = $errors; return FALSE; } if ($action == ‘none’) 471 472 Part IV: Not So Simple Applications { // no change to existing customer record } else { // remove customer_id and customer_code from list of fields // at first $fields = array_diff( $customer_fields , array(‘customer_id’,... array(status_id(‘Closed’), $staff_id, $staff_id); $params[‘order_by’] = ‘ staff_id, last_entry_dt asc ‘; $list_titles = array( ‘’ => ‘Unowned Calls’ , $staff_id => ‘Open Calls for ‘.$staff_name ); 473 474 Part IV: Not So Simple Applications $list_key = ‘staff_id’; } else { fetch_customer($params); $list_titles = array( $params[‘customer_code’] => ‘Calls for ‘.$params[‘firstname’].’ ‘.$params[‘lastname’] ); $list_key... default // if no phone number is given, set them to NULL if (empty($day_prefix)) { $day_start = NULL; $day_end = NULL; } if (empty($eve_prefix)) { $eve_start = NULL; $eve_end = NULL; } 4 67 468 Part IV: Not So Simple Applications // the $action variable will be set to reflect what the script // should do with the customer data as it passes through a // myriad of tests by default, create a new customer... username varchar(50) not null , password varchar(255) not null , primary key (username) ) type=InnoDB ; insert into admin values (‘jay’,password(‘rules’)); delete from mysql. db where Db = ‘tracking’; Continued 451 452 Part IV: Not So Simple Applications Listing 13-1 (Continued) grant delete, insert, select, update on tracking.* to nobody@localhost identified by ‘ydobon’ ; flush privileges; Code Overview... error in query: ‘ $dbh->last_query ; user_error( ‘Could not fetch customer from database , E_USER_ERROR ); return FALSE; } $params = array_merge($params, $record); return TRUE; } fetch_problem() The difference between fetch_problem() and fetch_customer() is at the end of the function When you get a problem from the database, you want more than the problem record itself You want information about... = $eve_suffix; } if ($email != ‘’) { $wheres[] = ‘(email like ?)’; $bind[] = $email; } if (count($wheres) == 0) { // nothing to look for user_error( ‘find_customer: no wheres supplied’ 4 57 458 Part IV: Not So Simple Applications , E_USER_NOTICE ); return FALSE; } // run a query with the constructed qualification // and return the result // separate each part of the qualification with OR // any part... statements The simplest case is that in which all or part of the customer record — as identified by the customer_id — exists in the database already and when none of the information Chapter 13: Problem-Tracking System entered into the form conflicts with anything that’s in the database If that’s so, we just pick up the customer information and move along A more complicated situation exists when more than... $problem_id) ); } } // build an absolute URL calling the problem_status.php page // to check on this problem $problem_url = regular_url( ‘problem.php?problem_code=’.$problem_code 461 462 Part IV: Not So Simple Applications ); if (strpos($problem_url, ‘/staff’) !== FALSE) $problem_url = str_replace(‘/staff’, ‘’, $problem_url); // set the body of the email $msgtext = . live, PHP and MySQL can do nothing to make your girl/ boyfriend love you more or make your dealings with your parents or in-laws any easier. But no scripting language or relational database is. complies with database limitations. You might want to endow your forms with some client-side scripting that checks values for obvious problems before sending them in. Designing the Database As. open. The staff page would look something like the one in Figure 13-3. 442 Part IV: Not So Simple Applications Figure 13-2: Problem update form Figure 13-3: Staff page Chapter 13: Problem-Tracking

Ngày đăng: 12/08/2014, 21:20

Từ khóa liên quan

Mục lục

  • Part IV Not So Simple Applications

    • 13 Problem-Tracking System

      • Determining the Scope and Goals of the Application

        • What do you need?

        • What do you need to prevent?

        • Designing the Database

        • Code Overview

        • Code Breakdown

          • Reusable functions from / book/ tracking/functions. php

          • Scripts

          • Summary

          • 14 Shopping Cart

            • Determining the Scope and Goals of the Application

              • What do you need?

              • What do you need to prevent?

              • The Data

              • Configuration Overview

                • Configuring for encryption and security

                • Configuring Apache for credit- card authorization

                • Configuring for session handling

                • Code Overview

                  • Session functions

                  • Dealing with the credit- card processor

                  • Code Breakdown

                    • Classes

                    • Scripts

                    • Summary

                    • 15 XML Parsing

                      • Scope and Goals of Application

                      • Code Overview

                        • An introduction to parsers

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan