Commit f8de498e authored by Nigel McNie's avatar Nigel McNie Committed by Nigel McNie

Broke $SESSION and $USER into distinct roles. $SESSION is now a waffer thin

wrapper around $_SESSION, and $USER deals with system users and their
preferences.
parent 26deabdf
......@@ -60,7 +60,7 @@ $type = param_alpha('type', 'all');
$limit = param_integer('limit', 10);
$offset = param_integer('offset', 0);
$userid = $SESSION->get('id');
$userid = $USER->get('id');
if ($type == 'all') {
$count = count_records('notification_internal_activity', 'usr', $userid);
......
......@@ -37,7 +37,7 @@ $notifications = plugins_installed('notification');
$elements = array();
foreach ($activitytypes as $type) {
if (!$dv = $SESSION->get_activity_preference($type->name)) {
if (!$dv = $USER->get_activity_preference($type->name)) {
$dv = 'internal';
}
$elements[$type->name] = array(
......@@ -76,11 +76,11 @@ $smarty->assign('form', pieform($prefsform));
$smarty->display('account/activity/preferences/index.tpl');
function activityprefs_submit($values) {
global $activitytypes, $SESSION;
global $activitytypes, $USER;
$userid = $SESSION->get('id');
$userid = $USER->get('id');
foreach ($activitytypes as $type) {
$SESSION->set_activity_preference($type->name, $values[$type->name]);
$USER->set_activity_preference($type->name, $values[$type->name]);
}
json_reply(false, get_string('prefssaved', 'account'));
exit;
......
......@@ -32,9 +32,9 @@ require(dirname(dirname(__FILE__)) . '/init.php');
require_once('pieforms/pieform.php');
// load up user preferences
$prefs = (object)($SESSION->get('accountprefs'));
$prefs = (object)($USER->get('accountprefs'));
$authtype = auth_get_authtype_for_institution($USER->institution);
$authtype = auth_get_authtype_for_institution($USER->get('institution'));
$authclass = 'Auth' . ucfirst($authtype);
safe_require('auth', $authtype);
......@@ -149,15 +149,12 @@ $smarty->display('account/index.tpl');
function accountprefs_validate(Pieform $form, $values) {
if ($values['oldpassword'] !== '') {
global $SESSION, $authtype, $authclass;
if (!call_static_method($authclass, 'authenticate_user_account', $SESSION->get('username'), $values['oldpassword'], $SESSION->get('institution'))) {
global $USER, $authtype, $authclass;
if (!call_static_method($authclass, 'authenticate_user_account', $USER->get('username'), $values['oldpassword'], $USER->get('institution'))) {
$form->set_error('oldpassword', get_string('oldpasswordincorrect', 'account'));
return;
}
$user = new StdClass;
$user->username = $SESSION->get('username');
$user->institution = $SESSION->get('institution');
password_validate($form, $values, $user);
password_validate($form, $values, $USER);
}
else if ($values['password1'] !== '' || $values['password2'] !== '') {
$form->set_error('oldpassword', get_string('mustspecifyoldpassword'));
......@@ -165,26 +162,26 @@ function accountprefs_validate(Pieform $form, $values) {
}
function accountprefs_submit($values) {
global $SESSION;
global $USER;
db_begin();
if ($values['password1'] !== '') {
global $authclass;
$password = call_static_method($authclass, 'change_password', $SESSION->get('username'), $values['password1']);
$password = call_static_method($authclass, 'change_password', $USER->get('username'), $values['password1']);
$user = new StdClass;
$user->password = $password;
$user->passwordchange = 0;
$where = new StdClass;
$where->username = $SESSION->get('username');
$where->username = $USER->get('username');
update_record('usr', $user, $where);
$SESSION->set('password', $password);
$SESSION->set('passwordchange', 0);
$USER->set('password', $password);
$USER->set('passwordchange', 0);
}
// use this as looping through values is not safe.
$expectedprefs = expected_account_preferences();
foreach (array_keys($expectedprefs) as $pref) {
$SESSION->set_account_preference($pref, $values[$pref]);
$USER->set_account_preference($pref, $values[$pref]);
}
db_commit();
......
......@@ -34,7 +34,7 @@ $stopmonitoring = param_integer('stopmonitoring', 0);
$getartefacts = param_integer('getartefacts', 0);
if ($stopmonitoring) {
$userid = $SESSION->get('id');
$userid = $USER->get('id');
$count = 0;
db_begin();
try {
......@@ -71,7 +71,7 @@ $type = param_alpha('type', 'views');
$limit = param_integer('limit', 10);
$offset = param_integer('offset', 0);
$userid = $SESSION->get('id');
$userid = $USER->get('id');
$prefix = get_config('dbprefix');
if ($type == 'views') {
......
......@@ -37,7 +37,7 @@ $upgrades = check_upgrades();
if (isset($upgrades['core']) && !empty($upgrades['core']->install)) {
$smarty->assign('installing', true);
$smarty->assign('releaseargs', array($upgrades['core']->torelease,$upgrades['core']->to));
$smarty->assign('releaseargs', array($upgrades['core']->torelease, $upgrades['core']->to));
$smarty->display('admin/installgpl.tpl');
exit;
}
......
......@@ -132,6 +132,9 @@ EOJS;
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->assign_by_ref('upgrades', $upgrades);
if (isset($upgrades['core'])) {
$smarty->assign('releaseargs', array($upgrades['core']->torelease, $upgrades['core']->to));
}
$smarty->display('admin/upgrade.tpl');
?>
......@@ -36,7 +36,7 @@ $element_required = call_static_method('ArtefactTypeProfile', 'get_mandatory_fie
// load existing profile information
$profilefields = array();
$profile_data = get_records_select('artefact', "owner=? AND artefacttype IN (" . join(",",array_map(create_function('$a','return db_quote($a);'),array_keys($element_list))) . ")", array($USER->id));
$profile_data = get_records_select('artefact', "owner=? AND artefacttype IN (" . join(",",array_map(create_function('$a','return db_quote($a);'),array_keys($element_list))) . ")", array($USER->get('id')));
if ($profile_data) {
foreach ($profile_data as $field) {
......@@ -45,7 +45,7 @@ if ($profile_data) {
}
$profilefields['email'] = array();
$profilefields['email']['all'] = get_rows('artefact_internal_profile_email', 'owner', $USER->id);
$profilefields['email']['all'] = get_rows('artefact_internal_profile_email', 'owner', $USER->get('id'));
$profilefields['email']['validated'] = array();
$profilefields['email']['unvalidated'] = array();
if ($profilefields['email']['all']) {
......@@ -148,20 +148,20 @@ function profileform_submit($values) {
email_user(
(object)array(
'firstname' => $USER->firstname,
'lastname' => $USER->lastname,
'preferredname' => $USER->preferredname,
'firstname' => $USER->get('firstname'),
'lastname' => $USER->get('lastname'),
'preferredname' => $USER->get('preferredname'),
'email' => $email,
),
null,
get_string('emailvalidation_subject', 'artefact.internal'),
get_string('emailvalidation_body', 'artefact.internal', $USER->firstname, $email, $key_url)
get_string('emailvalidation_body', 'artefact.internal', $USER->get('firstname'), $email, $key_url)
);
insert_record(
'artefact_internal_profile_email',
(object) array(
'owner' => $USER->id,
'owner' => $USER->get('id'),
'email' => $email,
'verified' => 0,
'key' => $key,
......@@ -179,9 +179,9 @@ function profileform_submit($values) {
continue;
}
$artefact_id = get_field('artefact_internal_profile_email', 'artefact', 'email', $email, 'owner', $USER->id);
$artefact_id = get_field('artefact_internal_profile_email', 'artefact', 'email', $email, 'owner', $USER->get('id'));
delete_records('artefact_internal_profile_email', 'email', $email, 'owner', $USER->id);
delete_records('artefact_internal_profile_email', 'email', $email, 'owner', $USER->get('id'));
if ($artefact_id) {
global $db;
......@@ -205,7 +205,7 @@ function profileform_submit($values) {
continue;
}
delete_records('artefact_internal_profile_email', 'email', $email, 'owner', $USER->id);
delete_records('artefact_internal_profile_email', 'email', $email, 'owner', $USER->get('id'));
}
if ($profilefields['email']['default'] != $values['email']['default']) {
......@@ -215,7 +215,7 @@ function profileform_submit($values) {
'principal' => 0,
),
(object)array(
'owner' => $USER->id,
'owner' => $USER->get('id'),
'email' => $profilefields['email']['default'],
)
);
......@@ -225,7 +225,7 @@ function profileform_submit($values) {
'principal' => 1,
),
(object) array(
'owner' => $USER->id,
'owner' => $USER->get('id'),
'email' => $values['email']['default'],
)
);
......@@ -235,14 +235,14 @@ function profileform_submit($values) {
'email' => $values['email']['default'],
),
(object) array(
'id' => $USER->id,
'id' => $USER->get('id'),
)
);
}
}
else {
$classname = generate_artefact_class_name($element);
$profile = new $classname(0, array('owner' => $USER->id));
$profile = new $classname(0, array('owner' => $USER->get('id')));
$profile->set('title', $values[$element]);
$profile->commit();
}
......
This diff is collapsed.
......@@ -26,12 +26,13 @@
defined('INTERNAL') || die();
/**
* The session class handles user sessions and session messages.
* The session class handles session data and messages.
*
* This class stores information about the user across page loads,
* so it only needs to be requested once when a user logs in.
* This class stores information across page loads, using only a cookie to
* remember the info. User information is stored in the session so it does
* not have to be requested each time the page is loaded, however any other
* information can also be stored using this class.
*
* This class also is smart about giving out sessions - if a visitor
* has not logged in (e.g. they are a guest, searchbot or a simple
......@@ -43,39 +44,9 @@ defined('INTERNAL') || die();
class Session {
/**
* Defaults for user information.
*
* @var array
*/
private $defaults;
/**
* Sets defaults for the session object (only because PHP5 does not appear
* to support private static const arrays), and resumes a session only if
* a session already exists.
* Resumes an existing session, only if there is one
*/
public function __construct() {
$this->defaults = array(
'logout_time' => 0,
'id' => 0,
'username' => '',
'password' => '',
'salt' => '',
'institution' => 'mahara',
'passwordchange' => false,
'deleted' => false,
'expiry' => 0,
'lastlogin' => 0,
'staff' => false,
'admin' => false,
'firstname' => '',
'lastname' => '',
'preferredname' => '',
'email' => '',
'accountprefs' => array(),
'activityprefs' => array(),
'sesskey' => ''
);
// Resume an existing session if required
if (isset($_COOKIE['PHPSESSID'])) {
session_start();
......@@ -87,45 +58,11 @@ class Session {
*
* @param string $key The key to get the value of
* @return mixed
* @throws KeyInvalidException
* @todo<nigel>: Given that KeyInvalidException doesn't actually exist,
* referring to an incorrect key will be fatal. I'm not going to do anything
* about this until more is known about what will be stored in the session.
*/
public function get($key) {
if (!isset($this->defaults[$key])) {
throw new KeyInvalidException($key);
}
if (isset($_SESSION[$key])) {
return $_SESSION[$key];
}
return $this->defaults[$key];
}
/**
* This function returns a method for a particular
* activity type.
* or null if it's not set.
*
* @param string $key the activity type
*/
public function get_activity_preference($key) {
if (isset($_SESSION['activityprefs'][$key])) {
return $_SESSION['activityprefs'][$key];
}
return null;
}
/**
* This function returns a value for a particular
* account preference, or null if it's not set.
*
* @param string $key the field name
*/
public function get_account_preference($key) {
if (isset($_SESSION['accountprefs'][$key])) {
return $_SESSION['accountprefs'][$key];
}
return null;
}
......@@ -136,84 +73,10 @@ class Session {
* @param string $value The value to set for the key
*/
public function set($key, $value) {
if (!isset($this->defaults[$key])) {
throw new KeyInvalidException($key);
}
if (!$_SESSION) {
$this->create_session();
}
$this->ensure_session();
$_SESSION[$key] = $value;
}
/** @todo document these next two methods */
public function set_account_preference($field, $value) {
set_account_preference($this->get('id'), $field, $value);
$_SESSION['accountprefs'][$field] = $value;
}
public function set_activity_preference($activity, $method) {
set_activity_preference($this->get('id'), $activity, $method);
$_SESSION['activityprefs'][$activity] = $method;
}
/**
* Logs in the given user.
*
* The passed object should contain the basic information to persist across
* page loads.
*
* @param object $USER The user object with properties to persist already
* set
*/
public function login($USER) {
if (empty($_SESSION)) {
$this->create_session();
}
foreach (array_keys($this->defaults) as $key) {
$this->set($key, (isset($USER->{$key})) ? $USER->{$key} : $this->defaults[$key]);
}
$this->set('logout_time', time() + get_config('session_timeout'));
$this->set('sesskey', get_random_key());
$_SESSION['activityprefs'] = load_activity_preferences($this->get('id'));
$_SESSION['accountprefs'] = load_account_preferences($this->get('id'));
}
/**
* Assuming that a session is already active for a user, this method
* retrieves the information from the session and creates a user object
* that the script can use
*
* @return object
*/
public function renew() {
$this->set('logout_time', time() + get_config('session_timeout'));
$USER = new StdClass;
foreach (array_keys($this->defaults) as $key) {
$USER->{$key} = $this->get($key);
}
return $USER;
}
/**
* Logs the current user out
*/
public function logout () {
$_SESSION = array(
'logout_time' => 0,
'messages' => array()
);
}
/**
* Determines if the user is currently logged in
*
* @return boolean
*/
public function is_logged_in() {
return ($this->get('logout_time') > 0 ? true : false);
}
/**
* Adds a message that indicates something was successful
*
......@@ -221,12 +84,9 @@ class Session {
* @param boolean $escape Whether to HTML escape the message
*/
public function add_ok_msg($message, $escape=true) {
if (empty($_SESSION)) {
$this->create_session();
}
$this->ensure_session();
if ($escape) {
$message = htmlspecialchars($message, ENT_COMPAT, 'UTF-8');
$message = str_replace(' ', '&nbsp; ', $message);
$message = self::escape_message($message);
}
$_SESSION['messages'][] = array('type' => 'ok', 'msg' => $message);
}
......@@ -238,12 +98,9 @@ class Session {
* @param boolean $escape Whether to HTML escape the message
*/
public function add_info_msg($message, $escape=true) {
if (empty($_SESSION)) {
$this->create_session();
}
$this->ensure_session();
if ($escape) {
$message = htmlspecialchars($message, ENT_COMPAT, 'UTF-8');
$message = str_replace(' ', '&nbsp; ', $message);
$message = self::escape_message($message);
}
$_SESSION['messages'][] = array('type' => 'info', 'msg' => $message);
}
......@@ -255,12 +112,9 @@ class Session {
* @param boolean $escape Whether to HTML escape the message
*/
public function add_err_msg($message, $escape=true) {
if (empty($_SESSION)) {
$this->create_session();
}
$this->ensure_session();
if ($escape) {
$message = htmlspecialchars($message, ENT_COMPAT, 'UTF-8');
$message = str_replace(' ', '&nbsp; ', $message);
$message = self::escape_message($message);
}
$_SESSION['messages'][] = array('type' => 'err', 'msg' => $message);
}
......@@ -299,13 +153,27 @@ class Session {
/**
* Create a session, by initialising the $_SESSION array.
*/
private function create_session() {
if (!session_id()) {
session_start();
private function ensure_session() {
if (empty($_SESSION)) {
if (!session_id()) {
session_start();
}
$_SESSION = array(
'messages' => array()
);
}
$_SESSION = array(
'messages' => array()
);
}
/**
* Escape a message for HTML output
*
* @param string $message The message to escape
* @return string The message, escaped for output as HTML
*/
private static function escape_message($message) {
$message = hsc($message);
$message = str_replace(' ', '&nbsp; ', $message);
return $message;
}
}
......@@ -320,6 +188,4 @@ function insert_messages() {
return $SESSION->render_messages();
}
$SESSION =& new Session;
?>
<?php
/**
* This program is part of Mahara
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @package mahara
* @subpackage core
* @author Nigel McNie <nigel@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
*
*/
defined('INTERNAL') || die();
/** Thrown if the key requested doesn't exist */
class UserKeyInvalidException extends Exception {}
/**
* The user class represents a single logged in user in the system. The user
* has several properties that can be accessed and set, including account
* and activity preferences.
*
* The user class stores this information in the session, so that it does not
* need to be requested every page load.
*/
class User {
/**
* Defaults for user information.
*
* @var array
*/
private $defaults;
/**
* Sets defaults for the user object (only because PHP5 does not appear
* to support private static const arrays), and resumes a session
*/
public function __construct($SESSION) {
$this->defaults = array(
'logout_time' => 0,
'id' => 0,
'username' => '',
'password' => '',
'salt' => '',
'institution' => 'mahara',
'passwordchange' => false,
'deleted' => false,
'expiry' => 0,
'lastlogin' => 0,
'staff' => false,
'admin' => false,
'firstname' => '',
'lastname' => '',
'preferredname' => '',
'email' => '',
'accountprefs' => array(),
'activityprefs' => array(),
'sesskey' => ''
);
$this->SESSION = $SESSION;
}
/**
* Gets the user property keyed by $key.
*
* @param string $key The key to get the value of
* @return mixed
* @throws KeyInvalidException
* @todo<nigel>: Given that KeyInvalidException doesn't actually exist,
* referring to an incorrect key will be fatal. I'm not going to do anything
* about this until more is known about what will be stored in the session.
*/
public function get($key) {
if (!isset($this->defaults[$key])) {
throw new UserKeyInvalidException($key);
}
if (null !== ($value = $this->SESSION->get("user/$key"))) {
return $value;
}
return $this->defaults[$key];
}
/**
* Sets the property keyed by $key
*/
public function set($key, $value) {
if (!isset($this->defaults[$key])) {
throw new UserKeyInvalidException($key);
}
$this->SESSION->set("user/$key", $value);
}
/**
* This function returns a method for a particular
* activity type, or null if it's not set.
*
* @param string $key the activity type
*/
public function get_activity_preference($key) {
$activityprefs = $this->get('activityprefs');
return isset($activityprefs[$key]) ? $activityprefs[$key] : null;
}
/** @todo document this method */
public function set_activity_preference($activity, $method) {
log_debug("set_activity_preference($activity, $method)");
set_activity_preference($this->get('id'), $activity, $method);
$activityprefs = $this->get('activityprefs');
$activityprefs[$activity] = $method;
$this->set('activityprefs', $activityprefs);
}