WeberDev.com PHP and MySQL Code

LOG IN
BEGINNER GUIDES  |  PHP CLASSES  |  CODE SEARCH  |  ARTICLES SEARCH  |  PHP FORUMS  |  PHP MANUAL  |  PHP FUNCTIONS LIST  |  WEB SITE TEMPLATES
Start typing to search for PHP and MySQL Code Snippets and Articles Search
Submit a code Example / Snippet Submit Your Code
Search Engine Optimization Monitor SEO Monitor
Web Site UpTime Monitor UpTime Monitor
WeberDev's Monthly code contest PHP Code Contest
Your Personal Examples List My Favorite Examples
Your Personal Articles List My Favorite Articles
Edit Account Info Update Your Profile
PHP Code Search
Web Development Forums
Learn MySQL Playing Trivia
PHPBB2 Templates
Web Development Index
PHP Web Logs (BLogs)
Web Development Resources
Web Development Content
PHPClasses
PHP Editor
PHP Jobs
Vision.To Design
Ajax Tutorials
PHP Programming Help
PHP/MySQL Programming
Webmaster Resources
Webmaster Forum
XML meta language
website builder
Submit Site
Forex Trading Online forex trading platform

Go Back Add a Comment Send this Article to a friend Add this Article to your personal favoritest for easy future access to your favorite Code Examples and Articles. Submit a code example Print this code example.
BACK ADD A COMMENT SEND TO A FRIEND ADD TO MY FAVORITES SUBMIT AN ARTICLE PRINT
Title : User Authentication With patUser (part 2)
Categories : PHP, Authentication, Security Picture not available
Melonfire
Date : 2006-06-16
Grade : 0 of 5 (graded 0 times)
Viewed : 4672
Search : More Articles by Melonfire
Action : Grade This Article
Tools : My Favotite Articles


  Submit your own code examples 
 


Onwards and Upwards

In the first part of this article, I focused almost entirely on how patUser
could simplify the task of adding authentication to your site. I explained the
patUser database schema, ran you through the process of initializing a patUser
object instance and linking it to a database and template engine, and showed
you how built-in patUser methods could simplify the task of verifying user
credentials and writing login and logout scripts.

However, patUser can do a lot more than just handle user authentication - the
library also comes with a large number of methods designed to make the task of
managing user data as simple and efficient as possible. Over the course of
this second installment, I'm going to show you how these methods work, and how
they can be used to quickly create scripts to view, add, edit and delete users
(and user attributes) from your database. Keep reading!

Meeting The Family

Let's start with the basics - obtaining a list of current users from the
database. If you've been following along, you already know that right now, the
database has only a single user, "joe". Let's add a couple more:


INSERT INTO users ('uid', 'username', 'passwd') VALUES ('', 'sarah', 'sarah');
INSERT INTO users ('uid', 'username', 'passwd') VALUES ('', 'john', 'john');


You can verify the result with a quick SQL query to the "users" table:


mysql> SELECT uid, username FROM users;
+-----+----------+
| uid | username |
+-----+----------+
| 1 | joe |
| 2 | sarah |
| 3 | john |
+-----+----------+
3 rows in set (0.00 sec)




Now, let's try doing the same with patUser:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setAuthTable("users");

// get user list
$list = $u->getUsers(array("uid", "username"));

// uncomment this to see data structure
// print_r($list);

// print as list
echo "<h2>Users</h2>";
echo
"<ul>";
foreach (
$list as $l)
{
echo
"<li>" . $l['username'] . " (" . $l['uid'] . ")";
}
echo
"</ul>";

?>


The first part of this script should be easily recognizable to you by now - it consists of the code needed to instantiate a patUser object instance and prepare it for use. Once the object has been prepared, the getUsers() function is used to retrieve a list of all the users in the database. The return value of the getUsers() method is an associative array containing user records, one element for each record.

The first argument to the getUsers() function is an array containing the names of the fields to be included in the result set - these field names appear as keys in the returned array, and can be used to access the corresponding values. Here's the output:




You're not restricted to using just the default fields built into the patUser database schema - you can just as easily add your own. Find out how, on the next page.

Asking For More

Now, let's make some additions to the patUser-provided schema for the "users" table. You might remember that the original schema looked like this:


#
# Table structure for table 'users'
#

CREATE TABLE users (
uid int(10) unsigned NOT NULL auto_increment,
username varchar(20) NOT NULL default '',
passwd varchar(20) NOT NULL default '',
email varchar(200) default NULL,
nologin tinyint(1) NOT NULL default '0',
first_login datetime default NULL,
last_login datetime default NULL,
count_logins int(10) unsigned NOT NULL default '0',
count_pages int(10) unsigned NOT NULL default '0',
time_online int(11) NOT NULL default '0',
PRIMARY KEY (uid),
KEY username (username)
) TYPE=MyISAM;


Let's alter this to include some additional fields, for age, sex and telephone number:


CREATE TABLE users (
uid int(10) unsigned NOT NULL auto_increment,
username varchar(20) NOT NULL default '',
passwd varchar(20) NOT NULL default '',
email varchar(200) default NULL,
age tinyint(4) NOT NULL default '0',
sex char(1) NOT NULL default '',
tel varchar(50) NOT NULL default '',
nologin tinyint(1) NOT NULL default '0',
first_login datetime default NULL,
last_login datetime default NULL,
count_logins int(10) unsigned NOT NULL default '0',
count_pages int(10) unsigned NOT NULL default '0',
time_online int(11) NOT NULL default '0',
PRIMARY KEY (uid),
KEY username (username)
) TYPE=MyISAM;


While we're at it, let's also insert a few records into the new table:


INSERT INTO users (uid, username, passwd, email, age, sex, tel) VALUES (1, 'joe', 'joe', NULL, 19, 'M', '123 4567');
INSERT INTO users (uid, username, passwd, email, age, sex, tel) VALUES (2, 'sarah', 'sarah', NULL, 35, 'F', '543 18238');
INSERT INTO users (uid, username, passwd, email, age, sex, tel) VALUES (3, 'john', 'john', 'john@some.domain.com', 22, 'M', '853 2377');
INSERT INTO users (uid, username, passwd, email, age, sex, tel) VALUES (4, 'william', 'william', 'william@somewhere.com', 31, 'M', '123 2372');


As before, I can retrieve this information via an SQL query,


mysql> SELECT uid, username, age, sex, tel FROM users;
+-----+----------+-----+-----+-----------+
| uid | username | age | sex | tel |
+-----+----------+-----+-----+-----------+
| 1 | joe | 19 | M | 123 4567 |
| 2 | sarah | 35 | F | 543 18238 |
| 3 | john | 22 | M | 853 2377 |
| 4 | william | 31 | M | 123 2372 |
+-----+----------+-----+-----+-----------+
4 rows in set (0.00 sec)


or have patUser do it for me via its getUsers() function:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setAuthTable("users");

// get user list
$list = $u->getUsers(array("uid", "username", "age", "sex", "tel"));

// print as table
echo "<h2>Users</h2>";
echo
"<table border=1>";
echo
"<tr>";
echo
"<td><b>UID</b></td>";
echo
"<td><b>Username</b></td>";
echo
"<td><b>Age</b></td>";
echo
"<td><b>Sex</b></td>";
echo
"<td><b>Tel</b></td>";
echo
"</tr>";

// iterate over list
foreach ($list as $l)
{
echo
"<tr>";
echo
"<td>" . $l['uid'] . "</td>";
echo
"<td>" . $l['username'] . "</td>";
echo
"<td>" . $l['age'] . "</td>";
echo
"<td>" . $l['sex'] . "</td>";
echo
"<td>" . $l['tel'] . "</td>";
echo
"</tr>";
}

echo
"</table>";
?>


In this case, I've told getUsers() to retrieve a few extra fields from the database - specifically, the "age", "sex" and "tel" fields. You'll remember these are not standard patUser fields, but have been added by me for illustrative purposes.

Here's the output:







Drilling Deeper

You can also get fancy by adding selection criteria in your call to getUsers(), as a second argument to the method. Consider the following variant of the example above, which only returns records of those users who are male and between 18 and 25:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setAuthTable("users");

// get user list
$list = $u->getUsers(
array(
"uid", "username", "age", "sex", "tel"),
array( array(
"field" => "sex", "value" => "M", "match" => "exact"),
array(
"field" => "age", "value" => array(18,25), "match" => "between") )
);

// print as table
echo "<h2>Users</h2>";
echo
"<table border=1>";
echo
"<tr>";
echo
"<td><b>UID</b></td>";
echo
"<td><b>Username</b></td>";
echo
"<td><b>Age</b></td>";
echo
"<td><b>Sex</b></td>";
echo
"<td><b>Tel</b></td>";
echo
"</tr>";

// iterate over list
foreach ($list as $l)
{
echo
"<tr>";
echo
"<td>" . $l['uid'] . "</td>";
echo
"<td>" . $l['username'] . "</td>";
echo
"<td>" . $l['age'] . "</td>";
echo
"<td>" . $l['sex'] . "</td>";
echo
"<td>" . $l['tel'] . "</td>";
echo
"</tr>";
}

echo
"</table>";

?>


In this case, the second argument to the getUsers() method - a series of nested arrays containing selection criteria - provides patUser with a list of additional conditions to be satisfied when querying the database. Only those user records that match the specified conditions will be included in the result.

Here's the output:




All For One, And One For All

patUser also allows you to organize users into named collections or groups. You might remember, from the discussion of the patUser database schema in the previous segment of this article, that there are two tables designed specifically for this task, the "groups" table (which maintains a list of available groups) and the "usergroups" table (which maintains a list of which users belong to which group).

Here's the schema for the "groups" tables:


#
# Table structure for table 'groups'
#

CREATE TABLE groups (
gid int(11) NOT NULL auto_increment,
name varchar(50),
UNIQUE gid (gid)
);


Let's now add a couple of groups to the system,


INSERT INTO groups (gid, name) VALUES (1, 'Accounts');
INSERT INTO groups (gid, name) VALUES (2, 'Administration');
INSERT INTO groups (gid, name) VALUES (3, 'Operations');


and verify that they have been added correctly via an SQL query:


mysql> SELECT * FROM groups;
+-----+----------------+
| gid | name |
+-----+----------------+
| 1 | Accounts |
| 2 | Administration |
| 3 | Operations |
+-----+----------------+
3 rows in set (0.04 sec)


Obviously, we can perform the same task using patUser's getGroups() function, which works in much the same way as the getUsers() function discussed on the previous page. The following code listing demonstrates:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set tables
$u->setAuthTable("users");
$u->setGroupTable("groups");

// get group list
$list = $u->getGroups(array("gid", "name"));

// uncomment this to see data structure
// print_r($list);

// print as list
echo "<h2>Groups</h2>";
echo
"<ul>";
foreach (
$list as $l)
{
echo
"<li>" . $l['name'] . " (" . $l['gid'] . ")";
}
echo
"</ul>";

?>


Here's the output:




Note the introduction of a new method in the script above, setGroupTable(). This method, together with the setGroupFields()method, allows you to configure patUser to use a different set of tables than its default by remapping the default table and column references to custom values.

Accounting For Change

The default patUser-supplied database schema for the "groups" table includes only two group attributes: its name, and a unique group ID. Most of the time, this is sufficient; however, in case you need to add more attributes, patUser can be easily tweaked to work with this extra data.

Let's alter the default "groups" table to include some additional fields, for description and location:


#
# Table structure for table `groups`
#

CREATE TABLE groups (
gid int(11) NOT NULL auto_increment,
name varchar(50) default NULL,
dsc varchar(255) NOT NULL default '',
loc varchar(255) NOT NULL default '',
UNIQUE KEY gid (gid)
) TYPE=MyISAM;


While we're at it, let's also insert a few records into the new table:


INSERT INTO groups (gid, name, dsc, loc) VALUES (1, 'Accounts', 'Billing and finance activities', 'AZ');
INSERT INTO groups (gid, name, dsc, loc) VALUES (2, 'Administration', 'Administrative activities', 'CA');
INSERT INTO groups (gid, name, dsc, loc) VALUES (3, 'Operations', 'Logistics and operations', 'CA');


As before, I can retrieve this information via an SQL query,


mysql> SELECT * FROM groups;
+-----+----------------+--------------------------------+-----+
| gid | name | dsc | loc |
+-----+----------------+--------------------------------+-----+
| 1 | Accounts | Billing and finance activities | AZ |
| 2 | Administration | Administrative activities | CA |
| 3 | Operations | Logistics and operations | CA |
+-----+----------------+--------------------------------+-----+
3 rows in set (0.00 sec)


or have patUser do it for me via its getGroups() function:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set tables
$u->setAuthTable("users");
$u->setGroupTable("groups");

// get group list
$list = $u->getGroups(array("gid", "name", "dsc", "loc"));

// print as table
echo "<h2>Groups</h2>";
echo
"<table border=1>";
echo
"<tr>";
echo
"<td><b>GID</b></td>";
echo
"<td><b>Name</b></td>";
echo
"<td><b>Description</b></td>";
echo
"<td><b>Location</b></td>";
echo
"</tr>";

// iterate over list
foreach ($list as $l)
{
echo
"<tr>";
echo
"<td>" . $l['gid'] . "</td>";
echo
"<td>" . $l['name'] . "</td>";
echo
"<td>" . $l['dsc'] . "</td>";
echo
"<td>" . $l['loc'] . "</td>";
echo
"</tr>";
}

echo
"</table>";

?>


California Calling

You can also apply selection criteria in your call to getGroups(), so as to return only a specific subset of records. Consider the following variant of the example above, which only returns those groups located in California:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set tables
$u->setAuthTable("users");
$u->setGroupTable("groups");

// get group list
$list = $u->getGroups(
array(
"gid", "name", "dsc", "loc"),
array( array(
"field" => "loc", "value" => "CA", "match" => "exact") )
);

// print as table
echo "<h2>Groups</h2>";
echo
"<table border=1>";
echo
"<tr>";
echo
"<td><b>GID</b></td>";
echo
"<td><b>Name</b></td>";
echo
"<td><b>Description</b></td>";
echo
"<td><b>Location</b></td>";
echo
"</tr>";

// iterate over list
foreach ($list as $l)
{
echo
"<tr>";
echo
"<td>" . $l['gid'] . "</td>";
echo
"<td>" . $l['name'] . "</td>";
echo
"<td>" . $l['dsc'] . "</td>";
echo
"<td>" . $l['loc'] . "</td>";
echo
"</tr>";
}

echo
"</table>";

?>


Here's the output:




Making New Friends

It's just as simple to add new users and groups to the system - all you need to do is use patUser's addUser() and addGroup() methods, which accept an array of field-value pairs and uses them to create a new user or group record in the database. Both methods return the ID of the newly-created user or group if successful. Consider the following example, which demonstrates how to add new users:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setAuthTable("users");

// add user
$uid = $u->addUser( array("username" => "tom", "passwd" => "tom") );

// check to see if user added and display message
if ($uid)
{
echo
"User successfully added with UID $uid";
}
else
{
echo
"User could not be added!";
}

?>


By default, patUser automatically logs the newly-created user into the system. You can avoid this by specifying a second argument to addUser(), as in the example below:


<?php

$u
->addUser( array("username" => "tom", "passwd" => "tom"), false );

?>


In a similar manner, a new group may be added - here's how:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setGroupTable("groups");

// add group
$gid = $u->addGroup( array("name" => "Human Resources") );

// check to see if group added and display message
if ($gid)
{
echo
"Group successfully added with GID $gid";
}
else
{
echo
"Group could not be added!";
}

?>


A Fast Edit

Once a user is entered into the system, patUser allows you to add new data to the user record, or make changes to the existing data, with its modifyUser() method. This method accepts two primary arguments: an array containing the data to be inserted, and an array containing the user ID of the record to edited and related options.

Consider the following example, which illustrates the process of editing a user record and entering new information into it:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setAuthTable("users");

// modify record
$u->modifyUser( array (
"username" => "tom",
"passwd" => "tom",
"email" => "tom@some.domain.com",
"age" => 31,
"sex" => "M",
"tel" => "759 3539"
),

array (
"mode" => "update",
"uid" => 15
)
);

?>


Note that in the example above, all changes will be made to the record with user ID 15. If no user ID is provided, the currently logged-in user's ID is used instead.

You can also modify group data with the corresponding modifyGroup() method. I'll leave that to you to experiment with.

Here Today, Gone Tomorrow

Just as you can add and edit users, patUser() also comes with - obviously! - a deleteUser() method. This method accepts, as input, a user ID, and removes the corresponding user record from the database. If no user ID is provided, the currently logged-in user's ID is used instead. The following example demonstrates:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setAuthTable("users");

// delete user
$u->deleteUser( array ("uid" => 15) );

?>


Similarly, the deleteGroup() method allows you to remove a group from the group database.


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setGroupTable("groups");

// delete group
$u->deleteGroup( array("gid" => 4) );

?>


Connecting The Dots

Once you've got your users and groups created, you can begin organizing users into groups, via the addUserToGroup() and removeUserFromGroup() methods.

Given the following users and groups,


mysql> SELECT uid, username FROM users;
+-----+----------+
| uid | username |
+-----+----------+
| 2 | joe |
| 3 | sarah |
| 4 | john |
| 5 | tom |
+-----+----------+
4 rows in set (0.00 sec)

mysql> SELECT gid, name FROM groups;
+-----+-----------------+
| gid | name |
+-----+-----------------+
| 1 | Accounts |
| 2 | Administration |
| 3 | Operations |
| 4 | Human Resources |
+-----+-----------------+
4 rows in set (0.00 sec)


it's fairly easy to, say, add "joe" and "sarah" to the "Accounts" and "Operations" group,


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set table
$u->setAuthTable("users");
$u->setGroupTable("groups");
$u->setGroupRelTable("usergroups");

// add joe to Accounts
$u->addUserToGroup( array("uid" => 2, "gid" => 1) );

// add joe to Operations
$u->addUserToGroup( array("uid" => 2, "gid" => 3) );

// add sarah to Accounts
$u->addUserToGroup( array("uid" => 3, "gid" => 1) );

// add sarah to Operations
$u->addUserToGroup( array("uid" => 3, "gid" => 3) );

?>


or remove "sarah" from "Operations" and move her into "Human Reources".


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set tables
$u->setAuthTable("users");
$u->setGroupTable("groups");
$u->setGroupRelTable("usergroups");

// remove sarah from Operations
$u->removeUserFromGroup( array("uid" => 3, "gid" => 3) );

// add sarah to Human Resources
$u->addUserToGroup( array("uid" => 3, "gid" => 4) );

?>


Once you've got your users organized the way you want them, patUser also offers the following three utility functions to help you make sense of all the relationships:

getJoinedGroups() - returns a list of the groups the named user belongs to, accepts user ID as input

getUsersInGroup() - returns a list of all the users in a named group, accepts group ID and list of required user attributes as input

isMemberOfGroup() - returns a Boolean value indicating whether or not the named user belongs to the named group, accepts user ID and group ID as input

The following example illustrates how these work:


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database
$u->setAuthDbc($db);

// set tables
$u->setAuthTable("users");
$u->setGroupTable("groups");
$u->setGroupRelTable("usergroups");

// add joe to Accounts
$u->addUserToGroup( array("uid" => 2, "gid" => 1) );

// add joe to Operations
$u->addUserToGroup( array("uid" => 2, "gid" => 3) );

// add sarah to Human Resources
$u->addUserToGroup( array("uid" => 3, "gid" => 4) );

// add john to Operations
$u->addUserToGroup( array("uid" => 4, "gid" => 3) );


// which groups is joe a member of?
$foo = $u->getJoinedGroups( array("uid" => 2) );
print_r($foo);


// who belongs to the Operations group?
$foo = $u->getUsersInGroup( array("uid", "username"), array("gid" => 3) );
print_r($foo);


// does joe belong to Operations?
// returns Boolean true (1)
$foo = $u->isMemberOfGroup(2, 3);
print_r($foo);

?>


Here's the output:


Array
(
[0] => Array
(
[gid] => 1
[name] => Accounts
)

[1] => Array
(
[gid] => 3
[name] => Operations
)

)

Array
(
[0] => Array
(
[uid] => 2
[username] => joe
)

[1] => Array
(
[uid] => 4
[username] => john
)

)

1


Needless to say, these utility functions come in very handy when you need to find out which users belong to which groups, or if you need to alter the various user and group configurations. You'll see this in action in the composite example on the next page.

A Well-Formed Plan

Now, how about a couple of examples to put all this in context? This first example demonstrates how the various user and group manipulation methods discussed in this article can be used to rapidly build a user administration module for a Web application or Web site. Consider the following script, which is designed to allow administrators to add new users to the system.


<?php

// include classes
include("../include/patDbc.php");
include(
"../include/patUser.php");

// initialize database layer
$db = new patMySqlDbc("localhost", "db211", "us111", "secret");

// initialize patUser
$u = new patUser(true);

// connect patUser to database/template engines
$u->setAuthDbc($db);

// set tables
$u->setAuthTable("users");
$u->setGroupTable("groups");
$u->setGroupRelTable("usergroups");

?>

<html>
<head>
<basefont face="Arial">
</head>

<body>

<?php

// display initial form
if (!$_POST['submit'])
{
?>

<h2>New User</h2>
<form action="<?=$ME?>" method="post">

First name
<br>
<input type="text" name="fname" size="10">

<p>

Last name
<br>
<input type="text" name="lname" size="10">

<p>

Username
<br>
<input type="text" name="username" size="10">

<p>

Password
<br>
<input type="password" name="passwd" size="10">

<p>

Email address
<br>
<input type="text" name="email" size="25">

<p>

Department
<br>
<select name="gid[]" multiple>

<?php
// get group list
// display as multi-select box
$groups = $u-