Commit 5db41107 authored by Martyn Smith's avatar Martyn Smith Committed by Martyn Smith
Browse files
parents 8d3e5b9d 9060aaaf
......@@ -18,7 +18,7 @@
*
* @package mahara
* @subpackage admin
* @author Richard Mansfield <richard@catalyst.net.nz>
* @author Richard Mansfield <richard.mansfield@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
*
......
......@@ -38,7 +38,7 @@ asort($pageoptions);
$f = array(
'name' => 'editsitepage',
'method' => 'post',
'onsubmit' => 'return submitForm(\'editsitepage\',\'savesitepage.json.php\');',
'onsubmit' => 'return submitForm(\'editsitepage\',\'savesitepage.json.php\',contentSaved);',
'action' => '',
'elements' => array(
'pagename' => array(
......@@ -50,11 +50,11 @@ $f = array(
'pagetext' => array(
'name' => 'pagetext',
'type' => 'wysiwyg',
'rows' => 25,
'cols' => 85,
'title' => get_string('pagecontent'),
'description' => get_string('textdesc'),
'value' => 'blah',
'rows' => 20,
'cols' => 80,
'title' => get_string('pagetext'),
'description' => get_string('pagecontents'),
'value' => '',
'rules' => array(
'required' => true
)
......@@ -73,19 +73,30 @@ if (use_html_editor()) {
}
$ijs = <<< EOJS
setEditorContent = function(content) { $('pagetext').innerHTML = content; };
function onLoad() {
requestPageText();
connect('pagename', 'onchange', requestPageText);
if (typeof(tinyMCE) != 'undefined') {
setEditorContent = tinyMCE.setContent;
}
}
// global stuff, set in onLoad().
setEditorContent = function () {};
getEditorContent = function () {};
var oldpagename = '';
var originalcontent = '';
function requestPageText() {
// Allow the user to abort change if changes have been made in the editor.
if (getEditorContent() != originalcontent) {
var answer = confirm(get_string('discardchanges'));
if (!answer) {
$('pagename').value = oldpagename;
return;
}
}
displayMessage({'message':get_string('loadingpagecontent', $('pagename').value),'type':'info'});
var d = loadJSONDoc('editchangepage.json.php',{'pagename':$('pagename').value});
d.addCallback(function(data) {
if (data.success) {
displayMessage({'message':get_string('loadedsuccessfully', $('pagename').value),'type':'info'});
setEditorContent(data.content);
originalcontent = getEditorContent();
oldpagename = $('pagename').value;
}
else {
displayMessage({'message':get_string('failedloadingpagecontent', $('pagename').value),
......@@ -93,10 +104,34 @@ function requestPageText() {
}
});
}
// Called from submitForm on successful page save.
function contentSaved () {
originalcontent = getEditorContent();
requestPageText();
}
function onLoad() {
if (typeof(tinyMCE) != 'undefined') {
setEditorContent = function (c) {
tinyMCE.setContent(c);
tinyMCE.execCommand('mceFocus',false,'mce_editor_0');
}
getEditorContent = tinyMCE.getContent;
}
else {
setEditorContent = function (c) { $('pagetext').value = c; };
getEditorContent = function () { return $('pagetext').value; };
}
originalcontent = getEditorContent();
requestPageText();
connect('pagename', 'onchange', requestPageText);
}
addLoadEvent(onLoad);
EOJS;
$jsstrings = array('requiredfieldempty','noresponse');
$jsstrings = array('discardchanges');
$smarty = smarty($js,array(),$jsstrings);
$smarty->assign('pageeditform', $form);
......
......@@ -17,8 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @package mahara
* @subpackage core or plugintype/pluginname
* @author Your Name <you@example.org>
* @subpackage artefact-internal
* @author Penny Leach <penny@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
*
......
......@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @package mahara
* @subpackage artefact/internal
* @subpackage artefact-internal
* @author Martyn Smith <martyn@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
......
......@@ -29,3 +29,4 @@ defined('INTERNAL') || die();
$string['myprofile'] = 'My Profile';
$string['myfiles'] = 'My Files';
?>
......@@ -17,8 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @package mahara
* @subpackage artefact/internal
* @author Your Name <you@example.org>
* @subpackage artefact-internal
* @author Penny Leach <penny@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
*
......@@ -26,8 +26,6 @@
defined('INTERNAL') || die();
require_once(get_config('docroot') . 'artefact/lib.php');
class PluginArtefactInternal extends PluginArtefact {
public static function get_artefact_types() {
......
......@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @package mahara
* @subpackage artefact/internal
* @subpackage artefact-internal
* @author Martyn Smith <martyn@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
......
......@@ -17,8 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @package mahara
* @subpackage artefact/internal
* @author Your Name <you@example.org>
* @subpackage artefact-internal
* @author Penny Leach <penny@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
*
......
......@@ -18,7 +18,7 @@
*
* @package mahara
* @subpackage artefact
* @author Your Name <you@example.org>
* @author Penny Leach <penny@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
*
......@@ -31,11 +31,6 @@ defined('INTERNAL') || die();
*/
class ArtefactNotFoundException extends Exception {}
/**
* Exception - trying to get/set a field that doesn't exist
*/
class UndefinedArtefactFieldException extends Exception {}
/**
* Base artefact plugin class
* @abstract
......@@ -100,11 +95,12 @@ abstract class PluginArtefact extends Plugin {
*/
abstract class ArtefactType {
private $_dirty;
protected $dirty;
protected $parentdirty;
protected $id;
protected $type;
protected $container;
protected $parentid;
protected $parent;
protected $ctime;
protected $mtime;
protected $vtime;
......@@ -228,7 +224,7 @@ abstract class ArtefactType {
public function get($field) {
if (!property_exists($field)) {
throw new UndefinedArtefactFieldException("Field $field wasn't found in class " . get_class($this));
throw new InvalidArgumentException("Field $field wasn't found in class " . get_class($this));
}
return $this->{$field};
}
......@@ -236,14 +232,27 @@ abstract class ArtefactType {
public function set($field, $value) {
if (property_exists($field)) {
$this->{$field} = $value;
$this->_dirty = true;
$this->dirty = true;
if ($field == 'parent') {
$this->parentdirty = true;
}
return true;
}
throw new UndefinedArtefactFieldException("Field $field wasn't found in class " . get_class($this));
throw new InvalidArgumentException("Field $field wasn't found in class " . get_class($this));
}
/**
* Artefact destructor. Calls commit and marks the
* artefact cache as dirty if necessary.
*/
public function __destruct() {
$this->commit();
if (!empty($this->dirty)) {
$this->commit();
}
if (!empty($this->parentdirty)) {
set_field_select('artefact_parent_cache', 'dirty', 1,
'artefact = ? OR parent = ?', array($this->id, $this->id));
}
}
public function is_container() {
......@@ -258,6 +267,8 @@ abstract class ArtefactType {
/**
* Deletes current instance
* you MUST set $this->parentdirty to true
* when delete is called.
* @abstract
*/
public abstract function delete();
......
......@@ -49,8 +49,7 @@ class AuthInternal extends Auth {
* Given a user that we know about, return an array of information about them
*/
public static function get_user_info($username) {
// @todo: only select the information the session requires
$user = get_record('usr', 'username', $username);
$user = get_record('usr', 'username', $username, null, null, null, null, '*, ' . db_format_tsfield('expiry'));
return $user;
}
......
......@@ -214,36 +214,38 @@ function auth_setup () {
// The session is still active, so continue it.
log_debug('session still active from previous time');
$USER = $SESSION->renew();
auth_check_password_change();
auth_check_password_change($USER);
return $USER;
}
else if ($sessionlogouttime > 0) {
// The session timed out
log_debug('session timed out');
$SESSION->logout();
$SESSION->add_info_msg(get_string('sessiontimedout'));
auth_draw_login_page();
exit;
auth_draw_login_page(get_string('sessiontimedout'));
// The auth_draw_login_page function may authenticate a user if a login
// request was sent at the same time that the "timed out" message is to
// be displayed.
return $USER;
}
else {
// There is no session, so we check to see if one needs to be started.
// First, check if the page is public or the site is configured to be public.
if (defined('PUBLIC')) {
return;
}
// Build login form. If the form is submitted it will be handled here,
// and set $USER for us.
require_once('form.php');
$form = new Form(auth_get_login_form());
if ($USER) {
log_debug('user logged in just fine');
auth_check_password_change();
return $USER;
}
// Check if the page is public or the site is configured to be public.
if (defined('PUBLIC')) {
return;
}
log_debug('no session or old session, and page is private');
auth_draw_login_page($form);
auth_draw_login_page(null, $form);
exit;
}
}
......@@ -267,9 +269,9 @@ function auth_get_authtype_for_institution($institution) {
* will, in theory, have different data stores, making changing the password
* via the internal form difficult.
*/
function auth_check_password_change() {
function auth_check_password_change($user) {
global $SESSION;
log_debug('checking if the user needs to change their password');
log_debug('checking if the user needs to change their password');// @todo change this to $user instead of $SESSION, as long as it's safe
if (auth_get_authtype_for_institution($SESSION->get('institution')) == 'internal' && $SESSION->get('passwordchange')) {
log_debug('user DOES need to change their password');
require_once('form.php');
......@@ -307,6 +309,32 @@ function auth_check_password_change() {
}
}
/**
* Check if the given user's account has expired
*/
function auth_check_user_expired($user) {
log_debug('Checking to see if the user has expired');
if ($user->expiry > 0 && time() > $user->expiry) {
// Trash the $USER object, used for checking if the user is logged in
global $USER;
$USER = null;
die_info('Sorry, your account has expired');
}
}
function auth_check_user_suspended() {
global $USER;
log_debug('Checking to see if the user is suspended');
$suspend = get_record('usr_suspension', 'usr', $USER->id);
log_debug($suspend);
if ($suspend) {
global $USER;
$USER = null;
die_info('Sorry, your account has been SUSPENDED!');
}
}
/**
* Validates the form for changing the password for a user.
*
......@@ -404,18 +432,33 @@ function change_password_submit($values) {
* users can have their sessions time out, and then can log in again without
* losing any of their data.
*
* As this function builds and validates a login form, it is possible that
* calling this may validate a user to be logged in.
*
* @param Form $form If specified, just build this form to get the HTML
* required. Otherwise, this function will build and
* validate the form itself.
* @access private
*/
function auth_draw_login_page(Form $form=null) {
function auth_draw_login_page($message=null, Form $form=null) {
global $USER, $SESSION;
if ($form != null) {
$loginform = $form->build();
}
else {
require_once('form.php');
$loginform = form(auth_get_login_form());
// If this is true, the form was submitted even before being built.
// This happens when a user's session times out and they resend post
// data. The request should just continue if so.
if ($USER) {
return;
}
}
if ($message) {
$SESSION->add_info_msg($message);
}
$smarty = smarty();
$smarty->assign('login_form', $loginform);
......@@ -530,9 +573,11 @@ function login_submit($values) {
if (call_static_method($authclass, 'authenticate_user_account', $username, $password, $institution)) {
log_debug('user ' . $username . ' logged in OK');
$USER = call_static_method($authclass, 'get_user_info', $username);
auth_check_user_expired($USER);
auth_check_user_suspended($USER);
$SESSION->login($USER);
$USER->logout_time = $SESSION->get('logout_time');
auth_check_password_change();
auth_check_password_change($USER);
}
else {
// Login attempt failed
......
......@@ -57,9 +57,10 @@ class Session {
public function __construct() {
$this->defaults = array(
'logout_time' => 0,
'id' => 0,
'username' => '',
'passwordchange' => false,
'institution' => 'mahara'
'institution' => 'mahara'
);
// Resume an existing session if required
if (isset($_COOKIE['PHPSESSID'])) {
......
......@@ -76,6 +76,7 @@ require('dml.php');
require('ddl.php');
require('constants.php');
require('web.php');
require('activity.php');
// Database access functions
require('adodb/adodb-exceptions.inc.php');
......
......@@ -52,7 +52,7 @@ function testRequired(e,formid) {
// Gets form elements, submits them to a url via post, and waits for a
// JSON response containing the result of the submission.
function submitForm(formid,url) {
function submitForm(formid,url,callback) {
if (typeof(tinyMCE) != 'undefined') {
tinyMCE.triggerSave();
}
......@@ -73,6 +73,7 @@ function submitForm(formid,url) {
d.addCallback(function (result) {
var data = evalJSONRequest(result);
displayMessage({'message':data.message,'type':data.success});
callback();
});
d.addErrback(function() { displayMessage(get_string('unknownerror'),'error'); });
displayMessage({'message':get_string('processingform'),'type':'info'});
......
......@@ -17,8 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @package mahara
* @subpackage core or plugintype/pluginname
* @author Your Name <you@example.org>
* @subpackage lang
* @author Penny Leach <penny@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
*
......
......@@ -44,6 +44,17 @@ $string['usernamedesc'] = 'Your username';
$string['usernamehelp'] = 'The username you have been given to access this system.';
$string['cancel'] = 'Cancel';
// Admin site page editor
$string['discardchanges'] = 'Discard your changes to this page?';
$string['pagecontents'] = 'Text to appear on the page';
$string['pagename'] = 'Page name';
$string['pagetext'] = 'Page text';
// mahara.js
$string['processingform'] = 'Processing form';
$string['requiredfieldempty'] = 'A required field is empty';
$string['unknownerror'] = 'An unknown error occurred (0x20f91a0)';
// menu
$string['home'] = 'Home';
$string['mycontacts'] = 'My Contacts';
......@@ -59,6 +70,7 @@ $string['mycommunities'] = 'My Communities';
$string['myownedcommunities'] = 'My Owned Communities';
$string['mygroups'] = 'My Groups';
// mycontacts
// mygroups
......
<?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 Penny Leach <penny@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();
/**
* This is the function to call whenever anything happens
* that is going to end up on a user's activity page.
*
* @param string $activitytype type of activity
* @param mixed $data data
*/
function activity_occured($activitytype, $data) {
if (!$at = get_record('activity_type', 'name', $activitytype)) {
throw new Exception("Invalid activity type $activitytype");
}
if (!empty($at->delay)) {
$delayed = new StdClass;
$delayed->type = $activitytype;
$delayed->data = serialize($data);
$delayed->ctime = db_format_timestamp(time());
insert_record('activity_queue', $delayed);
}
else {
handle_activity($at, $data);
}
}
/**
* This function dispatches all the activity stuff
* to whatever notification plugin it needs to
* and figures out all the implications of
* activity and who needs to know about it.
*
* @param object $activitytype record from activity_type
* @param mixed $data must contain message to save.
* it can also contain url.
* each activity type has different requirements of $data -
* <b>admin types (contactus, objectionable, virusrepeat, virusrelease)</b> don't have any extra requirements
* <b>maharamessage</b> must contain $users, an array of userids.
* <b>usermessage</b> must contain $userto, id of recipient user.
* <b>feedback</b> must contain either $view (id of view) or $artefact (id of artefact)
* <b>watchlist</b> must contain either $view (id of view) or $artefact (id of artefact)
* <b>newview</b> must contain $owner userid of view owner AND $view (id of new view)
*/
function handle_activity($activitytype, $data) {
$data = (object)$data;
if (empty($data->message)) {
throw new InvalidArgumentException("message was empty for $activitytype!");
}
$users = array();
$prefix = get_config('dbprefix');
if (!empty($activitytype->admin)) {
$users = activity_get_users($activitytype->name, null, null, true);
}
else {
switch ($activitytype->name) {
// easy ones first :)
case 'maharamessage':
$users = activity_get_users($activitytype->name, $data->users);
break;
case 'usermessage':
$users = activity_get_users($activitytype->name, array($data->userto));
break;
case 'feedback':
if ($data->view) {
$userid = get_field('view', 'owner', 'id', $data->view);
}
else if ($data->artefact) {
$userid = get_field('artefact', 'owner', 'id', $data->artefact);
}
$users = activity_get_users($activitytype->name, array($userid));
break;
// and now the harder ones
case 'watchlist':
if ($data->view) {
$sql = 'SELECT u.*, p.method
FROM ' . $prefix . 'watchlist_view wv
JOIN ' . $prefix . 'usr u
ON wa.user = u.id
JOIN ' . $prefix . 'usr_preference p
ON p.user = u.id
WHERE pc.activity = ?
AND wv.view = ?
';
$users = get_records_sql($sql, array('watchlist', $data->view));
}
else if ($data->artefact) {
$sql = 'SELECT DISTINCT u.*, p.method
FROM ' . $prefix . 'watchlist_artefact wa
JOIN ' . $prefix . 'artefact_parent_cache pc
ON (pc.parent = wa.artefact OR pc.artefact = wa.artefact)
JOIN ' . $prefix . 'usr u
ON wa.user = u.id
JOIN ' . $prefix . 'usr_preference p
ON p.user = u.id
WHERE pc.activity = ?
AND (pc.parent = ? OR wa.artefact = ?)
';
$users = get_records_sql($sql, array('watchlist', $data->artefact));
}
else {