. 91
( 132 .)


The status table contains another set of values, describing whether a project or
task is late, on schedule, on a delayed schedule, completed, or abandoned.
The descriptions of these values are “On Track,” “Slipped,” “Overdue,” “Done,”
and “Cancelled.”

In this application, a project is defined as an entity in its own right. Though pro-
jects typically contain many files, it is the files that are mapped to projects, not the
reverse. Projects are recorded in the projects table.
Project records contain seven columns:

— project_id ” An auto-incrementing integer used as the primary key

— project ” The project name

— description ” A text description

— due_dt ” The current due date of the project (possibly not the same as its
original due date)
— status_id ” The status of the project, defined by a reference to the status table

— owner_id ” The manager of the project, defined by a reference to the
users table
— first_due_dt ” The original due date of the project; by comparing this
field to due_dt, you can see whether or not the project has been delayed
Chapter 17: Project Management 543

Project-user mappings
The project_user_map table exists solely for the purpose of establishing a correla-
tion between a project record, as identified by its project_id integer and stored in
the project_id field, and a user, identified by its user_id integer and stored in the
user_id field.

Tasks are like files in that they are associated with project, and many of them can be
associated with a single project. Tasks are recorded in a table called tasks, which
contains 10 fields:

— task_id ” An auto-incremented integer that serves as the table™s
primary key
— project_id ” An integer that maps to a project_id value in the project
— task ” A varchar name for the job

— description ” A text description of the task to be done

— due_dt ” A date variable describing the originally scheduled completion
— status_id ” An integer that maps to the status_id field in the status
— public ” A Boolean value describing whether users other than the owner
can see the task
— owner_id ” An integer that maps to the user_id field of the users table to
identify the task™s owner
— first_due_dt ” A date object denoting the current scheduled completion
date for the task
— completion_comments ” A text field for notes that are made upon

Projects contain many files, and files map to projects. The project management
application keeps track of projects™ constituent files in a table called, logically
enough, files. The files table contains 11 fields that describe the files:

— file_id ” An auto-incrementing integer used as the primary key

— project_id ” An integer that maps to a value in the project_id field in
the projects table
544 Part IV: Not So Simple Applications

— task_id ” An integer that maps to the task_id field in the tasks table

— description ” A text description of the file (not necessarily including its
— public ” A Boolean value that describes whether users other than the
owner can access the file
— owner_id ” An integer that maps to the user_id field of the users table to
identify the file™s owner
— upload_dt ” A date object describing when the file was last uploaded

— first_upload_dt ” A date object describing when the file was first
— fullpath ” The path and file name of the file in the file system, relative
to the project root, recorded as text
— mimetype ” A varchar description of the file™s MIME characteristics

— file ” The contents of the file itself

Code Overview
Aside from the database, the core of the project management application™s func-
tionality is in a series of PHP pages that closely parallel the application™s essential
functions (refer back to the requirements described earlier in this chapter in the
“Necessary pages” section). The program also makes use of a series of classes that
serve as software representations of logical entities, such as database connections.
Further, it uses a library of PHP snippets to guarantee that HTML pages throughout
the application have a consistent look, and that the pages™ design can be updated

Logging in and establishing a session
Users enter the application via the login page, login.php, which goes through the
process of presenting the user with an HTML form that collects a username and
password. The application validates these against the database before forwarding the
user to index.php, the main interface page. The login page also serves the critical
function of establishing a session with the user, enabling the application to distin-
guish him or her from other users across many request/response transactions.

Showing active projects
The main interface page, generated by index.php, provides the user with his or her
main project management “dashboard.” It shows the user, at a glance, what projects
he or she owns, what the status of each is, and how each one is performing relative
Chapter 17: Project Management 545

to its deadline. The user can see what tasks are associated with each project, and
can establish a new project record in the database.

Creating a new project
If the user chooses to create a new project, he or she is prompted for all the details
the database requires in its project record. The user gets an HTML form that asks for
the project™s title and description, its due date, its present status, and its owner
(which may be someone other than the user who™s adding the project).

Uploading a file
The application allows the user to associate files with projects. The application vali-
dates the path the user specifies and stores the file the user uploads ” which the user
does via a file upload interface of the sort that™s standard to his or her operating
system ” in the files table of the database.

Viewing a file
When a version of a project file exists in the files table of the database, the applica-
tion displays it to the user. The application lists the PHP code directly into the user™s
browser, where he or she can examine or save it.

Adding a user
Administrator-class users have the ability to add and edit users. They can determine
usernames and passwords and adjust the personal information kept about each user.

Code Breakdown
How does the application do all this? The application is really quite modular and
incorporates a lot of functions and other pieces you™ll probably find useful in other
kinds of applications. The details of the code are worth a look.

Session management
The first order of business on the login page is to figure out whether the user who
has accessed the page is already in a PHP-managed session. If so, it may not be
necessary for the user to log in manually at all. The application may be able to ver-
ify his or her credentials automatically and just present the requested page.
The code for doing this appears right at the top of the login page (and in several
other locations throughout the application files, as well). It looks like this:
546 Part IV: Not So Simple Applications

if (!isset($_SESSION))
global $_SESSION;

That code looks for a variable called $_SESSION. If the variable isn™t around, it
creates a new instance of it, effectively putting the user into a new session for
tracking purposes.
The function check_session() is interesting. It™s one of a library of functions
written expressly for this book. It makes sure the user™s environment (a browser,
typically) is set to support persistent cookies, and if so, it starts a session:

function &check_session()
if (!isset($_SESSION))
trace(˜_SESSION is not set™);
if (php_sapi_name() == ˜cli™)
global $_SESSION;
$_SESSION = array();
trace(˜can not use cookies, in CLI - set _SESSION to
trace(˜ok to use cookies, call session_start()™);
trace(˜results of check_session: _SESSION=™, $_SESSION);
return $_SESSION;

If the browser does not support cookies, or the user has them turned off, then the
code reacts politely, and other operations continue without session tracking.

Now you can have a look at the way the application handles user authentication.
The file login.php handles the work of prompting the user for a username and pass-
word, using an HTML form. What™s interesting is that this form makes use of the
variables $_SERVER[˜PHP_AUTH_USER™] and $_SERVER[˜PHP_AUTH_PW™], which
are PHP values that represent the username and password entered by the user.
Chapter 17: Project Management 547

Alternately, when the credentials are stored as part of a session, they can be
referred to as $_ SESSION [˜PHP_AUTH_USER™] and $_SESSION[˜PHP_AUTH_PW™].
This capability of PHP means that it™s possible to refer to the entered values with a
little more security than might otherwise exist during the authentication transaction.
The login.php file is called by the session_auth() function (a general-purpose
authorization function found in /book/functions/basic), which makes use of the
validate_user() function:

function validate_user()

static $_defaults = array(
˜username™ => NULL
, ˜password™ => NULL
static $_simple = array(˜username™,™password™);
$args = func_get_args();
$p = parse_arguments($args, $_simple, $_defaults);

session_user()->user = $p[˜username™];
session_user()->password = $p[˜password™];
return (bool)session_user()->validate();

validate_user() calls in its last line a method of the User class object returned
by session_user() called validate(). The validate() method is where the
actual database query (the interrogation of the users table) takes place. Have a look:

function validate()

$query = ˜select u.* from users u
left join user_types ut
on u.user_type_id = ut.user_type_id
where u.user = ? and u.password = ? ˜
$bind = array($this->user, md5($this->password));
if ($this->user_type())
$query .= ˜ and ut.user_type = ? ˜;
$bind[] = $this->user_type();
$row = $this->dbh()-
if (count($row) > 0)
548 Part IV: Not So Simple Applications

return TRUE;
return FALSE;

There™s some code to deal with encryption in there (the password is passed as a
hash), but essentially that function determines whether the user credentials the user
has sent as a result of the login attempt match an entry in the users table. The
validate() function returns a Boolean value, to which the lower functions react.

Viewing projects™ status
The main part of the project management application™s user interface is contained
in the file index.php. That file concerns itself with displaying status information
and other details, including deadline information, about the projects with which the
user is associated. In doing that, the main interface page must do a lot of database
queries and a fair bit of text-formatting work. Much of this work is delegated to
other functions (many of them in other PHP files), which makes the application
more modular and easier to maintain.
In index.php you see a strategy that™s commonplace across all the display scripts
in this application (and, indeed, in most HTML-generating PHP scripts everywhere).


. 91
( 132 .)