source: trunk/services/admins.php @ 1

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

Initial import.

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