source: trunk/services/admins.php @ 20

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

Tons of little updates and bugfixes. CSS updates to templates and core css files. File upload ability to module_maker. Remade Upload interface to use setParam/getParam.

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