source: trunk/services/admins.php @ 24

Last change on this file since 24 was 22, checked in by scdev, 19 years ago

More bugs and shifting things about.

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        'username' => '',
232        'userpass' => '',
233        'first_name' => '',
234        'last_name' => '',
235        'email' => '',
236        'user_type' => '',
237        'seconds_online' => '0',
238        'last_login_datetime' => '0000-00-00 00:00:00',
239        'last_access_datetime' => '0000-00-00 00:00:00',
240        'last_login_ip' => '0.0.0.0',
241        'added_by_user_id' => '',
242        'modified_by_user_id' => '',
243        'added_datetime' => '0000-00-00 00:00:00',
244        'modified_datetime' => '0000-00-00 00:00:00',
245        'new_op' => 'insert',
246        'submit_buttons' => array(
247            'submit' => _("Add Admin"),
248            'repeat' => _("Add &amp; repeat"),
249            'cancel' => _("Cancel"),
250        ),
251    );
252
253    return $frm;
254}
255
256function &editRecordForm($id)
257{
258    global $lock;
259
260    $lock->select('admin_tbl', 'admin_id', $id);
261    if ($lock->isLocked() && !$lock->isMine()) {
262        $lock->dieErrorPage();
263    }
264
265    // Get the information for the form.
266    $qid = DB::query("
267        SELECT *
268        FROM admin_tbl
269        WHERE admin_id = '" . addslashes($id) . "'
270    ");
271    if (!$frm = mysql_fetch_assoc($qid)) {
272        App::logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
273        App::raiseMsg(sprintf(_("The requested record %s could not be found."), $id), MSG_ERR, __FILE__, __LINE__);
274        App::dieBoomerangURL();
275    }
276   
277    // Lock this record.
278    $lock->set('admin_tbl', 'admin_id', $id, $frm['username']);
279   
280    // Set misc values for the form.
281    $frm = array_merge(array(
282        'admin_id' => '',
283        'old_username' => $frm['username'],
284        'username' => '',
285//         'userpass' => '****************',
286        'first_name' => '',
287        'last_name' => '',
288        'email' => '',
289        'user_type' => '',
290        'seconds_online' => '0',
291        'last_login_datetime' => '0000-00-00 00:00:00',
292        'last_access_datetime' => '0000-00-00 00:00:00',
293        'last_login_ip' => '0.0.0.0',
294        'added_by_user_id' => '',
295        'modified_by_user_id' => '',
296        'added_datetime' => '0000-00-00 00:00:00',
297        'modified_datetime' => '0000-00-00 00:00:00',
298        'new_op' => 'update',
299        'submit_buttons' => array(
300            'submit' => _("Save changes"),
301            'repeat' => _("Save &amp; edit next"),
302            'reset' => _("Reset"),
303            'cancel' => _("Cancel"),
304        ),
305    ), $frm, array('userpass' => '****************'));
306
307    return $frm;
308}
309
310function deleteRecord($id)
311{
312    global $auth, $lock;
313   
314    $lock->select('admin_tbl', 'admin_id', $id);
315    if ($lock->isLocked() && !$lock->isMine()) {
316        $lock->dieErrorPage();
317    }
318
319    // Break the cache because we are changing the list data.
320    SessionCache::breakCache($_SERVER['PHP_SELF']);
321   
322    // Get the information for this object.
323    $qid = DB::query("
324        SELECT username, user_type from admin_tbl
325        WHERE admin_id = '" . addslashes($id) . "'
326    ");
327    if (! list($name, $user_type) = mysql_fetch_row($qid)) {
328        App::logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
329        App::raiseMsg(sprintf(_("The requested record %s could not be found."), $id), MSG_ERR, __FILE__, __LINE__);
330        App::dieBoomerangURL();
331    }
332   
333    // Get the information for this object.
334    $qid = DB::query("SELECT COUNT(*) from admin_tbl");
335    list($num_admins) = mysql_fetch_row($qid);
336    if ('root' == $user_type && 'root' != $auth->getVal('user_type')) {
337        // Only root users can delete root users!
338        App::raiseMsg(_("You do not have clearance to delete a root administrator."), MSG_NOTICE, __FILE__, __LINE__);
339    } else if ($num_admins <= 1) {
340        // There must always be at least one admnistrator!
341        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__);
342    } else if ($auth->getVal('user_id') == $id) {
343        // Do not delete yourself!
344        App::raiseMsg(_("You cannot delete yourself."), MSG_NOTICE, __FILE__, __LINE__);
345    } else {
346        // Delete the record.
347        DB::query("DELETE FROM admin_tbl WHERE admin_id = '" . addslashes($id) . "'");
348        App::raiseMsg(sprintf(_("The admin <strong>%s</strong> has been deleted."), $name), MSG_SUCCESS, __FILE__, __LINE__);
349    }
350
351    // Unlock record.
352    $lock->remove();
353}
354
355function insertRecord($frm)
356{
357    global $auth;
358   
359    // Break the cache because we are changing the list data.
360    SessionCache::breakCache($_SERVER['PHP_SELF']);
361   
362    // Insert record data.
363    DB::query("
364        INSERT INTO admin_tbl (
365            username,
366            first_name,
367            last_name,
368            email,
369            user_type,
370            added_by_user_id,
371            added_datetime
372        ) VALUES (
373            '" . addslashes($frm['username']) . "',
374            '" . addslashes($frm['first_name']) . "',
375            '" . addslashes($frm['last_name']) . "',
376            '" . addslashes($frm['email']) . "',
377            '" . addslashes($frm['user_type']) . "',
378            '" . addslashes($auth->getVal('user_id')) . "',
379            NOW()
380        )
381    ");
382    $last_insert_id = mysql_insert_id(DB::getDBH());
383   
384    // Set admin password.
385    $auth->setPassword($last_insert_id, $frm['userpass']);
386   
387    // Create version.
388    $version = RecordVersion::getInstance($GLOBALS['auth']);
389    $version->create('admin_tbl', 'admin_id', $last_insert_id, $frm['username']);
390   
391    App::raiseMsg(sprintf(_("The Admin <strong>%s</strong> has been added."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
392   
393    return $last_insert_id;
394}
395
396function updateRecord($frm)
397{
398    global $auth, $lock;
399   
400    $lock->select('admin_tbl', 'admin_id', $frm['admin_id']);
401    if ($lock->isLocked() && !$lock->isMine()) {
402        $lock->dieErrorPage();
403    }
404
405    // Break the cache because we are changing the list data.
406    SessionCache::breakCache($_SERVER['PHP_SELF']);
407   
408    // If the userpass is left blank or with the filler **** characters, we don't want to update it.
409    if (!empty($frm['userpass']) && !preg_match('/[\*]{4,}/', $frm['userpass'])) {
410        // Set user password.
411        $auth->setPassword($frm['admin_id'], $frm['userpass']);
412    }
413   
414    // Update record data.
415    DB::query("
416        UPDATE admin_tbl SET
417            username = '" . addslashes($frm['username']) . "',
418            first_name = '" . addslashes($frm['first_name']) . "',
419            last_name = '" . addslashes($frm['last_name']) . "',
420            email = '" . addslashes($frm['email']) . "',
421            user_type = '" . addslashes($frm['user_type']) . "',
422            modified_by_user_id = '" . addslashes($auth->getVal('user_id')) . "',
423            modified_datetime = NOW()
424        WHERE admin_id = '" . addslashes($frm['admin_id']) . "'
425    ");
426
427    // Create version.
428    $version = RecordVersion::getInstance($GLOBALS['auth']);
429    $version->create('admin_tbl', 'admin_id', $frm['admin_id'], $frm['username']);
430
431    App::raiseMsg(sprintf(_("The Admin <strong>%s</strong> has been updated."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
432
433    // Unlock record.
434    $lock->remove();
435}
436
437function &getRecordList()
438{
439    global $page;
440    global $so;
441   
442    $where_clause = '';
443   
444    // Build search query if available.
445    if (getFormData('search_query', false)) {
446        $qry_words = preg_split('/[^\w]/', getFormData('search_query'));
447        for ($i=0; $i<sizeof($qry_words); $i++) {
448            $where_clause .= (empty($where_clause) ? 'WHERE' : 'AND') . "
449                (
450                    admin_tbl.username LIKE '%" . addslashes($qry_words[$i]) . "%'
451                    OR admin_tbl.first_name LIKE '%" . addslashes($qry_words[$i]) . "%'
452                    OR admin_tbl.last_name LIKE '%" . addslashes($qry_words[$i]) . "%'
453                    OR admin_tbl.email LIKE '%" . addslashes($qry_words[$i]) . "%'
454                )
455            ";
456        }
457    }
458
459    // Count the total number of records so we can do something about the page numbers.
460    $qid = DB::query("
461        SELECT COUNT(*)
462        FROM admin_tbl
463        $where_clause
464    ");
465    list($num_results) = mysql_fetch_row($qid);
466   
467    // Set page numbers now we know (needed for next step).
468    $page->setTotalItems($num_results);
469    $page->calculate();
470   
471    // Final SQL, with sort and page limiters.
472    $sql = "
473        SELECT
474            admin_tbl.*,
475            a1.username AS added_admin_username,
476            a2.username AS modified_admin_username
477        FROM admin_tbl
478        LEFT JOIN admin_tbl a1 ON (admin_tbl.added_by_user_id = a1.admin_id)
479        LEFT JOIN admin_tbl a2 ON (admin_tbl.modified_by_user_id = a2.admin_id)
480        $where_clause
481        " . $so->getSortOrderSQL() . "
482        " . $page->getLimitSQL() . "
483    ";
484   
485    // A unique key for this query, with the total_items in case db records
486    // were added since the last cache. This identifies a unique set of
487    // cached data, but we must refer to the list that is cached by a more
488    // generic name. so that we can flush the cache (if records updated)
489    // without knowing the hash.
490    $cache_hash = md5($sql . '|' . $page->total_items);
491    if (Prefs::getValue('cache_hash', $_SERVER['PHP_SELF']) != $cache_hash) {
492        SessionCache::breakCache($_SERVER['PHP_SELF']);
493        Prefs::setValue('cache_hash', $cache_hash, $_SERVER['PHP_SELF']);
494    }
495   
496    if (SessionCache::isCached($_SERVER['PHP_SELF']) && false) {
497        // Get the cached results.
498        $list = SessionCache::getCache($_SERVER['PHP_SELF']);
499    } else {
500        // If the list is not already cached, query now.
501        $qid = DB::query($sql);
502        // Fill an array with the items for this page.
503        while ($row = mysql_fetch_assoc($qid)) {
504            $list[] = $row;
505        }
506           
507        if (isset($list) && !empty($list)) {
508            // Cache the results.
509            SessionCache::putCache($list, $_SERVER['PHP_SELF']);
510        }
511    }
512
513    return $list;
514}
515
516?>
Note: See TracBrowser for help on using the repository browser.