source: trunk/services/admins.php @ 72

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

minor misc bug fixes

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