forked from science-ation/science-ation
bae700dead
the roles for that user.
1259 lines
36 KiB
PHP
1259 lines
36 KiB
PHP
<?
|
|
/*
|
|
This file is part of the 'Science Fair In A Box' project
|
|
SFIAB Website: http://www.sfiab.ca
|
|
|
|
Copyright (C) 2005 Sci-Tech Ontario Inc <info@scitechontario.org>
|
|
Copyright (C) 2005 James Grant <james@lightbox.org>
|
|
Copyright (C) 2007 David Grant <dave@lightbox.org>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public
|
|
License as published by the Free Software Foundation, version 2.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
*/
|
|
?>
|
|
<?
|
|
include_once('account.inc.php');
|
|
function user_valid_role($role)
|
|
{
|
|
global $roles;
|
|
if(!is_array($role)) $role = array($role);
|
|
|
|
foreach($role as $r) {
|
|
if(!array_key_exists($r, $roles)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
function user_load($users_id, $accounts_id = false)
|
|
{
|
|
user_get_fields(array('judge'));
|
|
/* Load user, join accounts so we also load the email, superuser flag */
|
|
//hand-code the list here because we dont want all the old stuff that hasnt been removed yet like username/password access_*, etc.
|
|
if($accounts_id != false) {
|
|
$accounts_id = intval($accounts_id);
|
|
$users_id = mysql_result(mysql_query("SELECT users.id FROM users WHERE accounts_id = $accounts_id LIMIT 1", 0));
|
|
} else {
|
|
$users_id = intval($users_id);
|
|
}
|
|
|
|
$count = mysql_result(mysql_query("SELECT COUNT(*) FROM users WHERE id = $users_id"), 0);
|
|
if($count == 0){
|
|
return false;
|
|
}
|
|
if($count > 1){
|
|
echo "ERROR: More than one user.\n";
|
|
return false;
|
|
}
|
|
|
|
// Load the user, we'll start with a blank slate
|
|
$u = array();
|
|
|
|
// Get roles, and active/complete status for each role
|
|
$u['roles'] = array();
|
|
$fields = array(
|
|
'id',
|
|
'accounts_id',
|
|
'conferences_id',
|
|
'salutation',
|
|
'firstname',
|
|
'lastname',
|
|
'sex',
|
|
'phonehome',
|
|
'phonework',
|
|
'phonecell',
|
|
'fax',
|
|
'organization',
|
|
'birthdate',
|
|
'lang',
|
|
'created',
|
|
'lastlogin',
|
|
'address',
|
|
'address2',
|
|
'city',
|
|
'province',
|
|
'postalcode',
|
|
'fairs_id'
|
|
);
|
|
$query = "SELECT user_roles.roles_id, user_roles.active, user_roles.complete, roles.type,roles.name FROM user_roles LEFT JOIN roles ON roles.id=user_roles.roles_id WHERE user_roles.users_id=$users_id";
|
|
$q = mysql_query($query);
|
|
while(($roledata = mysql_fetch_assoc($q))) {
|
|
$u['roles'][$roledata['type']] = $roledata;
|
|
|
|
$fields = array_merge($fields,
|
|
user_fields_enabled($roledata['type']));
|
|
$fields = array_merge($fields,
|
|
user_fields_required($roledata['type']));
|
|
|
|
switch($roledata['type']) {
|
|
case 'committee':
|
|
$fields = array_merge($fields, array('ord', 'displayemail'));
|
|
break;
|
|
|
|
case 'judge':
|
|
$fields = array_merge($fields, array(
|
|
'years_school', 'years_regional', 'years_national', 'willing_chair',
|
|
'special_award_only', 'cat_prefs', 'div_prefs', 'divsub_prefs',
|
|
'languages', 'highest_psd'
|
|
));
|
|
break;
|
|
|
|
case 'sponsor':
|
|
$fields[] = 'sponsors_id';
|
|
break;
|
|
|
|
case 'volunteer':
|
|
$fields[] = 'languages';
|
|
break;
|
|
|
|
default:
|
|
/* Nothing to do for all other roles */
|
|
break;
|
|
}
|
|
}
|
|
$fields = array_unique($fields);
|
|
if(count($u['roles']) == 0) {
|
|
/* No roles, that's ok actually, the previous logic here was that
|
|
* a user without roles is deleted.. but.. this could happen for
|
|
* new users, or if someone deletes all their roles before adding
|
|
* a new role */
|
|
}
|
|
|
|
// now let's grab the data from the users table
|
|
$query = "SELECT users." . implode(", users.", $fields) . ", accounts.email";
|
|
$query .= " FROM users JOIN accounts ON accounts.id=users.accounts_id";
|
|
$query .= " WHERE `users`.`id`='$users_id'";
|
|
$q = mysql_query($query);
|
|
echo mysql_error();
|
|
|
|
// Sanitize the user data
|
|
$userDat = mysql_fetch_assoc($q);
|
|
$u = array_merge($u, $userDat);
|
|
$u['id'] = intval($u['id']);
|
|
$u['accounts_id'] = intval($u['accounts_id']);
|
|
$u['year'] = intval($u['year']);
|
|
|
|
/* Convenience */
|
|
$u['name'] = ($u['firstname'] ? "{$u['firstname']} " : '').$u['lastname'];
|
|
|
|
/* Email recipient for "to" field on emails */
|
|
if( ($u['firstname'] || $u['lastname']) && $u['email']) {
|
|
//use their full name if we have it
|
|
//if the name contains anything non-standard, we need to quote it.
|
|
if(eregi("[^a-z0-9 ]",$u['name']))
|
|
$u['emailrecipient']="\"{$u['name']}\" <{$u['email']}>";
|
|
else
|
|
$u['emailrecipient']="{$u['name']} <{$u['email']}>";
|
|
}
|
|
else if($u['email']) {
|
|
//otherwise, just their email address
|
|
$u['emailrecipient']=$u['email'];
|
|
}
|
|
else {
|
|
$u['emailrecipient']="";
|
|
}
|
|
|
|
/* we dont want them thinking they can change the email, so dont include it here,
|
|
its part of the account, not the user, this way they still get the 'emailrecipient'
|
|
convenience variable, not not the email itself, for that, they need to access
|
|
the account. */
|
|
unset($u['email']);
|
|
$should_be_arrays=array();
|
|
|
|
|
|
foreach(array_keys($u['roles']) as $r) {
|
|
/* Do the load routines inline, the explosion of user roles
|
|
* means it's just silly to have a different function for each
|
|
* one. If we get one that has a crazy amount of stuff to do,
|
|
* we could move it all to a function and call it in the
|
|
* switch below */
|
|
switch($r) {
|
|
case 'committee':
|
|
$u['ord'] = intval($u['ord']);
|
|
$u['displayemail'] = ($u['displayemail'] == 'yes') ? 'yes' : 'no';
|
|
break;
|
|
|
|
case 'judge':
|
|
$u['years_school'] = intval($u['years_school']);
|
|
$u['years_regional'] = intval($u['years_regional']);
|
|
$u['years_national'] = intval($u['years_national']);
|
|
$u['willing_chair'] = ($u['willing_chair'] == 'yes') ? 'yes' : 'no';
|
|
$u['special_award_only'] = ($u['special_award_only'] == 'yes') ? 'yes' : 'no';
|
|
$u['cat_prefs'] = (strlen($u['cat_prefs']) > 0) ? unserialize($u['cat_prefs']) : array();
|
|
$u['div_prefs'] = (strlen($u['div_prefs']) > 0) ? unserialize($u['div_prefs']) : array();
|
|
$u['divsub_prefs'] = (strlen($u['divsub_prefs']) > 0) ? unserialize($u['divsub_prefs']) : array();
|
|
// $u['expertise_other'] = $u['expertise_other'];
|
|
//if it hasnt been parsed/converted yet
|
|
if(!is_array($u['languages']))
|
|
$u['languages'] = (strlen($u['languages']) > 0) ? unserialize($u['languages']) : array();
|
|
// $u['highest_psd'] = $u['highest_psd'];
|
|
|
|
/* Sanity check the arrays, make sure they are arrays */
|
|
$should_be_arrays = array('cat_prefs','div_prefs', 'divsub_prefs','languages');
|
|
break;
|
|
|
|
case 'sponsor':
|
|
$u['sponsors_id'] = intval($u['sponsors_id']);
|
|
if($u['sponsors_id']) {
|
|
$q=mysql_query("SELECT * FROM sponsors WHERE id='{$u['sponsors_id']}'");
|
|
$u['sponsor']=mysql_fetch_assoc($q);
|
|
}
|
|
break;
|
|
case 'volunteer':
|
|
//if it hasnt been parsed/converted yet
|
|
if(!is_array($u['languages']))
|
|
$u['languages'] = (strlen($u['languages']) > 0) ? unserialize($u['languages']) : array();
|
|
$should_be_arrays = array('languages');
|
|
break;
|
|
|
|
default:
|
|
/* Nothing to do for all other roles */
|
|
break;
|
|
}
|
|
}
|
|
foreach($should_be_arrays as $k) {
|
|
if(!is_array($u[$k])) $u[$k] = array();
|
|
}
|
|
|
|
/* Do this assignment without recursion :) */
|
|
unset($u['orig']);
|
|
$orig = $u;
|
|
$u['orig'] = $orig;
|
|
$u['required_fields']=user_all_fields_required(array_keys($u['roles']));
|
|
return $u;
|
|
}
|
|
|
|
function user_load_by_accounts_id($accounts_id)
|
|
{
|
|
return user_load(0, $accounts_id);
|
|
}
|
|
|
|
function user_load_by_email($email)
|
|
{
|
|
/* Find the accounts_id for the email, regardless of deleted status */
|
|
$e = mysql_real_escape_string($email);
|
|
$q = mysql_query("SELECT accounts_id FROM users WHERE email='$e' OR username='$e'");
|
|
|
|
if(mysql_num_rows($q) == 1) {
|
|
$i = mysql_fetch_assoc($q);
|
|
return user_load_by_accounts_id($i['accounts_id']);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function user_get_role_fields($role){
|
|
switch($role){
|
|
case 'committee':
|
|
$fields = array('emailprivate','ord','displayemail');
|
|
break;
|
|
case 'judge':
|
|
$fields = array('years_school','years_regional','years_national',
|
|
'willing_chair','special_award_only',
|
|
'cat_prefs','div_prefs','divsub_prefs',
|
|
'expertise_other','languages', 'highest_psd');
|
|
break;
|
|
case 'student':
|
|
$fields = array('grade', 'schools_id');
|
|
break;
|
|
case 'fair':
|
|
$fields = array('fairs_id');
|
|
break;
|
|
case 'sponsor':
|
|
$fields = array('sponsors_id','primary','position','notes');
|
|
break;
|
|
case 'teacher':
|
|
$fields = array();
|
|
break;
|
|
case 'volunteer':
|
|
$fields = array('languages');
|
|
break;
|
|
default:
|
|
$fields = array();
|
|
}
|
|
return $fields;
|
|
}
|
|
|
|
function user_get_field_labels(){
|
|
return array(
|
|
'salutation' => 'Salutation',
|
|
'firstname' => 'First Name',
|
|
'lastname' => 'Last Name',
|
|
'sex' => 'Sex',
|
|
'phonehome' => 'Home Phone',
|
|
'phonework' => 'Work Phone',
|
|
'phonecell' => 'Cell Phone',
|
|
'fax' => 'Fax Number',
|
|
'organization' => 'Organization',
|
|
'birthdate' => 'Date of Birth',
|
|
'lang' => 'Language',
|
|
'address' => 'Address',
|
|
'address2' => '',
|
|
'city' => 'City',
|
|
'province' => 'Province',
|
|
'postalcode' => 'Postal Code',
|
|
'firstaid' => 'First Aid',
|
|
'cpr' => 'CPR',
|
|
'displayemail' => 'Display Email',
|
|
'years_school' => 'Years experience judging at school level',
|
|
'years_regional' => 'Years experience judging at regional level',
|
|
'years_national' => 'Years experience judging at national level',
|
|
'willing_chair' => 'Willing to lead a judging team',
|
|
'special_award_only' => 'Judging only for a special award',
|
|
'languages' => 'Languages',
|
|
|
|
);
|
|
}
|
|
|
|
function role_field_required($role, $fieldname){
|
|
$returnval = 0;
|
|
$requiredFields = array(
|
|
'judge' => array('years_school','years_regional','years_national','languages'),
|
|
'student' => array('schools_id'),
|
|
'fair' => array('fairs_id'),
|
|
'sponsor' => array('sponsors_id','primary','position'),
|
|
'volunteer' => array('languages')
|
|
);
|
|
|
|
if(array_key_exists($role, $requiredFields)){
|
|
if(in_array($fieldname, $requiredFields[$role])){
|
|
$returnval = 1;
|
|
}
|
|
}
|
|
return $returnval;
|
|
}
|
|
|
|
// accepts either an array of roles (eg. {'judge', 'teacher', 'foo'}), a single one as a string (eg. 'judge'), or a null value (no roles at all)
|
|
function user_get_fields($userRoles = null){
|
|
global $roles;
|
|
|
|
if($userRoles == null){
|
|
$userRoles = array();
|
|
}else if(!is_array($userRoles)){
|
|
// assume that they passed a string identifying a single role (eg. "judge")
|
|
$userRoles = array($userRoles);
|
|
}
|
|
|
|
// scrub for only valid roles, and fetch their special fields
|
|
$enabledFields = array();
|
|
$requiredFields = array();
|
|
$roleFields = array();
|
|
foreach($userRoles as $role){
|
|
if(array_key_exists($role, $roles)){
|
|
$requiredFields = array_merge($requiredFields, user_fields_required($role));
|
|
$enabledFields = array_merge($enabledFields, user_fields_enabled($role));
|
|
$roleFields[$role] = user_get_role_fields($role);
|
|
}
|
|
}
|
|
|
|
// build a list of all fields that are applicable to this user, and assemble them into an array
|
|
$fields = array();
|
|
foreach($requiredFields as $field){
|
|
if(!array_key_exists($field, $fields)){
|
|
$fields[$field] = array(
|
|
'field' => $field,
|
|
'required' => 1
|
|
);
|
|
}
|
|
}
|
|
|
|
foreach($roleFields as $role => $fieldList){
|
|
foreach($fieldList as $field){
|
|
if(!array_key_exists($field, $fields)){
|
|
$fields[$field] = array(
|
|
'field' => $field,
|
|
'required' => role_field_required($role, $field)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach($enabledFields as $field){
|
|
if(!array_key_exists($field, $fields)){
|
|
$fields[$field] = array(
|
|
'field' => $field,
|
|
'required' => 0
|
|
);
|
|
}
|
|
}
|
|
|
|
// get the field types
|
|
$query = mysql_query("DESCRIBE users");
|
|
$fieldType = array();
|
|
while($row = mysql_fetch_assoc($query)){
|
|
$fieldType[$row['Field']] = $row['Type'];
|
|
}
|
|
|
|
$fieldLabels = user_get_field_labels();
|
|
|
|
foreach($fields as $fieldName => $field){
|
|
$ftype = $fieldType[$fieldName];
|
|
if(array_key_exists($fieldName, $fieldLabels)){
|
|
$fields[$fieldName]['display'] = $fieldLabels[$fieldName];
|
|
}
|
|
switch($fieldName){
|
|
case 'languages':
|
|
case 'cat_prefs':
|
|
case 'div_prefs':
|
|
case 'divsub_prefs':
|
|
// cases not yet handled
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
if(!strncasecmp($ftype, "varchar", 7)){
|
|
$parts = explode(')', $ftype);
|
|
$parts = explode('(', $parts[0]);
|
|
$fields[$fieldName]['type'] = $parts[0] . ':' . $parts[1];
|
|
}else if(!strncasecmp($ftype, "enum", 4)){
|
|
$fields[$fieldName]['type'] = 'enum';
|
|
$fields[$fieldName]['options'] = array();
|
|
$parts = explode("'", $ftype);
|
|
for($n = 1; $n < count($parts); $n += 2){
|
|
$fields[$fieldName]['options'][$parts[$n]] = ucfirst($parts[$n]);
|
|
}
|
|
}else if(!strcmp($ftype, "date")){
|
|
$fields[$fieldName]['type'] = $fieldType[$fieldName];
|
|
}else if(!strncmp($ftype, "tinyint", 7)){
|
|
$fields[$fieldName]['type'] = 'integer';
|
|
}else if(!strncmp($ftype, "tinytext", 8)){
|
|
$fields[$fieldName]['type'] = 'text';
|
|
}else{
|
|
$fields[$fieldName]['type'] = "ERROR:" . $fieldType[$fieldName];
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
echo "<pre>";
|
|
print_r(($userRoles));
|
|
print_r($fields);
|
|
echo "</pre>";
|
|
*/
|
|
return $fields;
|
|
}
|
|
|
|
/* FIXME: these are going to need conference IDs too */
|
|
function user_load_by_accounts_id_year($uid, $year)
|
|
{
|
|
echo "FIXME";
|
|
exit;
|
|
$q = mysql_query("SELECT id FROM users WHERE uid='$uid' AND year <= '$year'");
|
|
if(!mysql_num_rows($q)) return false;
|
|
$i = mysql_fetch_assoc($q);
|
|
return user_load($i['id']);
|
|
}
|
|
|
|
// this depends on the naming convention that any given role that needs a completion check
|
|
// will have a function called <role>_status_update, which updates their status with the
|
|
// current session data and returns 'complete' or 'incomplete' accordingly.
|
|
// I love the fact that this remark took more characters than the function.
|
|
function user_check_role_complete($u, $role){
|
|
$func = $role . '_status_update';
|
|
if(function_exists($func)){
|
|
$result = $func($u); // that's right, func(u)!
|
|
}else{
|
|
$result = 'complete';
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
function user_save(&$u)
|
|
{
|
|
global $conference;
|
|
global $roles;
|
|
|
|
/* Sanity check */
|
|
if($u['conferences_id'] != $u['orig']['conferences_id']) {
|
|
//echo "The user's conference changed. Can't save a user to a difference conference, use user_dupe to copy the user to a new conference.\n";
|
|
return -1;
|
|
}
|
|
|
|
// Update 'active' status for all roles
|
|
$new_roles = array_keys($u['roles']);
|
|
foreach($new_roles as $r) {
|
|
mysql_query("UPDATE user_roles SET active='{$u['roles'][$r]['active']}' WHERE roles_id='{$u['roles'][$r]['roles_id']}' AND users_id='{$u['id']}'");
|
|
echo mysql_error();
|
|
}
|
|
|
|
$fields = array('salutation','firstname','lastname',
|
|
'phonehome','phonework','phonecell','fax','organization',
|
|
'address','address2','city','province','postalcode','sex',
|
|
'firstaid', 'cpr', 'lang', 'notes');
|
|
|
|
$fields_for_role['committee'] = array('emailprivate','ord','displayemail');
|
|
$fields_for_role['judge'] = array('years_school','years_regional','years_national',
|
|
'willing_chair','special_award_only',
|
|
'cat_prefs','div_prefs','divsub_prefs',
|
|
'expertise_other','languages', 'highest_psd');
|
|
$fields_for_role['student'] = array('schools_id');
|
|
$fields_for_role['fair'] = array('fairs_id');
|
|
$fields_for_role['sponsor'] = array('sponsors_id','primary','position');
|
|
$fields_for_role['teacher'] = array();
|
|
$fields_for_role['volunteer'] = array('languages');
|
|
|
|
/* Merge fields as necessary, build a big list of fields to save */
|
|
foreach($new_roles as $r) {
|
|
if(!array_key_exists($r, $fields_for_role)) continue;
|
|
$fields = array_merge($fields, $fields_for_role[$r]);
|
|
}
|
|
|
|
$set = "";
|
|
foreach($fields as $f) {
|
|
if($u[$f] == $u['orig'][$f]) continue;
|
|
|
|
if($set != "") $set .=',';
|
|
|
|
if($u[$f] == NULL) {
|
|
$set .= "$f=NULL";
|
|
continue;
|
|
}
|
|
|
|
if(is_array($u[$f]))
|
|
$data = mysql_escape_string(serialize($u[$f]));
|
|
else
|
|
$data = mysql_escape_string(stripslashes($u[$f]));
|
|
$set .= "$f='$data'";
|
|
}
|
|
|
|
if($set != "") {
|
|
$query = "UPDATE users SET $set WHERE id='{$u['id']}'";
|
|
mysql_query($query);
|
|
echo mysql_error();
|
|
}
|
|
|
|
/* Record all the data in orig that we saved so subsequent
|
|
* calls to user_save don't try to overwrite data already
|
|
* saved to the database */
|
|
unset($u['orig']);
|
|
$orig = $u;
|
|
$u['orig'] = $orig;
|
|
|
|
// print_r($u);
|
|
}
|
|
|
|
|
|
// mark the role as complete if it's qualifications are met
|
|
function user_complete_role($users_id, $role){
|
|
// avoid SQL injections
|
|
$role = mysql_real_escape_string($role);
|
|
$users_id *= 1;
|
|
|
|
// get the id of the role
|
|
$row = mysql_fetch_assoc(mysql_query("SELECT id FROM roles WHERE type = '$role'"));
|
|
if(!is_array($row)){
|
|
return false;
|
|
}
|
|
$roles_id = $row['id'];
|
|
|
|
// does this user have the given role?
|
|
$row = mysql_fetch_array(mysql_query("SELECT * FROM user_roles WHERE users_id = $users_id AND roles_id = $roles_id"));
|
|
if(!is_array($row)){
|
|
return false;
|
|
}
|
|
|
|
// ok, it's a valid role and the specified user has it. Now let's see if we can mark it as complete
|
|
$user = user_load($users_id);
|
|
$result = user_check_role_complete($user, $role);
|
|
|
|
if($result == 'ok'){
|
|
return true;
|
|
}else{
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
// mark the role as being incomplete - not a verb sadly
|
|
function user_uncomplete_role($users_id, $role){
|
|
// avoid SQL injections
|
|
$role = mysql_real_escape_string($role);
|
|
$users_id *= 1;
|
|
|
|
// get the id of the role
|
|
$row = mysql_fetch_assoc(mysql_query("SELECT id FROM roles WHERE type = '$role'"));
|
|
if(!is_array($row)){
|
|
return false;
|
|
}
|
|
$roles_id = $row['id'];
|
|
|
|
// and update said role for the given user id
|
|
return mysql_query("UPDATE user_roles SET complete = 'no' WHERE users_id = $users_id AND roles_id = $roles_id");
|
|
|
|
}
|
|
|
|
// activate the specified role for the specified user if they have that role
|
|
function user_activate_role($users_id, $roles_id){
|
|
// Make sure the role is indeed there
|
|
$query = "SELECT * FROM user_roles WHERE roles_id = $roles_id AND users_id = $users_id";
|
|
$data = mysql_fetch_array(mysql_query($query));
|
|
if(!is_array($data)){
|
|
// can't be activated if you don't have it!
|
|
return false;
|
|
}
|
|
|
|
return mysql_query("UPDATE user_roles SET active='yes' WHERE users_id = $users_id AND roles_id = $roles_id");
|
|
}
|
|
|
|
// deactivate the specified role for the specified user if they have that role
|
|
function user_deactivate_role($users_id, $roles_id){
|
|
// Make sure the role is indeed there
|
|
$query = "SELECT * FROM user_roles WHERE roles_id = $roles_id AND users_id = $users_id";
|
|
$data = mysql_fetch_array(mysql_query($query));
|
|
if(!is_array($data)){
|
|
// can't be deactivated if you don't have it!
|
|
return false;
|
|
}
|
|
|
|
return mysql_query("UPDATE user_roles SET active='no' WHERE users_id = $users_id AND roles_id = $roles_id");
|
|
}
|
|
|
|
// Remove a role for a user.
|
|
// now just a skin on top of account_remove_role
|
|
function user_remove_role(&$u, $role)
|
|
{
|
|
global $roles;
|
|
$result = account_remove_role($u['accounts_id'], $roles[$role]['id'], $u['conferences_id']);
|
|
|
|
// Delete the role
|
|
if(array_key_exists($role, $u['roles'])) {
|
|
unset($u['roles'][$role]);
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/* If role is specified, just delete the role from the user.
|
|
* If not, delete the whole user, all roles */
|
|
function user_delete($u, $role=false)
|
|
{
|
|
$finish_delete = false;
|
|
|
|
if(!is_array($u)) {
|
|
$u = user_load($u);
|
|
}
|
|
if($role != false) {
|
|
account_remove_role($u['accounts_id'], $roles[$role]['id'], $u['conferences_id']);
|
|
if(array_key_exists($role, $u['roles'])) {
|
|
unset($u['roles'][$role]);
|
|
}
|
|
|
|
if(count($u['roles']) == 0) {
|
|
/* No roles left, finish the delete */
|
|
$finish_delete = true;
|
|
}
|
|
} else {
|
|
/* Delete the whole user, every role */
|
|
foreach(array_keys($u['roles']) as $r){
|
|
account_remove_role($u['accounts_id'], $roles[$r]['id'], $u['conferences_id']);
|
|
if(array_key_exists($role, $u['roles'])) {
|
|
unset($u['roles'][$role]);
|
|
}
|
|
}
|
|
|
|
$finish_delete = true;
|
|
}
|
|
|
|
if($finish_delete) {
|
|
mysql_query("UPDATE users SET deleted='yes', deleteddatetime=NOW() WHERE id='{$u['id']}'");
|
|
return true;
|
|
}
|
|
|
|
/* User had some other role, so delete was not completed. */
|
|
return false;
|
|
}
|
|
|
|
/* Purge functions. These completely eliminate all traces of a user from the
|
|
* database. This action cannot be undone. We prefer the committee to use the
|
|
* "delete" functions, which simply mark the account as "deleted". */
|
|
function user_purge($u, $role=false)
|
|
{
|
|
/* Delete the user, then completely delete them from
|
|
* the DB if delete returns true, that is, if there's
|
|
* no other role blocking the delete/purge */
|
|
$finish_purge = user_delete($u, $role);
|
|
|
|
if($finish_purge == true) {
|
|
mysql_query("DELETE FROM users WHERE id='{$u['id']}'");
|
|
return true;
|
|
}
|
|
|
|
/* Not purged, some other role existed */
|
|
return false;
|
|
}
|
|
|
|
|
|
/* Duplicate a row in the users table, or any one of the users_* tables. */
|
|
function user_dupe_row($db, $key, $val, $newval)
|
|
{
|
|
global $config;
|
|
$nullfields = array('deleteddatetime'); /* Fields that can be null */
|
|
$q = mysql_query("SELECT * FROM $db WHERE $key='$val'");
|
|
if(mysql_num_rows($q) != 1) {
|
|
echo "ERROR duplicating row in $db: $key=$val NOT FOUND.\n";
|
|
exit;
|
|
}
|
|
$i = mysql_fetch_assoc($q);
|
|
$i[$key] = $newval;
|
|
|
|
foreach($i as $k=>$v) {
|
|
if($v == NULL && in_array($k, $nullfields))
|
|
$i[$k] = 'NULL';
|
|
else if($k == 'year')
|
|
$i[$k] = $config['FAIRYEAR'];
|
|
else
|
|
$i[$k] = '\''.mysql_escape_string($v).'\'';
|
|
}
|
|
|
|
$keys = '`'.join('`,`', array_keys($i)).'`';
|
|
$vals = join(',', array_values($i));
|
|
|
|
$q = "INSERT INTO $db ($keys) VALUES ($vals)";
|
|
// echo "Dupe Query: [$q]";
|
|
$r = mysql_query($q);
|
|
echo mysql_error();
|
|
|
|
$id = mysql_insert_id();
|
|
return $id;
|
|
}
|
|
/* Used by the login scripts to copy one user from one year to another */
|
|
function user_dupe($u, $new_year)
|
|
{
|
|
/* Dupe a user if:
|
|
* - They don't exist in the current year
|
|
* (users->year != the target year (passed in so we can use it in the rollover script) )
|
|
* - They have a previous year entry
|
|
* (users->year DESC LIMIT 1 == 1 row)
|
|
* - That previous entry has deleted=no */
|
|
|
|
/* Find the last entry */
|
|
$q = mysql_query("SELECT id,uid,year,deleted FROM users WHERE uid='{$u['uid']}'
|
|
ORDER BY year DESC LIMIT 1");
|
|
$r = mysql_fetch_object($q);
|
|
if($r->deleted == 'yes') {
|
|
echo "Cannot duplicate user ID {$u['id']}, they are deleted. Undelete them first.\n";
|
|
exit;
|
|
}
|
|
if($r->year == $new_year) {
|
|
echo "Cannot duplicate user ID {$u['id']}, they already exist in year $new_year\n";
|
|
exit;
|
|
}
|
|
|
|
$id = user_dupe_row('users', 'id', $u['id'], NULL);
|
|
$q = mysql_query("UPDATE users SET year='$new_year' WHERE id='$id'");
|
|
|
|
/* Load the new user */
|
|
$u2 = user_load($id);
|
|
|
|
foreach($u2['types'] as $t) {
|
|
user_dupe_row("users_$t", 'users_id', $u['id'], $id);
|
|
}
|
|
/* Return the ID of the new user */
|
|
return $id;
|
|
}
|
|
|
|
/* Returns true if loaded user ($u) is allowed to add role $role to their
|
|
* profile. THis is intended as a last-stop mechanism, preventing, for example
|
|
* a student from co-existing with any other role . */
|
|
function user_add_role_allowed(&$u, $role)
|
|
{
|
|
foreach(array_keys($u['orig']['roles']) as $ur) {
|
|
switch($ur) {
|
|
case 'student':
|
|
/* Student cant' add any other role */
|
|
return false;
|
|
|
|
default:
|
|
if($role == 'student') {
|
|
/* No role can add the student role */
|
|
return false;
|
|
}
|
|
|
|
/* All other roles can coexist (even the fair role) */
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
// Add a role for a user.
|
|
// now just a skin on top of account_add_role
|
|
function user_add_role(&$u, $role, $password = null){
|
|
$row = mysql_fetch_assoc(mysql_query("SELECT conferences_id FROM users WHERE id = " . $u['id']));
|
|
if(!is_array($q)){
|
|
return 'no conference';
|
|
}
|
|
$conference_id = $q['conferences_id'];
|
|
$result = account_add_role($u['accounts_id'], $roles[$role]['id'], $password);
|
|
if($result == 'ok'){
|
|
// we need this "if" because account_add_role will return "ok" if they already have this role
|
|
if(!in_array($role, $_SESSION['roles'])){
|
|
$_SESSION['roles'][] = $role;
|
|
}
|
|
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
function user_create($accounts_id, $conferences_id=0)
|
|
{
|
|
global $config, $conference;
|
|
|
|
if($conferences_id == 0) $conferences_id = $conference['id'];
|
|
|
|
/* Make sure the user doesn't already exist */
|
|
$q = mysql_query("SELECT id FROM users WHERE accounts_id='$accounts_id' AND conferences_id='$conferences_id'");
|
|
echo mysql_error();
|
|
if(mysql_num_rows($q)) {
|
|
echo "ERROR: user_create called for a user that already exists.\n";
|
|
exit;
|
|
}
|
|
|
|
$fields = array(
|
|
'accounts_id' => $accounts_id,
|
|
'conferences_id' => $conferences_id,
|
|
);
|
|
|
|
/* Get old user data if available */
|
|
$results = mysql_fetch_assoc(mysql_query("SELECT * FROM users WHERE accounts_id = '$accounts_id' ORDER BY id DESC LIMIT 1"));
|
|
if(is_array($results)){
|
|
$skipfields = array('id', 'created', 'lastlogin', 'year', 'accounts_id', 'conferences_id', 'deleted', 'deleteddatetime');
|
|
foreach($results as $fname => $value){
|
|
if(!in_array($fname, $skipfields) && $value != null){
|
|
$fields[$fname] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Create the user */
|
|
$fieldList = array_keys($fields);
|
|
$query = "INSERT INTO users(`created`, `" . implode('`,`', $fieldList) . "`) VALUES(NOW(), '" . implode("','", $fields) . "')";
|
|
|
|
mysql_query($query);
|
|
$id = mysql_insert_id();
|
|
|
|
/* Return a loaded user with no roles */
|
|
return user_load($id);
|
|
}
|
|
|
|
|
|
|
|
/* Perform some checks. Make sure the person is logged in, and that their
|
|
* password hasn't expired (the password_expired var is set in the login page)
|
|
*/
|
|
function user_auth_required($all_required = array(), $one_required = array())
|
|
{
|
|
global $config;
|
|
$ok = true;
|
|
|
|
unset($_SESSION['request_uri']);
|
|
if(!isset($_SESSION['roles']) || !isset($_SESSION['accounts_id'])) {
|
|
message_push(error(i18n("You must login to view that page")));
|
|
$_SESSION['request_uri'] = $_SERVER['REQUEST_URI'];
|
|
header("location: {$config['SFIABDIRECTORY']}/user_login.php");
|
|
exit;
|
|
}
|
|
|
|
/* Make sure the user has each role in $all_required, this returns
|
|
* an array in the same order as $all_required, with all members
|
|
* in $all_required that are also in the session roles */
|
|
if(!is_array($all_required)) $all_required = array($all_required);
|
|
|
|
$match = array_intersect($all_required, $_SESSION['roles']);
|
|
if($all_required != $match) {
|
|
/* Something is missing */
|
|
$ok = false;
|
|
}
|
|
|
|
/* Make sure the user has one role in $one_required */
|
|
if(!is_array($one_required)) $one_required = array($one_required);
|
|
if(count($one_required)) {
|
|
$match = array_intersect($one_required, $_SESSION['roles']);
|
|
if(count($match) == 0) {
|
|
/* Missing any role in $one_required */
|
|
$ok = false;
|
|
}
|
|
}
|
|
|
|
if(!$ok) {
|
|
message_push(error(i18n("You do not have permission to view that page")));
|
|
header("location: {$config['SFIABDIRECTORY']}/user_login.php");
|
|
exit;
|
|
}
|
|
|
|
/* Forward to password expired, remember the target URI */
|
|
if($_SESSION['password_expired'] == true) {
|
|
$_SESSION['request_uri'] = $_SERVER['REQUEST_URI'];
|
|
header("location: {$config['SFIABDIRECTORY']}/user_edit.php");
|
|
exit;
|
|
}
|
|
|
|
/* Return the first role that matched, this retains the previous
|
|
* behaviour */
|
|
return $match[0];
|
|
}
|
|
|
|
/* Perform some checks. Make sure the person is logged in, and that their
|
|
* password hasn't expired (the password_expired var is set in the login page)
|
|
*/
|
|
function api_user_auth_required($all_required = array(), $one_required = array())
|
|
{
|
|
global $config;
|
|
$ok = true;
|
|
$ret=array();
|
|
|
|
if(!isset($_SESSION['roles']) || !isset($_SESSION['accounts_id'])) {
|
|
$ret['status']="error";
|
|
$ret['error']="Not logged in";
|
|
return $ret;
|
|
}
|
|
|
|
/* Make sure the user has each role in $all_required, this returns
|
|
* an array in the same order as $all_required, with all members
|
|
* in $all_required that are also in the session roles */
|
|
if(!is_array($all_required)) $all_required = array($all_required);
|
|
|
|
$match = array_intersect($all_required, $_SESSION['roles']);
|
|
if($all_required != $match) {
|
|
/* Something is missing */
|
|
$ok = false;
|
|
}
|
|
|
|
/* Make sure the user has one role in $one_required */
|
|
if(!is_array($one_required)) $one_required = array($one_required);
|
|
if(count($one_required)) {
|
|
$match = array_intersect($one_required, $_SESSION['roles']);
|
|
if(count($match) == 0) {
|
|
/* Missing any role in $one_required */
|
|
$ok = false;
|
|
}
|
|
}
|
|
|
|
if(!$ok) {
|
|
$ret['status']="error";
|
|
$ret['error']="You do not have permission to access that information";
|
|
return $ret;
|
|
}
|
|
|
|
/* Forward to password expired, remember the target URI */
|
|
if($_SESSION['password_expired'] == true) {
|
|
$ret['status']="error";
|
|
$ret['error']="Your password has expired";
|
|
return $ret;
|
|
}
|
|
$ret['status']="ok";
|
|
$ret['match']=$match[0];
|
|
return $ret;
|
|
}
|
|
|
|
|
|
function user_volunteer_registration_status()
|
|
{
|
|
global $config;
|
|
// $now = date('Y-m-d H:i:s');
|
|
// if($now < $config['dates']['judgeregopen']) return "notopenyet";
|
|
// if($now > $config['dates']['judgeregclose']) return "closed";
|
|
return "open";
|
|
}
|
|
|
|
function user_teacher_registration_status(){
|
|
return "open";
|
|
}
|
|
|
|
function user_judge_registration_status()
|
|
{
|
|
global $config;
|
|
$now = date('Y-m-d H:i:s');
|
|
if(array_key_exists('judgeregopen', $config['dates'])){
|
|
if($now < $config['dates']['judgeregopen']) return "notopenyet";
|
|
if($now > $config['dates']['judgeregclose']) return "closed";
|
|
}
|
|
return "open";
|
|
}
|
|
|
|
$user_fields_map = array(
|
|
/* Account -- Email requirement is set based on username, which
|
|
* is always required. Password is not required unless they type
|
|
* in the field, in which case the form validator kicks
|
|
* (checks pass1==pass2 and all that) */
|
|
// 'email' => array('email'),
|
|
/* Personal */
|
|
'salutation' => array('salutation'),
|
|
'name' => array('firstname','lastname'),
|
|
'sex' => array('sex'),
|
|
'phonehome' => array('phonehome'),
|
|
'phonecell' => array('phonecell'),
|
|
'birthdate' => array('birthdate'),
|
|
'lang' => array('lang'),
|
|
'address' => array('address', 'address2', 'postalcode'),
|
|
'city' => array('city'),
|
|
'province' => array('province'),
|
|
'firstaid' => array('firstaid','cpr'),
|
|
/* Organization */
|
|
'org' => array('organization'),
|
|
'phonework' => array('phonework'),
|
|
'fax' => array('fax'),
|
|
);
|
|
|
|
/* Return fields to show based on role. In the user editor, many
|
|
* fields are always shown and some have hard-coded requirements, but
|
|
* any in this list can be made optionally-required or not shown
|
|
* at all */
|
|
function user_fields_enabled($role)
|
|
{
|
|
global $config, $user_fields_map;
|
|
$ret = array('firstname','lastname');
|
|
$fields = $config["{$role}_personal_fields"];
|
|
if($fields != '') {
|
|
$fields = explode(',', $fields);
|
|
foreach($fields as $f) {
|
|
$ret = array_merge($ret, $user_fields_map[$f]);
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
/* Return required fields. Some fields are always shown and can be
|
|
* set to required. Some have hard-coded requirement status. This is only
|
|
* for the fields where the requirement can be configured. Not for ALL fields
|
|
* the user sees */
|
|
function user_fields_required($role)
|
|
{
|
|
global $config, $user_fields_map;
|
|
$ret = array('firstname','lastname');
|
|
$required = $config["{$role}_personal_required"];
|
|
if($required != '') {
|
|
$fields = explode(',', $required);
|
|
foreach($fields as $f) {
|
|
$ret = array_merge($ret, $user_fields_map[$f]);
|
|
}
|
|
}
|
|
/* Filter some elements that are never required.
|
|
* - address2
|
|
*/
|
|
$ret = array_diff($ret, array('address2'));
|
|
return $ret;
|
|
}
|
|
|
|
function user_all_fields_required($roles) {
|
|
$ret=array();
|
|
foreach($roles AS $role) {
|
|
$ret=array_merge($ret,user_fields_required($role));
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
//this function checks if $field is set in the user record, if it is, it returns it, otherwise, it returns false __AND__ redirects to the redirect page.
|
|
function user_field_required($field,$redirect) {
|
|
$u=user_load($_SESSION['users_id']);
|
|
if($u[$field])
|
|
return $u[$field];
|
|
else {
|
|
header("Location: $redirect");
|
|
}
|
|
|
|
}
|
|
|
|
/* user_{$role}_login() is called with a full $u loaded */
|
|
|
|
function user_fair_login($u)
|
|
{
|
|
/* Double check, make sure the user is of this role */
|
|
if(!array_key_exists('fair', $u['roles'])) {
|
|
echo "ERROR: attempted to login fair on a non-fair user\n";
|
|
exit;
|
|
}
|
|
|
|
$_SESSION['fairs_id'] = $u['fairs_id'];// == 'yes') ? true : false;
|
|
}
|
|
|
|
function superuser_required() {
|
|
//first, they have to be logged in
|
|
user_auth_required();
|
|
|
|
//next, they need superuser
|
|
if($_SESSION['superuser']!="yes") {
|
|
send_header("Superuser access required");
|
|
send_footer();
|
|
exit;
|
|
}
|
|
}
|
|
|
|
function try_login($user, $pass)
|
|
{
|
|
/* Ensure sanity of inputs */
|
|
/* User could be a username, or could be an email, check */
|
|
if(!account_valid_user($user) && !account_valid_email($user)) {
|
|
return false;
|
|
}
|
|
|
|
/* Don't check for a valid password, administrators can set any password they'd like, but
|
|
* there has to be a password */
|
|
if(!strlen($pass)) {
|
|
return false;
|
|
}
|
|
|
|
$user = mysql_real_escape_string($user);
|
|
$q = mysql_query("SELECT id,password,deleted FROM accounts WHERE username='$user'");
|
|
echo mysql_error();
|
|
/*
|
|
$q = mysql_query("SELECT id,username,password,year,deleted
|
|
FROM users
|
|
WHERE username='$user'
|
|
AND deleted='no'
|
|
ORDER BY year DESC LIMIT 1");
|
|
*/
|
|
if(mysql_num_rows($q) < 1) return false;
|
|
|
|
$r = mysql_fetch_assoc($q);
|
|
|
|
/* See if the user account has been deleted */
|
|
if($r['deleted'] == 'yes') return false;
|
|
|
|
/* See if the password matches */
|
|
if($r['password'] != $pass) return false;
|
|
|
|
/* Login successful */
|
|
return $r['id'];
|
|
}
|
|
|
|
function updateSessionRoles($u=null) {
|
|
if(!$u)
|
|
$u=user_load($_SESSION['users_id']);
|
|
$_SESSION['roles']=array();
|
|
// echo "updateSessionRole for {$_SESSION['users_id']}:";print_r($u);
|
|
if($u && is_array($u['roles'])) {
|
|
foreach($u['roles'] AS $r=>$rd) {
|
|
if($rd['active']=="yes" || $r=='admin' || $r=='config' || $r=='committee')
|
|
$_SESSION['roles'][]=$r;
|
|
}
|
|
}
|
|
}
|
|
|
|
function user_conference_load($accounts_id,$conferences_id) {
|
|
global $config;
|
|
if(! ($accounts_id && $conferences_id))
|
|
return $config['SFIABDIRECTORY']."/index.php";
|
|
|
|
/* Use the active conference to find the user id to load */
|
|
/* FIXME: Need to be able to handle the case where there is no
|
|
* active conference, but one step at a time */
|
|
$q = mysql_query("SELECT id FROM users WHERE accounts_id=$accounts_id AND conferences_id=$conferences_id");
|
|
if(mysql_num_rows($q) == 0) {
|
|
/* FIXME: this should probably just return false, but for now, see if there's an error */
|
|
// return false;
|
|
// header("location: user_edit.php");
|
|
// echo "No user {$accounts_id} for conference {$_SESSION['conferences_id']}";
|
|
return $config['SFIABDIRECTORY']."/user_main.php";
|
|
}
|
|
if(mysql_num_rows($q) > 1) {
|
|
echo "DATABASE ERROR: More than one user for account $accounts_id conference {$conferences_id}";
|
|
exit;
|
|
}
|
|
$uid = mysql_fetch_assoc($q);
|
|
$id = $uid['id'];
|
|
|
|
$u = user_load($id);
|
|
|
|
$_SESSION['name']="{$u['firstname']} {$u['lastname']}";
|
|
$_SESSION['users_id']=$u['id'];
|
|
updateSessionRoles();
|
|
/* Load the password expiry for each user role, and
|
|
* find the longest expiry, which is the one we'll use
|
|
* for this user to determine if the passwd has
|
|
* expired. */
|
|
$longest_expiry = 0;
|
|
foreach(array_keys($u['roles']) as $r) {
|
|
$e = $config["{$r}_password_expiry_days"];
|
|
if($e == 0) {
|
|
/* Catch a never expire case. */
|
|
$longest_expiry = 0;
|
|
break;
|
|
} else if($e > $longest_expiry) {
|
|
$longest_expiry = $e;
|
|
}
|
|
}
|
|
|
|
if($u['passwordset'] == '0000-00-00') {
|
|
/* Force the password to expire */
|
|
$_SESSION['password_expired'] = true;
|
|
} else if($longest_expiry == 0) {
|
|
/* Never expires */
|
|
unset($_SESSION['password_expired']);
|
|
} else {
|
|
/* Check expiry */
|
|
$expires = date('Y-m-d', strtotime("{$u['passwordset']} +$longest_expiry days"));
|
|
$now = date('Y-m-d');
|
|
if($now > $expires) {
|
|
$_SESSION['password_expired'] = true;
|
|
} else {
|
|
unset($_SESSION['password_expired']);
|
|
}
|
|
}
|
|
/* If password_expired == true, the main page (or any
|
|
* other user page) will catch this and require
|
|
* them to set a password */
|
|
|
|
/* Call login functions for each role */
|
|
foreach(array_keys($u['roles']) as $r) {
|
|
if(is_callable("user_{$r}_login")) {
|
|
call_user_func_array("user_{$r}_login", array($u));
|
|
}
|
|
}
|
|
|
|
// mysql_query("UPDATE accounts SET lastlogin=NOW()
|
|
// WHERE id={$u['id']}");
|
|
|
|
/* Setup multirole so a multirole user can switch if they want to
|
|
* without logging in/out */
|
|
/* if(count($u['roes']) > 1) {
|
|
$_SESSION['multirole'] = true;
|
|
} else {
|
|
$_SESSION['multirole'] = false;
|
|
}
|
|
*/
|
|
/* See if there is a redirect, and do that instead of
|
|
* taking them to their main page */
|
|
/* if($redirect != '') {
|
|
switch($redirect) {
|
|
case 'roleadd':
|
|
if(!user_valid_role($multirole_data))
|
|
$multirole_data = '';
|
|
|
|
header("location: user_multirole.php?action=add&role=$multirole_data");
|
|
exit;
|
|
case 'roleattached':
|
|
message_push(happy(i18n('The %1 role has been attached to your account', array($roles[$role]['name']))));
|
|
message_push(notice(i18n('Use the [Switch Roles] link in the upper right to change roles while you are logged in')));
|
|
header("location: {$role}_main.php");
|
|
exit;
|
|
|
|
}
|
|
}
|
|
*/
|
|
/* Is there a saved requesT_uri from a failed login attempt?, if so
|
|
* take them there */
|
|
if(array_key_exists('request_uri', $_SESSION)) {
|
|
// header("location: {$_SESSION['request_uri']}");
|
|
unset($_SESSION['request_uri']);
|
|
return $_SESSION['request_uri'];
|
|
}
|
|
return "user_main.php";
|
|
// header("location: user_main.php");
|
|
//exit;
|
|
}
|
|
|
|
|
|
?>
|