Login

User Authentication With patUser (part 3)

In this concluding article, find out about how to use patUser
to
identify users and groups by different criteria, track a user’s clicks, maintain user statistics, and gracefully handle errors.In the previous segment of this article, I discussed the various library
functions related to user and group management, and also showed you some
examples of how they could be used in real-world Web application
development.

While the API for user and group management does form the
core of the patUser library, it’s not all there is on display. patUser also
includes a number of utility functions that can come in handy for certain
specialized tasks. These functions include identifying users and groups by
different criteria (such as name or email address); keeping track of the URLs
visited by the user so as to generate a user trail; maintaining user account
statistics for auditing purposes; and providing exception-handling routines for
more graceful error handling.

All these (and more) are discussed in the
following pages – so keep reading!{mospagebreak title=Making Exceptions} First
up, error handling. You’ll have seen, from the previous sections of this
article, that many of patUser’s functions return either true or false to
indicate success or failure; this value can then be used in your script to
display an appropriate status message.

However, patUser also goes
further, allowing you to display a more verbose message indicating the cause of
error if one occurred. A built-in error stack keeps track of all the errors that
have occurred, and the library include a number of functions designed to help
you read and modify this stack.

The two functions you’re most likely to
use are getLastErrorCode() and getLastErrorMessage(), which return the last
error code and message respectively. Consider the following example, which
demonstrates:

Since there’s a subtle error in the script above, patUser
will not be able to execute the call to addUser() successfully. An error code
will be generated internally and added to the error stack; this code can be
viewed and retrieved via the calls to getLastErrorCode() and
getLastErrorMessage(). Here’s an example of what you might see:

Obviously, this is a little more informative than the
standard “User could not be added” message.

You can also use the shortcut
getLastError() method, which returns an array containing both error code and
message. The following example, which is equivalent to the one above,
illustrates:

You can obtain a complete list of all the errors in the stack
via the getAllErrorCodes() and getAllErrorMessages() methods, which return
arrays of all the error codes and messages generated by patUser during the
execution of the script, or again use the equivalent shortcut method
getAllErrors() to get both codes and messages in one pass. A complete list of
possible error codes and what they mean is available in the patUser
documentation.{mospagebreak title=The History Channel} patUser allows you to
track user movement through your application with a set of history functions,
which maintain a buffer of all the URLs visited and provide you with hooks to
return to any of them. As you might imagine, this comes in handy if you need to
provide users with controls to go back to the previous page, or to show them
their browsing history.

The primary method to accomplish this is the
keepHistory() method, a call to which should be included on every page of your
application. The function accepts two parameters, the size of the history buffer
and the title of the current page, and stores the current URL and supplied title
in the session for easy retrieval.

Once the history buffer has been created, data from it may be
retrieved via the getHistory() method, which returns an array holding a list of
all the URLs and pages visited by the user in the current session. The following
example illustrates, using the sample data above as reference.

An additional goHistory() method makes it possible to send
the browser back to a specific page in the buffer via HTTP redirection. Consider
the following script, which accepts a number and redirects the browser back that
many pages (note that the goHistory() method must be provided with negative
values as input):

{mospagebreak title=Natural Selection} You’ve already seen,
in my examination of the getUsers() and getGroups() methods, that you can apply
selection criteria (as the second argument to those methods) to return a result
subset containing only the records you need. Here’s an example:

The code snippet above would return a list of only those
users who were female.

There are three components to the second argument
in the snippet above: the field, the value, and the selection criteria. The
first two are fairly obvious: the “field” key specifies the field against which
to match, while the “value” specifies the value against which records are to be
compared. The critical element, though, is the third key, “match”, which defines
how the comparison between the “field” and the “value” will actually be
performed.

patUser permits comparison using any of the following
conditions:

“match” => “exact” field value equals “value” when
compared in a case-sensitive manner

“match” => “greater” field value
must be greater than “value”

“match” => “lower” field value must be
lower than “value”

“match” => “greaterorequal” field value must be
greater than or equal to “value”

“match” => “lowerorequal” field value
must be lower than or equal to “value”

“match” => “contains” field
value contains “value”

“match” => “like” field value equals “value”
when compared in a case-insensitive manner

“match” => “startswith”
field value starts with “value”

“match” => “endswith” field value
starts with “value”

“match” => “between” field value is between the
“value” array (x,y)

The following snippet would return the IDs of all
users whose username contains an “e”,

{mospagebreak title=No Distinguishing Marks} That isn’t all,
though – patUser also comes with two other functions, identifyUser() and
identifyGroup(), which allow you to identify users and groups by other criteria.
Consider the following example, which demonstrates:

If no user or group can be found matching the specified
criteria, both functions will return false.{mospagebreak title=Big Brother Is Watching} patUser also allows you to record statistical information about user
logins via its very cool addStats() and updateStats() methods. There are five
different pieces of data you can store: the user’s first login, last login,
total number of logins, total number of pages visited and total time on your
site. The data thus collected is stored in the “users” table as a component of
each user record, and can be viewed using regular SQL queries.

In order
to enable this feature, you need to tell patUser which pieces of data you want
to track by calling addStats()at the top of your PHP scripts, once for each
item. Once that’s done, you can update the database with the latest statistics
at any time by calling updateStats(). The following example demonstrates:

If you’re using a single init() function to initialize your
patUser object, the calls to addStats() should probably go into that function,
so that statistics generation is enabled every time patUser starts up. And if
you’re not using patUser’s default tables, you can have the data saved to your
own custom fields, simply by specifying each field name as the second argument
in your calls to addStats().

These statistics can come in handy for
database administrators to track user logins and gauge site popularity via time
spent online and number of logins; it can also provide an audit trail for
internal usage tracking and monitoring.{mospagebreak title=Endgame} And that’s
about it for this series. Over the last few pages, I spent lots of time and
energy driving you through the landscape of the patUser library. I explained the
important utility functions in the library, discussing error handling, history
tracking, user identification and statistics generation within the context of
not-so-real-life illustrative examples.

You should now (hopefully!) know
enough about patUser to begin using it in your daily development activities. The
authors have spent a fair amount of time thinking about the most common
requirements of a user management library, and the end result of their efforts
is a class that’s both sophisticated and flexible enough to be used for a wide
variety of purposes. I strongly encourage you to exploit this power for your own
projects – I can tell you from experience that it will substantially reduce the
amount of timeyou spend bulding user management modules for your Web
applications.

In case you’d like to learn more about patUser and other,
related projects, you should consider visiting the following links: