source: trunk/services/admins.php @ 458

Last change on this file since 458 was 458, checked in by anonymous, 10 years ago

Fixed /services/admin.php rm sql.

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