source: trunk/services/admins.php @ 266

Last change on this file since 266 was 266, checked in by quinn, 17 years ago

Bugfixes found during strangecode site upgrade.

File size: 19.5 KB
Line 
1<?php
2/**
3 * admins.php
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();
10$app->sslOn();
11
12require_once 'codebase/lib/PageNumbers.inc.php';
13require_once 'codebase/lib/Cache.inc.php';
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';
18require_once 'codebase/lib/Lock.inc.php';
19require_once 'codebase/lib/Version.inc.php';
20
21
22/********************************************************************
23* CONFIG
24********************************************************************/
25
26// Titles and navigation header.
27$nav->add(_("Administrators"), null);
28
29// The object to validate form input.
30$fv = new FormValidator();
31
32// Configure the prefs object.
33$tmp_prefs = new Prefs('admins');
34$tmp_prefs->setParam(array('persistent' => false));
35
36// Configure the cache object.
37$cache = new Cache('admins');
38$cache->setParam(array('enable' => true));
39
40// Instantiate a sorting object with the default sort and order. Add SQL for each column.
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');
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
63// Search limiters retain their values between page requests.
64$app->carryQuery('search_query');
65
66
67/********************************************************************
68* MAIN
69********************************************************************/
70
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.
73if (getFormData('boomerang', false) && isset($_SERVER['HTTP_REFERER'])) {
74    $app->setBoomerangURL($_SERVER['HTTP_REFERER'], 'admins');
75}
76
77if (getFormData('break_list_cache', false)) {
78    // Remove any stale cached list data.
79    $cache->delete('list');
80}
81
82// What action to take.
83switch (getFormData('op')) {
84
85case 'add' :
86    // Initialize variables for the form template.
87    $frm =& addRecordForm();
88    $nav->add(_("Add Administrator"));
89    $main_template = 'admin_form.ihtml';
90    break;
91
92case 'edit' :
93    // Initialize variables for the form template.
94    $frm =& editRecordForm(getFormData('admin_id'));
95    $nav->add(_("Edit Administrator"));
96    $main_template = 'admin_form.ihtml';
97    break;
98
99case 'del' :
100    deleteRecord(getFormData('admin_id'));
101    if ($app->validBoomerangURL('admins')) {
102        // Display boomerang page.
103        $app->dieBoomerangURL('admins');
104    }
105    // Display default page.
106    $app->dieURL($_SERVER['PHP_SELF']);
107    break;
108
109case 'insert' :
110    if (getFormdata('cancel', false)) {
111        if ($app->validBoomerangURL('admins')) {
112            // Display boomerang page.
113            $app->dieBoomerangURL('admins');
114        }
115        // Display default page.
116        $app->dieURL($_SERVER['PHP_SELF']);
117    }
118    validateInput();
119    if ($fv->anyErrors()) {
120        $frm =& addRecordForm();
121        $frm = array_merge($frm, getFormData());
122        $nav->add(_("Add Administrator"));
123        $main_template = 'admin_form.ihtml';
124    } else {
125        $admin_id = insertRecord(getFormData());
126        if (getFormdata('repeat', false)) {
127            // Display function again.
128            $app->dieURL($_SERVER['PHP_SELF'] . '?op=add');
129        } else if ($app->validBoomerangURL('admins')) {
130            // Display boomerang page.
131            $app->dieBoomerangURL('admins');
132        }
133        // Display default page.
134        $app->dieURL($_SERVER['PHP_SELF']);
135    }
136    break;
137
138case 'update' :
139    if (getFormdata('reset', false)) {
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'));
142    }
143    if (getFormdata('cancel', false)) {
144        // Remove lock
145        $lock->select('admin_tbl', 'admin_id', getFormData('admin_id'));
146        $lock->remove();
147        if ($app->validBoomerangURL('admins')) {
148            // Display boomerang page.
149            $app->dieBoomerangURL('admins');
150        }
151        // Display default page.
152        $app->dieURL($_SERVER['PHP_SELF']);
153    }
154    validateInput();
155    if ($fv->anyErrors()) {
156        $frm =& editRecordForm(getFormData('admin_id'));
157        $frm = array_merge($frm, getFormData());
158        $nav->add(_("Edit Administrator"));
159        $main_template = 'admin_form.ihtml';
160    } else {
161        updateRecord(getFormData());
162        if (getFormdata('repeat', false)) {
163            // Display edit function with next available ID.
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");
165            if (list($next_id) = mysql_fetch_row($qid)) {
166                $app->dieURL($_SERVER['PHP_SELF'] . '?op=edit&admin_id=' . $next_id);
167            } else {
168                $app->raiseMsg(_("Cannot edit next, the end of the list was reached"), MSG_NOTICE, __FILE__, __LINE__);
169            }
170        } else if ($app->validBoomerangURL('admins')) {
171            // Display boomerang page.
172            $app->dieBoomerangURL('admins');
173        }
174        // Display default page.
175        $app->dieURL($_SERVER['PHP_SELF']);
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
193/********************************************************************
194* FUNCTIONS
195********************************************************************/
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'))) {
206            $fv->addError('username', sprintf(_("The username %s already exists. Please choose another."), getFormData('username')));
207        }
208    }
209
210    if (getFormData('user_type') == 'root' && 'root' != $auth->get('user_type')) {
211        $fv->addError('user_type', sprintf(_("You do not have clearance to create a user with root privileges."), null));
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."));
218
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."));
221
222    $fv->stringLength('first_name', 0, 255, _("<strong>First name</strong> must contain less than 256 characters."));
223
224    $fv->stringLength('last_name', 0, 255, _("<strong>Last name</strong> must contain less than 256 characters."));
225
226    $fv->isEmpty('email', _("<strong>Email</strong> cannot be blank."));
227    $fv->stringLength('email', 0, 255, _("<strong>Email</strong> must contain less than 256 characters."));
228    $fv->validateEmail('email');
229
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."));
232}
233
234function &addRecordForm()
235{
236    // Set default values for the reset of the fields.
237    $frm = array(
238        'admin_id' => '',
239        'old_username' => '',
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 Administrator"),
257            'repeat' => _("Add &amp; repeat"),
258            'cancel' => _("Cancel"),
259        ),
260    );
261
262    return $frm;
263}
264
265function &editRecordForm($id)
266{
267    global $lock;
268    $app =& App::getInstance();
269    $db =& DB::getInstance();
270   
271    $lock->select('admin_tbl', 'admin_id', $id);
272    if ($lock->isLocked() && !$lock->isMine()) {
273        $lock->dieErrorPage();
274    }
275
276    // Get the information for the form.
277    $qid = $db->query("
278        SELECT *
279        FROM admin_tbl
280        WHERE admin_id = '" . $db->escapeString($id) . "'
281    ");
282    if (!$frm = mysql_fetch_assoc($qid)) {
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();
286    }
287
288    // Lock this record.
289    $lock->set('admin_tbl', 'admin_id', $id, $frm['username']);
290
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',
310        'old_username' => $frm['username'],
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;
320}
321
322function deleteRecord($id)
323{
324    global $auth;
325    global $lock;
326    global $cache;
327    $app =& App::getInstance();
328    $db =& DB::getInstance();
329   
330    $lock->select('admin_tbl', 'admin_id', $id);
331    if ($lock->isLocked() && !$lock->isMine()) {
332        $lock->dieErrorPage();
333    }
334
335    // Remove any stale cached list data.
336    $cache->delete('list');
337
338    // Get the information for this object.
339    $qid = $db->query("
340        SELECT username, user_type from admin_tbl
341        WHERE admin_id = '" . $db->escapeString($id) . "'
342    ");
343    if (! list($name, $user_type) = mysql_fetch_row($qid)) {
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();
347    }
348
349    // Get the information for this object.
350    $qid = $db->query("SELECT COUNT(*) from admin_tbl");
351    list($num_admins) = mysql_fetch_row($qid);
352    if ('root' == $user_type && 'root' != $auth->get('user_type')) {
353        // Only root users can delete root users!
354        $app->raiseMsg(_("You do not have clearance to delete a root administrator."), MSG_NOTICE, __FILE__, __LINE__);
355    } else if ($num_admins <= 1) {
356        // There must always be at least one admnistrator!
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__);
358    } else if ($auth->get('user_id') == $id) {
359        // Do not delete yourself!
360        $app->raiseMsg(_("You cannot delete yourself."), MSG_NOTICE, __FILE__, __LINE__);
361    } else {
362        // Delete the record.
363        $db->query("DELETE FROM admin_tbl WHERE admin_id = '" . $db->escapeString($id) . "'");
364        $app->raiseMsg(sprintf(_("The admin <em>%s</em> has been deleted."), $name), MSG_SUCCESS, __FILE__, __LINE__);
365    }
366
367    // Unlock record.
368    $lock->remove();
369}
370
371function insertRecord($frm)
372{
373    global $auth;
374    global $cache;
375    $app =& App::getInstance();
376    $db =& DB::getInstance();
377   
378    // Remove any stale cached list data.
379    $cache->delete('list');
380
381    // Insert record data.
382    $db->query("
383        INSERT INTO admin_tbl (
384            username,
385            first_name,
386            last_name,
387            email,
388            user_type,
389            added_by_user_id,
390            added_datetime
391        ) VALUES (
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']) . "',
397            '" . $db->escapeString($auth->get('user_id')) . "',
398            NOW()
399        )
400    ");
401    $last_insert_id = mysql_insert_id($db->getDBH());
402
403    // Set admin password.
404    $auth->setPassword($last_insert_id, $frm['userpass']);
405
406    // Create version.
407    $version = Version::getInstance($auth);
408    $version->create('admin_tbl', 'admin_id', $last_insert_id, $frm['username']);
409
410    $app->raiseMsg(sprintf(_("The Administrator <em>%s</em> has been added."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
411
412    return $last_insert_id;
413}
414
415function updateRecord($frm)
416{
417    global $auth;
418    global $lock;
419    global $cache;
420    $app =& App::getInstance();
421    $db =& DB::getInstance();
422   
423    $lock->select('admin_tbl', 'admin_id', $frm['admin_id']);
424    if ($lock->isLocked() && !$lock->isMine()) {
425        $lock->dieErrorPage();
426    }
427
428    // Remove any stale cached list data.
429    $cache->delete('list');
430
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    }
436
437    // Update record data.
438    $db->query("
439        UPDATE admin_tbl SET
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']) . "',
445            modified_by_user_id = '" . $db->escapeString($auth->get('user_id')) . "',
446            modified_datetime = NOW()
447        WHERE admin_id = '" . $db->escapeString($frm['admin_id']) . "'
448    ");
449
450    // Create version.
451    $version = Version::getInstance($auth);
452    $version->create('admin_tbl', 'admin_id', $frm['admin_id'], $frm['username']);
453
454    $app->raiseMsg(sprintf(_("The Administrator <em>%s</em> has been updated."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
455
456    // Unlock record.
457    $lock->remove();
458}
459
460function &getRecordList()
461{
462    global $page;
463    global $so;
464    global $tmp_prefs;
465    global $cache;
466    $db =& DB::getInstance();
467   
468    $where_clause = '';
469
470    // Build search query if available.
471    if (getFormData('search_query', false)) {
472        $qry_words = preg_split('/[^\w]/', getFormData('search_query'));
473        for ($i=0; $i<sizeof($qry_words); $i++) {
474            $where_clause .= (empty($where_clause) ? 'WHERE' : 'AND') . "
475                (
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]) . "%'
480                )
481            ";
482        }
483    }
484
485    // Count the total number of records so we can do something about the page numbers.
486    $qid = $db->query("
487        SELECT COUNT(*)
488        FROM admin_tbl
489        $where_clause
490    ");
491    list($num_results) = mysql_fetch_row($qid);
492
493    // Set page numbers now we know (needed for next step).
494    $page->setTotalItems($num_results);
495    $page->calculate();
496
497    // Final SQL, with sort and page limiters.
498    $sql = "
499        SELECT
500            admin_tbl.*,
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)
506        $where_clause
507        " . $so->getSortOrderSQL() . "
508        " . $page->getLimitSQL() . "
509    ";
510
511    // Use a cash hash to determine if the result-set has changed.
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);
518    if ($tmp_prefs->get('cache_hash') != $cache_hash) {
519        $cache->delete('list');
520        $tmp_prefs->set('cache_hash', $cache_hash);
521    }
522
523    // First try to return from the cache.
524    if ($cache->exists('list')) {
525        $list = $cache->get('list');
526        return $list;
527    }
528   
529    // The list was not cached, so issue the real query.
530    $qid = $db->query($sql);
531    while ($row = mysql_fetch_assoc($qid)) {
532        $list[] = $row;
533    }
534
535    // Save this list into the cache.
536    if (isset($list) && !empty($list)) {
537        $cache->set('list', $list);
538    }
539
540    return $list;
541}
542
543?>
Note: See TracBrowser for help on using the repository browser.