requireLogin();
App::sslOn();
require_once 'codebase/lib/PageNumbers.inc.php';
require_once 'codebase/lib/SessionCache.inc.php';
require_once 'codebase/lib/FormValidator.inc.php';
require_once 'codebase/lib/SortOrder.inc.php';
require_once 'codebase/lib/TemplateGlue.inc.php';
require_once 'codebase/lib/Prefs.inc.php';
require_once 'codebase/lib/RecordLock.inc.php';
require_once 'codebase/lib/RecordVersion.inc.php';
/******************************************************************************
* CONFIG
*****************************************************************************/
// Titles and navigation header.
$nav->addPage(_("Administrators"), $_SERVER['PHP_SELF']);
// The object to validate form input.
$fv = new FormValidator();
// Instantiate a sorting object with the default sort and order. Add SQL for each column.
$so = new SortOrder('admin_tbl.admin_id', 'DESC');
$so->setColumn('admin_tbl.admin_id', 'admin_tbl.admin_id ASC', 'admin_tbl.admin_id DESC');
$so->setColumn('admin_tbl.username', 'admin_tbl.username ASC', 'admin_tbl.username DESC');
$so->setColumn('admin_tbl.userpass', 'admin_tbl.userpass ASC', 'admin_tbl.userpass DESC');
$so->setColumn('admin_tbl.first_name', 'admin_tbl.first_name ASC', 'admin_tbl.first_name DESC');
$so->setColumn('admin_tbl.last_name', 'admin_tbl.last_name ASC', 'admin_tbl.last_name DESC');
$so->setColumn('admin_tbl.email', 'admin_tbl.email ASC', 'admin_tbl.email DESC');
$so->setColumn('admin_tbl.user_type', 'admin_tbl.user_type ASC', 'admin_tbl.user_type DESC');
$so->setColumn('admin_tbl.seconds_online', 'admin_tbl.seconds_online ASC', 'admin_tbl.seconds_online DESC');
$so->setColumn('admin_tbl.last_login_datetime', 'admin_tbl.last_login_datetime ASC', 'admin_tbl.last_login_datetime DESC');
$so->setColumn('admin_tbl.last_access_datetime', 'admin_tbl.last_access_datetime ASC', 'admin_tbl.last_access_datetime DESC');
$so->setColumn('admin_tbl.last_login_ip', 'admin_tbl.last_login_ip ASC', 'admin_tbl.last_login_ip DESC');
$so->setColumn('admin_tbl.added_by_user_id', 'admin_tbl.added_by_user_id ASC', 'admin_tbl.added_by_user_id DESC');
$so->setColumn('admin_tbl.modified_by_user_id', 'admin_tbl.modified_by_user_id ASC', 'admin_tbl.modified_by_user_id DESC');
$so->setColumn('admin_tbl.added_datetime', 'admin_tbl.added_datetime ASC', 'admin_tbl.added_datetime DESC');
$so->setColumn('admin_tbl.modified_datetime', 'admin_tbl.modified_datetime ASC', 'admin_tbl.modified_datetime DESC');
// Instantiate page numbers. Total items are set and calculation is done in the getRecordList function.
$page = new PageNumbers();
$page->setPerPage(getFormData('per_page'), 50);
$page->setPageNumber(getFormData('page_number'));
// Search limiters retain their values between page requests.
App::carryQuery('search_query');
/******************************************************************************
* MAIN
*****************************************************************************/
// We may want to use the add/edit interface from another script, so this
// allows us to remember which page we came from so we can go back there.
if (getFormData('boomerang', false) && isset($_SERVER['HTTP_REFERER'])) {
App::setBoomerangURL($_SERVER['HTTP_REFERER'], 'admins');
}
if (getFormData('break_list_cache', false)) {
// Break the cache because we are changing the list data.
SessionCache::breakCache($_SERVER['PHP_SELF']);
}
// What action to take.
switch (getFormData('op')) {
case 'add' :
// Initialize variables for the form template.
$frm =& addRecordForm();
$nav->addPage(_("Add Admin"));
$main_template = 'admin_form.ihtml';
break;
case 'edit' :
// Initialize variables for the form template.
$frm =& editRecordForm(getFormData('admin_id'));
$nav->addPage(_("Edit Admin"));
$main_template = 'admin_form.ihtml';
break;
case 'del' :
deleteRecord(getFormData('admin_id'));
if (App::validBoomerangURL('admins')) {
// Display boomerang page.
App::dieBoomerangURL('admins');
}
// Display default page.
App::dieURL($_SERVER['PHP_SELF']);
break;
case 'insert' :
if (getFormdata('cancel', false)) {
if (App::validBoomerangURL('admins')) {
// Display boomerang page.
App::dieBoomerangURL('admins');
}
// Display default page.
App::dieURL($_SERVER['PHP_SELF']);
}
validateInput();
if ($fv->anyErrors()) {
$frm =& addRecordForm();
$frm = array_merge($frm, getFormData());
$nav->addPage(_("Add Admin"));
$main_template = 'admin_form.ihtml';
} else {
$admin_id = insertRecord(getFormData());
if (getFormdata('repeat', false)) {
// Display function again.
App::dieURL($_SERVER['PHP_SELF'] . '?op=add');
} else if (App::validBoomerangURL('admins')) {
// Display boomerang page.
App::dieBoomerangURL('admins');
}
// Display default page.
App::dieURL($_SERVER['PHP_SELF']);
}
break;
case 'update' :
if (getFormdata('reset', false)) {
App::raiseMsg(_("Saved values have been reloaded."), MSG_NOTICE, __FILE__, __LINE__);
App::dieURL($_SERVER['PHP_SELF'] . '?op=edit&admin_id=' . getFormData('admin_id'));
}
if (getFormdata('cancel', false)) {
// Remove lock
$lock->select('admin_tbl', 'admin_id', getFormData('admin_id'));
$lock->remove();
if (App::validBoomerangURL('admins')) {
// Display boomerang page.
App::dieBoomerangURL('admins');
}
// Display default page.
App::dieURL($_SERVER['PHP_SELF']);
}
validateInput();
if ($fv->anyErrors()) {
$frm =& editRecordForm(getFormData('admin_id'));
$frm = array_merge($frm, getFormData());
$nav->addPage(_("Edit Admin"));
$main_template = 'admin_form.ihtml';
} else {
updateRecord(getFormData());
if (getFormdata('repeat', false)) {
// Display edit function with next available ID.
$qid = DB::query("SELECT admin_id FROM admin_tbl WHERE admin_id > '" . DB::escapeString(getFormData('admin_id')) . "' ORDER BY admin_id ASC LIMIT 1");
if (list($next_id) = mysql_fetch_row($qid)) {
App::dieURL($_SERVER['PHP_SELF'] . '?op=edit&admin_id=' . $next_id);
} else {
App::raiseMsg(_("Cannot edit next, the end of the list was reached"), MSG_NOTICE, __FILE__, __LINE__);
}
} else if (App::validBoomerangURL('admins')) {
// Display boomerang page.
App::dieBoomerangURL('admins');
}
// Display default page.
App::dieURL($_SERVER['PHP_SELF']);
}
break;
default :
$list =& getRecordList();
$main_template = 'admin_list.ihtml';
break;
}
/******************************************************************************
* TEMPLATE INITIALIZATION
*****************************************************************************/
include 'header.ihtml';
include 'codebase/services/templates/' . $main_template;
include 'footer.ihtml';
/******************************************************************************
* FUNCTIONS
*****************************************************************************/
function validateInput()
{
global $fv, $auth;
// If the username was changed during edit, verify.
if (((getFormData('username') != getFormData('old_username')) && 'update' == getFormData('op'))
|| 'insert' == getFormData('op')) {
if ($auth->usernameExists(getFormData('username'))) {
$fv->addError('username', sprintf(_("The username %s already exists. Please choose another."), getFormData('username')));
}
}
if (getFormData('user_type') == 'root' && 'root' != $auth->getVal('user_type')) {
$fv->addError('user_type', sprintf(_("You do not have clearance to create a user with root privileges."), null));
}
$fv->numericRange('admin_id', -32768, 32767, _("Admin id must be a valid number between -32768 and 32767."));
$fv->isEmpty('username', _("Username cannot be blank."));
$fv->stringLength('username', 0, 255, _("Username must contain less than 256 characters."));
$fv->isEmpty('userpass', _("Passwords cannot be blank."));
$fv->stringLength('userpass', 6, 36, _("Passwords must be between 6 and 36 characters long."));
$fv->stringLength('first_name', 0, 255, _("First name must contain less than 256 characters."));
$fv->stringLength('last_name', 0, 255, _("Last name must contain less than 256 characters."));
$fv->isEmpty('email', _("Email cannot be blank."));
$fv->stringLength('email', 0, 255, _("Email must contain less than 256 characters."));
$fv->validateEmail('email');
$fv->isEmpty('user_type', _("User type cannot be blank."));
$fv->stringLength('user_type', 0, 255, _("User type has an invalid selection."));
}
function &addRecordForm()
{
// Set default values for the reset of the fields.
$frm = array(
'admin_id' => '',
'old_username' => '',
'username' => '',
'userpass' => '',
'first_name' => '',
'last_name' => '',
'email' => '',
'user_type' => '',
'seconds_online' => '0',
'last_login_datetime' => '0000-00-00 00:00:00',
'last_access_datetime' => '0000-00-00 00:00:00',
'last_login_ip' => '0.0.0.0',
'added_by_user_id' => '',
'modified_by_user_id' => '',
'added_datetime' => '0000-00-00 00:00:00',
'modified_datetime' => '0000-00-00 00:00:00',
'new_op' => 'insert',
'submit_buttons' => array(
'submit' => _("Add Admin"),
'repeat' => _("Add & repeat"),
'cancel' => _("Cancel"),
),
);
return $frm;
}
function &editRecordForm($id)
{
global $lock;
$lock->select('admin_tbl', 'admin_id', $id);
if ($lock->isLocked() && !$lock->isMine()) {
$lock->dieErrorPage();
}
// Get the information for the form.
$qid = DB::query("
SELECT *
FROM admin_tbl
WHERE admin_id = '" . DB::escapeString($id) . "'
");
if (!$frm = mysql_fetch_assoc($qid)) {
App::logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
App::raiseMsg(sprintf(_("The requested record %s could not be found."), $id), MSG_ERR, __FILE__, __LINE__);
App::dieBoomerangURL();
}
// Lock this record.
$lock->set('admin_tbl', 'admin_id', $id, $frm['username']);
// Set misc values for the form.
$frm = array_merge(array(
'admin_id' => '',
'old_username' => $frm['username'],
'username' => '',
// 'userpass' => '****************',
'first_name' => '',
'last_name' => '',
'email' => '',
'user_type' => '',
'seconds_online' => '0',
'last_login_datetime' => '0000-00-00 00:00:00',
'last_access_datetime' => '0000-00-00 00:00:00',
'last_login_ip' => '0.0.0.0',
'added_by_user_id' => '',
'modified_by_user_id' => '',
'added_datetime' => '0000-00-00 00:00:00',
'modified_datetime' => '0000-00-00 00:00:00',
'new_op' => 'update',
'old_username' => $frm['username'],
'submit_buttons' => array(
'submit' => _("Save changes"),
'repeat' => _("Save & edit next"),
'reset' => _("Reset"),
'cancel' => _("Cancel"),
),
), $frm, array('userpass' => '****************'));
return $frm;
}
function deleteRecord($id)
{
global $auth, $lock;
$lock->select('admin_tbl', 'admin_id', $id);
if ($lock->isLocked() && !$lock->isMine()) {
$lock->dieErrorPage();
}
// Break the cache because we are changing the list data.
SessionCache::breakCache($_SERVER['PHP_SELF']);
// Get the information for this object.
$qid = DB::query("
SELECT username, user_type from admin_tbl
WHERE admin_id = '" . DB::escapeString($id) . "'
");
if (! list($name, $user_type) = mysql_fetch_row($qid)) {
App::logMsg('Could not find record with admin_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
App::raiseMsg(sprintf(_("The requested record %s could not be found."), $id), MSG_ERR, __FILE__, __LINE__);
App::dieBoomerangURL();
}
// Get the information for this object.
$qid = DB::query("SELECT COUNT(*) from admin_tbl");
list($num_admins) = mysql_fetch_row($qid);
if ('root' == $user_type && 'root' != $auth->getVal('user_type')) {
// Only root users can delete root users!
App::raiseMsg(_("You do not have clearance to delete a root administrator."), MSG_NOTICE, __FILE__, __LINE__);
} else if ($num_admins <= 1) {
// There must always be at least one admnistrator!
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__);
} else if ($auth->getVal('user_id') == $id) {
// Do not delete yourself!
App::raiseMsg(_("You cannot delete yourself."), MSG_NOTICE, __FILE__, __LINE__);
} else {
// Delete the record.
DB::query("DELETE FROM admin_tbl WHERE admin_id = '" . DB::escapeString($id) . "'");
App::raiseMsg(sprintf(_("The admin %s has been deleted."), $name), MSG_SUCCESS, __FILE__, __LINE__);
}
// Unlock record.
$lock->remove();
}
function insertRecord($frm)
{
global $auth;
// Break the cache because we are changing the list data.
SessionCache::breakCache($_SERVER['PHP_SELF']);
// Insert record data.
DB::query("
INSERT INTO admin_tbl (
username,
first_name,
last_name,
email,
user_type,
added_by_user_id,
added_datetime
) VALUES (
'" . DB::escapeString($frm['username']) . "',
'" . DB::escapeString($frm['first_name']) . "',
'" . DB::escapeString($frm['last_name']) . "',
'" . DB::escapeString($frm['email']) . "',
'" . DB::escapeString($frm['user_type']) . "',
'" . DB::escapeString($auth->getVal('user_id')) . "',
NOW()
)
");
$last_insert_id = mysql_insert_id(DB::getDBH());
// Set admin password.
$auth->setPassword($last_insert_id, $frm['userpass']);
// Create version.
$version = RecordVersion::getInstance($GLOBALS['auth']);
$version->create('admin_tbl', 'admin_id', $last_insert_id, $frm['username']);
App::raiseMsg(sprintf(_("The Admin %s has been added."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
return $last_insert_id;
}
function updateRecord($frm)
{
global $auth, $lock;
$lock->select('admin_tbl', 'admin_id', $frm['admin_id']);
if ($lock->isLocked() && !$lock->isMine()) {
$lock->dieErrorPage();
}
// Break the cache because we are changing the list data.
SessionCache::breakCache($_SERVER['PHP_SELF']);
// If the userpass is left blank or with the filler **** characters, we don't want to update it.
if (!empty($frm['userpass']) && !preg_match('/[\*]{4,}/', $frm['userpass'])) {
// Set user password.
$auth->setPassword($frm['admin_id'], $frm['userpass']);
}
// Update record data.
DB::query("
UPDATE admin_tbl SET
username = '" . DB::escapeString($frm['username']) . "',
first_name = '" . DB::escapeString($frm['first_name']) . "',
last_name = '" . DB::escapeString($frm['last_name']) . "',
email = '" . DB::escapeString($frm['email']) . "',
user_type = '" . DB::escapeString($frm['user_type']) . "',
modified_by_user_id = '" . DB::escapeString($auth->getVal('user_id')) . "',
modified_datetime = NOW()
WHERE admin_id = '" . DB::escapeString($frm['admin_id']) . "'
");
// Create version.
$version = RecordVersion::getInstance($GLOBALS['auth']);
$version->create('admin_tbl', 'admin_id', $frm['admin_id'], $frm['username']);
App::raiseMsg(sprintf(_("The Admin %s has been updated."), $frm['username']), MSG_SUCCESS, __FILE__, __LINE__);
// Unlock record.
$lock->remove();
}
function &getRecordList()
{
global $page;
global $so;
$where_clause = '';
// Build search query if available.
if (getFormData('search_query', false)) {
$qry_words = preg_split('/[^\w]/', getFormData('search_query'));
for ($i=0; $isetTotalItems($num_results);
$page->calculate();
// Final SQL, with sort and page limiters.
$sql = "
SELECT
admin_tbl.*,
a1.username AS added_admin_username,
a2.username AS modified_admin_username
FROM admin_tbl
LEFT JOIN admin_tbl a1 ON (admin_tbl.added_by_user_id = a1.admin_id)
LEFT JOIN admin_tbl a2 ON (admin_tbl.modified_by_user_id = a2.admin_id)
$where_clause
" . $so->getSortOrderSQL() . "
" . $page->getLimitSQL() . "
";
// A unique key for this query, with the total_items in case db records
// were added since the last cache. This identifies a unique set of
// cached data, but we must refer to the list that is cached by a more
// generic name. so that we can flush the cache (if records updated)
// without knowing the hash.
$cache_hash = md5($sql . '|' . $page->total_items);
if (Prefs::getValue('cache_hash', $_SERVER['PHP_SELF']) != $cache_hash) {
SessionCache::breakCache($_SERVER['PHP_SELF']);
Prefs::setValue('cache_hash', $cache_hash, $_SERVER['PHP_SELF']);
}
if (SessionCache::isCached($_SERVER['PHP_SELF']) && false) {
// Get the cached results.
$list = SessionCache::getCache($_SERVER['PHP_SELF']);
} else {
// If the list is not already cached, query now.
$qid = DB::query($sql);
// Fill an array with the items for this page.
while ($row = mysql_fetch_assoc($qid)) {
$list[] = $row;
}
if (isset($list) && !empty($list)) {
// Cache the results.
SessionCache::putCache($list, $_SERVER['PHP_SELF']);
}
}
return $list;
}
?>