Index: trunk/services/admins.php
===================================================================
--- trunk/services/admins.php	(revision 1)
+++ trunk/services/admins.php	(revision 19)
@@ -21,5 +21,5 @@
 
 /******************************************************************************
- * CODE CONFIG
+ * CONFIG
  *****************************************************************************/
  
@@ -31,18 +31,20 @@
 
 // Instantiate a sorting object with the default sort and order. Add SQL for each column.
-$so = new SortOrder('admin_id', 'DESC');
-$so->setColumn('admin_id', 'admin_id ASC', 'admin_id DESC');
-$so->setColumn('username', 'username ASC', 'username DESC');
-$so->setColumn('userpass', 'userpass ASC', 'userpass DESC');
-$so->setColumn('first_name', 'first_name ASC', 'first_name DESC');
-$so->setColumn('last_name', 'last_name ASC', 'last_name DESC');
-$so->setColumn('phone', 'phone ASC', 'phone DESC');
-$so->setColumn('email', 'email ASC', 'email DESC');
-$so->setColumn('priv', 'priv ASC', 'priv DESC');
-$so->setColumn('seconds_online', 'seconds_online ASC', 'seconds_online DESC');
-$so->setColumn('added_datetime', 'added_datetime ASC', 'added_datetime DESC');
-$so->setColumn('last_login_datetime', 'last_login_datetime ASC', 'last_login_datetime DESC');
-$so->setColumn('last_access_datetime', 'last_access_datetime ASC', 'last_access_datetime DESC');
-$so->setColumn('last_login_ip', 'last_login_ip ASC', 'last_login_ip DESC');
+$so = new SortOrder('admin_tbl.admin_id', 'DESC');
+$so->setColumn('admin_tbl.admin_id', 'admin_tbl.admin_id ASC', 'admin_tbl.admin_id DESC');
+$so->setColumn('admin_tbl.username', 'admin_tbl.username ASC', 'admin_tbl.username DESC');
+$so->setColumn('admin_tbl.userpass', 'admin_tbl.userpass ASC', 'admin_tbl.userpass DESC');
+$so->setColumn('admin_tbl.first_name', 'admin_tbl.first_name ASC', 'admin_tbl.first_name DESC');
+$so->setColumn('admin_tbl.last_name', 'admin_tbl.last_name ASC', 'admin_tbl.last_name DESC');
+$so->setColumn('admin_tbl.email', 'admin_tbl.email ASC', 'admin_tbl.email DESC');
+$so->setColumn('admin_tbl.user_type', 'admin_tbl.user_type ASC', 'admin_tbl.user_type DESC');
+$so->setColumn('admin_tbl.seconds_online', 'admin_tbl.seconds_online ASC', 'admin_tbl.seconds_online DESC');
+$so->setColumn('admin_tbl.last_login_datetime', 'admin_tbl.last_login_datetime ASC', 'admin_tbl.last_login_datetime DESC');
+$so->setColumn('admin_tbl.last_access_datetime', 'admin_tbl.last_access_datetime ASC', 'admin_tbl.last_access_datetime DESC');
+$so->setColumn('admin_tbl.last_login_ip', 'admin_tbl.last_login_ip ASC', 'admin_tbl.last_login_ip DESC');
+$so->setColumn('admin_tbl.added_by_user_id', 'admin_tbl.added_by_user_id ASC', 'admin_tbl.added_by_user_id DESC');
+$so->setColumn('admin_tbl.modified_by_user_id', 'admin_tbl.modified_by_user_id ASC', 'admin_tbl.modified_by_user_id DESC');
+$so->setColumn('admin_tbl.added_datetime', 'admin_tbl.added_datetime ASC', 'admin_tbl.added_datetime DESC');
+$so->setColumn('admin_tbl.modified_datetime', 'admin_tbl.modified_datetime ASC', 'admin_tbl.modified_datetime DESC');
 
 // Instantiate page numbers. Total items are set and calculation is done in the getRecordList function.
@@ -192,6 +194,6 @@
 
     // If the username was changed during edit, verify.
-    if (getFormData('priv') == 'root' && 'root' != $auth->getVal('priv')) {
-        $fv->addError('priv', sprintf(_("You do not have clearance to create a user with root privileges."), null));
+    if (getFormData('user_type') == 'root' && 'root' != $auth->getVal('user_type')) {
+        $fv->addError('user_type', sprintf(_("You do not have clearance to create a user with root privileges."), null));
     }
 
@@ -207,24 +209,39 @@
     
     $fv->stringLength('last_name', 0, 255, _("<strong>Last name</strong> must contain less than 256 characters."));
-    
-    $fv->stringLength('phone', 0, 255, _("<strong>Phone</strong> must contain less than 256 characters."));
-    $fv->validatePhone('phone');
-    
+
+    $fv->isEmpty('email', _("<strong>Email</strong> cannot be blank."));
     $fv->stringLength('email', 0, 255, _("<strong>Email</strong> must contain less than 256 characters."));
     $fv->validateEmail('email');
     
-    $fv->stringLength('county', 0, 255, _("<strong>County</strong> has an invalid selection."));
-    
-    $fv->stringLength('priv', 0, 255, _("<strong>Priv</strong> has an invalid selection."));
+    $fv->isEmpty('user_type', _("<strong>User type</strong> cannot be blank."));
+    $fv->stringLength('user_type', 0, 255, _("<strong>User type</strong> has an invalid selection."));
 }
 
 function &addRecordForm()
 {
-    // set default values for the reset of the fields.
-    $frm['priv'] = 'admin';
-    $frm['new_op'] = 'insert';
-    $frm['submit_caption'] = _("Add admin");
-    $frm['repeat_caption'] = _("Add &amp; repeat");
-    $frm['cancel_caption'] = _("Cancel");
+    // Set default values for the reset of the fields.
+    $frm = array(
+        'admin_id' => '',
+        'username' => '',
+        'userpass' => '',
+        'first_name' => '',
+        'last_name' => '',
+        'email' => '',
+        'user_type' => '',
+        'seconds_online' => '0',
+        'last_login_datetime' => '0000-00-00 00:00:00',
+        'last_access_datetime' => '0000-00-00 00:00:00',
+        'last_login_ip' => '0.0.0.0',
+        'added_by_user_id' => '',
+        'modified_by_user_id' => '',
+        'added_datetime' => '0000-00-00 00:00:00',
+        'modified_datetime' => '0000-00-00 00:00:00',
+        'new_op' => 'insert',
+        'submit_buttons' => array(
+            'submit' => _("Add Admin"),
+            'repeat' => _("Add &amp; repeat"),
+            'cancel' => _("Cancel"),
+        ),
+    );
 
     return $frm;
@@ -237,31 +254,49 @@
     if ($lock->isLocked() && !$lock->isMine()) {
         $lock->dieErrorPage();
-    } else {
-        // Get the information for the form.
-        $qid = DB::query("
-            SELECT * from admin_tbl
-            WHERE admin_id = '" . addslashes($id) . "'
-        ");
-        if (!$frm = mysql_fetch_assoc($qid)) {
-            App::logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
-            App::raiseMsg(sprintf(_("The requested record %s could not be found"), $id), MSG_ERR, __FILE__, __LINE__);
-            App::dieBoomerangURL();
-        }
-        
-        // Lock this record.
-        $lock->set('admin_tbl', 'admin_id', $id, $frm['address']);
-        
-        // Set misc values for the form.
-        $frm['old_username'] = $frm['username'];
-        $frm['userpass'] = '***************';
-        $frm['new_op'] = 'update';
-        $frm['submit_caption'] = _("Save changes");
-        $frm['repeat_caption'] = _("Save &amp; edit next");
-        $frm['reset_caption']  = _("Reset");
-        $frm['cancel_caption'] = _("Cancel");
-        $frm['admin_id'] = $id;
-    
-        return $frm;
-    }
+    }
+
+    // Get the information for the form.
+    $qid = DB::query("
+        SELECT * 
+        FROM admin_tbl
+        WHERE admin_id = '" . addslashes($id) . "'
+    ");
+    if (!$frm = mysql_fetch_assoc($qid)) {
+        App::logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
+        App::raiseMsg(sprintf(_("The requested record %s could not be found"), $id), MSG_ERR, __FILE__, __LINE__);
+        App::dieBoomerangURL();
+    }
+    
+    // Lock this record.
+    $lock->set('admin_tbl', 'admin_id', $id, $frm['username']);
+    
+    // Set misc values for the form.
+    $frm = array_merge(array(
+        'admin_id' => '',
+        'old_username' => $frm['username'],
+        'username' => '',
+//         'userpass' => '****************',
+        'first_name' => '',
+        'last_name' => '',
+        'email' => '',
+        'user_type' => '',
+        'seconds_online' => '0',
+        'last_login_datetime' => '0000-00-00 00:00:00',
+        'last_access_datetime' => '0000-00-00 00:00:00',
+        'last_login_ip' => '0.0.0.0',
+        'added_by_user_id' => '',
+        'modified_by_user_id' => '',
+        'added_datetime' => '0000-00-00 00:00:00',
+        'modified_datetime' => '0000-00-00 00:00:00',
+        'new_op' => 'update',
+        'submit_buttons' => array(
+            'submit' => _("Save changes"),
+            'repeat' => _("Save &amp; edit next"),
+            'reset' => _("Reset"),
+            'cancel' => _("Cancel"),
+        ),
+    ), $frm, array('userpass' => '****************'));
+
+    return $frm;
 }
 
@@ -280,8 +315,8 @@
         // Get the information for this object.
         $qid = DB::query("
-            SELECT username, priv from admin_tbl
+            SELECT username, user_type from admin_tbl
             WHERE admin_id = '" . addslashes($id) . "'
         ");
-        if (! list($name, $priv) = mysql_fetch_row($qid)) {
+        if (! list($name, $user_type) = mysql_fetch_row($qid)) {
             App::logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
             App::raiseMsg(sprintf(_("The requested record %s could not be found"), $id), MSG_ERR, __FILE__, __LINE__);
@@ -292,5 +327,5 @@
         $qid = DB::query("SELECT COUNT(*) from admin_tbl");
         list($num_admins) = mysql_fetch_row($qid);
-        if ('root' == $priv && 'root' != $auth->getVal('priv')) {
+        if ('root' == $user_type && 'root' != $auth->getVal('user_type')) {
             // Only root users can delete root users!
             App::raiseMsg(_("You do not have clearance to delete a root administrator."), MSG_NOTICE, __FILE__, __LINE__);
@@ -325,7 +360,7 @@
             first_name,
             last_name,
-            phone,
             email,
-            priv,
+            user_type,
+            added_by_user_id,
             added_datetime
         ) VALUES (
@@ -333,7 +368,7 @@
             '" . addslashes($frm['first_name']) . "',
             '" . addslashes($frm['last_name']) . "',
-            '" . addslashes($frm['phone']) . "',
             '" . addslashes($frm['email']) . "',
-            '" . addslashes($frm['priv']) . "',
+            '" . addslashes($frm['user_type']) . "',
+            '" . addslashes($auth->getVal('user_id')) . "',
             NOW()
         )
@@ -344,5 +379,9 @@
     $auth->setPassword($last_insert_id, $frm['userpass']);
     
-    App::raiseMsg(sprintf(_("The admin <strong>%s</strong> has been added."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
+    // Create version.
+    $version = new RecordVersion($GLOBALS['auth']);
+    $version->create('admin_tbl', 'admin_id', $last_insert_id, $frm['username']);
+    
+    App::raiseMsg(sprintf(_("The Admin <strong>%s</strong> has been added."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
     
     return $last_insert_id;
@@ -373,11 +412,16 @@
                 first_name = '" . addslashes($frm['first_name']) . "',
                 last_name = '" . addslashes($frm['last_name']) . "',
-                phone = '" . addslashes($frm['phone']) . "',
                 email = '" . addslashes($frm['email']) . "',
-                priv = '" . addslashes($frm['priv']) . "'
+                user_type = '" . addslashes($frm['user_type']) . "',
+                modified_by_user_id = '" . addslashes($auth->getVal('user_id')) . "',
+                modified_datetime = NOW()
             WHERE admin_id = '" . addslashes($frm['admin_id']) . "'
         ");
 
-        App::raiseMsg(sprintf(_("The admin <strong>%s</strong> has been updated."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
+        // Create version.
+        $version = new RecordVersion($GLOBALS['auth']);
+        $version->create('admin_tbl', 'admin_id', $frm['admin_id'], $frm['username']);
+    
+        App::raiseMsg(sprintf(_("The Admin <strong>%s</strong> has been updated."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
 
         // Unlock record.
@@ -391,37 +435,36 @@
     global $so;
     
-    // Build search query if $qry is not empty.
-    $sql_delim = 'WHERE';
-    $search_where_clause = '';
-    $qry = getFormData('search_query');
-    if (!empty($qry)) {
-        $qry_words = preg_split('/[^\w]/', $qry);
+    $where_clause = '';
+    
+    // Build search query if available.
+    if (getFormData('search_query', false)) {
+        $qry_words = preg_split('/[^\w]/', getFormData('search_query'));
         for ($i=0; $i<sizeof($qry_words); $i++) {
-            $search_where_clause .= "
-                $sql_delim (
-                    username LIKE '%" . addslashes($qry_words[$i]) . "%'
-                    OR first_name LIKE '%" . addslashes($qry_words[$i]) . "%'
-                    OR last_name LIKE '%" . addslashes($qry_words[$i]) . "%'
-                    OR phone LIKE '%" . addslashes($qry_words[$i]) . "%'
-                    OR email LIKE '%" . addslashes($qry_words[$i]) . "%'
-                    OR priv LIKE '%" . addslashes($qry_words[$i]) . "%'
+            $where_clause .= (empty($where_clause) ? 'WHERE' : 'AND') . "
+                (
+                    admin_tbl.username LIKE '%" . addslashes($qry_words[$i]) . "%'
+                    OR admin_tbl.first_name LIKE '%" . addslashes($qry_words[$i]) . "%'
+                    OR admin_tbl.last_name LIKE '%" . addslashes($qry_words[$i]) . "%'
+                    OR admin_tbl.email LIKE '%" . addslashes($qry_words[$i]) . "%'
                 )
             ";
-            $sql_delim = 'AND';
-        }
-    }
-    
-    $where_clause = '';
+        }
+    }
+
     if (getFormData('search_query', false)) {
         // Search query.
         $where_clause = $search_where_clause;
     }
-    if (getFormData('filter_admin_priv', false)) {
+    if (getFormData('filter_admin_user_type', false)) {
         // Limit by filter.
-        $where_clause .= (empty($where_clause) ? 'WHERE' : 'AND') . " priv = '" . addslashes(getFormData('filter_admin_priv')) . "'";
+        $where_clause .= (empty($where_clause) ? 'WHERE' : 'AND') . " user_type = '" . addslashes(getFormData('filter_admin_user_type')) . "'";
     }
 
     // Count the total number of records so we can do something about the page numbers.
-    $qid = DB::query("SELECT COUNT(*) FROM admin_tbl $where_clause");
+    $qid = DB::query("
+        SELECT COUNT(*) 
+        FROM admin_tbl 
+        $where_clause
+    ");
     list($num_results) = mysql_fetch_row($qid);
     
@@ -432,5 +475,11 @@
     // Final SQL, with sort and page limiters.
     $sql = "
-        SELECT * FROM admin_tbl
+        SELECT 
+            admin_tbl.*, 
+            a1.username AS added_admin_username,
+            a2.username AS modified_admin_username
+        FROM admin_tbl
+        LEFT JOIN admin_tbl a1 ON (admin_tbl.added_by_user_id = a1.admin_id)
+        LEFT JOIN admin_tbl a2 ON (admin_tbl.modified_by_user_id = a2.admin_id)
         $where_clause
         " . $so->getSortOrderSQL() . "
@@ -449,5 +498,5 @@
     }
     
-    if (SessionCache::isCached($_SERVER['PHP_SELF']) && FALSE) { ///
+    if (SessionCache::isCached($_SERVER['PHP_SELF']) && false) {
         // Get the cached results.
         $list = SessionCache::getCache($_SERVER['PHP_SELF']);
@@ -460,6 +509,8 @@
         }
             
-        // Cache the results.
-        SessionCache::putCache($list, $_SERVER['PHP_SELF']);
+        if (isset($list) && !empty($list)) {
+            // Cache the results.
+            SessionCache::putCache($list, $_SERVER['PHP_SELF']);
+        }
     }
 
Index: trunk/services/templates/admin_form.ihtml
===================================================================
--- trunk/services/templates/admin_form.ihtml	(revision 1)
+++ trunk/services/templates/admin_form.ihtml	(revision 19)
@@ -7,16 +7,11 @@
 <input type="hidden" name="old_username" value="<?php echo $frm['old_username']; ?>">
 
-<table border="0" cellspacing="0" cellpadding="4">
+<table>
     <tr>
-        <td class="formlabel" align="right" valign="top">&nbsp;</td>
-        <td valign="top">
-        <?php if (!empty($frm['submit_caption'])) { ?><input type="submit" class="formsubmitbutton" name="submit" value="<?php echo oTxt($frm['submit_caption']); ?>" /><?php } ?>
-        <?php if (!empty($frm['repeat_caption'])) { ?><input type="submit" class="formsubmitbutton" name="repeat" value="<?php echo oTxt($frm['repeat_caption']); ?>" /><?php } ?>
-        <?php if (!empty($frm['reset_caption'])) { ?><input type="submit" class="formsubmitbutton" name="reset" value="<?php echo oTxt($frm['reset_caption']); ?>" /><?php } ?>
-        <?php if (!empty($frm['cancel_caption'])) { ?><input type="submit" class="formsubmitbutton" name="cancel" value="<?php echo oTxt($frm['cancel_caption']); ?>" /><?php } ?>
-        </td>
+        <td>&nbsp;</td>
+        <td valign="top"><?php printSubmitButtons($frm['submit_buttons']); ?></td>
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('username', ' style="color:#f33;"') ?>><?php echo _("Username"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('username', ' class="error"') ?>><?php echo _("Username"); ?></td>
         <td valign="top">
             <input type="text" class="forminputtext" size="50" name="username" value="<?php echo oTxt($frm['username']); ?>">
@@ -24,5 +19,5 @@
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('userpass', ' style="color:#f33;"') ?>><?php echo _("Password"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('userpass', ' class="error"') ?>><?php echo _("Password"); ?></td>
         <td valign="top">
             <input type="password" class="forminputtext" size="50" name="userpass" value="<?php echo oTxt($frm['userpass']); ?>">
@@ -30,5 +25,5 @@
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('first_name', ' style="color:#f33;"') ?>><?php echo _("First name"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('first_name', ' class="error"') ?>><?php echo _("First name"); ?></td>
         <td valign="top">
             <input type="text" class="forminputtext" size="50" name="first_name" value="<?php echo oTxt($frm['first_name']); ?>">
@@ -36,5 +31,5 @@
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('last_name', ' style="color:#f33;"') ?>><?php echo _("Last name"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('last_name', ' class="error"') ?>><?php echo _("Last name"); ?></td>
         <td valign="top">
             <input type="text" class="forminputtext" size="50" name="last_name" value="<?php echo oTxt($frm['last_name']); ?>">
@@ -42,11 +37,5 @@
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('phone', ' style="color:#f33;"') ?>><?php echo _("Phone"); ?></td>
-        <td valign="top">
-            <input type="text" class="forminputtext" size="50" name="phone" value="<?php echo oTxt($frm['phone']); ?>">
-        </td>
-    </tr>
-    <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('email', ' style="color:#f33;"') ?>><?php echo _("Email"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('email', ' class="error"') ?>><?php echo _("Email"); ?></td>
         <td valign="top">
             <input type="text" class="forminputtext" size="50" name="email" value="<?php echo oTxt($frm['email']); ?>">
@@ -54,19 +43,14 @@
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('priv', ' style="color:#f33;"') ?>><?php echo _("Priv"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('user_type', ' class="error"') ?>><?php echo _("User type"); ?></td>
         <td valign="top">
-            <select name="priv">
-            <?php printSetSelectForm('admin_tbl', 'priv', $frm['priv'], true); ?>
+            <select name="user_type">
+            <?php printSetSelectForm('admin_tbl', 'user_type', $frm['user_type'], true); ?>
             </select>
         </td>
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top">&nbsp;</td>
-        <td valign="top">
-        <?php if (!empty($frm['submit_caption'])) { ?><input type="submit" class="formsubmitbutton" name="submit" value="<?php echo oTxt($frm['submit_caption']); ?>" /><?php } ?>
-        <?php if (!empty($frm['repeat_caption'])) { ?><input type="submit" class="formsubmitbutton" name="repeat" value="<?php echo oTxt($frm['repeat_caption']); ?>" /><?php } ?>
-        <?php if (!empty($frm['reset_caption'])) { ?><input type="submit" class="formsubmitbutton" name="reset" value="<?php echo oTxt($frm['reset_caption']); ?>" /><?php } ?>
-        <?php if (!empty($frm['cancel_caption'])) { ?><input type="submit" class="formsubmitbutton" name="cancel" value="<?php echo oTxt($frm['cancel_caption']); ?>" /><?php } ?>
-        </td>
+        <td>&nbsp;</td>
+        <td valign="top"><?php printSubmitButtons($frm['submit_buttons']); ?></td>
     </tr>
 </table>
Index: trunk/services/templates/admin_list.ihtml
===================================================================
--- trunk/services/templates/admin_list.ihtml	(revision 1)
+++ trunk/services/templates/admin_list.ihtml	(revision 19)
@@ -2,5 +2,5 @@
 <?php $fv->printErrorMessages(); ?>
 <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
-<?php $carry_queries = array('search_query', 'filter_admin_priv'); ?>
+<?php $carry_queries = array('search_query', 'filter_admin_user_type'); ?>
 <?php App::printHiddenSession(false); ?>
 <div id="commandbox">
@@ -8,42 +8,48 @@
     <br />
     
-    <input type="text" class="forminputtext" size="20" name="search_query" value="<?php echo getFormData('search_query'); ?>" title="<?php echo oTxt(_("Fields searched: username, first & last name, phone, email, county.")); ?>" />
-    <input type="submit" name="list" value="<?php echo _("Search"); ?>" class="formsubmitbutton" />
-    
-<!--     <select name="filter_admin_priv"> -->
-<!--     <?php printSetSelectForm('admin_tbl', 'filter_admin_priv', getFormData('filter_admin_priv'), true); ?> -->
-<!--     </select> -->
-<!--     <input type="submit" name="list" value="Filter by privilege" class="formsubmitbutton"> -->
+    <input type="text" class="forminputtext" size="20" name="search_query" value="<?php echo getFormData('search_query'); ?>" title="<?php echo oTxt(_("Fields searched: Admin id, Username, Userpass, First name, Last name, Email, User type, Login abuse exempt, Blocked, Blocked reason, Abuse warning level, Seconds online, Last login datetime, Last access datetime, Last login ip, Added by user id, Modified by user id, Added datetime, Modified datetime.")); ?>" />
+<!-- 
+    <select name="filter_<##>">
+        <?php // printSelectForm('<##>_tbl', "CONCAT(<##>_id, '&mdash;', city, '&mdash;', title)", '<##>_id', getFormData('filter_<##>'), array('Any <##>'), 'ORDER BY <##> ASC'); ?>
+    </select>
+ -->
+    <input type="submit" name="list" value="<?php echo _("Search"); ?>" />
 </div>
 
 <?php include 'list_info.ihtml'; ?>
 
-<table class="list" border="0" cellpadding="2" cellspacing="0">
+<table class="list">
     <tr>
-        <th class="padleft">&nbsp;</th>
-        <th class="padleft"><?php $so->printSortHeader('admin_id', _("ID"), 'ASC'); ?></th>
-        <th class="padleft"><?php $so->printSortHeader('username', _("Username"), 'ASC'); ?></th>
-        <th class="padleft"><?php $so->printSortHeader('first_name', _("First"), 'ASC'); ?>
-            <?php $so->printSortHeader('last_name', _("Last name"), 'ASC'); ?></th>
-        <th class="padleft"><?php $so->printSortHeader('last_access_datetime', _("Logged-in"), 'DESC'); ?></th>
-        <th class="padleft"><?php $so->printSortHeader('seconds_online', _("Total min logged-in"), 'DESC'); ?></th>
-        <th class="padleft"><?php $so->printSortHeader('last_login_ip', _("Last remote addr"), 'ASC'); ?></th>
-        <th class="padleft">&nbsp;</th>
+        <th>&nbsp;</th>
+        <th>&nbsp;</th>
+        <th><?php echo $so->printSortHeader('admin_tbl.admin_id', _("ID"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.username', _("Username"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.first_name', _("First"), 'ASC'); ?> <?php echo $so->printSortHeader('admin_tbl.last_name', _("Last name"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.email', _("Email"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.user_type', _("User type"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.seconds_online', _("Min online"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.last_login_datetime', _("Last login"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.last_login_ip', _("Remote host"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.added_datetime', _("Added"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.added_by_user_id', _("by admin"), 'ASC'); ?></th>
+        <th><?php echo $so->printSortHeader('admin_tbl.modified_datetime', _("Last modified"), 'ASC'); ?></th>
+        <th>&nbsp;</th>
     </tr>
-    <?php for ($i = 0; $i <= $page->last_item - $page->first_item && $page->total_items; $i++) { ?>
+    <?php for ($i = 0; $i <= $page->last_item - $page->first_item && $page->total_items > 0; $i++) { ?>
     <tr>
-        <td class="padleft nowrap">
-            <a title="<?php printf(_("Edit %s"), oTxt($list[$i]['username'])) ?>" href="<?php echo App::oHREF('/admin/admins.php?op=edit&admin_id=' . $list[$i]['admin_id']); ?>"><img src="/admin/_widgets/edit.gif" alt="Edit" width="14" height="18" border="0"></a>
-        </td>
-        <td class="padleft nowrap"><?php echo $list[$i]['admin_id']; ?> &nbsp;</td>
-        <td class="padleft nowrap"><?php echo oTxt($list[$i]['username']); ?> &nbsp;</td>
-        <td class="padleft nowrap"><a href="mailto:<?php echo oTxt($list[$i]['email']); ?>"><?php echo oTxt($list[$i]['first_name']); ?> 
-            <?php echo oTxt($list[$i]['last_name']); ?></a> &nbsp;</td>
-        <td class="padleft nowrap"><a href="#" style="text-decoration:none;" title="<?php printf(_("Last accessed %s"), $list[$i]['last_access_datetime']) ?>"><?php echo $auth->isLoggedIn($list[$i]['admin_id']) ? '<strong>' . _("yes") . '</strong>' : _("no"); ?></a>  &nbsp;</td>
-        <td class="padleft nowrap"><?php echo round($list[$i]['seconds_online'] / 60); ?> &nbsp;</td>
-        <td class="padleft nowrap"><?php echo gethostbyaddr($list[$i]['last_login_ip']); ?> &nbsp;</td>
-        <td class="padleft right nowrap">
-            <a title="<?php printf(_("Delete %s"), oTxt($list[$i]['username'])) ?>" href="<?php echo App::oHREF('/admin/admins.php?op=del&admin_id=' . $list[$i]['admin_id']); ?>" onClick="javascript:return confirm('<?php printf(_("Are you sure you want to delete %s? This action is permanent and cannot be undone."), oTxt($list[$i]['username'])) ?>')"><img src="/admin/_widgets/delete.gif" alt="Delete" width="16" height="17" border="0"></a>
-        </td>
+        <td class="padleft nowrap"><a title="<?php printf(_("Edit %s"), oTxt($list[$i]['username'])) ?>" href="<?php echo App::oHREF($_SERVER['PHP_SELF'] . '?op=edit&admin_id=' . $list[$i]['admin_id']); ?>"><img src="/admin/_widgets/edit.gif" alt="Edit" width="14" height="18" border="0"></a> &nbsp;</td>
+        <td class="padleft nowrap"><a title="<?php printf(_("Versions of %s"), oTxt($list[$i]['username'])) ?>" href="<?php echo App::oHREF('/admin/versions.php?record_table=admin_tbl&record_key=admin_id&boomerang=true&record_val=' . $list[$i]['admin_id']); ?>"><img src="/admin/_widgets/subcategory.gif" alt="" width="18" height="14" border="0" /></a> &nbsp;</td>
+        <td class="nowrap"><?php echo oTxt($list[$i]['admin_id'], true); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo oTxt($list[$i]['username'], true); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo oTxt($list[$i]['first_name'], true); ?> <?php echo oTxt($list[$i]['last_name'], true); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo oTxt($list[$i]['email'], true); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo oTxt($list[$i]['user_type'], true); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo round($list[$i]['seconds_online'] / 60); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo '0000-00-00 00:00:00' == $list[$i]['last_login_datetime'] ? '' : date(App::getParam('date_format'), strtotime($list[$i]['last_login_datetime'])); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo gethostbyaddr($list[$i]['last_login_ip']); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo '0000-00-00 00:00:00' == $list[$i]['added_datetime'] ? '' : date(App::getParam('date_format'), strtotime($list[$i]['added_datetime'])); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo oTxt($list[$i]['added_admin_username'], true); ?> &nbsp;</td>
+        <td class="nowrap"><?php echo '0000-00-00 00:00:00' == $list[$i]['modified_datetime'] ? '' : date(App::getParam('date_format'), strtotime($list[$i]['modified_datetime'])); ?> &nbsp;</td>
+        <td class="padleft nowrap" align="right"><a title="<?php printf(_("Delete %s"), oTxt($list[$i]['username'])) ?>" href="<?php echo App::oHREF($_SERVER['PHP_SELF'] . "?op=del&admin_id=" . $list[$i]['admin_id']); ?>" onClick="javascript:return confirm('<?php printf(_("Are you sure you want to delete the record %s? This action is permanent and cannot be undone."), oTxt($list[$i]['username'])) ?>')"><img src="/admin/_widgets/delete.gif" alt="Delete" width="16" height="17" border="0"></a> &nbsp;</td>
     </tr>
     <?php } ?>
Index: trunk/services/templates/passwd.ihtml
===================================================================
--- trunk/services/templates/passwd.ihtml	(revision 1)
+++ trunk/services/templates/passwd.ihtml	(revision 19)
@@ -6,13 +6,13 @@
 <table border="0" cellspacing="0" cellpadding="4">
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('oldpassword', ' style="color:#f33;"') ?>><?php echo _("Old password"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('oldpassword', ' class="error"') ?>><?php echo _("Old password"); ?></td>
         <td valign="top"><input type="password" class="forminputtext" size="25" name="oldpassword" /></td>
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('newpassword', ' style="color:#f33;"') ?>><?php echo _("New password"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('newpassword', ' class="error"') ?>><?php echo _("New password"); ?></td>
         <td valign="top"><input type="password" class="forminputtext" size="25" name="newpassword" /></td>
     </tr>
     <tr>
-        <td class="formlabel" align="right" valign="top"<?php $fv->err('newpassword2', ' style="color:#f33;"') ?>><?php echo _("New password again"); ?></td>
+        <td class="formlabel" align="right" valign="top"<?php $fv->err('newpassword2', ' class="error"') ?>><?php echo _("New password again"); ?></td>
         <td valign="top"><input type="password" class="forminputtext" size="25" name="newpassword2" /></td>
     </tr>
Index: trunk/services/versions.php
===================================================================
--- trunk/services/versions.php	(revision 1)
+++ trunk/services/versions.php	(revision 19)
@@ -17,5 +17,5 @@
  *****************************************************************************/
 
-$version = new RecordVersion();
+$version = new RecordVersion($GLOBALS['auth']);
 
 // These values must be kept across requests.
