<<

. 78
( 132 .)



>>

if ($email)
{
// we have a valid email address - use it to
// notify the customer that the call record
// has been updated.
Chapter 13: Problem-Tracking System 461

notify_customer($problem_id,$email,$notes,$problem_code);
}
}
return TRUE;
}

notify_customer()
This function constructs an email and sends it. The email informs the user that his
or her problem is being tracked and provides a link to the page that gives the status
of the problem in the system.

function notify_customer (
$problem_id=NULL
, $email=NULL
, $notes=NULL
, $problem_code=NULL
)
{
// remove any HTML tags from $notes.
$notes = cleanup_text($notes);

$dbh = db_connect();

if (!$problem_code)
{
$problem_code = $dbh->getOne(
˜select problem_code from problems where problem_id = ?™
, array($problem_id)
);
if (!$problem_code)
{
$problem_code = create_problem_code();
$dbh->query(
˜update problems set problem_code = ? where
problem_id = ?™
, array($problem_code, $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
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 = <<<EOQ

Problem Update:

$notes

You can check the current status of this problem at

$problem_url

Thanks for your patience.

EOQ;

// set the headers of the email
// the Apache variable $_SERVER[˜SERVER_NAME™] is the name
// of the server we™re running on, minus any port number.

$headers = ˜From: webmaster@™.$_SERVER[˜SERVER_NAME™].”\n”
. ˜Reply-To: webmaster@™.$_SERVER[˜SERVER_NAME™].”\n”
. ˜X-Mailer: PHP/™.phpversion()
. ˜Bcc: webmaster@™.$_SERVER[˜SERVER_NAME™].”\n”
;

// send the email
return mail($email, ˜Problem Update™, $msgtext, $headers);
}



PHP will have to be able to find sendmail or another SMTP-compliant mail
server in order for this to work. Check your php.ini file if you™re having
problems.



status_change()
The status of a problem is going to be something like “open,” “closed,” or “pending.”
If it changes you are going to want to mark the exact change and record something
like “Status changed to closed by John.” The change should be recorded in the his-
tory table.
Chapter 13: Problem-Tracking System 463

function status_change($problem_id=NULL
, $entered_by=™customer™
, $new_status_id=NULL
, $old_status_id=NULL
)
{
$error = NULL;
if (empty($problem_id))
{
$error = ˜No problem ID supplied for status change™;
}
elseif (empty($new_status_id))
{
$error = ˜No new status ID supplied for status change™;
}
elseif (!($new_status = status($new_status_id)))
{
$error = “New status ID $new_status_id is not valid.”;
}

if ($error)
{
user_error($error, E_USER_WARNING);
return FALSE;
}

// just return if no change - not an error condition,
// just a no-op
if ($old_status_id == $new_status_id)
{
return TRUE;
}



if (empty($entered_by)) { $entered_by = ˜customer™; }

// get the ID of the entry_type ˜public™, and construct
// a string containing the new status value and either
// the real name of the staff member who made the change,
// or the value of $entered_by if no matching staff
// member is found. for example, if the staff member Joe Blow
// closes a call, the notes field will be set to
// ˜Status set to Closed by Joe Blow™. if a customer
// re-opens a call, notes will be set to
464 Part IV: Not So Simple Applications

// ˜Status set to Re-opened by customer™.

$entry_type_id = entry_type_id(˜public™);
$notes = “Status set to $new_status by “;
if ($entered_by != ˜customer™ && isset($GLOBALS[˜staff_name™]))
{
$notes .= $_GLOBALS[˜staff_name™];
}
else
{
$notes .= $entered_by;
}

history_entry($problem_id, $entry_type_id, $entered_by,
˜program™, $notes);
}

create_problem_code()
This function creates a unique and highly random 8-character alphanumeric code.

function create_problem_code()
{
return substr(md5(uniqid(rand())),0,8);
}


Scripts
Here are the pages that are actually called by URLs and include statements.

problem.php
This page does little but call either the enter_problem() or update_problem()
function.

require_once(˜header.php™);

$params = $_REQUEST;
$params[˜entered_by™] = ˜customer™;
$params[˜source™] = ˜web™;



if (empty($params[˜problem_code™]))
{
enter_problem($params);
}
Chapter 13: Problem-Tracking System 465

else
{
update_problem($params);
}

problem_entry_form.php
Mostly this form makes calls to the functions in your /book/functions/ folder. It
prints the form shown in Figure 13-1 and determines the default information in the
form. The call_entry.php page will include this page.
The interesting part of this script is its use of a template class to define the
appearance of the generated HTML document. The variable $tpl is defined as a
template_object():

$tpl = template_object();

It is then loaded with an HTML template (problem_entry.html) that includes sev-
eral named variables in its code.
These named variables come in handy when it™s time to enter dynamic informa-
tion into the HTML document. The general procedure for writing to a named block
is this:

$tpl->setCurrentBlock(block_name™);
$tpl->setVariable(˜template_variable_name™,$local_variable_name);
$tpl->parseCurrentBlock();

This strategy enables you to enter programmatically determined values ” typi-
cally from database lookups ” into templates, and to have the templates apply stan-
dardized formatting. It insulates you from formatting issues, which can be no end
of trouble. Here is the complete listing:

function problem_entry_form(&$params)
{
global $default_page_title;



$tpl = template_object();



if ($tpl->loadTemplatefile(˜problem_entry.html™) === FALSE)
{
user_error(
˜Could not load problem entry template™
, E_USER_ERROR
);
466 Part IV: Not So Simple Applications

}

if (!empty($params[˜error_messages™]))
{
foreach ((array)$params[˜error_messages™] as $error_message)
{
$tpl->setCurrentBlock(˜error_messages™);
$tpl->setVariable(˜error_message™,$error_message);
$tpl->parseCurrentBlock();
}
}

if (!empty($params[˜dup_results™]))
{
foreach ((array)$params[˜dup_results™] as $result)
{
$tpl->setCurrentBlock(˜dup_row™);
foreach ($result as $f => $v)
$tpl->setVariable(“dup_{$f}”, $v);
$tpl->parseCurrentblock();
}
}



$tpl->setCurrentBlock(˜problem_entry_form™);
$tpl->setVariable($params);

<<

. 78
( 132 .)



>>