source: trunk/services/admins.php @ 211

Last change on this file since 211 was 202, checked in by scdev, 18 years ago

Q - updated usage of $nav.

File size: 19.4 KB
RevLine 
[1]1<?php
2/**
[42]3 * admins.php
[1]4 * Code by Strangecode :: www.strangecode.com :: This document contains copyrighted information
5 */
6
7// require_once dirname(__FILE__) . '/_config.inc.php';
8
9$auth->requireLogin();
[136]10$app->sslOn();
[1]11
12require_once 'codebase/lib/PageNumbers.inc.php';
[136]13require_once 'codebase/lib/Cache.inc.php';
[1]14require_once 'codebase/lib/FormValidator.inc.php';
15require_once 'codebase/lib/SortOrder.inc.php';
16require_once 'codebase/lib/TemplateGlue.inc.php';
17require_once 'codebase/lib/Prefs.inc.php';
[137]18require_once 'codebase/lib/Lock.inc.php';
19require_once 'codebase/lib/Version.inc.php';
[1]20
21
[143]22/********************************************************************
23* CONFIG
24********************************************************************/
[42]25
[1]26// Titles and navigation header.
[202]27$nav->add(_("Administrators"), null);
[42]28
[1]29// The object to validate form input.
30$fv = new FormValidator();
31
[152]32// Configure the prefs object.
[153]33$tmp_prefs = new Prefs('admins');
34$tmp_prefs->setParam(array('persistent' => false));
[136]35
[152]36// Configure the cache object.
[153]37$cache = new Cache('admins');
[152]38$cache->setParam(array('enable' => true));
39
[1]40// Instantiate a sorting object with the default sort and order. Add SQL for each column.
[19]41$so = new SortOrder('admin_tbl.admin_id', 'DESC');
42$so->setColumn('admin_tbl.admin_id', 'admin_tbl.admin_id ASC', 'admin_tbl.admin_id DESC');
43$so->setColumn('admin_tbl.username', 'admin_tbl.username ASC', 'admin_tbl.username DESC');
44$so->setColumn('admin_tbl.userpass', 'admin_tbl.userpass ASC', 'admin_tbl.userpass DESC');
45$so->setColumn('admin_tbl.first_name', 'admin_tbl.first_name ASC', 'admin_tbl.first_name DESC');
46$so->setColumn('admin_tbl.last_name', 'admin_tbl.last_name ASC', 'admin_tbl.last_name DESC');
47$so->setColumn('admin_tbl.email', 'admin_tbl.email ASC', 'admin_tbl.email DESC');
48$so->setColumn('admin_tbl.user_type', 'admin_tbl.user_type ASC', 'admin_tbl.user_type DESC');
49$so->setColumn('admin_tbl.seconds_online', 'admin_tbl.seconds_online ASC', 'admin_tbl.seconds_online DESC');
50$so->setColumn('admin_tbl.last_login_datetime', 'admin_tbl.last_login_datetime ASC', 'admin_tbl.last_login_datetime DESC');
51$so->setColumn('admin_tbl.last_access_datetime', 'admin_tbl.last_access_datetime ASC', 'admin_tbl.last_access_datetime DESC');
52$so->setColumn('admin_tbl.last_login_ip', 'admin_tbl.last_login_ip ASC', 'admin_tbl.last_login_ip DESC');
53$so->setColumn('admin_tbl.added_by_user_id', 'admin_tbl.added_by_user_id ASC', 'admin_tbl.added_by_user_id DESC');
54$so->setColumn('admin_tbl.modified_by_user_id', 'admin_tbl.modified_by_user_id ASC', 'admin_tbl.modified_by_user_id DESC');
55$so->setColumn('admin_tbl.added_datetime', 'admin_tbl.added_datetime ASC', 'admin_tbl.added_datetime DESC');
56$so->setColumn('admin_tbl.modified_datetime', 'admin_tbl.modified_datetime ASC', 'admin_tbl.modified_datetime DESC');
[1]57
58// Instantiate page numbers. Total items are set and calculation is done in the getRecordList function.
59$page = new PageNumbers();
60$page->setPerPage(getFormData('per_page'), 50);
61$page->setPageNumber(getFormData('page_number'));
62
[20]63// Search limiters retain their values between page requests.
[136]64$app->carryQuery('search_query');
[1]65
[20]66
[143]67/********************************************************************
68* MAIN
69********************************************************************/
[42]70
[1]71// We may want to use the add/edit interface from another script, so this
72// allows us to remember which page we came from so we can go back there.
[20]73if (getFormData('boomerang', false) && isset($_SERVER['HTTP_REFERER'])) {
[136]74    $app->setBoomerangURL($_SERVER['HTTP_REFERER'], 'admins');
[1]75}
76
77if (getFormData('break_list_cache', false)) {
[152]78    // Remove any stale cached list data.
79    $cache->delete('list');
[1]80}
81
82// What action to take.
83switch (getFormData('op')) {
84
85case 'add' :
86    // Initialize variables for the form template.
87    $frm =& addRecordForm();
[202]88    $nav->add(_("Add Admin"));
[1]89    $main_template = 'admin_form.ihtml';
90    break;
91
92case 'edit' :
93    // Initialize variables for the form template.
94    $frm =& editRecordForm(getFormData('admin_id'));
[202]95    $nav->add(_("Edit Admin"));
[1]96    $main_template = 'admin_form.ihtml';
97    break;
98
99case 'del' :
100    deleteRecord(getFormData('admin_id'));
[136]101    if ($app->validBoomerangURL('admins')) {
[1]102        // Display boomerang page.
[136]103        $app->dieBoomerangURL('admins');
[1]104    }
105    // Display default page.
[136]106    $app->dieURL($_SERVER['PHP_SELF']);
[1]107    break;
108
109case 'insert' :
110    if (getFormdata('cancel', false)) {
[136]111        if ($app->validBoomerangURL('admins')) {
[22]112            // Display boomerang page.
[136]113            $app->dieBoomerangURL('admins');
[22]114        }
115        // Display default page.
[136]116        $app->dieURL($_SERVER['PHP_SELF']);
[1]117    }
118    validateInput();
119    if ($fv->anyErrors()) {
120        $frm =& addRecordForm();
121        $frm = array_merge($frm, getFormData());
[202]122        $nav->add(_("Add Admin"));
[1]123        $main_template = 'admin_form.ihtml';
124    } else {
125        $admin_id = insertRecord(getFormData());
126        if (getFormdata('repeat', false)) {
127            // Display function again.
[136]128            $app->dieURL($_SERVER['PHP_SELF'] . '?op=add');
129        } else if ($app->validBoomerangURL('admins')) {
[1]130            // Display boomerang page.
[136]131            $app->dieBoomerangURL('admins');
[1]132        }
133        // Display default page.
[136]134        $app->dieURL($_SERVER['PHP_SELF']);
[1]135    }
136    break;
137
138case 'update' :
139    if (getFormdata('reset', false)) {
[136]140        $app->raiseMsg(_("Saved values have been reloaded."), MSG_NOTICE, __FILE__, __LINE__);
141        $app->dieURL($_SERVER['PHP_SELF'] . '?op=edit&admin_id=' . getFormData('admin_id'));
[1]142    }
143    if (getFormdata('cancel', false)) {
144        // Remove lock
145        $lock->select('admin_tbl', 'admin_id', getFormData('admin_id'));
146        $lock->remove();
[136]147        if ($app->validBoomerangURL('admins')) {
[1]148            // Display boomerang page.
[136]149            $app->dieBoomerangURL('admins');
[1]150        }
151        // Display default page.
[136]152        $app->dieURL($_SERVER['PHP_SELF']);
[1]153    }
154    validateInput();
155    if ($fv->anyErrors()) {
156        $frm =& editRecordForm(getFormData('admin_id'));
157        $frm = array_merge($frm, getFormData());
[202]158        $nav->add(_("Edit Admin"));
[1]159        $main_template = 'admin_form.ihtml';
160    } else {
161        updateRecord(getFormData());
162        if (getFormdata('repeat', false)) {
163            // Display edit function with next available ID.
[136]164            $qid = $db->query("SELECT admin_id FROM admin_tbl WHERE admin_id > '" . $db->escapeString(getFormData('admin_id')) . "' ORDER BY admin_id ASC LIMIT 1");
[1]165            if (list($next_id) = mysql_fetch_row($qid)) {
[136]166                $app->dieURL($_SERVER['PHP_SELF'] . '?op=edit&admin_id=' . $next_id);
[1]167            } else {
[136]168                $app->raiseMsg(_("Cannot edit next, the end of the list was reached"), MSG_NOTICE, __FILE__, __LINE__);
[1]169            }
[136]170        } else if ($app->validBoomerangURL('admins')) {
[1]171            // Display boomerang page.
[136]172            $app->dieBoomerangURL('admins');
[1]173        }
174        // Display default page.
[136]175        $app->dieURL($_SERVER['PHP_SELF']);
[1]176    }
177    break;
178
179default :
180    $list =& getRecordList();
181    $main_template = 'admin_list.ihtml';
182    break;
183}
184
185/******************************************************************************
186 * TEMPLATE INITIALIZATION
187 *****************************************************************************/
188
189include 'header.ihtml';
190include 'codebase/services/templates/' . $main_template;
191include 'footer.ihtml';
192
[143]193/********************************************************************
194* FUNCTIONS
195********************************************************************/
[1]196
197
198function validateInput()
199{
200    global $fv, $auth;
201
202    // If the username was changed during edit, verify.
203    if (((getFormData('username') != getFormData('old_username')) && 'update' == getFormData('op'))
204    || 'insert' == getFormData('op')) {
205        if ($auth->usernameExists(getFormData('username'))) {
[141]206            $fv->addError('username', sprintf(_("The username %s already exists. Please choose another."), getFormData('username')));
[1]207        }
208    }
209
[147]210    if (getFormData('user_type') == 'root' && 'root' != $auth->get('user_type')) {
[19]211        $fv->addError('user_type', sprintf(_("You do not have clearance to create a user with root privileges."), null));
[1]212    }
213
214    $fv->numericRange('admin_id', -32768, 32767, _("<strong>Admin id</strong> must be a valid number between -32768 and 32767."));
215
216    $fv->isEmpty('username', _("<strong>Username</strong> cannot be blank."));
217    $fv->stringLength('username', 0, 255, _("<strong>Username</strong> must contain less than 256 characters."));
[42]218
[1]219    $fv->isEmpty('userpass', _("<strong>Passwords</strong> cannot be blank."));
220    $fv->stringLength('userpass', 6, 36, _("<strong>Passwords</strong> must be between 6 and 36 characters long."));
[42]221
[1]222    $fv->stringLength('first_name', 0, 255, _("<strong>First name</strong> must contain less than 256 characters."));
[42]223
[1]224    $fv->stringLength('last_name', 0, 255, _("<strong>Last name</strong> must contain less than 256 characters."));
[19]225
226    $fv->isEmpty('email', _("<strong>Email</strong> cannot be blank."));
[1]227    $fv->stringLength('email', 0, 255, _("<strong>Email</strong> must contain less than 256 characters."));
228    $fv->validateEmail('email');
[42]229
[19]230    $fv->isEmpty('user_type', _("<strong>User type</strong> cannot be blank."));
231    $fv->stringLength('user_type', 0, 255, _("<strong>User type</strong> has an invalid selection."));
[1]232}
233
234function &addRecordForm()
235{
[19]236    // Set default values for the reset of the fields.
237    $frm = array(
238        'admin_id' => '',
[72]239        'old_username' => '',
[19]240        'username' => '',
241        'userpass' => '',
242        'first_name' => '',
243        'last_name' => '',
244        'email' => '',
245        'user_type' => '',
246        'seconds_online' => '0',
247        'last_login_datetime' => '0000-00-00 00:00:00',
248        'last_access_datetime' => '0000-00-00 00:00:00',
249        'last_login_ip' => '0.0.0.0',
250        'added_by_user_id' => '',
251        'modified_by_user_id' => '',
252        'added_datetime' => '0000-00-00 00:00:00',
253        'modified_datetime' => '0000-00-00 00:00:00',
254        'new_op' => 'insert',
255        'submit_buttons' => array(
256            'submit' => _("Add Admin"),
257            'repeat' => _("Add &amp; repeat"),
258            'cancel' => _("Cancel"),
259        ),
260    );
[1]261
262    return $frm;
263}
264
265function &editRecordForm($id)
266{
[22]267    global $lock;
[136]268    $app =& App::getInstance();
269    $db =& DB::getInstance();
270   
[1]271    $lock->select('admin_tbl', 'admin_id', $id);
272    if ($lock->isLocked() && !$lock->isMine()) {
273        $lock->dieErrorPage();
[19]274    }
275
276    // Get the information for the form.
[136]277    $qid = $db->query("
[42]278        SELECT *
[19]279        FROM admin_tbl
[136]280        WHERE admin_id = '" . $db->escapeString($id) . "'
[19]281    ");
282    if (!$frm = mysql_fetch_assoc($qid)) {
[136]283        $app->logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
284        $app->raiseMsg(sprintf(_("The requested record %s could not be found."), $id), MSG_ERR, __FILE__, __LINE__);
285        $app->dieBoomerangURL();
[19]286    }
[42]287
[19]288    // Lock this record.
289    $lock->set('admin_tbl', 'admin_id', $id, $frm['username']);
[42]290
[19]291    // Set misc values for the form.
292    $frm = array_merge(array(
293        'admin_id' => '',
294        'old_username' => $frm['username'],
295        'username' => '',
296//         'userpass' => '****************',
297        'first_name' => '',
298        'last_name' => '',
299        'email' => '',
300        'user_type' => '',
301        'seconds_online' => '0',
302        'last_login_datetime' => '0000-00-00 00:00:00',
303        'last_access_datetime' => '0000-00-00 00:00:00',
304        'last_login_ip' => '0.0.0.0',
305        'added_by_user_id' => '',
306        'modified_by_user_id' => '',
307        'added_datetime' => '0000-00-00 00:00:00',
308        'modified_datetime' => '0000-00-00 00:00:00',
309        'new_op' => 'update',
[25]310        'old_username' => $frm['username'],
[19]311        'submit_buttons' => array(
312            'submit' => _("Save changes"),
313            'repeat' => _("Save &amp; edit next"),
314            'reset' => _("Reset"),
315            'cancel' => _("Cancel"),
316        ),
317    ), $frm, array('userpass' => '****************'));
318
319    return $frm;
[1]320}
321
322function deleteRecord($id)
323{
[153]324    global $auth;
325    global $lock;
326    global $cache;
[136]327    $app =& App::getInstance();
328    $db =& DB::getInstance();
329   
[1]330    $lock->select('admin_tbl', 'admin_id', $id);
331    if ($lock->isLocked() && !$lock->isMine()) {
332        $lock->dieErrorPage();
[21]333    }
334
[152]335    // Remove any stale cached list data.
336    $cache->delete('list');
[42]337
[21]338    // Get the information for this object.
[136]339    $qid = $db->query("
[21]340        SELECT username, user_type from admin_tbl
[136]341        WHERE admin_id = '" . $db->escapeString($id) . "'
[21]342    ");
343    if (! list($name, $user_type) = mysql_fetch_row($qid)) {
[136]344        $app->logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
345        $app->raiseMsg(sprintf(_("The requested record %s could not be found."), $id), MSG_ERR, __FILE__, __LINE__);
346        $app->dieBoomerangURL();
[21]347    }
[42]348
[21]349    // Get the information for this object.
[136]350    $qid = $db->query("SELECT COUNT(*) from admin_tbl");
[21]351    list($num_admins) = mysql_fetch_row($qid);
[147]352    if ('root' == $user_type && 'root' != $auth->get('user_type')) {
[21]353        // Only root users can delete root users!
[136]354        $app->raiseMsg(_("You do not have clearance to delete a root administrator."), MSG_NOTICE, __FILE__, __LINE__);
[21]355    } else if ($num_admins <= 1) {
356        // There must always be at least one admnistrator!
[136]357        $app->raiseMsg(_("You cannot delete the only administrator in the database. There must be at least one to log in and create other users."), MSG_NOTICE, __FILE__, __LINE__);
[147]358    } else if ($auth->get('user_id') == $id) {
[21]359        // Do not delete yourself!
[136]360        $app->raiseMsg(_("You cannot delete yourself."), MSG_NOTICE, __FILE__, __LINE__);
[1]361    } else {
[21]362        // Delete the record.
[136]363        $db->query("DELETE FROM admin_tbl WHERE admin_id = '" . $db->escapeString($id) . "'");
[141]364        $app->raiseMsg(sprintf(_("The admin <em>%s</em> has been deleted."), $name), MSG_SUCCESS, __FILE__, __LINE__);
[21]365    }
[1]366
[21]367    // Unlock record.
368    $lock->remove();
[1]369}
370
371function insertRecord($frm)
372{
373    global $auth;
[153]374    global $cache;
[136]375    $app =& App::getInstance();
376    $db =& DB::getInstance();
377   
[152]378    // Remove any stale cached list data.
379    $cache->delete('list');
[42]380
[1]381    // Insert record data.
[136]382    $db->query("
[1]383        INSERT INTO admin_tbl (
384            username,
385            first_name,
386            last_name,
387            email,
[19]388            user_type,
389            added_by_user_id,
[1]390            added_datetime
391        ) VALUES (
[136]392            '" . $db->escapeString($frm['username']) . "',
393            '" . $db->escapeString($frm['first_name']) . "',
394            '" . $db->escapeString($frm['last_name']) . "',
395            '" . $db->escapeString($frm['email']) . "',
396            '" . $db->escapeString($frm['user_type']) . "',
[147]397            '" . $db->escapeString($auth->get('user_id')) . "',
[1]398            NOW()
399        )
400    ");
[136]401    $last_insert_id = mysql_insert_id($db->getDBH());
[42]402
[1]403    // Set admin password.
404    $auth->setPassword($last_insert_id, $frm['userpass']);
[42]405
[19]406    // Create version.
[159]407    $version = Version::getInstance($auth);
[19]408    $version->create('admin_tbl', 'admin_id', $last_insert_id, $frm['username']);
[42]409
[141]410    $app->raiseMsg(sprintf(_("The Admin <em>%s</em> has been added."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
[42]411
[1]412    return $last_insert_id;
413}
414
415function updateRecord($frm)
416{
[153]417    global $auth;
418    global $lock;
419    global $cache;
[136]420    $app =& App::getInstance();
421    $db =& DB::getInstance();
422   
[1]423    $lock->select('admin_tbl', 'admin_id', $frm['admin_id']);
424    if ($lock->isLocked() && !$lock->isMine()) {
425        $lock->dieErrorPage();
[21]426    }
[1]427
[152]428    // Remove any stale cached list data.
429    $cache->delete('list');
[42]430
[21]431    // If the userpass is left blank or with the filler **** characters, we don't want to update it.
432    if (!empty($frm['userpass']) && !preg_match('/[\*]{4,}/', $frm['userpass'])) {
433        // Set user password.
434        $auth->setPassword($frm['admin_id'], $frm['userpass']);
435    }
[42]436
[21]437    // Update record data.
[136]438    $db->query("
[21]439        UPDATE admin_tbl SET
[136]440            username = '" . $db->escapeString($frm['username']) . "',
441            first_name = '" . $db->escapeString($frm['first_name']) . "',
442            last_name = '" . $db->escapeString($frm['last_name']) . "',
443            email = '" . $db->escapeString($frm['email']) . "',
444            user_type = '" . $db->escapeString($frm['user_type']) . "',
[147]445            modified_by_user_id = '" . $db->escapeString($auth->get('user_id')) . "',
[21]446            modified_datetime = NOW()
[136]447        WHERE admin_id = '" . $db->escapeString($frm['admin_id']) . "'
[21]448    ");
[1]449
[21]450    // Create version.
[159]451    $version = Version::getInstance($auth);
[21]452    $version->create('admin_tbl', 'admin_id', $frm['admin_id'], $frm['username']);
453
[141]454    $app->raiseMsg(sprintf(_("The Admin <em>%s</em> has been updated."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
[21]455
456    // Unlock record.
457    $lock->remove();
[1]458}
459
460function &getRecordList()
461{
462    global $page;
463    global $so;
[153]464    global $tmp_prefs;
465    global $cache;
[136]466    $db =& DB::getInstance();
467   
[19]468    $where_clause = '';
[42]469
[19]470    // Build search query if available.
471    if (getFormData('search_query', false)) {
472        $qry_words = preg_split('/[^\w]/', getFormData('search_query'));
[1]473        for ($i=0; $i<sizeof($qry_words); $i++) {
[19]474            $where_clause .= (empty($where_clause) ? 'WHERE' : 'AND') . "
475                (
[136]476                    admin_tbl.username LIKE '%" . $db->escapeString($qry_words[$i]) . "%'
477                    OR admin_tbl.first_name LIKE '%" . $db->escapeString($qry_words[$i]) . "%'
478                    OR admin_tbl.last_name LIKE '%" . $db->escapeString($qry_words[$i]) . "%'
479                    OR admin_tbl.email LIKE '%" . $db->escapeString($qry_words[$i]) . "%'
[1]480                )
481            ";
482        }
483    }
[19]484
[1]485    // Count the total number of records so we can do something about the page numbers.
[136]486    $qid = $db->query("
[42]487        SELECT COUNT(*)
488        FROM admin_tbl
[19]489        $where_clause
490    ");
[1]491    list($num_results) = mysql_fetch_row($qid);
[42]492
[1]493    // Set page numbers now we know (needed for next step).
494    $page->setTotalItems($num_results);
495    $page->calculate();
[42]496
[1]497    // Final SQL, with sort and page limiters.
498    $sql = "
[42]499        SELECT
500            admin_tbl.*,
[19]501            a1.username AS added_admin_username,
502            a2.username AS modified_admin_username
503        FROM admin_tbl
504        LEFT JOIN admin_tbl a1 ON (admin_tbl.added_by_user_id = a1.admin_id)
505        LEFT JOIN admin_tbl a2 ON (admin_tbl.modified_by_user_id = a2.admin_id)
[1]506        $where_clause
507        " . $so->getSortOrderSQL() . "
508        " . $page->getLimitSQL() . "
509    ";
[42]510
[152]511    // Use a cash hash to determine if the result-set has changed.
[1]512    // A unique key for this query, with the total_items in case db records
513    // were added since the last cache. This identifies a unique set of
514    // cached data, but we must refer to the list that is cached by a more
515    // generic name. so that we can flush the cache (if records updated)
516    // without knowing the hash.
517    $cache_hash = md5($sql . '|' . $page->total_items);
[153]518    if ($tmp_prefs->get('cache_hash') != $cache_hash) {
[152]519        $cache->delete('list');
[153]520        $tmp_prefs->set('cache_hash', $cache_hash);
[1]521    }
[42]522
[152]523    // First try to return from the cache.
524    if ($cache->exists('list')) {
525        return $cache->get('list');
526    }
527   
528    // The list was not cached, so issue the real query.
529    $qid = $db->query($sql);
530    while ($row = mysql_fetch_assoc($qid)) {
531        $list[] = $row;
532    }
[42]533
[152]534    // Save this list into the cache.
535    if (isset($list) && !empty($list)) {
536        $cache->set('list', $list);
[1]537    }
538
539    return $list;
540}
541
542?>
Note: See TracBrowser for help on using the repository browser.