requireLogin();
$app->sslOn();
require_once 'codebase/lib/PageNumbers.inc.php';
require_once 'codebase/lib/Cache.inc.php';
require_once 'codebase/lib/SortOrder.inc.php';
require_once 'codebase/lib/HTML.inc.php';
require_once 'models/User.inc.php';
/********************************************************************
* CONFIG
********************************************************************/
// Titles and navigation header.
$nav->add(_("Users"), null);
// Instantiate a sorting object with the default sort and order. Add SQL for each column.
$so = new SortOrder('user_tbl.username', 'ASC');
$so->asc_widget = '';
$so->desc_widget = '';
$so->setColumn('user_tbl.user_id', 'user_tbl.user_id ASC', 'user_tbl.user_id DESC');
$so->setColumn('user_tbl.account_id', 'user_tbl.account_id ASC', 'user_tbl.account_id DESC');
$so->setColumn('user_tbl.username', 'user_tbl.username ASC', 'user_tbl.username DESC');
$so->setColumn('user_tbl.userpass', 'user_tbl.userpass ASC', 'user_tbl.userpass DESC');
$so->setColumn('user_tbl.first_name', 'user_tbl.first_name ASC', 'user_tbl.first_name DESC');
$so->setColumn('user_tbl.last_name', 'user_tbl.last_name ASC', 'user_tbl.last_name DESC');
$so->setColumn('user_tbl.email', 'user_tbl.email ASC', 'user_tbl.email DESC');
$so->setColumn('user_tbl.user_type', 'user_tbl.user_type ASC', 'user_tbl.user_type DESC');
$so->setColumn('user_tbl.status', 'user_tbl.status ASC', 'user_tbl.status DESC');
$so->setColumn('user_tbl.login_abuse_exempt', 'user_tbl.login_abuse_exempt ASC', 'user_tbl.login_abuse_exempt DESC');
$so->setColumn('user_tbl.blocked', 'user_tbl.blocked ASC', 'user_tbl.blocked DESC');
$so->setColumn('user_tbl.blocked_reason', 'user_tbl.blocked_reason ASC', 'user_tbl.blocked_reason DESC');
$so->setColumn('user_tbl.abuse_warning_level', 'user_tbl.abuse_warning_level ASC', 'user_tbl.abuse_warning_level DESC');
$so->setColumn('user_tbl.seconds_online', 'user_tbl.seconds_online ASC', 'user_tbl.seconds_online DESC');
$so->setColumn('user_tbl.last_login_datetime', 'user_tbl.last_login_datetime ASC', 'user_tbl.last_login_datetime DESC');
$so->setColumn('user_tbl.last_access_datetime', 'user_tbl.last_access_datetime ASC', 'user_tbl.last_access_datetime DESC');
$so->setColumn('user_tbl.last_login_ip', 'user_tbl.last_login_ip ASC', 'user_tbl.last_login_ip DESC');
$so->setColumn('user_tbl.added_datetime', 'user_tbl.added_datetime ASC', 'user_tbl.added_datetime DESC');
$so->setColumn('user_tbl.added_by_user_id', 'user_tbl.added_by_user_id ASC', 'user_tbl.added_by_user_id DESC');
$so->setColumn('user_tbl.modified_datetime', 'user_tbl.modified_datetime ASC', 'user_tbl.modified_datetime DESC');
$so->setColumn('user_tbl.modified_by_user_id', 'user_tbl.modified_by_user_id ASC', 'user_tbl.modified_by_user_id DESC');
// Instantiate page numbers. Total items are set and calculation is done in the User::getPaginatedList() method.
$page = new PageNumbers();
$page->setPerPage(getFormData('per_page'), 100);
$page->setPageNumber(getFormData('page_number'));
// Query parameters to retain always.
$app->carryQuery(array(
'filter_account_id',
));
// Query parameters to retain only locally.
$locally_carried_queries = array(
'q',
);
/********************************************************************
* 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'], 'user');
}
if (getFormData('break_list_cache', false)) {
// Remove any stale cached list data.
$cache->delete('user list');
}
// What action to take.
switch (getFormData('op')) {
case 'add' :
// Bounce the user if they don't have permission to create a record.
User::requireAllow('create');
// Initialize variables for the form template.
$frm = getAddFields();
$nav->add(_("Add User"));
$main_template = 'user_form.inc.html';
break;
case 'edit' :
// Bounce the user if they don't have permission to update a record.
User::requireAllow('update');
// Initialize variables for the form template.
$frm = getEditFields(getFormData('user_id', $auth->get('user_id')));
$nav->add(_("Edit User"));
$main_template = 'user_form.inc.html';
break;
case 'del' :
$app->requireValidCSRFToken();
// Bounce the user if they don't have permission to delete the specified record.
User::requireAllow('delete', User::get(array('user_id' => getFormData('user_id')), 1));
if ($del_row = User::get(array('user_id' => getFormData('user_id')), 1)) {
User::delete(getFormData('user_id'));
$app->raiseMsg(sprintf(_("The user %s has been deleted."), $del_row['username']), MSG_SUCCESS, __FILE__, __LINE__);
}
if ($app->validBoomerangURL('user')) {
// Display boomerang page.
$app->dieBoomerangURL('user', $locally_carried_queries);
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF'], $locally_carried_queries);
break;
case 'insert' :
$app->requireValidCSRFToken();
if (getFormData('account_id')) {
// Bounce the user if they don't have permission to create a record under the specified account_id.
User::requireAllow('create', array(array('account_id' => getFormData('account_id'))));
} else {
// Bounce the user if they don't have permission to create a record at all.
User::requireAllow('create');
}
if (getFormdata('btn_cancel', false)) {
if ($app->validBoomerangURL('user')) {
// Display boomerang page.
$app->dieBoomerangURL('user', $locally_carried_queries);
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF'], $locally_carried_queries);
}
$fv = validateInput($fv);
if ($fv->anyErrors()) {
$frm = getAddFields();
$frm = array_merge($frm, getFormData());
$nav->add(_("Add User"));
$main_template = 'user_form.inc.html';
} else {
$user_id = User::insert(getFormData());
$app->raiseMsg(sprintf(_("The user %s has been added."), getFormData('username')), MSG_SUCCESS, __FILE__, __LINE__);
if (getFormdata('btn_repeat', false)) {
// Display function again.
$app->dieURL($_SERVER['PHP_SELF'] . '?op=add', $locally_carried_queries);
} else if ($app->validBoomerangURL('user')) {
// Display boomerang page.
$app->dieBoomerangURL('user', $locally_carried_queries);
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF'], $locally_carried_queries);
}
break;
case 'update' :
$app->requireValidCSRFToken();
if (getFormData('account_id')) {
// Bounce the user if they don't have permission to update the specified record or don't have permission to assign this record to the specified account_id.
$check_rows = array_merge(User::get(array('user_id' => getFormData('user_id')), 1), array(array('account_id' => getFormData('account_id'))));
User::requireAllow('update', $check_rows);
} else {
// Bounce the user if they don't have permission to update the specified record.
User::requireAllow('update', User::get(array('user_id' => getFormData('user_id')), 1));
}
if (getFormdata('btn_reset', false)) {
$app->raiseMsg(_("Saved values have been reloaded."), MSG_NOTICE, __FILE__, __LINE__);
$app->dieURL($_SERVER['PHP_SELF'] . '?op=edit&user_id=' . getFormData('user_id'), $locally_carried_queries);
}
if (getFormdata('btn_cancel', false)) {
// Remove lock
$lock->select('user_tbl', 'user_id', getFormData('user_id'));
$lock->remove();
if ($app->validBoomerangURL('user')) {
// Display boomerang page.
$app->dieBoomerangURL('user', $locally_carried_queries);
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF'], $locally_carried_queries);
}
$fv = validateInput($fv);
if ($fv->anyErrors()) {
$frm = getEditFields(getFormData('user_id'));
$frm = array_merge($frm, getFormData());
$nav->add(_("Edit User"));
$main_template = 'user_form.inc.html';
} else {
User::update(getFormData());
$app->raiseMsg(sprintf(_("The user %s has been updated."), getFormData('username')), MSG_SUCCESS, __FILE__, __LINE__);
if (getFormdata('btn_repeat', false)) {
// Display edit function with next available ID.
$qid = $db->query("SELECT user_id FROM user_tbl WHERE user_id > '" . $db->escapeString(getFormData('user_id')) . "' ORDER BY user_id ASC LIMIT 1");
if (list($next_id) = mysql_fetch_row($qid)) {
$app->dieURL($_SERVER['PHP_SELF'] . '?op=edit&user_id=' . $next_id, $locally_carried_queries);
} else {
$app->raiseMsg(_("Cannot edit next, the end of the list was reached"), MSG_NOTICE, __FILE__, __LINE__);
}
} else if ($app->validBoomerangURL('user')) {
// Display boomerang page.
$app->dieBoomerangURL('user', $locally_carried_queries);
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF'], $locally_carried_queries);
}
break;
default :
// Bounce the user if they don't have permission to list records.
User::requireAllow('read');
// If the user does not have access to 'any' record, limit by their account_id.
$where_clause = '';
if (!$acl->check('user_id:' . $auth->get('user_id'), 'user:read', 'any')) {
$where_clause = "WHERE user_tbl.account_id = '" . $db->escapeString($auth->get('account_id')) . "'";
}
$list = User::getPaginatedList($where_clause);
$main_template = 'user_list.inc.html';
break;
}
/********************************************************************
* OUTPUT
********************************************************************/
include 'header.inc.html';
$app->carryQuery($locally_carried_queries);
include $main_template;
include 'footer.inc.html';
/********************************************************************
* FUNCTIONS
********************************************************************/
/*
*
*
* @access public
* @param
* @return
* @author Quinn Comendant
* @version 1.0
* @since 16 Nov 2014 17:45:40
*/
function validateInput($fv)
{
global $auth;
// if (!verifySignature(getFormData('form_sig'))) {
// $app->logMsg(sprintf('Invalid form signature: %s', getFormData('form_sig')), LOG_NOTICE, __FILE__, __LINE__);
// $fv->addError('form_sig', _("Something went wrong; please try again."), MSG_ERR, __FILE__, __LINE__);
// return false;
// }
$fv->numericRange('user_id', 0, 65536, sprintf(_("%s must be a number between %d and %d."), _("User ID"), 0, 65536));
$fv->isInteger('user_id', sprintf(_("%s must be an integer."), _("User ID")));
$fv->notEmpty('account_id', sprintf(_("%s cannot be blank."), _("Account ID")));
$fv->numericRange('account_id', 0, 65536, sprintf(_("%s must be a number between %d and %d."), _("Account ID"), 0, 65536));
$fv->isInteger('account_id', sprintf(_("%s must be an integer."), _("Account ID")));
// $fv->notEmpty('first_name', sprintf(_("%s cannot be blank."), _("First name")));
$fv->stringLength('first_name', 0, 255, sprintf(_("%s must be %d-to-%d characters in length."), _("First name"), 0, 255));
// $fv->notEmpty('last_name', sprintf(_("%s cannot be blank."), _("Last name")));
$fv->stringLength('last_name', 0, 255, sprintf(_("%s must be %d-to-%d characters in length."), _("Last name"), 0, 255));
if ($fv->notEmpty('email', sprintf(_("%s cannot be blank."), _("Email address")))
&& $fv->stringLength('email', 0, 255, sprintf(_("%s must be %d-to-%d characters in length."), _("Email address"), 0, 255))
&& $fv->validateEmail('email')
&& User::get(array('email' => getFormData('email')))) {
$fv->addError('email', sprintf(_("A Pulso user already exists with the email address %s. If you want to create a new user, you’ll need to use a different address."), getFormData('email')), MSG_ERR, __FILE__, __LINE__);
return $fv;
}
if ($fv->notEmpty('username', sprintf(_("%s cannot be blank."), _("Username")))) {
// Alphanumeric only!
$fv->stringLength('username', 2, 100, sprintf(_("%s must be %d-to-%d characters in length."), _("Username"), 2, 100));
if ($fv->checkRegex('username', '/^[\w]{2,}$/i', true, _("Username must be 2 or more characters or numbers, without punctuation or spaces."))) {
// If the username was changed during edit, verify.
if (((getFormData('username') != getFormData('old_username')) && 'update' == getFormData('op')) || 'insert' == getFormData('op')) {
// Unique username!
if ($auth->usernameExists(getFormData('username'))) {
$fv->addError('username', sprintf(_("The %s %s is not available. Please choose another."), _("username"), getFormData('username')));
}
}
}
}
if ('create' == getFormData('op') && $fv->notEmpty('userpass', sprintf(_("%s cannot be blank."), _("Password")))) {
if (getFormData('complexity') < 20) {
$fv->addError('userpass', sprintf(_("Please choose a more complex password. Make it longer or add numbers and punctuation."), null), MSG_ERR, __FILE__, __LINE__);
}
}
// $fv->notEmpty('user_type', sprintf(_("%s cannot be blank."), _("User type")));
// $fv->stringLength('user_type', 0, 255, sprintf(_("%s has an invalid selection."), _("User type")));
// $fv->notEmpty('status', sprintf(_("%s cannot be blank."), _("Status")));
// $fv->stringLength('status', 0, 255, sprintf(_("%s has an invalid selection."), _("Status")));
// Ensure there is at least one master user.
// $qid = $db->query("
// SELECT * FROM user_tbl
// WHERE account_id = '" . $db->escapeString(getFormData('account_id')) . "'
// AND user_id != '" . $db->escapeString(getFormData('user_id')) . "'
// AND user_type = 'primary'
// ");
// if (mysql_num_rows($qid) < 1 && 'master' != getFormData('user_type')) {
// $fv->addError('user_type', _("The primary user cannot be deleted."));
// }
return $fv;
}
/*
*
*
* @access public
* @param
* @return
* @author Quinn Comendant
* @version 1.0
* @since 16 Nov 2014 17:45:40
*/
function getAddFields()
{
// Set default values for the reset of the fields.
return User::merge(array(
'new_op' => 'insert',
'submit_buttons' => array(
array('name' => 'btn_submit', 'value' => _("Add User"), 'class' => 'small button', 'accesskey' => 's'),
array('name' => 'btn_repeat', 'value' => _("Add & repeat"), 'class' => 'small button secondary', 'accesskey' => 'r'),
array('name' => 'btn_cancel', 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'c'),
),
));
}
/*
*
*
* @access public
* @param
* @return
* @author Quinn Comendant
* @version 1.0
* @since 16 Nov 2014 17:45:40
*/
function getEditFields($id)
{
global $lock, $locally_carried_queries;
$db =& DB::getInstance();
$app =& App::getInstance();
$lock->select('user_tbl', 'user_id', $id);
if ($lock->isLocked() && !$lock->isMine()) {
$lock->dieErrorPage();
}
// Get the information for the form.
$qid = $db->query("
SELECT *, '' AS userpass
FROM user_tbl
WHERE user_id = '" . $db->escapeString($id) . "'
");
if (!$frm = mysql_fetch_assoc($qid)) {
$app->logMsg('Could not find record with user_id: ' . $id, LOG_WARNING, __FILE__, __LINE__);
$app->raiseMsg(sprintf(_("The requested record %s could not be found."), $id), MSG_ERR, __FILE__, __LINE__);
$app->dieBoomerangURL('user', $locally_carried_queries);
}
// Lock this record.
$lock->set('user_tbl', 'user_id', $id, $frm['username']);
// Set misc values for the form.
return User::merge(array(
'new_op' => 'update',
'old_username' => $frm['username'],
'old_email' => $frm['email'],
'submit_buttons' => array(
array('name' => 'btn_submit', 'value' => _("Save changes"), 'class' => 'small button', 'accesskey' => 's'),
array('name' => 'btn_repeat', 'value' => _("Save & edit next"), 'class' => 'small button secondary', 'accesskey' => 'e'),
array('name' => 'btn_reset', 'value' => _("Reset"), 'class' => 'small button secondary', 'accesskey' => 'r'),
array('name' => 'btn_cancel', 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'c'),
),
), $frm);
}