TechSupport/Ch 21 project.doc
1
Projects.doc
Project 21-1:
Add user authentication
For this project, you will use a secure connection and require all users to log in including customers, technicians, and administrators. (Required reading: chapters 1-6, 10, and 21)
The Home page
Operation
· If you’ve been using the starting Home page for these projects, you’ll have to replace it with a Home page like the one above.
· When the user clicks one of the links on the main menu, the application displays a login form that’s appropriate for the type of user.
The Admin Login page
Operation
· When the user enters a valid username and password, the Admin Menu page is displayed. Otherwise, the Admin Login page is displayed again.
· To log in, you can use “admin” as the username and “sesame” as the password.
The Admin Menu page
Operation
· To navigate to an application, the user can click on the appropriate link.
· The page displays a message that indicates the login status.
· To log out, the user can click on the Logout button. This displays the Main Menu page.
Specifications
· All pages should include a link to the Home page in the header for the page.
· Except for the Home page, all pages should use a secure (https) connection.
· No pages should allow an unauthorized user to access them. For example, only a user that’s logged in as an administrator should be able to access the Admin Menu page.
The Technician Login page
Operation
· When the user enters a valid technician email and password, the Select Incident page is displayed. Otherwise, the Technician Login page is displayed again.
The Select Incident page
Operation
· Same as project 20-3, but the bottom of the page displays a message about the technician that’s logged in and provides a Logout button that the technician can use to log out.
· If there are open incidents for the current technician, this page displays a table of incidents as shown in project 20-3.
· If there are no open incidents for the current technician, this page displays a message and a link as shown above. However, this link only displays new incidents if new incidents have been assigned to the technician.
The Customer Login page
Operation
· When the user enters a valid customer email and password, the Register Product page is displayed. Otherwise, the Customer Login page is displayed again.
The Register Product page
Operation
· Same as project 6-4, but the bottom of the page displays a message about the customer that’s logged in and provides a Logout button that the customer can use to log out.
TechSupport/ch21_tech_support/admin/admin_login.php
<?php include '../view/header.php'; ?>
<div id="main">
<h1>Admin Login</h1>
<form action="" method="post" id="aligned">
<input type="hidden" name="action" value="login" />
<label>Username:</label>
<input type="text" name="username" size="30" />
<br />
<label>Password:</label>
<input type="pa ...
1. TechSupport/Ch 21 project.doc
1
Projects.doc
Project 21-1:
Add user authentication
For this project, you will use a secure connection and require all
users to log in including customers, technicians, and
administrators. (Required reading: chapters 1-6, 10, and 21)
The Home page
Operation
· If you’ve been using the starting Home page for these
projects, you’ll have to replace it with a Home page like the one
above.
· When the user clicks one of the links on the main menu, the
application displays a login form that’s appropriate for the type
of user.
The Admin Login page
Operation
· When the user enters a valid username and password, the
Admin Menu page is displayed. Otherwise, the Admin Login
page is displayed again.
· To log in, you can use “admin” as the username and “sesame”
2. as the password.
The Admin Menu page
Operation
· To navigate to an application, the user can click on the
appropriate link.
· The page displays a message that indicates the login status.
· To log out, the user can click on the Logout button. This
displays the Main Menu page.
Specifications
· All pages should include a link to the Home page in the header
for the page.
· Except for the Home page, all pages should use a secure
(https) connection.
· No pages should allow an unauthorized user to access them.
For example, only a user that’s logged in as an administrator
should be able to access the Admin Menu page.
The Technician Login page
Operation
· When the user enters a valid technician email and password,
the Select Incident page is displayed. Otherwise, the Technician
Login page is displayed again.
3. The Select Incident page
Operation
· Same as project 20-3, but the bottom of the page displays a
message about the technician that’s logged in and provides a
Logout button that the technician can use to log out.
· If there are open incidents for the current technician, this page
displays a table of incidents as shown in project 20-3.
· If there are no open incidents for the current technician, this
page displays a message and a link as shown above. However,
this link only displays new incidents if new incidents have been
assigned to the technician.
The Customer Login page
Operation
· When the user enters a valid customer email and password, the
Register Product page is displayed. Otherwise, the Customer
Login page is displayed again.
The Register Product page
Operation
· Same as project 6-4, but the bottom of the page displays a
message about the customer that’s logged in and provides a
Logout button that the customer can use to log out.
18. break;
case 'display_customers':
$last_name = $_POST['last_name'];
if (empty($last_name)) {
$message = 'You must enter a last name.';
} else {
$customers =
get_customers_by_last_name($last_name);
}
include('customer_search.php');
break;
case 'display_customer':
$customer_id = $_POST['customer_id'];
$customer = get_customer($customer_id);
// Get data from $customer array
$customer_id = $customer['customerID'];
$first_name = $customer['firstName'];
19. $last_name = $customer['lastName'];
$address = $customer['address'];
$city = $customer['city'];
$state = $customer['state'];
$postal_code = $customer['postalCode'];
$country_code = $customer['countryCode'];
$phone = $customer['phone'];
$email = $customer['email'];
$password = $customer['password'];
// Get countries
$countries = get_countries();
// Set action and button text for form
$action = 'update_customer';
$button_text = 'Update Customer';
include('customer_display.php');
20. break;
case 'display_add':
$password = ''; // don't display db connect password
$country_code = 'US'; // set default country code
$countries = get_countries();
$action = 'add_customer';
$button_text = 'Add Customer';
include('customer_display.php');
break;
case 'add_customer':
// Get data from POST request
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$address = $_POST['address'];
$city = $_POST['city'];
$state = $_POST['state'];
25. <?php include '../view/header.php'; ?>
<div id="main">
<h1 class="top">Database Error</h1>
<p>An error occurred while attempting to work with the
database.</p>
<p>Message: <?php echo $error_message; ?></p>
</div>
<?php include '../view/footer.php'; ?>
TechSupport/ch21_tech_support/errors/db_error_connect.php
<?php include '../view/header.php'; ?>
<div id="main">
<h1 class="top">Database Error</h1>
<p>There was an error connecting to the database.</p>
<p>The database must be installed as described in appendix
A.</p>
<p>The database must be running as described in chapter
1.</p>
<p>Error message: <?php echo $error_message; ?></p>
<p> </p>
</div><!-- end main -->
26. <?php include '../view/footer.php'; ?>
TechSupport/ch21_tech_support/errors/error.php
<?php include '../view/header.php'; ?>
<div id="main">
<h1 class="top">Error</h1>
<p><?php echo $error; ?></p>
</div>
<?php include '../view/footer.php'; ?>
TechSupport/ch21_tech_support/incident_assign/incident_assig
n.php
<?php
require_once('../util/secure_conn.php');
require_once('../util/valid_admin.php');
?>
<?php include '../view/header.php'; ?>
<div id="main">
<div id="content">
<h2>Assign Incident</h2>
<?php if (isset($message)) : ?>
31. require('../model/incident_db.php');
session_start();
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else if (isset($_GET['action'])) {
$action = $_GET['action'];
} else {
$action = 'display_incident_select';
}
switch ($action) {
case 'display_incident_select':
$incidents = get_incidents_unassigned();
include('incident_select.php');
break;
case 'select_incident':
32. // Set incident in session
$incident_id = $_POST['incident_id'];
$_SESSION['incident_id'] = $incident_id;
$technicians = get_technicians_with_count();
include('technician_select.php');
break;
case 'select_technician':
// Set technician ID in session
$technician_id = $_POST['technician_id'];
$_SESSION['technician_id'] = $technician_id;
// Get incident ID from session
$incident_id = $_SESSION['incident_id'];
// Get data
$technician = get_technician($technician_id);
$incident = get_incident($incident_id);
33. $customer = get_customer($incident['customerID']);
include('incident_assign.php');
break;
case 'assign_incident':
$count = assign_incident($_SESSION['incident_id'],
$_SESSION['technician_id']);
if ($count == 1) {
$message = "This incident was assigned to a
technician.";
} else {
$message = "An error occurred while attempting to
update the database.";
}
include('incident_assign.php');
break;
}
?>
TechSupport/ch21_tech_support/incident_assign/technician_sele
ct.php
<?php
56. </form>
<p>You are logged in as <?php echo
$_SESSION['technician']['email']; ?></p>
<form action="" method="post">
<input type="hidden" name="action" value="logout"
/>
<input type="submit" value="Logout" />
</form>
<?php endif; ?>
</div>
</div>
<?php include '../view/footer.php'; ?>
TechSupport/ch21_tech_support/incident_update/index.php
<?php
require('../model/database.php');
require('../model/customer_db.php');
require('../model/technician_db.php');
require('../model/incident_db.php');
57. session_start();
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else if (isset($_GET['action'])) {
$action = $_GET['action'];
} else if (isset($_SESSION['technician'])) { // Skip login if
technician is in the session
$action = 'display_incident_select';
} else {
$action = 'display_login';
}
switch ($action) {
case 'display_login':
include('technician_login.php');
break;
case 'display_incident_select':
58. // If technician is not in the session, set it in the session
if (!isset($_SESSION['technician'])) {
$email = $_POST['email'];
$password = $_POST['password'];
if (is_valid_technician_login($email, $password)) {
$technician = get_technician_by_email($email);
$_SESSION['technician'] = $technician;
}
}
$technician = $_SESSION['technician'];
$incidents =
get_incidents_by_technician($technician['techID']);
if (count($incidents) == 0) {
$message = 'There are no open incidents for this
technician.';
}
include('incident_select.php');
break;
case 'select_incident':
59. // Set incident in session
$incident_id = $_POST['incident_id'];
$_SESSION['incident_id'] = $incident_id;
$incident = get_incident($incident_id);
include('incident_update.php');
break;
case 'update_incident':
$date_closed = $_POST['date_closed'];
$description = $_POST['description'];
$incident_id = $_SESSION['incident_id'];
// convert date to correct format
$ts = strtotime($date_closed);
$date_closed = date('Y-m-d', $ts);
$count = update_incident($incident_id, $date_closed,
60. $description);
if ($count == 1) {
$message = "This incident was updated.";
} else {
$message = "An error occurred while attempting to
update the database.";
}
include('incident_update.php');
break;
case 'logout':
unset($_SESSION['technician']);
include('technician_login.php');
break;
}
?>
TechSupport/ch21_tech_support/incident_update/technician_log
in.php
<?php
require_once('../util/secure_conn.php');
?>
61. <?php include '../view/header.php'; ?>
<div id="main">
<h2>Technician Login</h2>
<p>You must login before you can update an incident.</p>
<div id="content">
<!-- display a search form -->
<form action="" method="post" id="aligned">
<input type="hidden" name="action"
value="display_incident_select" />
<label>Email:</label>
<input type="input" name="email" value="<?php echo
$technician['email']; ?>" />
<br />
<label>Password:</label>
<input type="password" name="password"
value="<?php echo $technician['password']; ?>" />
79. private static $options = array(PDO::ATTR_ERRMODE =>
PDO::ERRMODE_EXCEPTION);
private static $db;
private function __construct() {}
public static function getDB () {
if (!isset(self::$db)) {
try {
self::$db = new PDO(self::$dsn,
self::$username,
self::$password,
self::$options);
} catch (PDOException $e) {
$error_message = $e->getMessage();
include('../errors/database_error.php');
exit();
}
80. }
return self::$db;
}
}
?>
TechSupport/ch21_tech_support/model/fields.php
<?php
class Field {
private $name;
private $message = '';
private $hasError = false;
public function __construct($name, $message = '') {
$this->name = $name;
$this->message = $message;
}
public function getName() { return $this->name; }
public function getMessage() { return $this->message; }
public function hasError() { return $this->hasError; }
public function setErrorMessage($message) {
$this->message = $message;
$this->hasError = true;
}
public function clearErrorMessage() {
$this->message = '';
$this->hasError = false;
}
public function getHTML() {
$message = htmlspecialchars($this->message);
81. if ($this->hasError()) {
return '<span class="error">' . $message . '</span>';
} else {
return '<span>' . $message . '</span>';
}
}
}
class Fields {
private $fields = array();
public function addField($name, $message = '') {
$field = new Field($name, $message);
$this->fields[$field->getName()] = $field;
}
public function getField($name) {
return $this->fields[$name];
}
public function hasErrors() {
foreach ($this->fields as $field) {
if ($field->hasError()) return true;
}
return false;
}
}
?>
TechSupport/ch21_tech_support/model/incident_db.php
<?php
function get_incidents() {
global $db;
$query = 'SELECT c.firstName, c.lastName, i.*
FROM incidents i
INNER JOIN customers c ON c.customerID =
82. i.customerID';
try {
$statement = $db->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function get_incidents_unassigned() {
global $db;
$query = 'SELECT c.firstName, c.lastName,
p.name AS productName,
i.*
FROM incidents i
INNER JOIN customers c ON c.customerID =
i.customerID
INNER JOIN products p ON p.productCode =
i.productCode
WHERE techID IS NULL';
try {
$statement = $db->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function get_incidents_assigned() {
global $db;
83. $query = 'SELECT c.firstName AS customerFirstName,
c.lastName AS customerLastName,
t.firstName AS techFirstName, t.lastName AS
techLastName,
p.name AS productName,
i.*
FROM incidents i
INNER JOIN customers c ON c.customerID =
i.customerID
INNER JOIN products p ON p.productCode =
i.productCode
INNER JOIN technicians t ON t.techID = i.techID';
try {
$statement = $db->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function get_incidents_by_technician($id) {
global $db;
$query = 'SELECT c.firstName, c.lastName, i.*
FROM incidents i
INNER JOIN customers c ON c.customerID =
i.customerID
WHERE techID = :id AND dateClosed IS NULL';
try {
$statement = $db->prepare($query);
$statement->bindValue(':id', $id);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
84. return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function get_incident($id) {
global $db;
$query = 'SELECT *
FROM incidents
WHERE incidentID = :id';
try {
$statement = $db->prepare($query);
$statement->bindValue(':id', $id);
$statement->execute();
$result = $statement->fetch();
$statement->closeCursor();
return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function add_incident($customer_id, $product_code, $title,
$description) {
global $db;
$date_opened = date('Y-m-d'); // get current date in yyyy-
mm-dd format
$query =
'INSERT INTO incidents
(customerID, productCode, dateOpened, title,
description)
VALUES (
:customer_id, :product_code, :date_opened,
:title, :description)';
try {
85. $statement = $db->prepare($query);
$statement->bindValue(':customer_id', $customer_id);
$statement->bindValue(':product_code', $product_code);
$statement->bindValue(':date_opened', $date_opened);
$statement->bindValue(':title', $title);
$statement->bindValue(':description', $description);
$statement->execute();
$statement->closeCursor();
// Get the last product ID that was automatically generated
$id = $db->lastInsertId();
return $id;
} catch (PDOException $e) {
$error_message = $e->getMessage();
display_db_error($error_message);
}
}
function assign_incident($incident_id, $technician_id) {
global $db;
$query =
'UPDATE incidents
SET techID = :technician_id
WHERE incidentID = :incident_id';
try {
$statement = $db->prepare($query);
$statement->bindValue(':incident_id', $incident_id);
$statement->bindValue(':technician_id', $technician_id);
$row_count = $statement->execute();
$statement->closeCursor();
return $row_count;
} catch (PDOException $e) {
$error_message = $e->getMessage();
display_db_error($error_message);
}
}
86. function update_incident($incident_id, $date_closed,
$description) {
global $db;
$query =
'UPDATE incidents
SET dateClosed = :date_closed,
description = :description
WHERE incidentID = :incident_id';
try {
$statement = $db->prepare($query);
$statement->bindValue(':date_closed', $date_closed);
$statement->bindValue(':description', $description);
$statement->bindValue(':incident_id', $incident_id);
$row_count = $statement->execute();
$statement->closeCursor();
return $row_count;
} catch (PDOException $e) {
$error_message = $e->getMessage();
display_db_error($error_message);
}
}
?>
TechSupport/ch21_tech_support/model/product_db.php
<?php
function get_products() {
global $db;
$query = 'SELECT * FROM products
ORDER BY name';
try {
$statement = $db->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
87. return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function get_products_by_customer($email) {
global $db;
$query = 'SELECT products.productCode, products.name
FROM products
INNER JOIN registrations ON products.productCode
= registrations.productCode
INNER JOIN customers ON registrations.customerID
= customers.customerID
WHERE customers.email = :email';
try {
$statement = $db->prepare($query);
$statement->bindValue(':email', $email);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function get_product($product_code) {
global $db;
$query = 'SELECT * FROM products
WHERE productCode = :product_code';
try {
$statement = $db->prepare($query);
$statement->bindValue(':product_code', $product_code);
$statement->execute();
89. $statement->execute();
$statement->closeCursor();
// Get the last product ID that was automatically generated
$id = $db->lastInsertId();
return $id;
} catch (PDOException $e) {
$error_message = $e->getMessage();
display_db_error($error_message);
}
}
function update_product($code, $name, $version, $release_date)
{
global $db;
$query = 'UPDATE products
SET name = :name,
version = :version,
releaseDate = :release_date
WHERE productCode = :product_code';
try {
$statement = $db->prepare($query);
$statement->bindValue(':code', $code);
$statement->bindValue(':name', $name);
$statement->bindValue(':version', $version);
$statement->bindValue(':release_date', $release_date);
$row_count = $statement->execute();
$statement->closeCursor();
return $row_count;
} catch (PDOException $e) {
$error_message = $e->getMessage();
display_db_error($error_message);
}
}
?>
90. TechSupport/ch21_tech_support/model/registration_db.php
<?php
function add_registration($customer_id, $product_code) {
global $db;
$date = date('Y-m-d'); // get current date in yyyy-mm-dd
format
$query = 'INSERT INTO registrations VALUES
(:customer_id, :product_code, :date)';
try {
$statement = $db->prepare($query);
$statement->bindValue(':customer_id', $customer_id);
$statement->bindValue(':product_code', $product_code);
$statement->bindValue(':date', $date);
$statement->execute();
$statement->closeCursor();
// Get the last product ID that was automatically generated
$id = $db->lastInsertId();
return $id;
} catch (PDOException $e) {
$error_message = $e->getMessage();
display_db_error($error_message);
}
}
?>
TechSupport/ch21_tech_support/model/technician.php
<?php
class Technician {
private $id, $first_name, $last_name, $email, $phone,
$password;
public function __construct($first_name, $last_name, $email,
$phone, $password) {
$this->first_name = $first_name;
91. $this->last_name = $last_name;
$this->email = $email;
$this->phone = $phone;
$this->password = $password;
}
public function getID() {
return $this->id;
}
public function setID($value) {
$this->id = $value;
}
public function getFirstName() {
return $this->first_name;
}
public function setFirstName($value) {
$this->first_name = $value;
}
public function getLastName() {
return $this->last_name;
}
public function setLastName($value) {
$this->last_name = $value;
}
public function getFullName() {
return $this->first_name . ' ' . $this->last_name;
}
public function getEmail() {
return $this->email;
92. }
public function setEmail($value) {
$this->email = $value;
}
public function getPhone() {
return $this->phone;
}
public function setPhone($value) {
$this->phone = $value;
}
public function getPassword() {
return $this->password;
}
public function setPassword($value) {
$this->password = $value;
}
}
?>
TechSupport/ch21_tech_support/model/technician_db.php
<?php
function is_valid_technician_login($email, $password) {
global $db;
$query = '
SELECT * FROM technicians
WHERE email = :email AND password = :password';
$statement = $db->prepare($query);
$statement->bindValue(':email', $email);
$statement->bindValue(':password', $password);
$statement->execute();
if ($statement->rowCount() == 1) {
93. $valid = true;
} else {
$valid = false;
}
$statement->closeCursor();
return $valid;
}
function get_technicians() {
global $db;
$query = 'SELECT * FROM technicians
ORDER BY lastName';
try {
$statement = $db->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
return $result;
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
}
function get_technicians_with_count() {
global $db;
$query = 'SELECT *,
(SELECT COUNT(*) FROM incidents
WHERE incidents.techID = technicians.techID) AS
openIncidentCount
FROM technicians
ORDER BY openIncidentCount';
try {
$statement = $db->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$statement->closeCursor();
97. TechSupport/ch21_tech_support/model/technician_db_oo.php
<?php
class TechnicianDB {
public static function getTechnicians() {
$db = Database::getDB();
$query = 'SELECT * FROM technicians
ORDER BY lastName';
// get an array of rows
try {
$statement = $db->prepare($query);
$statement->execute();
$rows = $statement->fetchAll();
$statement->closeCursor();
} catch (PDOException $e) {
display_db_error($e->getMessage());
}
// convert the array of rows to an array of Technician
objects
$technicians = array();
foreach($rows as $row) {
$t = new Technician(
$row['firstName'], $row['lastName'],
$row['email'], $row['phone'], $row['password']);
$t->setID($row['techID']);
$technicians[] = $t;
}
return $technicians;
}
public static function deleteTechnician($technician_id) {
$db = Database::getDB();
$query = 'DELETE FROM technicians
99. // Get the last product ID that was automatically
generated
$id = $db->lastInsertId();
return $id;
} catch (PDOException $e) {
$error_message = $e->getMessage();
display_db_error($error_message);
}
}
}
?>
TechSupport/ch21_tech_support/model/validate.php
<?php
class Validate {
private $fields;
public function __construct() {
$this->fields = new Fields();
}
public function getFields() {
return $this->fields;
}
// Validate a generic text field
public function text($name, $value,
$required = true, $min = 1, $max = 255) {
// Get Field object
$field = $this->fields->getField($name);
// If field is not required and empty, remove errors and
exit
if (!$required && empty($value)) {
100. $field->clearErrorMessage();
return;
}
// Check field and set or clear error message
if ($required && empty($value)) {
$field->setErrorMessage('Required.');
} else if (strlen($value) < $min) {
$field->setErrorMessage('Too short.');
} else if (strlen($value) > $max) {
$field->setErrorMessage('Too long.');
} else {
$field->clearErrorMessage();
}
}
// Validate a field with a generic pattern
public function pattern($name, $value, $pattern, $message,
$required = true) {
// Get Field object
$field = $this->fields->getField($name);
// If field is not required and empty, remove errors and
exit
if (!$required && empty($value)) {
$field->clearErrorMessage();
return;
}
// Check field and set or clear error message
$match = preg_match($pattern, $value);
if ($match === false) {
$field->setErrorMessage('Error testing field.');
} else if ( $match != 1 ) {
$field->setErrorMessage($message);
101. } else {
$field->clearErrorMessage();
}
}
public function phone($name, $value, $required = false) {
$field = $this->fields->getField($name);
// Call the text method and exit if it yields an error
$this->text($name, $value, $required);
if ($field->hasError()) { return; }
// Call the pattern method to validate a phone number in
the (999) 999-9999 format
$pattern = '/^([[:digit:]]{3}) [[:digit:]]{3}-
[[:digit:]]{4}$/';
$message = 'Use (999) 999-9999 format.';
$this->pattern($name, $value, $pattern, $message,
$required);
}
public function email($name, $value, $required = true) {
$field = $this->fields->getField($name);
// If field is not required and empty, remove errors and
exit
if (!$required && empty($value)) {
$field->clearErrorMessage();
return;
}
// Call the text method and exit if it yields an error
$this->text($name, $value, $required);
if ($field->hasError()) { return; }
// Split email address on @ sign and check parts
102. $parts = explode('@', $value);
if (count($parts) < 2) {
$field->setErrorMessage('At sign required.');
return;
}
if (count($parts) > 2) {
$field->setErrorMessage('Only one at sign allowed.');
return;
}
$local = $parts[0];
$domain = $parts[1];
// Check lengths of local and domain parts
if (strlen($local) > 64) {
$field->setErrorMessage('Username part too long.');
return;
}
if (strlen($domain) > 255) {
$field->setErrorMessage('Domain name part too long.');
return;
}
// Patterns for address formatted local part
$atom = '[[:alnum:]_!#$%&'*+/=?^`{|}~-]+';
$dotatom = '(.' . $atom . ')*';
$address = '(^' . $atom . $dotatom . '$)';
// Patterns for quoted text formatted local part
$char = '([^"])';
$esc = '(["])';
$text = '(' . $char . '|' . $esc . ')+';
$quoted = '(^"' . $text . '"$)';
// Combined pattern for testing local part
$localPattern = '/' . $address . '|' . $quoted . '/';
103. // Call the pattern method and exit if it yields an error
$this->pattern($name, $local, $localPattern,
'Invalid username part.');
if ($field->hasError()) { return; }
// Patterns for domain part
$hostname = '([[:alnum:]]([-
[:alnum:]]{0,62}[[:alnum:]])?)';
$hostnames = '(' . $hostname . '(.' . $hostname . ')*)';
$top = '.[[:alnum:]]{2,6}';
$domainPattern = '/^' . $hostnames . $top . '$/';
// Call the pattern method
$this->pattern($name, $domain, $domainPattern,
'Invalid domain name part.');
}
public function password($name, $password, $required =
true) {
$field = $this->fields->getField($name);
if (!$required && empty($value)) {
$field->clearErrorMessage();
return;
}
// Must be at least 6 characters
$this->text($name, $password, $required, 6, 20);
if ($field->hasError()) { return; }
}
}
?>
TechSupport/ch21_tech_support/nbproject/private/config.proper
ties
115. // Start session
session_start();
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else if (isset($_GET['action'])) {
$action = $_GET['action'];
} else if (isset($_SESSION['customer'])) { // Skip login if
customer is in the session
$action = 'display_register';
} else {
$action = 'display_login';
}
switch ($action) {
case 'display_login':
include('customer_login.php');
break;
116. case 'display_register':
// If customer is not in the session, set it in the session
if (!isset($_SESSION['customer'])) {
$email = $_POST['email'];
$password = $_POST['password'];
if (is_valid_customer_login($email, $password)) {
$customer = get_customer_by_email($email);
$_SESSION['customer'] = $customer;
}
}
$customer = $_SESSION['customer'];
$products = get_products();
include('product_register.php');
break;
case 'register_product':
$customer = $_SESSION['customer'];
$product_code = $_POST['product_code'];
128. <div id="main">
<h2>Sorry, this page is currently under construction.</h2>
<p>We'll finish it as quickly as we can. Thanks!</p>
</div>
<?php include 'view/footer.php'; ?>
TechSupport/ch21_tech_support/util/secure_conn.php
<?php
// make sure the page uses a secure connection
if (!isset($_SERVER['HTTPS'])) {
$url = 'https://' . $_SERVER['HTTP_HOST'] .
$_SERVER['REQUEST_URI'];
header("Location: " . $url);
exit();
}
?>
TechSupport/ch21_tech_support/util/valid_admin.php
<?php
// make sure the user is logged in as a valid administrator
if (!isset($_SESSION['admin'])) {
header('Location: .' );
}
?>
TechSupport/ch21_tech_support/util/valid_customer.php
<?php
// make sure the user is logged in as a valid customer
if (!isset($_SESSION['customer'])) {
header('Location: .' );
}
?>
143. (1117, 'DRAFT10', '2009-05-06'),
(1117, 'TRNY10', '2007-03-04'),
(1117, 'TRNY20', '2009-08-22'),
(1118, 'DRAFT10', '2008-11-23');
CREATE TABLE incidents(
incidentID int NOT NULL AUTO_INCREMENT,
customerID int NOT NULL,
productCode varchar(10) NOT NULL,
techID int NULL,
dateOpened datetime NOT NULL,
dateClosed datetime NULL,
title varchar(50) NOT NULL,
description varchar(2000) NOT NULL,
PRIMARY KEY (incidentID)
);
INSERT INTO incidents VALUES
144. (27, 1010, 'LEAG10', 11, '2010-06-05', '2010-06-06', 'Could not
install', 'Media appears to be bad.'),
(28, 1117, 'TRNY20', 11, '2010-06-14', NULL, 'Error importing
data', 'Received error message 415 while trying to import data
from previous version.'),
(29, 1116, 'DRAFT10', 13, '2010-06-20', NULL, 'Could not
install', 'Setup failed with code 104.'),
(30, 1010, 'TEAM10', 14, '2010-06-21', '2010-06-24', 'Error
launching program', 'Program fails with error code 510, unable
to open database.'),
(31, 1010, 'TRNY20', 14, '2010-06-21', NULL, 'Unable to
activate product', 'Customer''s product activation key does not
work.'),
(32, 1056, 'TRNY20', 12, '2010-06-24', NULL, 'Product
activation error', 'Customer could not activate product because
of an invalid product activation code.'),
(34, 1018, 'DRAFT10', 13, '2010-07-02', '2010-07-04', 'Error
launching program', 'Program fails with error code 340:
Database exceeds size limit.'),
(36, 1065, 'LEAG10', NULL, '2010-07-04', NULL, 'Error adding
data', 'Received error message 201 when trying to add records:
database must be reorganized.'),
(42, 1097, 'TRNY20', NULL, '2010-07-08', NULL, 'Unable to
import data', 'Import command not available for importing data
from previous version.'),
(44, 1063, 'LEAG10', NULL, '2010-07-09', NULL, 'Installation
error', 'Error during installation: cmd.exe not found.'),
145. (45, 1089, 'LEAGD10', NULL, '2010-07-09', NULL, 'Problem
upgrading from League Scheduler 1.0', 'Program fails with error
303 when trying to install upgrade.'),
(46, 1016, 'TEAM10', NULL, '2010-07-09', NULL, 'Unable to
restore data from backup', 'Error 405 encountered while
restoring backup: File not found.'),
(47, 1034, 'DRAFT10', NULL, '2010-07-09', NULL, 'Can''t
activate product', 'Product activation code invalid.'),
(48, 1049, 'TRNY20', NULL, '2010-07-09', NULL, 'Unable to
print brackets', 'Program doesn''t recognize printer.'),
(49, 1083, 'LEAGD10', NULL, '2010-07-10', NULL, 'Can''t start
application', 'Error 521 on startup: database must be
reorganized.'),
(50, 1116, 'DRAFT10', NULL, '2010-07-10', NULL, 'Error
during data file backup', 'Program abends with error 228 during
database backup'),
(51, 1067, 'LEAGD10', NULL, '2010-07-10', NULL, 'Error when
adding new records', 'Received error 340: database exceeds size
limit.'),
(52, 1066, 'TEAM10', NULL, '2010-07-11', NULL, 'Installation
problem', 'Customer states that the setup program failed with
code 203 during configuration.');
CREATE TABLE countries (
countryCode char(2) NOT NULL,