2004-10-10 01:07:47 +00:00
|
|
|
|
<?php // $Id$
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2002-12-20 14:44:14 +00:00
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// //
|
|
|
|
|
// NOTICE OF COPYRIGHT //
|
|
|
|
|
// //
|
|
|
|
|
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
2004-03-10 13:23:00 +00:00
|
|
|
|
// http://moodle.org //
|
2002-12-20 14:44:14 +00:00
|
|
|
|
// //
|
2007-10-11 09:01:29 +00:00
|
|
|
|
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
|
2002-12-20 14:44:14 +00:00
|
|
|
|
// //
|
|
|
|
|
// 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: //
|
|
|
|
|
// //
|
|
|
|
|
// http://www.gnu.org/copyleft/gpl.html //
|
|
|
|
|
// //
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
2002-11-06 07:54:44 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* moodlelib.php - Moodle main library
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
|
|
|
|
* Main library file of miscellaneous general-purpose Moodle functions.
|
|
|
|
|
* Other main libraries:
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* - weblib.php - functions that produce web output
|
|
|
|
|
* - datalib.php - functions that access the database
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @author Martin Dougiamas
|
|
|
|
|
* @version $Id$
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @package moodlecore
|
|
|
|
|
*/
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/// CONSTANTS (Encased in phpdoc proper comments)/////////////////////////
|
2003-12-30 17:18:06 +00:00
|
|
|
|
|
2004-12-12 04:33:13 +00:00
|
|
|
|
/**
|
|
|
|
|
* Used by some scripts to check they are being called by Moodle
|
|
|
|
|
*/
|
|
|
|
|
define('MOODLE_INTERNAL', true);
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/// Date and time constants ///
|
2007-02-15 02:53:00 +00:00
|
|
|
|
/**
|
|
|
|
|
* Time constant - the number of seconds in a year
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
define('YEARSECS', 31536000);
|
|
|
|
|
|
2004-09-28 05:53:08 +00:00
|
|
|
|
/**
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* Time constant - the number of seconds in a week
|
2004-09-28 05:53:08 +00:00
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
define('WEEKSECS', 604800);
|
2004-09-29 18:56:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Time constant - the number of seconds in a day
|
|
|
|
|
*/
|
2004-09-28 05:53:08 +00:00
|
|
|
|
define('DAYSECS', 86400);
|
2004-09-29 18:56:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Time constant - the number of seconds in an hour
|
|
|
|
|
*/
|
2004-09-28 05:53:08 +00:00
|
|
|
|
define('HOURSECS', 3600);
|
2004-09-29 18:56:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Time constant - the number of seconds in a minute
|
|
|
|
|
*/
|
2004-09-28 05:53:08 +00:00
|
|
|
|
define('MINSECS', 60);
|
2004-09-29 18:56:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Time constant - the number of minutes in a day
|
|
|
|
|
*/
|
2004-09-28 05:53:08 +00:00
|
|
|
|
define('DAYMINS', 1440);
|
2004-09-29 18:56:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Time constant - the number of minutes in an hour
|
|
|
|
|
*/
|
2004-09-28 05:53:08 +00:00
|
|
|
|
define('HOURMINS', 60);
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2005-12-30 15:54:19 +00:00
|
|
|
|
/// Parameter constants - every call to optional_param(), required_param() ///
|
|
|
|
|
/// or clean_param() should have a specified type of parameter. //////////////
|
|
|
|
|
|
2004-10-01 12:09:52 +00:00
|
|
|
|
/**
|
2006-03-07 19:20:23 +00:00
|
|
|
|
* PARAM_RAW specifies a parameter that is not cleaned/processed in any way;
|
|
|
|
|
* originally was 0, but changed because we need to detect unknown
|
|
|
|
|
* parameter types and swiched order in clean_param().
|
2004-10-01 12:09:52 +00:00
|
|
|
|
*/
|
2006-03-07 19:20:23 +00:00
|
|
|
|
define('PARAM_RAW', 666);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_CLEAN - obsoleted, please try to use more specific type of parameter.
|
|
|
|
|
* It was one of the first types, that is why it is abused so much ;-)
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-02-25 13:10:24 +00:00
|
|
|
|
define('PARAM_CLEAN', 0x0001);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_INT - integers only, use when expecting only numbers.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-02-25 13:10:24 +00:00
|
|
|
|
define('PARAM_INT', 0x0002);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* PARAM_INTEGER - an alias for PARAM_INT
|
|
|
|
|
*/
|
|
|
|
|
define('PARAM_INTEGER', 0x0002);
|
|
|
|
|
|
2006-12-22 13:29:20 +00:00
|
|
|
|
/**
|
2007-07-18 05:17:45 +00:00
|
|
|
|
* PARAM_NUMBER - a real/floating point number.
|
2006-12-22 13:29:20 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_NUMBER', 0x000a);
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_ALPHA - contains only english letters.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-02-25 13:10:24 +00:00
|
|
|
|
define('PARAM_ALPHA', 0x0004);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_ACTION - an alias for PARAM_ALPHA, use for various actions in formas and urls
|
|
|
|
|
* @TODO: should we alias it to PARAM_ALPHANUM ?
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_ACTION', 0x0004);
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_FORMAT - an alias for PARAM_ALPHA, use for names of plugins, formats, etc.
|
|
|
|
|
* @TODO: should we alias it to PARAM_ALPHANUM ?
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_FORMAT', 0x0004);
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_NOTAGS - all html tags are stripped from the text. Do not abuse this type.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-02-25 13:10:24 +00:00
|
|
|
|
define('PARAM_NOTAGS', 0x0008);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
2006-09-18 17:40:22 +00:00
|
|
|
|
/**
|
2006-10-16 07:46:35 +00:00
|
|
|
|
* PARAM_MULTILANG - alias of PARAM_TEXT.
|
2006-09-18 17:40:22 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_MULTILANG', 0x0009);
|
|
|
|
|
|
2006-10-16 07:46:35 +00:00
|
|
|
|
/**
|
|
|
|
|
* PARAM_TEXT - general plain text compatible with multilang filter, no other html tags.
|
|
|
|
|
*/
|
|
|
|
|
define('PARAM_TEXT', 0x0009);
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_FILE - safe file name, all dangerous chars are stripped, protects against XSS, SQL injections and directory traversals
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-02-25 13:10:24 +00:00
|
|
|
|
define('PARAM_FILE', 0x0010);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
2007-09-16 14:20:32 +00:00
|
|
|
|
/**
|
|
|
|
|
* PARAM_TAG - one tag (interests, blogs, etc.) - mostly international alphanumeric with spaces
|
|
|
|
|
*/
|
|
|
|
|
define('PARAM_TAG', 0x0011);
|
|
|
|
|
|
2008-02-25 08:11:07 +00:00
|
|
|
|
/**
|
|
|
|
|
* PARAM_TAGLIST - list of tags separated by commas (interests, blogs, etc.)
|
|
|
|
|
*/
|
|
|
|
|
define('PARAM_TAGLIST', 0x0012);
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_PATH - safe relative path name, all dangerous chars are stripped, protects against XSS, SQL injections and directory traversals
|
|
|
|
|
* note: the leading slash is not removed, window drive letter is not allowed
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-02-25 13:10:24 +00:00
|
|
|
|
define('PARAM_PATH', 0x0020);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_HOST - expected fully qualified domain name (FQDN) or an IPv4 dotted quad (IP address)
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_HOST', 0x0040);
|
|
|
|
|
|
|
|
|
|
/**
|
2007-09-29 11:01:34 +00:00
|
|
|
|
* PARAM_URL - expected properly formatted URL. Please note that domain part is required, http://localhost/ is not acceppted but http://localhost.localdomain/ is ok.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-02-25 13:10:24 +00:00
|
|
|
|
define('PARAM_URL', 0x0080);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_LOCALURL - expected properly formatted URL as well as one that refers to the local server itself. (NOT orthogonal to the others! Implies PARAM_URL!)
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_LOCALURL', 0x0180);
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_CLEANFILE - safe file name, all dangerous and regional chars are removed,
|
|
|
|
|
* use when you want to store a new file submitted by students
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-01-29 15:53:24 +00:00
|
|
|
|
define('PARAM_CLEANFILE',0x0200);
|
2004-10-01 12:09:52 +00:00
|
|
|
|
|
2005-02-01 07:39:21 +00:00
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_ALPHANUM - expected numbers and letters only.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_ALPHANUM', 0x0400);
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_BOOL - converts input into 0 or 1, use for switches in forms and urls.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_BOOL', 0x0800);
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_CLEANHTML - cleans submitted HTML code and removes slashes
|
|
|
|
|
* note: do not forget to addslashes() before storing into database!
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_CLEANHTML',0x1000);
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_ALPHAEXT the same contents as PARAM_ALPHA plus the chars in quotes: "/-_" allowed,
|
|
|
|
|
* suitable for include() and require()
|
|
|
|
|
* @TODO: should we rename this function to PARAM_SAFEDIRS??
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_ALPHAEXT', 0x2000);
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 15:54:19 +00:00
|
|
|
|
* PARAM_SAFEDIR - safe directory name, suitable for include() and require()
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PARAM_SAFEDIR', 0x4000);
|
|
|
|
|
|
2006-08-29 02:26:37 +00:00
|
|
|
|
/**
|
|
|
|
|
* PARAM_SEQUENCE - expects a sequence of numbers like 8 to 1,5,6,4,6,8,9. Numbers and comma only.
|
|
|
|
|
*/
|
|
|
|
|
define('PARAM_SEQUENCE', 0x8000);
|
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* PARAM_PEM - Privacy Enhanced Mail format
|
|
|
|
|
*/
|
|
|
|
|
define('PARAM_PEM', 0x10000);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* PARAM_BASE64 - Base 64 encoded format
|
|
|
|
|
*/
|
|
|
|
|
define('PARAM_BASE64', 0x20000);
|
|
|
|
|
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/// Page types ///
|
|
|
|
|
/**
|
|
|
|
|
* PAGE_COURSE_VIEW is a definition of a page type. For more information on the page class see moodle/lib/pagelib.php.
|
2005-02-01 07:39:21 +00:00
|
|
|
|
*/
|
|
|
|
|
define('PAGE_COURSE_VIEW', 'course-view');
|
|
|
|
|
|
2006-09-23 09:38:39 +00:00
|
|
|
|
/// Debug levels ///
|
|
|
|
|
/** no warnings at all */
|
|
|
|
|
define ('DEBUG_NONE', 0);
|
|
|
|
|
/** E_ERROR | E_PARSE */
|
|
|
|
|
define ('DEBUG_MINIMAL', 5);
|
|
|
|
|
/** E_ERROR | E_PARSE | E_WARNING | E_NOTICE */
|
|
|
|
|
define ('DEBUG_NORMAL', 15);
|
2007-12-26 13:33:25 +00:00
|
|
|
|
/** E_ALL without E_STRICT for now, do show recoverable fatal errors */
|
|
|
|
|
define ('DEBUG_ALL', 6143);
|
2006-09-23 09:38:39 +00:00
|
|
|
|
/** DEBUG_ALL with extra Moodle debug messages - (DEBUG_ALL | 32768) */
|
2007-12-26 13:33:25 +00:00
|
|
|
|
define ('DEBUG_DEVELOPER', 38911);
|
2005-07-12 02:06:33 +00:00
|
|
|
|
|
2006-12-28 21:21:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Blog access level constant declaration
|
|
|
|
|
*/
|
|
|
|
|
define ('BLOG_USER_LEVEL', 1);
|
|
|
|
|
define ('BLOG_GROUP_LEVEL', 2);
|
|
|
|
|
define ('BLOG_COURSE_LEVEL', 3);
|
|
|
|
|
define ('BLOG_SITE_LEVEL', 4);
|
|
|
|
|
define ('BLOG_GLOBAL_LEVEL', 5);
|
|
|
|
|
|
2007-09-16 18:41:57 +00:00
|
|
|
|
/**
|
|
|
|
|
* Tag constanst
|
|
|
|
|
*/
|
2008-02-25 01:58:17 +00:00
|
|
|
|
//To prevent problems with multibytes strings, this should not exceed the
|
|
|
|
|
//length of "varchar(255) / 3 (bytes / utf-8 character) = 85".
|
|
|
|
|
define('TAG_MAX_LENGTH', 50);
|
2007-09-16 18:41:57 +00:00
|
|
|
|
|
2008-04-18 08:04:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Password policy constants
|
|
|
|
|
*/
|
|
|
|
|
define ('PASSWORD_LOWER', 'abcdefghijklmnopqrstuvwxyz');
|
|
|
|
|
define ('PASSWORD_UPPER', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
|
|
|
|
define ('PASSWORD_DIGITS', '0123456789');
|
|
|
|
|
define ('PASSWORD_NONALPHANUM', '.,;:!?_-+/*@#&$');
|
|
|
|
|
|
2008-01-21 18:18:07 +00:00
|
|
|
|
if (!defined('SORT_LOCALE_STRING')) { // PHP < 4.4.0 - TODO: remove in 2.0
|
|
|
|
|
define('SORT_LOCALE_STRING', SORT_STRING);
|
|
|
|
|
}
|
2006-12-28 21:21:44 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
|
2002-12-20 14:44:14 +00:00
|
|
|
|
/// PARAMETER HANDLING ////////////////////////////////////////////////////
|
2002-08-04 16:20:30 +00:00
|
|
|
|
|
2004-10-01 12:09:52 +00:00
|
|
|
|
/**
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* Returns a particular value for the named variable, taken from
|
|
|
|
|
* POST or GET. If the parameter doesn't exist then an error is
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* thrown because we require this variable.
|
|
|
|
|
*
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* This function should be used to initialise all required values
|
|
|
|
|
* in a script that are based on parameters. Usually it will be
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* used like this:
|
|
|
|
|
* $id = required_param('id');
|
|
|
|
|
*
|
2006-03-04 18:05:41 +00:00
|
|
|
|
* @param string $parname the name of the page parameter we want
|
|
|
|
|
* @param int $type expected type of parameter
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2006-03-04 18:05:41 +00:00
|
|
|
|
function required_param($parname, $type=PARAM_CLEAN) {
|
2004-10-01 12:09:52 +00:00
|
|
|
|
|
2005-11-15 23:28:10 +00:00
|
|
|
|
// detect_unchecked_vars addition
|
|
|
|
|
global $CFG;
|
|
|
|
|
if (!empty($CFG->detect_unchecked_vars)) {
|
|
|
|
|
global $UNCHECKED_VARS;
|
2006-03-04 18:05:41 +00:00
|
|
|
|
unset ($UNCHECKED_VARS->vars[$parname]);
|
2005-11-15 23:28:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
if (isset($_POST[$parname])) { // POST has precedence
|
|
|
|
|
$param = $_POST[$parname];
|
|
|
|
|
} else if (isset($_GET[$parname])) {
|
|
|
|
|
$param = $_GET[$parname];
|
2004-10-01 12:09:52 +00:00
|
|
|
|
} else {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('A required parameter ('.$parname.') was missing');
|
2004-10-01 12:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
return clean_param($param, $type);
|
2004-10-01 12:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* Returns a particular value for the named variable, taken from
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* POST or GET, otherwise returning a given default.
|
|
|
|
|
*
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* This function should be used to initialise all optional values
|
|
|
|
|
* in a script that are based on parameters. Usually it will be
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* used like this:
|
|
|
|
|
* $name = optional_param('name', 'Fred');
|
|
|
|
|
*
|
2006-03-04 18:05:41 +00:00
|
|
|
|
* @param string $parname the name of the page parameter we want
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* @param mixed $default the default value to return if nothing is found
|
2006-03-04 18:05:41 +00:00
|
|
|
|
* @param int $type expected type of parameter
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2006-03-04 18:05:41 +00:00
|
|
|
|
function optional_param($parname, $default=NULL, $type=PARAM_CLEAN) {
|
2004-10-01 12:09:52 +00:00
|
|
|
|
|
2005-11-15 23:28:10 +00:00
|
|
|
|
// detect_unchecked_vars addition
|
|
|
|
|
global $CFG;
|
|
|
|
|
if (!empty($CFG->detect_unchecked_vars)) {
|
|
|
|
|
global $UNCHECKED_VARS;
|
2006-03-04 18:05:41 +00:00
|
|
|
|
unset ($UNCHECKED_VARS->vars[$parname]);
|
2005-11-15 23:28:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
if (isset($_POST[$parname])) { // POST has precedence
|
|
|
|
|
$param = $_POST[$parname];
|
|
|
|
|
} else if (isset($_GET[$parname])) {
|
|
|
|
|
$param = $_GET[$parname];
|
2004-10-01 12:09:52 +00:00
|
|
|
|
} else {
|
|
|
|
|
return $default;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
return clean_param($param, $type);
|
2004-10-01 12:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* Used by {@link optional_param()} and {@link required_param()} to
|
|
|
|
|
* clean the variables and/or cast to specific types, based on
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* an options field.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* <code>
|
|
|
|
|
* $course->format = clean_param($course->format, PARAM_ALPHA);
|
|
|
|
|
* $selectedgrade_item = clean_param($selectedgrade_item, PARAM_CLEAN);
|
|
|
|
|
* </code>
|
2004-10-01 12:09:52 +00:00
|
|
|
|
*
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @uses $CFG
|
2008-02-04 06:45:56 +00:00
|
|
|
|
* @uses PARAM_RAW
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @uses PARAM_CLEAN
|
2008-02-04 06:45:56 +00:00
|
|
|
|
* @uses PARAM_CLEANHTML
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @uses PARAM_INT
|
2008-02-04 06:45:56 +00:00
|
|
|
|
* @uses PARAM_NUMBER
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @uses PARAM_ALPHA
|
|
|
|
|
* @uses PARAM_ALPHANUM
|
2006-07-28 20:57:19 +00:00
|
|
|
|
* @uses PARAM_ALPHAEXT
|
2008-02-04 06:45:56 +00:00
|
|
|
|
* @uses PARAM_SEQUENCE
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @uses PARAM_BOOL
|
2008-02-04 06:45:56 +00:00
|
|
|
|
* @uses PARAM_NOTAGS
|
|
|
|
|
* @uses PARAM_TEXT
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @uses PARAM_SAFEDIR
|
|
|
|
|
* @uses PARAM_CLEANFILE
|
|
|
|
|
* @uses PARAM_FILE
|
|
|
|
|
* @uses PARAM_PATH
|
|
|
|
|
* @uses PARAM_HOST
|
|
|
|
|
* @uses PARAM_URL
|
|
|
|
|
* @uses PARAM_LOCALURL
|
2008-02-04 06:45:56 +00:00
|
|
|
|
* @uses PARAM_PEM
|
|
|
|
|
* @uses PARAM_BASE64
|
|
|
|
|
* @uses PARAM_TAG
|
2006-08-29 02:26:37 +00:00
|
|
|
|
* @uses PARAM_SEQUENCE
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* @param mixed $param the variable we are cleaning
|
2006-03-04 18:05:41 +00:00
|
|
|
|
* @param int $type expected format of param after cleaning.
|
2004-10-01 12:09:52 +00:00
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2006-03-04 18:05:41 +00:00
|
|
|
|
function clean_param($param, $type) {
|
2004-10-01 12:09:52 +00:00
|
|
|
|
|
2005-01-25 06:09:39 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2005-10-12 01:29:34 +00:00
|
|
|
|
if (is_array($param)) { // Let's loop
|
|
|
|
|
$newparam = array();
|
|
|
|
|
foreach ($param as $key => $value) {
|
2006-03-04 18:05:41 +00:00
|
|
|
|
$newparam[$key] = clean_param($value, $type);
|
2005-10-12 01:29:34 +00:00
|
|
|
|
}
|
|
|
|
|
return $newparam;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
switch ($type) {
|
2006-03-06 06:25:33 +00:00
|
|
|
|
case PARAM_RAW: // no cleaning at all
|
|
|
|
|
return $param;
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_CLEAN: // General HTML cleaning, try to use more specific type if possible
|
|
|
|
|
if (is_numeric($param)) {
|
|
|
|
|
return $param;
|
|
|
|
|
}
|
|
|
|
|
$param = stripslashes($param); // Needed for kses to work fine
|
|
|
|
|
$param = clean_text($param); // Sweep for scripts, etc
|
|
|
|
|
return addslashes($param); // Restore original request parameter slashes
|
2004-10-08 06:11:17 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_CLEANHTML: // prepare html fragment for display, do not store it into db!!
|
|
|
|
|
$param = stripslashes($param); // Remove any slashes
|
|
|
|
|
$param = clean_text($param); // Sweep for scripts, etc
|
|
|
|
|
return trim($param);
|
2004-10-01 12:09:52 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_INT:
|
|
|
|
|
return (int)$param; // Convert to integer
|
2004-10-01 12:09:52 +00:00
|
|
|
|
|
2006-12-22 13:29:20 +00:00
|
|
|
|
case PARAM_NUMBER:
|
|
|
|
|
return (float)$param; // Convert to integer
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_ALPHA: // Remove everything not a-z
|
|
|
|
|
return eregi_replace('[^a-zA-Z]', '', $param);
|
2004-10-01 12:09:52 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_ALPHANUM: // Remove everything not a-zA-Z0-9
|
|
|
|
|
return eregi_replace('[^A-Za-z0-9]', '', $param);
|
2005-02-03 18:14:45 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_ALPHAEXT: // Remove everything not a-zA-Z/_-
|
|
|
|
|
return eregi_replace('[^a-zA-Z/_-]', '', $param);
|
2005-03-23 01:54:45 +00:00
|
|
|
|
|
2006-08-29 02:26:37 +00:00
|
|
|
|
case PARAM_SEQUENCE: // Remove everything not 0-9,
|
|
|
|
|
return eregi_replace('[^0-9,]', '', $param);
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_BOOL: // Convert to 1 or 0
|
|
|
|
|
$tempstr = strtolower($param);
|
2006-04-12 16:55:47 +00:00
|
|
|
|
if ($tempstr == 'on' or $tempstr == 'yes' ) {
|
2006-03-04 18:05:41 +00:00
|
|
|
|
$param = 1;
|
2006-04-12 16:55:47 +00:00
|
|
|
|
} else if ($tempstr == 'off' or $tempstr == 'no') {
|
2006-03-04 18:05:41 +00:00
|
|
|
|
$param = 0;
|
|
|
|
|
} else {
|
|
|
|
|
$param = empty($param) ? 0 : 1;
|
|
|
|
|
}
|
|
|
|
|
return $param;
|
2005-02-03 18:14:45 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_NOTAGS: // Strip all tags
|
|
|
|
|
return strip_tags($param);
|
2004-10-08 06:11:17 +00:00
|
|
|
|
|
2006-10-16 07:46:35 +00:00
|
|
|
|
case PARAM_TEXT: // leave only tags needed for multilang
|
2006-09-18 17:40:22 +00:00
|
|
|
|
return clean_param(strip_tags($param, '<lang><span>'), PARAM_CLEAN);
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_SAFEDIR: // Remove everything not a-zA-Z0-9_-
|
|
|
|
|
return eregi_replace('[^a-zA-Z0-9_-]', '', $param);
|
2005-07-04 20:23:53 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_CLEANFILE: // allow only safe characters
|
|
|
|
|
return clean_filename($param);
|
2005-01-29 15:53:24 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_FILE: // Strip all suspicious characters from filename
|
|
|
|
|
$param = ereg_replace('[[:cntrl:]]|[<>"`\|\':\\/]', '', $param);
|
|
|
|
|
$param = ereg_replace('\.\.+', '', $param);
|
|
|
|
|
if($param == '.') {
|
2005-01-25 06:08:06 +00:00
|
|
|
|
$param = '';
|
|
|
|
|
}
|
2006-03-04 18:05:41 +00:00
|
|
|
|
return $param;
|
|
|
|
|
|
|
|
|
|
case PARAM_PATH: // Strip all suspicious characters from file path
|
|
|
|
|
$param = str_replace('\\\'', '\'', $param);
|
|
|
|
|
$param = str_replace('\\"', '"', $param);
|
|
|
|
|
$param = str_replace('\\', '/', $param);
|
|
|
|
|
$param = ereg_replace('[[:cntrl:]]|[<>"`\|\':]', '', $param);
|
|
|
|
|
$param = ereg_replace('\.\.+', '', $param);
|
|
|
|
|
$param = ereg_replace('//+', '/', $param);
|
|
|
|
|
return ereg_replace('/(\./)+', '/', $param);
|
|
|
|
|
|
|
|
|
|
case PARAM_HOST: // allow FQDN or IPv4 dotted quad
|
2008-01-01 17:23:05 +00:00
|
|
|
|
$param = preg_replace('/[^\.\d\w-]/','', $param ); // only allowed chars
|
2006-03-04 18:05:41 +00:00
|
|
|
|
// match ipv4 dotted quad
|
|
|
|
|
if (preg_match('/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/',$param, $match)){
|
|
|
|
|
// confirm values are ok
|
|
|
|
|
if ( $match[0] > 255
|
|
|
|
|
|| $match[1] > 255
|
|
|
|
|
|| $match[3] > 255
|
|
|
|
|
|| $match[4] > 255 ) {
|
|
|
|
|
// hmmm, what kind of dotted quad is this?
|
|
|
|
|
$param = '';
|
|
|
|
|
}
|
|
|
|
|
} elseif ( preg_match('/^[\w\d\.-]+$/', $param) // dots, hyphens, numbers
|
|
|
|
|
&& !preg_match('/^[\.-]/', $param) // no leading dots/hyphens
|
|
|
|
|
&& !preg_match('/[\.-]$/', $param) // no trailing dots/hyphens
|
|
|
|
|
) {
|
|
|
|
|
// all is ok - $param is respected
|
|
|
|
|
} else {
|
|
|
|
|
// all is not ok...
|
|
|
|
|
$param='';
|
|
|
|
|
}
|
|
|
|
|
return $param;
|
2005-01-25 06:09:39 +00:00
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
case PARAM_URL: // allow safe ftp, http, mailto urls
|
|
|
|
|
include_once($CFG->dirroot . '/lib/validateurlsyntax.php');
|
2006-12-03 10:23:56 +00:00
|
|
|
|
if (!empty($param) && validateUrlSyntax($param, 's?H?S?F?E?u-P-a?I?p?f?q?r?')) {
|
2006-03-04 18:05:41 +00:00
|
|
|
|
// all is ok, param is respected
|
2005-02-25 06:08:40 +00:00
|
|
|
|
} else {
|
2006-03-04 18:05:41 +00:00
|
|
|
|
$param =''; // not really ok
|
|
|
|
|
}
|
|
|
|
|
return $param;
|
|
|
|
|
|
|
|
|
|
case PARAM_LOCALURL: // allow http absolute, root relative and relative URLs within wwwroot
|
2007-05-27 11:19:04 +00:00
|
|
|
|
$param = clean_param($param, PARAM_URL);
|
2006-03-04 18:05:41 +00:00
|
|
|
|
if (!empty($param)) {
|
|
|
|
|
if (preg_match(':^/:', $param)) {
|
|
|
|
|
// root-relative, ok!
|
|
|
|
|
} elseif (preg_match('/^'.preg_quote($CFG->wwwroot, '/').'/i',$param)) {
|
|
|
|
|
// absolute, and matches our wwwroot
|
2005-01-25 06:09:39 +00:00
|
|
|
|
} else {
|
2006-03-04 18:05:41 +00:00
|
|
|
|
// relative - let's make sure there are no tricks
|
|
|
|
|
if (validateUrlSyntax($param, 's-u-P-a-p-f+q?r?')) {
|
|
|
|
|
// looks ok.
|
|
|
|
|
} else {
|
|
|
|
|
$param = '';
|
|
|
|
|
}
|
2005-02-25 06:08:40 +00:00
|
|
|
|
}
|
2005-01-25 06:09:39 +00:00
|
|
|
|
}
|
2006-03-04 18:05:41 +00:00
|
|
|
|
return $param;
|
2007-09-16 14:20:32 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
case PARAM_PEM:
|
|
|
|
|
$param = trim($param);
|
|
|
|
|
// PEM formatted strings may contain letters/numbers and the symbols
|
|
|
|
|
// forward slash: /
|
|
|
|
|
// plus sign: +
|
|
|
|
|
// equal sign: =
|
|
|
|
|
// , surrounded by BEGIN and END CERTIFICATE prefix and suffixes
|
|
|
|
|
if (preg_match('/^-----BEGIN CERTIFICATE-----([\s\w\/\+=]+)-----END CERTIFICATE-----$/', trim($param), $matches)) {
|
|
|
|
|
list($wholething, $body) = $matches;
|
|
|
|
|
unset($wholething, $matches);
|
|
|
|
|
$b64 = clean_param($body, PARAM_BASE64);
|
|
|
|
|
if (!empty($b64)) {
|
|
|
|
|
return "-----BEGIN CERTIFICATE-----\n$b64\n-----END CERTIFICATE-----\n";
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return '';
|
2007-09-16 14:20:32 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
case PARAM_BASE64:
|
|
|
|
|
if (!empty($param)) {
|
|
|
|
|
// PEM formatted strings may contain letters/numbers and the symbols
|
|
|
|
|
// forward slash: /
|
|
|
|
|
// plus sign: +
|
|
|
|
|
// equal sign: =
|
|
|
|
|
if (0 >= preg_match('/^([\s\w\/\+=]+)$/', trim($param))) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
$lines = preg_split('/[\s]+/', $param, -1, PREG_SPLIT_NO_EMPTY);
|
|
|
|
|
// Each line of base64 encoded data must be 64 characters in
|
|
|
|
|
// length, except for the last line which may be less than (or
|
|
|
|
|
// equal to) 64 characters long.
|
|
|
|
|
for ($i=0, $j=count($lines); $i < $j; $i++) {
|
|
|
|
|
if ($i + 1 == $j) {
|
|
|
|
|
if (64 < strlen($lines[$i])) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2005-01-25 06:09:39 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
if (64 != strlen($lines[$i])) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return implode("\n",$lines);
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2007-09-16 14:20:32 +00:00
|
|
|
|
|
|
|
|
|
case PARAM_TAG:
|
2008-02-25 01:58:17 +00:00
|
|
|
|
//as long as magic_quotes_gpc is used, a backslash will be a
|
|
|
|
|
//problem, so remove *all* backslash.
|
|
|
|
|
$param = str_replace('\\', '', $param);
|
|
|
|
|
//convert many whitespace chars into one
|
2007-09-16 14:20:32 +00:00
|
|
|
|
$param = preg_replace('/\s+/', ' ', $param);
|
2007-09-16 18:49:41 +00:00
|
|
|
|
$textlib = textlib_get_instance();
|
2008-02-25 01:58:17 +00:00
|
|
|
|
$param = $textlib->substr(trim($param), 0, TAG_MAX_LENGTH);
|
2008-03-19 08:12:14 +00:00
|
|
|
|
return $param;
|
2007-09-16 14:20:32 +00:00
|
|
|
|
|
2008-02-25 07:17:04 +00:00
|
|
|
|
|
|
|
|
|
case PARAM_TAGLIST:
|
|
|
|
|
$tags = explode(',', $param);
|
|
|
|
|
$result = array();
|
|
|
|
|
foreach ($tags as $tag) {
|
|
|
|
|
$res = clean_param($tag, PARAM_TAG);
|
|
|
|
|
if ($res != '') {
|
|
|
|
|
$result[] = $res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($result) {
|
|
|
|
|
return implode(',', $result);
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 18:05:41 +00:00
|
|
|
|
default: // throw error, switched parameters in optional_param or another serious problem
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error("Unknown parameter type: $type");
|
2005-02-25 13:10:24 +00:00
|
|
|
|
}
|
2004-10-01 12:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-04 16:20:30 +00:00
|
|
|
|
|
2005-06-10 09:51:25 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Set a key in global configuration
|
|
|
|
|
*
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* Set a key/value pair in both this session's {@link $CFG} global variable
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* and in the 'config' database table for future sessions.
|
2006-03-04 16:53:02 +00:00
|
|
|
|
*
|
|
|
|
|
* Can also be used to update keys for plugin-scoped configs in config_plugin table.
|
|
|
|
|
* In that case it doesn't affect $CFG.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
2007-11-14 22:10:21 +00:00
|
|
|
|
* A NULL value will delete the entry.
|
|
|
|
|
*
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @param string $name the key to set
|
2006-11-27 08:44:38 +00:00
|
|
|
|
* @param string $value the value to set (without magic quotes)
|
2005-06-02 05:39:41 +00:00
|
|
|
|
* @param string $plugin (optional) the plugin scope
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2005-06-02 05:39:41 +00:00
|
|
|
|
function set_config($name, $value, $plugin=NULL) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
/// No need for get_config because they are usually always available in $CFG
|
2004-01-28 14:14:19 +00:00
|
|
|
|
|
2003-08-18 17:41:06 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2005-06-02 05:39:41 +00:00
|
|
|
|
if (empty($plugin)) {
|
2007-12-19 17:35:20 +00:00
|
|
|
|
if (!array_key_exists($name, $CFG->config_php_settings)) {
|
|
|
|
|
// So it's defined for this invocation at least
|
|
|
|
|
if (is_null($value)) {
|
|
|
|
|
unset($CFG->$name);
|
|
|
|
|
} else {
|
2007-12-19 22:32:43 +00:00
|
|
|
|
$CFG->$name = (string)$value; // settings from db are always strings
|
2007-12-19 17:35:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2005-06-02 05:39:41 +00:00
|
|
|
|
if (get_field('config', 'name', 'name', $name)) {
|
2007-11-14 22:10:21 +00:00
|
|
|
|
if ($value===null) {
|
|
|
|
|
return delete_records('config', 'name', $name);
|
|
|
|
|
} else {
|
|
|
|
|
return set_field('config', 'value', addslashes($value), 'name', $name);
|
|
|
|
|
}
|
2005-06-02 05:39:41 +00:00
|
|
|
|
} else {
|
2007-11-14 22:10:21 +00:00
|
|
|
|
if ($value===null) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2006-11-27 08:44:38 +00:00
|
|
|
|
$config = new object();
|
2005-06-02 05:39:41 +00:00
|
|
|
|
$config->name = $name;
|
2006-11-27 08:44:38 +00:00
|
|
|
|
$config->value = addslashes($value);
|
2005-06-02 05:39:41 +00:00
|
|
|
|
return insert_record('config', $config);
|
|
|
|
|
}
|
|
|
|
|
} else { // plugin scope
|
|
|
|
|
if ($id = get_field('config_plugins', 'id', 'name', $name, 'plugin', $plugin)) {
|
2007-11-14 22:10:21 +00:00
|
|
|
|
if ($value===null) {
|
|
|
|
|
return delete_records('config_plugins', 'name', $name, 'plugin', $plugin);
|
|
|
|
|
} else {
|
|
|
|
|
return set_field('config_plugins', 'value', addslashes($value), 'id', $id);
|
|
|
|
|
}
|
2005-06-02 05:39:41 +00:00
|
|
|
|
} else {
|
2007-11-14 22:10:21 +00:00
|
|
|
|
if ($value===null) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2006-11-27 08:44:38 +00:00
|
|
|
|
$config = new object();
|
|
|
|
|
$config->plugin = addslashes($plugin);
|
2005-06-02 05:39:41 +00:00
|
|
|
|
$config->name = $name;
|
2007-02-13 03:16:22 +00:00
|
|
|
|
$config->value = addslashes($value);
|
2005-06-02 05:39:41 +00:00
|
|
|
|
return insert_record('config_plugins', $config);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2006-03-04 16:53:02 +00:00
|
|
|
|
* Get configuration values from the global config table
|
2005-06-02 05:39:41 +00:00
|
|
|
|
* or the config_plugins table.
|
|
|
|
|
*
|
|
|
|
|
* If called with no parameters it will do the right thing
|
|
|
|
|
* generating $CFG safely from the database without overwriting
|
2006-03-04 16:53:02 +00:00
|
|
|
|
* existing values.
|
2005-06-02 05:39:41 +00:00
|
|
|
|
*
|
2007-01-16 23:25:19 +00:00
|
|
|
|
* If called with 2 parameters it will return a $string single
|
|
|
|
|
* value or false of the value is not found.
|
|
|
|
|
*
|
2006-03-04 16:53:02 +00:00
|
|
|
|
* @param string $plugin
|
|
|
|
|
* @param string $name
|
2005-06-02 05:39:41 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @return hash-like object or single value
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function get_config($plugin=NULL, $name=NULL) {
|
2004-09-23 02:48:41 +00:00
|
|
|
|
|
2005-06-02 05:39:41 +00:00
|
|
|
|
global $CFG;
|
2002-11-10 08:43:44 +00:00
|
|
|
|
|
2005-06-02 05:39:41 +00:00
|
|
|
|
if (!empty($name)) { // the user is asking for a specific value
|
|
|
|
|
if (!empty($plugin)) {
|
2007-01-16 23:25:19 +00:00
|
|
|
|
return get_field('config_plugins', 'value', 'plugin' , $plugin, 'name', $name);
|
2005-06-02 05:39:41 +00:00
|
|
|
|
} else {
|
2007-01-16 23:25:19 +00:00
|
|
|
|
return get_field('config', 'value', 'name', $name);
|
2005-06-02 05:39:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the user is after a recordset
|
|
|
|
|
if (!empty($plugin)) {
|
|
|
|
|
if ($configs=get_records('config_plugins', 'plugin', $plugin, '', 'name,value')) {
|
|
|
|
|
$configs = (array)$configs;
|
|
|
|
|
$localcfg = array();
|
|
|
|
|
foreach ($configs as $config) {
|
|
|
|
|
$localcfg[$config->name] = $config->value;
|
|
|
|
|
}
|
|
|
|
|
return (object)$localcfg;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2002-11-10 07:37:15 +00:00
|
|
|
|
} else {
|
2005-06-02 05:39:41 +00:00
|
|
|
|
// this was originally in setup.php
|
|
|
|
|
if ($configs = get_records('config')) {
|
|
|
|
|
$localcfg = (array)$CFG;
|
|
|
|
|
foreach ($configs as $config) {
|
|
|
|
|
if (!isset($localcfg[$config->name])) {
|
|
|
|
|
$localcfg[$config->name] = $config->value;
|
|
|
|
|
}
|
2007-12-19 17:35:20 +00:00
|
|
|
|
// do not complain anymore if config.php overrides settings from db
|
2005-06-02 05:39:41 +00:00
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2005-06-02 05:39:41 +00:00
|
|
|
|
$localcfg = (object)$localcfg;
|
|
|
|
|
return $localcfg;
|
|
|
|
|
} else {
|
|
|
|
|
// preserve $CFG if DB returns nothing or error
|
|
|
|
|
return $CFG;
|
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2002-07-29 06:21:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-20 02:17:27 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes a key from global configuration
|
|
|
|
|
*
|
|
|
|
|
* @param string $name the key to set
|
|
|
|
|
* @param string $plugin (optional) the plugin scope
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
function unset_config($name, $plugin=NULL) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
unset($CFG->$name);
|
|
|
|
|
|
|
|
|
|
if (empty($plugin)) {
|
|
|
|
|
return delete_records('config', 'name', $name);
|
2007-07-18 05:17:45 +00:00
|
|
|
|
} else {
|
2006-09-20 02:17:27 +00:00
|
|
|
|
return delete_records('config_plugins', 'name', $name, 'plugin', $plugin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-02 08:39:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Get volatile flags
|
|
|
|
|
*
|
|
|
|
|
* @param string $type
|
|
|
|
|
* @param int $changedsince
|
|
|
|
|
* @return records array
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function get_cache_flags($type, $changedsince=NULL) {
|
|
|
|
|
|
|
|
|
|
$type = addslashes($type);
|
|
|
|
|
|
|
|
|
|
$sqlwhere = 'flagtype=\'' . $type . '\' AND expiry >= ' . time();
|
|
|
|
|
if ($changedsince !== NULL) {
|
|
|
|
|
$changedsince = (int)$changedsince;
|
|
|
|
|
$sqlwhere .= ' AND timemodified > ' . $changedsince;
|
|
|
|
|
}
|
|
|
|
|
$cf = array();
|
|
|
|
|
if ($flags=get_records_select('cache_flags', $sqlwhere, '', 'name,value')) {
|
|
|
|
|
foreach ($flags as $flag) {
|
|
|
|
|
$cf[$flag->name] = $flag->value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $cf;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-27 02:57:33 +00:00
|
|
|
|
/**
|
|
|
|
|
* Get volatile flags
|
|
|
|
|
*
|
|
|
|
|
* @param string $type
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @param int $changedsince
|
|
|
|
|
* @return records array
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function get_cache_flag($type, $name, $changedsince=NULL) {
|
|
|
|
|
|
|
|
|
|
$type = addslashes($type);
|
|
|
|
|
$name = addslashes($name);
|
|
|
|
|
|
|
|
|
|
$sqlwhere = 'flagtype=\'' . $type . '\' AND name=\'' . $name . '\' AND expiry >= ' . time();
|
|
|
|
|
if ($changedsince !== NULL) {
|
|
|
|
|
$changedsince = (int)$changedsince;
|
|
|
|
|
$sqlwhere .= ' AND timemodified > ' . $changedsince;
|
|
|
|
|
}
|
|
|
|
|
return get_field_select('cache_flags', 'value', $sqlwhere);
|
|
|
|
|
}
|
2007-10-02 08:39:44 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set a volatile flag
|
|
|
|
|
*
|
|
|
|
|
* @param string $type the "type" namespace for the key
|
|
|
|
|
* @param string $name the key to set
|
|
|
|
|
* @param string $value the value to set (without magic quotes) - NULL will remove the flag
|
|
|
|
|
* @param int $expiry (optional) epoch indicating expiry - defaults to now()+ 24hs
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
function set_cache_flag($type, $name, $value, $expiry=NULL) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$timemodified = time();
|
|
|
|
|
if ($expiry===NULL || $expiry < $timemodified) {
|
|
|
|
|
$expiry = $timemodified + 24 * 60 * 60;
|
|
|
|
|
} else {
|
|
|
|
|
$expiry = (int)$expiry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($value === NULL) {
|
|
|
|
|
return unset_cache_flag($type,$name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$type = addslashes($type);
|
|
|
|
|
$name = addslashes($name);
|
2007-10-09 12:49:54 +00:00
|
|
|
|
if ($f = get_record('cache_flags', 'name', $name, 'flagtype', $type)) { // this is a potentail problem in DEBUG_DEVELOPER
|
|
|
|
|
if ($f->value == $value and $f->expiry == $expiry and $f->timemodified == $timemodified) {
|
|
|
|
|
return true; //no need to update; helps rcache too
|
|
|
|
|
}
|
|
|
|
|
$f->value = addslashes($value);
|
2007-10-02 08:39:44 +00:00
|
|
|
|
$f->expiry = $expiry;
|
|
|
|
|
$f->timemodified = $timemodified;
|
|
|
|
|
return update_record('cache_flags', $f);
|
|
|
|
|
} else {
|
2007-10-09 12:49:54 +00:00
|
|
|
|
$f = new object();
|
2007-10-02 08:39:44 +00:00
|
|
|
|
$f->flagtype = $type;
|
|
|
|
|
$f->name = $name;
|
2007-10-09 12:49:54 +00:00
|
|
|
|
$f->value = addslashes($value);
|
2007-10-02 08:39:44 +00:00
|
|
|
|
$f->expiry = $expiry;
|
|
|
|
|
$f->timemodified = $timemodified;
|
2007-10-09 12:49:54 +00:00
|
|
|
|
return (bool)insert_record('cache_flags', $f);
|
2007-10-02 08:39:44 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes a single volatile flag
|
|
|
|
|
*
|
|
|
|
|
* @param string $type the "type" namespace for the key
|
|
|
|
|
* @param string $name the key to set
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
function unset_cache_flag($type, $name) {
|
|
|
|
|
|
|
|
|
|
return delete_records('cache_flags',
|
|
|
|
|
'name', addslashes($name),
|
|
|
|
|
'flagtype', addslashes($type));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Garbage-collect volatile flags
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function gc_cache_flags() {
|
|
|
|
|
return delete_records_select('cache_flags', 'expiry < ' . time());
|
|
|
|
|
}
|
2005-06-02 05:39:41 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Refresh current $USER session global variable with all their current preferences.
|
|
|
|
|
* @uses $USER
|
|
|
|
|
*/
|
2004-01-28 14:14:19 +00:00
|
|
|
|
function reload_user_preferences() {
|
|
|
|
|
|
|
|
|
|
global $USER;
|
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
//reset preference
|
|
|
|
|
$USER->preference = array();
|
2004-12-01 21:47:02 +00:00
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (!isloggedin() or isguestuser()) {
|
2008-02-25 07:48:24 +00:00
|
|
|
|
// no permanent storage for not-logged-in user and guest
|
2004-01-28 14:14:19 +00:00
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
} else if ($preferences = get_records('user_preferences', 'userid', $USER->id)) {
|
2004-01-28 14:14:19 +00:00
|
|
|
|
foreach ($preferences as $preference) {
|
|
|
|
|
$USER->preference[$preference->name] = $preference->value;
|
|
|
|
|
}
|
2004-09-25 01:29:37 +00:00
|
|
|
|
}
|
2007-03-05 20:02:27 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
2004-01-28 14:14:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets a preference for the current user
|
|
|
|
|
* Optionally, can set a preference for a different user object
|
|
|
|
|
* @uses $USER
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @todo Add a better description and include usage examples. Add inline links to $USER and user functions in above line.
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @param string $name The key to set as preference for the specified user
|
|
|
|
|
* @param string $value The value to set forthe $name key in the specified user's record
|
2007-03-05 20:02:27 +00:00
|
|
|
|
* @param int $otheruserid A moodle user ID
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2007-03-05 20:02:27 +00:00
|
|
|
|
function set_user_preference($name, $value, $otheruserid=NULL) {
|
2004-01-28 14:14:19 +00:00
|
|
|
|
|
|
|
|
|
global $USER;
|
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (!isset($USER->preference)) {
|
|
|
|
|
reload_user_preferences();
|
2004-09-20 09:08:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-01-28 14:14:19 +00:00
|
|
|
|
if (empty($name)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
$nostore = false;
|
|
|
|
|
|
|
|
|
|
if (empty($otheruserid)){
|
|
|
|
|
if (!isloggedin() or isguestuser()) {
|
|
|
|
|
$nostore = true;
|
|
|
|
|
}
|
|
|
|
|
$userid = $USER->id;
|
|
|
|
|
} else {
|
|
|
|
|
if (isguestuser($otheruserid)) {
|
|
|
|
|
$nostore = true;
|
|
|
|
|
}
|
|
|
|
|
$userid = $otheruserid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$return = true;
|
|
|
|
|
if ($nostore) {
|
2008-02-25 07:48:24 +00:00
|
|
|
|
// no permanent storage for not-logged-in user and guest
|
2007-03-05 20:02:27 +00:00
|
|
|
|
|
|
|
|
|
} else if ($preference = get_record('user_preferences', 'userid', $userid, 'name', addslashes($name))) {
|
2007-09-19 07:01:41 +00:00
|
|
|
|
if ($preference->value === $value) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (!set_field('user_preferences', 'value', addslashes((string)$value), 'id', $preference->id)) {
|
|
|
|
|
$return = false;
|
2004-01-28 14:47:39 +00:00
|
|
|
|
}
|
2004-01-28 14:14:19 +00:00
|
|
|
|
|
|
|
|
|
} else {
|
2007-03-05 20:02:27 +00:00
|
|
|
|
$preference = new object();
|
2004-09-23 03:56:53 +00:00
|
|
|
|
$preference->userid = $userid;
|
2007-03-05 20:02:27 +00:00
|
|
|
|
$preference->name = addslashes($name);
|
|
|
|
|
$preference->value = addslashes((string)$value);
|
|
|
|
|
if (!insert_record('user_preferences', $preference)) {
|
|
|
|
|
$return = false;
|
2004-01-28 14:14:19 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-03-05 20:02:27 +00:00
|
|
|
|
|
|
|
|
|
// update value in USER session if needed
|
|
|
|
|
if ($userid == $USER->id) {
|
|
|
|
|
$USER->preference[$name] = (string)$value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $return;
|
2004-01-28 14:14:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 04:15:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Unsets a preference completely by deleting it from the database
|
|
|
|
|
* Optionally, can set a preference for a different user id
|
|
|
|
|
* @uses $USER
|
|
|
|
|
* @param string $name The key to unset as preference for the specified user
|
2007-03-05 20:02:27 +00:00
|
|
|
|
* @param int $otheruserid A moodle user ID
|
2004-09-23 04:15:19 +00:00
|
|
|
|
*/
|
2007-03-05 20:02:27 +00:00
|
|
|
|
function unset_user_preference($name, $otheruserid=NULL) {
|
2004-09-23 04:15:19 +00:00
|
|
|
|
|
|
|
|
|
global $USER;
|
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (!isset($USER->preference)) {
|
|
|
|
|
reload_user_preferences();
|
2004-09-23 04:15:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (empty($otheruserid)){
|
|
|
|
|
$userid = $USER->id;
|
|
|
|
|
} else {
|
|
|
|
|
$userid = $otheruserid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Delete the preference from $USER if needed
|
|
|
|
|
if ($userid == $USER->id) {
|
2005-07-21 18:48:26 +00:00
|
|
|
|
unset($USER->preference[$name]);
|
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2005-07-21 18:48:26 +00:00
|
|
|
|
//Then from DB
|
2007-03-05 20:02:27 +00:00
|
|
|
|
return delete_records('user_preferences', 'userid', $userid, 'name', addslashes($name));
|
2004-09-23 04:15:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets a whole array of preferences for the current user
|
|
|
|
|
* @param array $prefarray An array of key/value pairs to be set
|
2007-03-05 20:02:27 +00:00
|
|
|
|
* @param int $otheruserid A moodle user ID
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2007-03-05 20:02:27 +00:00
|
|
|
|
function set_user_preferences($prefarray, $otheruserid=NULL) {
|
2004-01-28 14:14:19 +00:00
|
|
|
|
|
|
|
|
|
if (!is_array($prefarray) or empty($prefarray)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$return = true;
|
|
|
|
|
foreach ($prefarray as $name => $value) {
|
2007-03-05 20:02:27 +00:00
|
|
|
|
// The order is important; test for return is done first
|
|
|
|
|
$return = (set_user_preference($name, $value, $otheruserid) && $return);
|
2004-01-28 14:14:19 +00:00
|
|
|
|
}
|
|
|
|
|
return $return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* If no arguments are supplied this function will return
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* all of the current user preferences as an array.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* If a name is specified then this function
|
|
|
|
|
* attempts to return that particular preference value. If
|
|
|
|
|
* none is found, then the optional value $default is returned,
|
|
|
|
|
* otherwise NULL.
|
|
|
|
|
* @param string $name Name of the key to use in finding a preference value
|
|
|
|
|
* @param string $default Value to be returned if the $name key is not set in the user preferences
|
2007-03-05 20:02:27 +00:00
|
|
|
|
* @param int $otheruserid A moodle user ID
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @uses $USER
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2007-03-05 20:02:27 +00:00
|
|
|
|
function get_user_preferences($name=NULL, $default=NULL, $otheruserid=NULL) {
|
2004-01-28 14:14:19 +00:00
|
|
|
|
global $USER;
|
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (!isset($USER->preference)) {
|
|
|
|
|
reload_user_preferences();
|
|
|
|
|
}
|
2004-09-23 03:56:53 +00:00
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (empty($otheruserid)){
|
|
|
|
|
$userid = $USER->id;
|
2004-09-23 03:56:53 +00:00
|
|
|
|
} else {
|
2007-03-05 20:02:27 +00:00
|
|
|
|
$userid = $otheruserid;
|
|
|
|
|
}
|
2004-09-23 03:56:53 +00:00
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if ($userid == $USER->id) {
|
|
|
|
|
$preference = $USER->preference;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
$preference = array();
|
|
|
|
|
if ($prefdata = get_records('user_preferences', 'userid', $userid)) {
|
|
|
|
|
foreach ($prefdata as $pref) {
|
|
|
|
|
$preference[$pref->name] = $pref->value;
|
|
|
|
|
}
|
2004-09-23 03:56:53 +00:00
|
|
|
|
}
|
2007-03-05 20:02:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($name)) {
|
|
|
|
|
return $preference; // All values
|
|
|
|
|
|
|
|
|
|
} else if (array_key_exists($name, $preference)) {
|
|
|
|
|
return $preference[$name]; // The single value
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
return $default; // Default value (or NULL)
|
2004-01-28 14:14:19 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-12-20 14:44:14 +00:00
|
|
|
|
/// FUNCTIONS FOR HANDLING TIME ////////////////////////////////////////////
|
2002-07-29 06:21:37 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Given date parts in user time produce a GMT timestamp.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @param int $year The year part to create timestamp of
|
|
|
|
|
* @param int $month The month part to create timestamp of
|
|
|
|
|
* @param int $day The day part to create timestamp of
|
|
|
|
|
* @param int $hour The hour part to create timestamp of
|
|
|
|
|
* @param int $minute The minute part to create timestamp of
|
|
|
|
|
* @param int $second The second part to create timestamp of
|
|
|
|
|
* @param float $timezone ?
|
|
|
|
|
* @param bool $applydst ?
|
2005-02-21 08:55:40 +00:00
|
|
|
|
* @return int timestamp
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2005-01-12 11:17:18 +00:00
|
|
|
|
function make_timestamp($year, $month=1, $day=1, $hour=0, $minute=0, $second=0, $timezone=99, $applydst=true) {
|
2002-07-29 06:21:37 +00:00
|
|
|
|
|
2008-04-03 18:09:15 +00:00
|
|
|
|
$strtimezone = NULL;
|
|
|
|
|
if (!is_numeric($timezone)) {
|
|
|
|
|
$strtimezone = $timezone;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-10 09:41:46 +00:00
|
|
|
|
$timezone = get_user_timezone_offset($timezone);
|
|
|
|
|
|
2003-01-13 02:42:57 +00:00
|
|
|
|
if (abs($timezone) > 13) {
|
2005-07-12 03:09:25 +00:00
|
|
|
|
$time = mktime((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$year);
|
2003-01-13 02:37:47 +00:00
|
|
|
|
} else {
|
2005-07-12 03:09:25 +00:00
|
|
|
|
$time = gmmktime((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$year);
|
2005-02-16 21:50:25 +00:00
|
|
|
|
$time = usertime($time, $timezone);
|
2005-05-01 16:50:35 +00:00
|
|
|
|
if($applydst) {
|
2008-04-03 18:09:15 +00:00
|
|
|
|
$time -= dst_offset_on($time, $strtimezone);
|
2005-05-01 16:50:35 +00:00
|
|
|
|
}
|
2005-01-12 11:17:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-02-16 21:50:25 +00:00
|
|
|
|
return $time;
|
2005-02-17 21:58:45 +00:00
|
|
|
|
|
2002-07-29 06:21:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given an amount of time in seconds, returns string
|
2007-02-15 02:53:00 +00:00
|
|
|
|
* formatted nicely as weeks, days, hours etc as needed
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* @uses MINSECS
|
|
|
|
|
* @uses HOURSECS
|
|
|
|
|
* @uses DAYSECS
|
2007-02-15 02:53:00 +00:00
|
|
|
|
* @uses YEARSECS
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $totalsecs ?
|
|
|
|
|
* @param array $str ?
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @return string
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
|
|
|
|
function format_time($totalsecs, $str=NULL) {
|
2002-06-08 06:47:33 +00:00
|
|
|
|
|
2002-08-04 16:20:30 +00:00
|
|
|
|
$totalsecs = abs($totalsecs);
|
2002-06-08 06:47:33 +00:00
|
|
|
|
|
2002-10-03 04:04:59 +00:00
|
|
|
|
if (!$str) { // Create the str structure the slow way
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$str->day = get_string('day');
|
|
|
|
|
$str->days = get_string('days');
|
|
|
|
|
$str->hour = get_string('hour');
|
|
|
|
|
$str->hours = get_string('hours');
|
|
|
|
|
$str->min = get_string('min');
|
|
|
|
|
$str->mins = get_string('mins');
|
|
|
|
|
$str->sec = get_string('sec');
|
|
|
|
|
$str->secs = get_string('secs');
|
2007-02-15 02:53:00 +00:00
|
|
|
|
$str->year = get_string('year');
|
|
|
|
|
$str->years = get_string('years');
|
2002-10-03 04:04:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-02-15 02:53:00 +00:00
|
|
|
|
|
|
|
|
|
$years = floor($totalsecs/YEARSECS);
|
|
|
|
|
$remainder = $totalsecs - ($years*YEARSECS);
|
|
|
|
|
$days = floor($remainder/DAYSECS);
|
2004-09-28 05:53:08 +00:00
|
|
|
|
$remainder = $totalsecs - ($days*DAYSECS);
|
|
|
|
|
$hours = floor($remainder/HOURSECS);
|
|
|
|
|
$remainder = $remainder - ($hours*HOURSECS);
|
|
|
|
|
$mins = floor($remainder/MINSECS);
|
|
|
|
|
$secs = $remainder - ($mins*MINSECS);
|
2002-10-03 04:04:59 +00:00
|
|
|
|
|
|
|
|
|
$ss = ($secs == 1) ? $str->sec : $str->secs;
|
|
|
|
|
$sm = ($mins == 1) ? $str->min : $str->mins;
|
|
|
|
|
$sh = ($hours == 1) ? $str->hour : $str->hours;
|
|
|
|
|
$sd = ($days == 1) ? $str->day : $str->days;
|
2007-02-15 02:53:00 +00:00
|
|
|
|
$sy = ($years == 1) ? $str->year : $str->years;
|
2002-10-03 04:04:59 +00:00
|
|
|
|
|
2007-02-15 02:53:00 +00:00
|
|
|
|
$oyears = '';
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$odays = '';
|
|
|
|
|
$ohours = '';
|
|
|
|
|
$omins = '';
|
|
|
|
|
$osecs = '';
|
2002-12-29 17:32:32 +00:00
|
|
|
|
|
2007-02-15 02:53:00 +00:00
|
|
|
|
if ($years) $oyears = $years .' '. $sy;
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($days) $odays = $days .' '. $sd;
|
|
|
|
|
if ($hours) $ohours = $hours .' '. $sh;
|
|
|
|
|
if ($mins) $omins = $mins .' '. $sm;
|
|
|
|
|
if ($secs) $osecs = $secs .' '. $ss;
|
2002-08-04 16:20:30 +00:00
|
|
|
|
|
2007-04-16 18:51:52 +00:00
|
|
|
|
if ($years) return trim($oyears .' '. $odays);
|
|
|
|
|
if ($days) return trim($odays .' '. $ohours);
|
|
|
|
|
if ($hours) return trim($ohours .' '. $omins);
|
|
|
|
|
if ($mins) return trim($omins .' '. $osecs);
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($secs) return $osecs;
|
|
|
|
|
return get_string('now');
|
2002-08-04 16:20:30 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a formatted string that represents a date in user time
|
|
|
|
|
* <b>WARNING: note that the format is for strftime(), not date().</b>
|
|
|
|
|
* Because of a bug in most Windows time libraries, we can't use
|
|
|
|
|
* the nicer %e, so we have to use %d which has leading zeroes.
|
|
|
|
|
* A lot of the fuss in the function is just getting rid of these leading
|
|
|
|
|
* zeroes as efficiently as possible.
|
2004-11-22 18:38:33 +00:00
|
|
|
|
*
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* If parameter fixday = true (default), then take off leading
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* zero from %d, else mantain it.
|
|
|
|
|
*
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* @uses HOURSECS
|
2005-02-21 08:55:40 +00:00
|
|
|
|
* @param int $date timestamp in GMT
|
|
|
|
|
* @param string $format strftime format
|
2005-02-25 06:08:40 +00:00
|
|
|
|
* @param float $timezone
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @param bool $fixday If true (default) then the leading
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* zero from %d is removed. If false then the leading zero is mantained.
|
|
|
|
|
* @return string
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2004-09-22 14:39:15 +00:00
|
|
|
|
function userdate($date, $format='', $timezone=99, $fixday = true) {
|
2002-07-02 07:02:28 +00:00
|
|
|
|
|
2005-03-10 14:10:21 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2008-04-03 18:09:15 +00:00
|
|
|
|
$strtimezone = NULL;
|
|
|
|
|
if (!is_numeric($timezone)) {
|
|
|
|
|
$strtimezone = $timezone;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-16 21:00:06 +00:00
|
|
|
|
if (empty($format)) {
|
|
|
|
|
$format = get_string('strftimedaydatetime');
|
2002-06-05 14:05:59 +00:00
|
|
|
|
}
|
2002-12-02 01:35:18 +00:00
|
|
|
|
|
2005-05-12 06:37:24 +00:00
|
|
|
|
if (!empty($CFG->nofixday)) { // Config.php can force %d not to be fixed.
|
|
|
|
|
$fixday = false;
|
|
|
|
|
} else if ($fixday) {
|
|
|
|
|
$formatnoday = str_replace('%d', 'DD', $format);
|
2003-05-02 09:37:41 +00:00
|
|
|
|
$fixday = ($formatnoday != $format);
|
|
|
|
|
}
|
2003-01-15 10:55:54 +00:00
|
|
|
|
|
2008-04-03 18:09:15 +00:00
|
|
|
|
$date += dst_offset_on($date, $strtimezone);
|
2005-02-17 22:43:18 +00:00
|
|
|
|
|
2005-04-08 07:42:50 +00:00
|
|
|
|
$timezone = get_user_timezone_offset($timezone);
|
2005-02-19 02:49:31 +00:00
|
|
|
|
|
|
|
|
|
if (abs($timezone) > 13) { /// Server time
|
2005-02-25 06:08:40 +00:00
|
|
|
|
if ($fixday) {
|
2005-02-19 02:49:31 +00:00
|
|
|
|
$datestring = strftime($formatnoday, $date);
|
|
|
|
|
$daystring = str_replace(' 0', '', strftime(' %d', $date));
|
|
|
|
|
$datestring = str_replace('DD', $daystring, $datestring);
|
|
|
|
|
} else {
|
|
|
|
|
$datestring = strftime($format, $date);
|
|
|
|
|
}
|
2005-02-18 13:44:14 +00:00
|
|
|
|
} else {
|
2005-02-19 02:49:31 +00:00
|
|
|
|
$date += (int)($timezone * 3600);
|
|
|
|
|
if ($fixday) {
|
|
|
|
|
$datestring = gmstrftime($formatnoday, $date);
|
|
|
|
|
$daystring = str_replace(' 0', '', gmstrftime(' %d', $date));
|
|
|
|
|
$datestring = str_replace('DD', $daystring, $datestring);
|
|
|
|
|
} else {
|
|
|
|
|
$datestring = gmstrftime($format, $date);
|
|
|
|
|
}
|
2005-02-18 13:44:14 +00:00
|
|
|
|
}
|
2005-02-19 02:49:31 +00:00
|
|
|
|
|
2006-11-11 16:07:53 +00:00
|
|
|
|
/// If we are running under Windows convert from windows encoding to UTF-8
|
|
|
|
|
/// (because it's impossible to specify UTF-8 to fetch locale info in Win32)
|
2006-03-25 12:26:33 +00:00
|
|
|
|
|
2006-11-11 16:07:53 +00:00
|
|
|
|
if ($CFG->ostype == 'WINDOWS') {
|
2006-03-25 12:26:33 +00:00
|
|
|
|
if ($localewincharset = get_string('localewincharset')) {
|
|
|
|
|
$textlib = textlib_get_instance();
|
2006-11-11 17:23:20 +00:00
|
|
|
|
$datestring = $textlib->convert($datestring, $localewincharset, 'utf-8');
|
2006-03-25 12:26:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-02 01:35:18 +00:00
|
|
|
|
return $datestring;
|
2002-06-05 03:15:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2005-02-16 21:50:25 +00:00
|
|
|
|
* Given a $time timestamp in GMT (seconds since epoch),
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* returns an array that represents the date in user time
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* @uses HOURSECS
|
2005-02-16 21:50:25 +00:00
|
|
|
|
* @param int $time Timestamp in GMT
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @param float $timezone ?
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return array An array that represents the date in user time
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2005-02-16 21:50:25 +00:00
|
|
|
|
function usergetdate($time, $timezone=99) {
|
2002-08-04 16:20:30 +00:00
|
|
|
|
|
2008-03-20 03:01:58 +00:00
|
|
|
|
$strtimezone = NULL;
|
|
|
|
|
if (!is_numeric($timezone)) {
|
|
|
|
|
$strtimezone = $timezone;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-08 07:42:50 +00:00
|
|
|
|
$timezone = get_user_timezone_offset($timezone);
|
2004-04-01 10:39:06 +00:00
|
|
|
|
|
2005-02-21 08:55:40 +00:00
|
|
|
|
if (abs($timezone) > 13) { // Server time
|
2005-02-22 06:52:42 +00:00
|
|
|
|
return getdate($time);
|
2005-02-25 06:08:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-02-21 08:55:40 +00:00
|
|
|
|
// There is no gmgetdate so we use gmdate instead
|
2008-03-20 03:01:58 +00:00
|
|
|
|
$time += dst_offset_on($time, $strtimezone);
|
2005-02-21 08:55:40 +00:00
|
|
|
|
$time += intval((float)$timezone * HOURSECS);
|
2005-03-23 14:43:32 +00:00
|
|
|
|
|
|
|
|
|
$datestring = gmstrftime('%S_%M_%H_%d_%m_%Y_%w_%j_%A_%B', $time);
|
2005-02-16 22:55:13 +00:00
|
|
|
|
|
2005-01-12 11:17:18 +00:00
|
|
|
|
list(
|
|
|
|
|
$getdate['seconds'],
|
|
|
|
|
$getdate['minutes'],
|
|
|
|
|
$getdate['hours'],
|
|
|
|
|
$getdate['mday'],
|
|
|
|
|
$getdate['mon'],
|
|
|
|
|
$getdate['year'],
|
|
|
|
|
$getdate['wday'],
|
|
|
|
|
$getdate['yday'],
|
|
|
|
|
$getdate['weekday'],
|
|
|
|
|
$getdate['month']
|
2005-03-23 14:43:32 +00:00
|
|
|
|
) = explode('_', $datestring);
|
2005-01-12 11:17:18 +00:00
|
|
|
|
|
2002-06-11 04:04:45 +00:00
|
|
|
|
return $getdate;
|
2002-06-10 09:43:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given a GMT timestamp (seconds since epoch), offsets it by
|
|
|
|
|
* the timezone. eg 3pm in India is 3pm GMT - 7 * 3600 seconds
|
|
|
|
|
*
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* @uses HOURSECS
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $date Timestamp in GMT
|
2005-02-21 08:55:40 +00:00
|
|
|
|
* @param float $timezone
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return int
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-06-10 09:43:40 +00:00
|
|
|
|
function usertime($date, $timezone=99) {
|
2004-04-01 10:39:06 +00:00
|
|
|
|
|
2005-04-08 07:42:50 +00:00
|
|
|
|
$timezone = get_user_timezone_offset($timezone);
|
2005-04-08 05:39:53 +00:00
|
|
|
|
|
2002-11-15 02:46:48 +00:00
|
|
|
|
if (abs($timezone) > 13) {
|
2002-06-10 09:43:40 +00:00
|
|
|
|
return $date;
|
|
|
|
|
}
|
2004-09-28 05:53:08 +00:00
|
|
|
|
return $date - (int)($timezone * HOURSECS);
|
2002-06-10 09:43:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given a time, return the GMT timestamp of the most recent midnight
|
|
|
|
|
* for the current user.
|
|
|
|
|
*
|
2005-02-21 08:55:40 +00:00
|
|
|
|
* @param int $date Timestamp in GMT
|
|
|
|
|
* @param float $timezone ?
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return ?
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2002-06-10 14:01:30 +00:00
|
|
|
|
function usergetmidnight($date, $timezone=99) {
|
|
|
|
|
|
|
|
|
|
$userdate = usergetdate($date, $timezone);
|
2002-08-08 17:28:30 +00:00
|
|
|
|
|
2005-02-16 22:55:13 +00:00
|
|
|
|
// Time of midnight of this user's day, in GMT
|
|
|
|
|
return make_timestamp($userdate['year'], $userdate['mon'], $userdate['mday'], 0, 0, 0, $timezone);
|
2002-06-10 14:01:30 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a string that prints the user's timezone
|
|
|
|
|
*
|
|
|
|
|
* @param float $timezone The user's timezone
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2002-06-10 09:43:40 +00:00
|
|
|
|
function usertimezone($timezone=99) {
|
|
|
|
|
|
2005-04-27 03:42:07 +00:00
|
|
|
|
$tz = get_user_timezone($timezone);
|
2004-04-01 12:27:37 +00:00
|
|
|
|
|
2005-04-27 03:42:07 +00:00
|
|
|
|
if (!is_float($tz)) {
|
|
|
|
|
return $tz;
|
2002-06-10 09:43:40 +00:00
|
|
|
|
}
|
2005-04-27 03:42:07 +00:00
|
|
|
|
|
|
|
|
|
if(abs($tz) > 13) { // Server time
|
|
|
|
|
return get_string('serverlocaltime');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($tz == intval($tz)) {
|
|
|
|
|
// Don't show .0 for whole hours
|
|
|
|
|
$tz = intval($tz);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($tz == 0) {
|
2007-11-22 06:28:58 +00:00
|
|
|
|
return 'UTC';
|
2002-06-10 09:43:40 +00:00
|
|
|
|
}
|
2005-04-27 03:42:07 +00:00
|
|
|
|
else if($tz > 0) {
|
2007-11-22 06:28:58 +00:00
|
|
|
|
return 'UTC+'.$tz;
|
2005-04-27 03:42:07 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2007-11-22 06:28:58 +00:00
|
|
|
|
return 'UTC'.$tz;
|
2002-06-10 09:43:40 +00:00
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a float which represents the user's timezone difference from GMT in hours
|
|
|
|
|
* Checks various settings and picks the most dominant of those which have a value
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $USER
|
2005-10-24 17:25:29 +00:00
|
|
|
|
* @param float $tz If this value is provided and not equal to 99, it will be returned as is and no other settings will be checked
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return int
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2005-04-08 07:42:50 +00:00
|
|
|
|
function get_user_timezone_offset($tz = 99) {
|
2004-04-01 12:27:37 +00:00
|
|
|
|
|
2005-04-08 05:28:39 +00:00
|
|
|
|
global $USER, $CFG;
|
|
|
|
|
|
2005-04-08 20:32:40 +00:00
|
|
|
|
$tz = get_user_timezone($tz);
|
2005-04-10 09:31:21 +00:00
|
|
|
|
|
2005-04-09 08:44:49 +00:00
|
|
|
|
if (is_float($tz)) {
|
|
|
|
|
return $tz;
|
|
|
|
|
} else {
|
2005-04-08 20:32:40 +00:00
|
|
|
|
$tzrecord = get_timezone_record($tz);
|
2005-04-09 08:44:49 +00:00
|
|
|
|
if (empty($tzrecord)) {
|
2005-04-08 20:32:40 +00:00
|
|
|
|
return 99.0;
|
|
|
|
|
}
|
2005-04-14 12:20:09 +00:00
|
|
|
|
return (float)$tzrecord->gmtoff / HOURMINS;
|
2005-04-08 20:32:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-16 18:33:50 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an int which represents the systems's timezone difference from GMT in seconds
|
|
|
|
|
* @param mixed $tz timezone
|
|
|
|
|
* @return int if found, false is timezone 99 or error
|
|
|
|
|
*/
|
|
|
|
|
function get_timezone_offset($tz) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if ($tz == 99) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_numeric($tz)) {
|
|
|
|
|
return intval($tz * 60*60);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$tzrecord = get_timezone_record($tz)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return intval($tzrecord->gmtoff * 60);
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
2005-10-24 17:25:29 +00:00
|
|
|
|
* Returns a float or a string which denotes the user's timezone
|
|
|
|
|
* A float value means that a simple offset from GMT is used, while a string (it will be the name of a timezone in the database)
|
|
|
|
|
* means that for this timezone there are also DST rules to be taken into account
|
|
|
|
|
* Checks various settings and picks the most dominant of those which have a value
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*
|
|
|
|
|
* @uses $USER
|
|
|
|
|
* @uses $CFG
|
2005-10-24 17:25:29 +00:00
|
|
|
|
* @param float $tz If this value is provided and not equal to 99, it will be returned as is and no other settings will be checked
|
|
|
|
|
* @return mixed
|
2005-07-12 02:06:33 +00:00
|
|
|
|
*/
|
2005-04-08 20:32:40 +00:00
|
|
|
|
function get_user_timezone($tz = 99) {
|
|
|
|
|
global $USER, $CFG;
|
2005-04-08 05:28:39 +00:00
|
|
|
|
|
2004-04-01 12:27:37 +00:00
|
|
|
|
$timezones = array(
|
2005-04-08 20:32:40 +00:00
|
|
|
|
$tz,
|
|
|
|
|
isset($CFG->forcetimezone) ? $CFG->forcetimezone : 99,
|
2005-04-08 05:28:39 +00:00
|
|
|
|
isset($USER->timezone) ? $USER->timezone : 99,
|
|
|
|
|
isset($CFG->timezone) ? $CFG->timezone : 99,
|
2004-04-01 12:27:37 +00:00
|
|
|
|
);
|
2005-04-08 05:28:39 +00:00
|
|
|
|
|
2005-04-08 20:32:40 +00:00
|
|
|
|
$tz = 99;
|
2005-04-08 05:28:39 +00:00
|
|
|
|
|
2008-04-03 18:09:15 +00:00
|
|
|
|
while(($tz == '' || $tz == 99 || $tz == NULL) && $next = each($timezones)) {
|
2005-04-08 20:32:40 +00:00
|
|
|
|
$tz = $next['value'];
|
2005-04-08 05:28:39 +00:00
|
|
|
|
}
|
2005-04-08 20:32:40 +00:00
|
|
|
|
|
|
|
|
|
return is_numeric($tz) ? (float) $tz : $tz;
|
2005-04-08 05:28:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
|
|
|
|
* ?
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $db
|
|
|
|
|
* @param string $timezonename ?
|
|
|
|
|
* @return object
|
|
|
|
|
*/
|
2005-04-08 05:28:39 +00:00
|
|
|
|
function get_timezone_record($timezonename) {
|
|
|
|
|
global $CFG, $db;
|
|
|
|
|
static $cache = NULL;
|
|
|
|
|
|
2005-04-10 18:27:15 +00:00
|
|
|
|
if ($cache === NULL) {
|
2005-04-08 05:28:39 +00:00
|
|
|
|
$cache = array();
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-10 18:27:15 +00:00
|
|
|
|
if (isset($cache[$timezonename])) {
|
2005-04-08 05:28:39 +00:00
|
|
|
|
return $cache[$timezonename];
|
2004-04-01 12:27:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-20 09:36:47 +00:00
|
|
|
|
return $cache[$timezonename] = get_record_sql('SELECT * FROM '.$CFG->prefix.'timezone
|
|
|
|
|
WHERE name = '.$db->qstr($timezonename).' ORDER BY year DESC', true);
|
2004-04-01 12:27:37 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
|
|
|
|
* ?
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $USER
|
|
|
|
|
* @param ? $fromyear ?
|
|
|
|
|
* @param ? $to_year ?
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-03-20 03:01:58 +00:00
|
|
|
|
function calculate_user_dst_table($from_year = NULL, $to_year = NULL, $strtimezone = NULL) {
|
2005-08-30 03:27:52 +00:00
|
|
|
|
global $CFG, $SESSION;
|
2005-02-17 21:58:45 +00:00
|
|
|
|
|
2008-04-03 18:09:15 +00:00
|
|
|
|
$usertz = get_user_timezone($strtimezone);
|
2005-02-19 03:14:06 +00:00
|
|
|
|
|
2005-04-09 10:12:30 +00:00
|
|
|
|
if (is_float($usertz)) {
|
|
|
|
|
// Trivial timezone, no DST
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-30 03:27:52 +00:00
|
|
|
|
if (!empty($SESSION->dst_offsettz) && $SESSION->dst_offsettz != $usertz) {
|
2005-04-09 10:12:30 +00:00
|
|
|
|
// We have precalculated values, but the user's effective TZ has changed in the meantime, so reset
|
2005-08-30 03:27:52 +00:00
|
|
|
|
unset($SESSION->dst_offsets);
|
|
|
|
|
unset($SESSION->dst_range);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-08-30 03:27:52 +00:00
|
|
|
|
if (!empty($SESSION->dst_offsets) && empty($from_year) && empty($to_year)) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// Repeat calls which do not request specific year ranges stop here, we have already calculated the table
|
|
|
|
|
// This will be the return path most of the time, pretty light computationally
|
|
|
|
|
return true;
|
2005-02-17 21:58:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// Reaching here means we either need to extend our table or create it from scratch
|
2005-04-09 10:12:30 +00:00
|
|
|
|
|
|
|
|
|
// Remember which TZ we calculated these changes for
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$SESSION->dst_offsettz = $usertz;
|
2005-04-09 10:12:30 +00:00
|
|
|
|
|
2005-08-30 03:27:52 +00:00
|
|
|
|
if(empty($SESSION->dst_offsets)) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// If we 're creating from scratch, put the two guard elements in there
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$SESSION->dst_offsets = array(1 => NULL, 0 => NULL);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
2005-08-30 03:27:52 +00:00
|
|
|
|
if(empty($SESSION->dst_range)) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// If creating from scratch
|
|
|
|
|
$from = max((empty($from_year) ? intval(date('Y')) - 3 : $from_year), 1971);
|
|
|
|
|
$to = min((empty($to_year) ? intval(date('Y')) + 3 : $to_year), 2035);
|
|
|
|
|
|
|
|
|
|
// Fill in the array with the extra years we need to process
|
|
|
|
|
$yearstoprocess = array();
|
|
|
|
|
for($i = $from; $i <= $to; ++$i) {
|
|
|
|
|
$yearstoprocess[] = $i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Take note of which years we have processed for future calls
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$SESSION->dst_range = array($from, $to);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// If needing to extend the table, do the same
|
|
|
|
|
$yearstoprocess = array();
|
|
|
|
|
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$from = max((empty($from_year) ? $SESSION->dst_range[0] : $from_year), 1971);
|
|
|
|
|
$to = min((empty($to_year) ? $SESSION->dst_range[1] : $to_year), 2035);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
|
2005-08-30 03:27:52 +00:00
|
|
|
|
if($from < $SESSION->dst_range[0]) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// Take note of which years we need to process and then note that we have processed them for future calls
|
2005-08-30 03:27:52 +00:00
|
|
|
|
for($i = $from; $i < $SESSION->dst_range[0]; ++$i) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
$yearstoprocess[] = $i;
|
|
|
|
|
}
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$SESSION->dst_range[0] = $from;
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
2005-08-30 03:27:52 +00:00
|
|
|
|
if($to > $SESSION->dst_range[1]) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// Take note of which years we need to process and then note that we have processed them for future calls
|
2005-08-30 03:27:52 +00:00
|
|
|
|
for($i = $SESSION->dst_range[1] + 1; $i <= $to; ++$i) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
$yearstoprocess[] = $i;
|
|
|
|
|
}
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$SESSION->dst_range[1] = $to;
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(empty($yearstoprocess)) {
|
|
|
|
|
// This means that there was a call requesting a SMALLER range than we have already calculated
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// From now on, we know that the array has at least the two guard elements, and $yearstoprocess has the years we need
|
|
|
|
|
// Also, the array is sorted in descending timestamp order!
|
|
|
|
|
|
|
|
|
|
// Get DB data
|
2008-02-03 16:01:33 +00:00
|
|
|
|
|
|
|
|
|
static $presets_cache = array();
|
|
|
|
|
if (!isset($presets_cache[$usertz])) {
|
|
|
|
|
$presets_cache[$usertz] = get_records('timezone', 'name', $usertz, 'year DESC', 'year, gmtoff, dstoff, dst_month, dst_startday, dst_weekday, dst_skipweeks, dst_time, std_month, std_startday, std_weekday, std_skipweeks, std_time');
|
|
|
|
|
}
|
|
|
|
|
if(empty($presets_cache[$usertz])) {
|
2005-03-23 03:03:43 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2005-02-18 01:18:00 +00:00
|
|
|
|
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// Remove ending guard (first element of the array)
|
2005-08-30 03:27:52 +00:00
|
|
|
|
reset($SESSION->dst_offsets);
|
|
|
|
|
unset($SESSION->dst_offsets[key($SESSION->dst_offsets)]);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
|
|
|
|
|
// Add all required change timestamps
|
|
|
|
|
foreach($yearstoprocess as $y) {
|
|
|
|
|
// Find the record which is in effect for the year $y
|
2008-02-03 16:01:33 +00:00
|
|
|
|
foreach($presets_cache[$usertz] as $year => $preset) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
if($year <= $y) {
|
|
|
|
|
break;
|
2005-03-05 22:23:08 +00:00
|
|
|
|
}
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$changes = dst_changes_for_year($y, $preset);
|
|
|
|
|
|
|
|
|
|
if($changes === NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if($changes['dst'] != 0) {
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$SESSION->dst_offsets[$changes['dst']] = $preset->dstoff * MINSECS;
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
|
|
|
|
if($changes['std'] != 0) {
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$SESSION->dst_offsets[$changes['std']] = 0;
|
2005-03-05 22:23:08 +00:00
|
|
|
|
}
|
2005-02-17 21:58:45 +00:00
|
|
|
|
}
|
2005-02-16 22:04:14 +00:00
|
|
|
|
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// Put in a guard element at the top
|
2005-08-30 03:27:52 +00:00
|
|
|
|
$maxtimestamp = max(array_keys($SESSION->dst_offsets));
|
|
|
|
|
$SESSION->dst_offsets[($maxtimestamp + DAYSECS)] = NULL; // DAYSECS is arbitrary, any "small" number will do
|
2005-03-26 18:43:58 +00:00
|
|
|
|
|
|
|
|
|
// Sort again
|
2005-08-30 03:27:52 +00:00
|
|
|
|
krsort($SESSION->dst_offsets);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
|
2005-03-23 03:03:43 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2005-02-16 22:04:14 +00:00
|
|
|
|
|
2005-03-23 03:03:43 +00:00
|
|
|
|
function dst_changes_for_year($year, $timezone) {
|
2005-02-19 03:14:06 +00:00
|
|
|
|
|
2005-03-23 03:03:43 +00:00
|
|
|
|
if($timezone->dst_startday == 0 && $timezone->dst_weekday == 0 && $timezone->std_startday == 0 && $timezone->std_weekday == 0) {
|
|
|
|
|
return NULL;
|
2005-02-16 22:04:14 +00:00
|
|
|
|
}
|
2005-02-19 03:14:06 +00:00
|
|
|
|
|
2005-03-23 03:03:43 +00:00
|
|
|
|
$monthdaydst = find_day_in_month($timezone->dst_startday, $timezone->dst_weekday, $timezone->dst_month, $year);
|
|
|
|
|
$monthdaystd = find_day_in_month($timezone->std_startday, $timezone->std_weekday, $timezone->std_month, $year);
|
|
|
|
|
|
|
|
|
|
list($dst_hour, $dst_min) = explode(':', $timezone->dst_time);
|
|
|
|
|
list($std_hour, $std_min) = explode(':', $timezone->std_time);
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
2005-04-09 09:50:08 +00:00
|
|
|
|
$timedst = make_timestamp($year, $timezone->dst_month, $monthdaydst, 0, 0, 0, 99, false);
|
|
|
|
|
$timestd = make_timestamp($year, $timezone->std_month, $monthdaystd, 0, 0, 0, 99, false);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
|
|
|
|
|
// Instead of putting hour and minute in make_timestamp(), we add them afterwards.
|
|
|
|
|
// This has the advantage of being able to have negative values for hour, i.e. for timezones
|
|
|
|
|
// where GMT time would be in the PREVIOUS day than the local one on which DST changes.
|
|
|
|
|
|
|
|
|
|
$timedst += $dst_hour * HOURSECS + $dst_min * MINSECS;
|
|
|
|
|
$timestd += $std_hour * HOURSECS + $std_min * MINSECS;
|
2005-02-16 22:04:14 +00:00
|
|
|
|
|
2005-03-23 03:03:43 +00:00
|
|
|
|
return array('dst' => $timedst, 0 => $timedst, 'std' => $timestd, 1 => $timestd);
|
2005-02-16 22:04:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-02-16 22:55:13 +00:00
|
|
|
|
// $time must NOT be compensated at all, it has to be a pure timestamp
|
2008-03-20 03:01:58 +00:00
|
|
|
|
function dst_offset_on($time, $strtimezone = NULL) {
|
2005-08-30 03:27:52 +00:00
|
|
|
|
global $SESSION;
|
2005-02-16 22:55:13 +00:00
|
|
|
|
|
2008-03-20 03:01:58 +00:00
|
|
|
|
if(!calculate_user_dst_table(NULL, NULL, $strtimezone) || empty($SESSION->dst_offsets)) {
|
2005-03-05 22:23:08 +00:00
|
|
|
|
return 0;
|
2005-02-17 21:58:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-08-30 03:27:52 +00:00
|
|
|
|
reset($SESSION->dst_offsets);
|
|
|
|
|
while(list($from, $offset) = each($SESSION->dst_offsets)) {
|
2005-03-05 23:57:19 +00:00
|
|
|
|
if($from <= $time) {
|
2005-03-05 22:23:08 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// This is the normal return path
|
|
|
|
|
if($offset !== NULL) {
|
|
|
|
|
return $offset;
|
2005-02-16 22:55:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-03-26 18:43:58 +00:00
|
|
|
|
// Reaching this point means we haven't calculated far enough, do it now:
|
|
|
|
|
// Calculate extra DST changes if needed and recurse. The recursion always
|
|
|
|
|
// moves toward the stopping condition, so will always end.
|
|
|
|
|
|
|
|
|
|
if($from == 0) {
|
2005-08-30 03:27:52 +00:00
|
|
|
|
// We need a year smaller than $SESSION->dst_range[0]
|
|
|
|
|
if($SESSION->dst_range[0] == 1971) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2008-03-20 03:01:58 +00:00
|
|
|
|
calculate_user_dst_table($SESSION->dst_range[0] - 5, NULL, $strtimezone);
|
|
|
|
|
return dst_offset_on($time, $strtimezone);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2005-08-30 03:27:52 +00:00
|
|
|
|
// We need a year larger than $SESSION->dst_range[1]
|
|
|
|
|
if($SESSION->dst_range[1] == 2035) {
|
2005-03-26 18:43:58 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2008-03-20 03:01:58 +00:00
|
|
|
|
calculate_user_dst_table(NULL, $SESSION->dst_range[1] + 5, $strtimezone);
|
|
|
|
|
return dst_offset_on($time, $strtimezone);
|
2005-03-26 18:43:58 +00:00
|
|
|
|
}
|
2005-02-17 21:58:45 +00:00
|
|
|
|
}
|
2005-02-16 22:55:13 +00:00
|
|
|
|
|
2005-03-18 04:38:30 +00:00
|
|
|
|
function find_day_in_month($startday, $weekday, $month, $year) {
|
2005-02-26 06:26:04 +00:00
|
|
|
|
|
|
|
|
|
$daysinmonth = days_in_month($month, $year);
|
|
|
|
|
|
2005-02-16 22:04:14 +00:00
|
|
|
|
if($weekday == -1) {
|
2005-03-18 04:38:30 +00:00
|
|
|
|
// Don't care about weekday, so return:
|
|
|
|
|
// abs($startday) if $startday != -1
|
|
|
|
|
// $daysinmonth otherwise
|
|
|
|
|
return ($startday == -1) ? $daysinmonth : abs($startday);
|
2005-02-26 06:26:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// From now on we 're looking for a specific weekday
|
|
|
|
|
|
2005-03-18 04:38:30 +00:00
|
|
|
|
// Give "end of month" its actual value, since we know it
|
|
|
|
|
if($startday == -1) {
|
|
|
|
|
$startday = -1 * $daysinmonth;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Starting from day $startday, the sign is the direction
|
2005-02-26 06:26:04 +00:00
|
|
|
|
|
2005-03-18 04:38:30 +00:00
|
|
|
|
if($startday < 1) {
|
2005-02-26 06:26:04 +00:00
|
|
|
|
|
2005-03-18 04:38:30 +00:00
|
|
|
|
$startday = abs($startday);
|
2005-02-26 06:26:04 +00:00
|
|
|
|
$lastmonthweekday = strftime('%w', mktime(12, 0, 0, $month, $daysinmonth, $year, 0));
|
|
|
|
|
|
|
|
|
|
// This is the last such weekday of the month
|
|
|
|
|
$lastinmonth = $daysinmonth + $weekday - $lastmonthweekday;
|
|
|
|
|
if($lastinmonth > $daysinmonth) {
|
|
|
|
|
$lastinmonth -= 7;
|
2005-02-16 22:04:14 +00:00
|
|
|
|
}
|
2005-02-26 06:26:04 +00:00
|
|
|
|
|
2005-03-18 04:38:30 +00:00
|
|
|
|
// Find the first such weekday <= $startday
|
|
|
|
|
while($lastinmonth > $startday) {
|
2005-02-26 06:26:04 +00:00
|
|
|
|
$lastinmonth -= 7;
|
2005-02-16 22:04:14 +00:00
|
|
|
|
}
|
2005-02-26 06:26:04 +00:00
|
|
|
|
|
|
|
|
|
return $lastinmonth;
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2005-02-16 22:04:14 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
|
2005-03-18 04:38:30 +00:00
|
|
|
|
$indexweekday = strftime('%w', mktime(12, 0, 0, $month, $startday, $year, 0));
|
2005-02-16 22:04:14 +00:00
|
|
|
|
|
2005-02-26 06:26:04 +00:00
|
|
|
|
$diff = $weekday - $indexweekday;
|
|
|
|
|
if($diff < 0) {
|
|
|
|
|
$diff += 7;
|
2005-02-16 22:04:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-03-18 04:38:30 +00:00
|
|
|
|
// This is the first such weekday of the month equal to or after $startday
|
|
|
|
|
$firstfromindex = $startday + $diff;
|
2005-02-16 22:04:14 +00:00
|
|
|
|
|
2005-02-26 06:26:04 +00:00
|
|
|
|
return $firstfromindex;
|
|
|
|
|
|
|
|
|
|
}
|
2005-02-16 22:04:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
|
|
|
|
* Calculate the number of days in a given month
|
|
|
|
|
*
|
|
|
|
|
* @param int $month The month whose day count is sought
|
|
|
|
|
* @param int $year The year of the month whose day count is sought
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
2005-02-16 22:04:14 +00:00
|
|
|
|
function days_in_month($month, $year) {
|
|
|
|
|
return intval(date('t', mktime(12, 0, 0, $month, 1, $year, 0)));
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
|
|
|
|
* Calculate the position in the week of a specific calendar day
|
|
|
|
|
*
|
|
|
|
|
* @param int $day The day of the date whose position in the week is sought
|
|
|
|
|
* @param int $month The month of the date whose position in the week is sought
|
|
|
|
|
* @param int $year The year of the date whose position in the week is sought
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
2005-02-26 06:26:04 +00:00
|
|
|
|
function dayofweek($day, $month, $year) {
|
|
|
|
|
// I wonder if this is any different from
|
|
|
|
|
// strftime('%w', mktime(12, 0, 0, $month, $daysinmonth, $year, 0));
|
|
|
|
|
return intval(date('w', mktime(12, 0, 0, $month, $day, $year, 0)));
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-20 14:44:14 +00:00
|
|
|
|
/// USER AUTHENTICATION AND LOGIN ////////////////////////////////////////
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2005-07-12 02:06:33 +00:00
|
|
|
|
/**
|
|
|
|
|
* Makes sure that $USER->sesskey exists, if $USER itself exists. It sets a new sesskey
|
|
|
|
|
* if one does not already exist, but does not overwrite existing sesskeys. Returns the
|
|
|
|
|
* sesskey string if $USER exists, or boolean false if not.
|
|
|
|
|
*
|
|
|
|
|
* @uses $USER
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2005-01-23 22:07:13 +00:00
|
|
|
|
function sesskey() {
|
2005-01-12 11:40:46 +00:00
|
|
|
|
global $USER;
|
|
|
|
|
|
|
|
|
|
if(!isset($USER)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($USER->sesskey)) {
|
|
|
|
|
$USER->sesskey = random_string(10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $USER->sesskey;
|
|
|
|
|
}
|
|
|
|
|
|
2006-01-24 06:00:32 +00:00
|
|
|
|
|
2006-09-03 08:10:10 +00:00
|
|
|
|
/**
|
|
|
|
|
* For security purposes, this function will check that the currently
|
|
|
|
|
* given sesskey (passed as a parameter to the script or this function)
|
|
|
|
|
* matches that of the current user.
|
|
|
|
|
*
|
|
|
|
|
* @param string $sesskey optionally provided sesskey
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
function confirm_sesskey($sesskey=NULL) {
|
|
|
|
|
global $USER;
|
2006-01-24 06:00:32 +00:00
|
|
|
|
|
2006-09-03 08:10:10 +00:00
|
|
|
|
if (!empty($USER->ignoresesskey) || !empty($CFG->ignoresesskey)) {
|
|
|
|
|
return true;
|
2006-01-24 06:00:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-03 08:10:10 +00:00
|
|
|
|
if (empty($sesskey)) {
|
|
|
|
|
$sesskey = required_param('sesskey', PARAM_RAW); // Check script parameters
|
2006-01-24 06:00:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-03 08:10:10 +00:00
|
|
|
|
if (!isset($USER->sesskey)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2006-01-24 06:00:32 +00:00
|
|
|
|
|
2006-09-03 08:10:10 +00:00
|
|
|
|
return ($USER->sesskey === $sesskey);
|
2006-01-24 06:00:32 +00:00
|
|
|
|
}
|
2006-09-03 08:10:10 +00:00
|
|
|
|
|
2007-01-27 19:56:08 +00:00
|
|
|
|
/**
|
2007-01-28 21:18:08 +00:00
|
|
|
|
* Setup all global $CFG course variables, set locale and also themes
|
|
|
|
|
* This function can be used on pages that do not require login instead of require_login()
|
|
|
|
|
*
|
2007-01-27 19:56:08 +00:00
|
|
|
|
* @param mixed $courseorid id of the course or course object
|
|
|
|
|
*/
|
|
|
|
|
function course_setup($courseorid=0) {
|
2007-03-16 21:00:06 +00:00
|
|
|
|
global $COURSE, $CFG, $SITE;
|
2007-01-27 19:56:08 +00:00
|
|
|
|
|
|
|
|
|
/// Redefine global $COURSE if needed
|
|
|
|
|
if (empty($courseorid)) {
|
|
|
|
|
// no change in global $COURSE - for backwards compatibiltiy
|
2007-07-18 05:17:45 +00:00
|
|
|
|
// if require_rogin() used after require_login($courseid);
|
2007-01-27 19:56:08 +00:00
|
|
|
|
} else if (is_object($courseorid)) {
|
|
|
|
|
$COURSE = clone($courseorid);
|
|
|
|
|
} else {
|
|
|
|
|
global $course; // used here only to prevent repeated fetching from DB - may be removed later
|
2008-02-23 12:13:47 +00:00
|
|
|
|
if ($courseorid == SITEID) {
|
2007-01-28 21:18:08 +00:00
|
|
|
|
$COURSE = clone($SITE);
|
|
|
|
|
} else if (!empty($course->id) and $course->id == $courseorid) {
|
2007-01-27 19:56:08 +00:00
|
|
|
|
$COURSE = clone($course);
|
|
|
|
|
} else {
|
|
|
|
|
if (!$COURSE = get_record('course', 'id', $courseorid)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Invalid course ID');
|
2007-01-27 19:56:08 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-28 21:18:08 +00:00
|
|
|
|
/// set locale and themes
|
2007-01-27 19:56:08 +00:00
|
|
|
|
moodle_setlocale();
|
|
|
|
|
theme_setup();
|
|
|
|
|
|
|
|
|
|
}
|
2006-09-03 08:10:10 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2005-02-16 10:40:48 +00:00
|
|
|
|
* This function checks that the current user is logged in and has the
|
|
|
|
|
* required privileges
|
|
|
|
|
*
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* This function checks that the current user is logged in, and optionally
|
2005-02-16 10:40:48 +00:00
|
|
|
|
* whether they are allowed to be in a particular course and view a particular
|
|
|
|
|
* course module.
|
|
|
|
|
* If they are not logged in, then it redirects them to the site login unless
|
2005-02-25 06:08:40 +00:00
|
|
|
|
* $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which
|
2005-02-16 10:40:48 +00:00
|
|
|
|
* case they are automatically logged in as guests.
|
|
|
|
|
* If $courseid is given and the user is not enrolled in that course then the
|
|
|
|
|
* user is redirected to the course enrolment page.
|
|
|
|
|
* If $cm is given and the coursemodule is hidden and the user is not a teacher
|
|
|
|
|
* in the course then the user is redirected to the course home page.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $SESSION
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @uses $USER
|
|
|
|
|
* @uses $FULLME
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses SITEID
|
2006-03-29 17:56:35 +00:00
|
|
|
|
* @uses $COURSE
|
2007-01-19 09:44:26 +00:00
|
|
|
|
* @param mixed $courseorid id of the course or course object
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @param bool $autologinguest
|
|
|
|
|
* @param object $cm course module object
|
2008-04-25 18:55:36 +00:00
|
|
|
|
* @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to
|
|
|
|
|
* true. Used to avoid (=false) some scripts (file.php...) to set that variable,
|
|
|
|
|
* in order to keep redirects working properly. MDL-14495
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2008-04-25 18:55:36 +00:00
|
|
|
|
function require_login($courseorid=0, $autologinguest=true, $cm=null, $setwantsurltome=true) {
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2007-01-27 21:28:26 +00:00
|
|
|
|
global $CFG, $SESSION, $USER, $COURSE, $FULLME;
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2007-01-27 21:28:26 +00:00
|
|
|
|
/// setup global $COURSE, themes, language and locale
|
2007-01-27 19:56:08 +00:00
|
|
|
|
course_setup($courseorid);
|
2006-07-30 10:39:21 +00:00
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
/// If the user is not even logged in yet then make sure they are
|
2007-01-27 21:28:26 +00:00
|
|
|
|
if (!isloggedin()) {
|
|
|
|
|
//NOTE: $USER->site check was obsoleted by session test cookie,
|
|
|
|
|
// $USER->confirmed test is in login/index.php
|
2008-04-25 18:55:36 +00:00
|
|
|
|
if ($setwantsurltome) {
|
|
|
|
|
$SESSION->wantsurl = $FULLME;
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (!empty($_SERVER['HTTP_REFERER'])) {
|
|
|
|
|
$SESSION->fromurl = $_SERVER['HTTP_REFERER'];
|
2003-01-22 01:55:54 +00:00
|
|
|
|
}
|
2007-04-03 14:59:56 +00:00
|
|
|
|
if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests) and ($COURSE->id == SITEID or $COURSE->guest) ) {
|
2004-07-01 22:29:04 +00:00
|
|
|
|
$loginguest = '?loginguest=true';
|
|
|
|
|
} else {
|
|
|
|
|
$loginguest = '';
|
2004-06-30 12:43:05 +00:00
|
|
|
|
}
|
2007-04-02 13:59:36 +00:00
|
|
|
|
if (empty($CFG->loginhttps) or $loginguest) { //do not require https for guest logins
|
2004-09-22 14:39:15 +00:00
|
|
|
|
redirect($CFG->wwwroot .'/login/index.php'. $loginguest);
|
2004-06-19 16:13:28 +00:00
|
|
|
|
} else {
|
2006-05-15 21:36:46 +00:00
|
|
|
|
$wwwroot = str_replace('http:','https:', $CFG->wwwroot);
|
2007-01-27 21:28:26 +00:00
|
|
|
|
redirect($wwwroot .'/login/index.php');
|
2004-06-19 16:13:28 +00:00
|
|
|
|
}
|
2005-02-17 06:15:22 +00:00
|
|
|
|
exit;
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
2002-12-30 15:30:05 +00:00
|
|
|
|
|
2007-03-19 18:54:58 +00:00
|
|
|
|
/// loginas as redirection if needed
|
|
|
|
|
if ($COURSE->id != SITEID and !empty($USER->realuser)) {
|
|
|
|
|
if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) {
|
|
|
|
|
if ($USER->loginascontext->instanceid != $COURSE->id) {
|
2007-03-20 07:42:41 +00:00
|
|
|
|
print_error('loginasonecourse', '', $CFG->wwwroot.'/course/view.php?id='.$USER->loginascontext->instanceid);
|
2007-07-18 05:17:45 +00:00
|
|
|
|
}
|
2007-03-19 18:54:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-15 02:53:00 +00:00
|
|
|
|
/// check whether the user should be changing password (but only if it is REALLY them)
|
2007-03-05 20:02:27 +00:00
|
|
|
|
if (get_user_preferences('auth_forcepasswordchange') && empty($USER->realuser)) {
|
2007-09-19 07:25:49 +00:00
|
|
|
|
$userauth = get_auth_plugin($USER->auth);
|
2007-01-04 02:52:44 +00:00
|
|
|
|
if ($userauth->can_change_password()) {
|
2005-02-17 06:15:22 +00:00
|
|
|
|
$SESSION->wantsurl = $FULLME;
|
2007-04-20 10:02:38 +00:00
|
|
|
|
if ($changeurl = $userauth->change_password_url()) {
|
2007-02-21 21:48:48 +00:00
|
|
|
|
//use plugin custom url
|
2007-04-20 10:02:38 +00:00
|
|
|
|
redirect($changeurl);
|
2006-12-02 14:38:31 +00:00
|
|
|
|
} else {
|
2007-02-21 21:48:48 +00:00
|
|
|
|
//use moodle internal method
|
|
|
|
|
if (empty($CFG->loginhttps)) {
|
|
|
|
|
redirect($CFG->wwwroot .'/login/change_password.php');
|
|
|
|
|
} else {
|
|
|
|
|
$wwwroot = str_replace('http:','https:', $CFG->wwwroot);
|
|
|
|
|
redirect($wwwroot .'/login/change_password.php');
|
|
|
|
|
}
|
2006-12-02 14:38:31 +00:00
|
|
|
|
}
|
2004-09-20 09:08:57 +00:00
|
|
|
|
} else {
|
2008-04-03 00:59:34 +00:00
|
|
|
|
print_error('nopasswordchangeforced', 'auth');
|
2004-09-20 09:08:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-01-27 21:28:26 +00:00
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
/// Check that the user account is properly set up
|
2002-12-30 15:30:05 +00:00
|
|
|
|
if (user_not_fully_set_up($USER)) {
|
2005-02-17 06:15:22 +00:00
|
|
|
|
$SESSION->wantsurl = $FULLME;
|
2004-09-22 14:39:15 +00:00
|
|
|
|
redirect($CFG->wwwroot .'/user/edit.php?id='. $USER->id .'&course='. SITEID);
|
2002-12-30 15:30:05 +00:00
|
|
|
|
}
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
/// Make sure current IP matches the one for this session (if required)
|
2004-11-22 18:38:33 +00:00
|
|
|
|
if (!empty($CFG->tracksessionip)) {
|
2004-09-27 14:35:37 +00:00
|
|
|
|
if ($USER->sessionIP != md5(getremoteaddr())) {
|
2008-04-03 00:59:34 +00:00
|
|
|
|
print_error('sessionipnomatch', 'error');
|
2004-09-27 14:35:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2004-10-08 06:06:03 +00:00
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
/// Make sure the USER has a sesskey set up. Used for checking script parameters.
|
2005-01-23 22:07:13 +00:00
|
|
|
|
sesskey();
|
2004-09-27 14:35:37 +00:00
|
|
|
|
|
2004-11-29 05:30:36 +00:00
|
|
|
|
// Check that the user has agreed to a site policy if there is one
|
|
|
|
|
if (!empty($CFG->sitepolicy)) {
|
|
|
|
|
if (!$USER->policyagreed) {
|
2004-11-29 06:22:12 +00:00
|
|
|
|
$SESSION->wantsurl = $FULLME;
|
2004-11-29 05:30:36 +00:00
|
|
|
|
redirect($CFG->wwwroot .'/user/policy.php');
|
|
|
|
|
}
|
2005-02-10 05:11:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
// Fetch the system context, we are going to use it a lot.
|
|
|
|
|
$sysctx = get_context_instance(CONTEXT_SYSTEM);
|
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
/// If the site is currently under maintenance, then print a message
|
2007-09-19 07:25:49 +00:00
|
|
|
|
if (!has_capability('moodle/site:config', $sysctx)) {
|
2005-05-11 08:57:14 +00:00
|
|
|
|
if (file_exists($CFG->dataroot.'/'.SITEID.'/maintenance.html')) {
|
2005-02-10 05:11:34 +00:00
|
|
|
|
print_maintenance_message();
|
2005-02-17 06:15:22 +00:00
|
|
|
|
exit;
|
2005-02-10 05:11:34 +00:00
|
|
|
|
}
|
2004-11-29 05:30:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-17 12:15:32 +00:00
|
|
|
|
/// groupmembersonly access control
|
|
|
|
|
if (!empty($CFG->enablegroupings) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) {
|
|
|
|
|
if (isguestuser() or !groups_has_membership($cm)) {
|
2008-04-03 00:59:34 +00:00
|
|
|
|
print_error('groupmembersonlyerror', 'group', $CFG->wwwroot.'/course/view.php?id='.$cm->course);
|
2007-08-17 12:15:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2006-09-12 09:31:23 +00:00
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
// Fetch the course context, and prefetch its child contexts
|
|
|
|
|
if (!isset($COURSE->context)) {
|
|
|
|
|
if ( ! $COURSE->context = get_context_instance(CONTEXT_COURSE, $COURSE->id) ) {
|
|
|
|
|
print_error('nocontext');
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-01-19 09:44:26 +00:00
|
|
|
|
if ($COURSE->id == SITEID) {
|
2007-09-19 07:25:49 +00:00
|
|
|
|
/// Eliminate hidden site activities straight away
|
|
|
|
|
if (!empty($cm) && !$cm->visible
|
|
|
|
|
&& !has_capability('moodle/course:viewhiddenactivities', $COURSE->context)) {
|
2007-01-19 09:44:26 +00:00
|
|
|
|
redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden'));
|
2004-09-25 15:23:10 +00:00
|
|
|
|
}
|
2008-04-15 21:46:04 +00:00
|
|
|
|
user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times
|
2007-01-19 09:44:26 +00:00
|
|
|
|
return;
|
2006-10-05 08:41:06 +00:00
|
|
|
|
|
2007-07-18 05:17:45 +00:00
|
|
|
|
} else {
|
2006-09-12 09:31:23 +00:00
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
/// Check if the user can be in a particular course
|
|
|
|
|
if (empty($USER->access['rsw'][$COURSE->context->path])) {
|
2007-09-19 07:19:20 +00:00
|
|
|
|
//
|
2008-04-03 00:59:34 +00:00
|
|
|
|
// MDL-13900 - If the course or the parent category are hidden
|
|
|
|
|
// and the user hasn't the 'course:viewhiddencourses' capability, prevent access
|
2007-09-19 07:19:20 +00:00
|
|
|
|
//
|
2008-04-03 00:59:34 +00:00
|
|
|
|
if ( !($COURSE->visible && course_parent_visible($COURSE)) &&
|
|
|
|
|
!has_capability('moodle/course:viewhiddencourses', $COURSE->context)) {
|
2007-09-19 07:19:20 +00:00
|
|
|
|
print_header_simple();
|
|
|
|
|
notice(get_string('coursehidden'), $CFG->wwwroot .'/');
|
|
|
|
|
}
|
2008-04-03 00:59:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-12-05 09:19:26 +00:00
|
|
|
|
/// Non-guests who don't currently have access, check if they can be allowed in as a guest
|
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
if ($USER->username != 'guest' and !has_capability('moodle/course:view', $COURSE->context)) {
|
2007-01-19 09:44:26 +00:00
|
|
|
|
if ($COURSE->guest == 1) {
|
2007-03-07 13:45:41 +00:00
|
|
|
|
// Temporarily assign them guest role for this context, if it fails later user is asked to enrol
|
2007-09-19 07:25:49 +00:00
|
|
|
|
$USER->access = load_temp_role($COURSE->context, $CFG->guestroleid, $USER->access);
|
2006-12-05 09:19:26 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
/// If the user is a guest then treat them according to the course policy about guests
|
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
if (has_capability('moodle/legacy:guest', $COURSE->context, NULL, false)) {
|
2008-02-18 23:34:38 +00:00
|
|
|
|
if (has_capability('moodle/site:doanything', $sysctx)) {
|
|
|
|
|
// administrators must be able to access any course - even if somebody gives them guest access
|
2008-04-15 21:46:04 +00:00
|
|
|
|
user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times
|
2008-02-18 23:40:21 +00:00
|
|
|
|
return;
|
2008-02-18 23:34:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-19 09:44:26 +00:00
|
|
|
|
switch ($COURSE->guest) { /// Check course policy about guest access
|
2006-09-12 09:31:23 +00:00
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
case 1: /// Guests always allowed
|
|
|
|
|
if (!has_capability('moodle/course:view', $COURSE->context)) { // Prohibited by capability
|
2006-09-12 09:31:23 +00:00
|
|
|
|
print_header_simple();
|
2007-02-28 06:25:22 +00:00
|
|
|
|
notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), "$CFG->wwwroot/login/index.php");
|
2006-09-12 09:31:23 +00:00
|
|
|
|
}
|
|
|
|
|
if (!empty($cm) and !$cm->visible) { // Not allowed to see module, send to course page
|
2007-07-18 05:17:45 +00:00
|
|
|
|
redirect($CFG->wwwroot.'/course/view.php?id='.$cm->course,
|
2006-09-12 09:31:23 +00:00
|
|
|
|
get_string('activityiscurrentlyhidden'));
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-15 21:46:04 +00:00
|
|
|
|
user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times
|
2006-09-12 09:31:23 +00:00
|
|
|
|
return; // User is allowed to see this course
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
2007-07-18 05:17:45 +00:00
|
|
|
|
case 2: /// Guests allowed with key
|
2007-01-19 09:44:26 +00:00
|
|
|
|
if (!empty($USER->enrolkey[$COURSE->id])) { // Set by enrol/manual/enrol.php
|
2008-04-15 21:46:04 +00:00
|
|
|
|
user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times
|
2006-10-23 06:38:15 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
// otherwise drop through to logic below (--> enrol.php)
|
2006-09-12 09:31:23 +00:00
|
|
|
|
break;
|
2006-08-08 05:13:06 +00:00
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
default: /// Guests not allowed
|
2007-08-17 19:09:11 +00:00
|
|
|
|
$strloggedinasguest = get_string('loggedinasguest');
|
|
|
|
|
print_header_simple('', '',
|
|
|
|
|
build_navigation(array(array('name' => $strloggedinasguest, 'link' => null, 'type' => 'misc'))));
|
2007-09-19 07:25:49 +00:00
|
|
|
|
if (empty($USER->access['rsw'][$COURSE->context->path])) { // Normal guest
|
2007-02-28 06:25:22 +00:00
|
|
|
|
notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), "$CFG->wwwroot/login/index.php");
|
2006-10-12 07:28:22 +00:00
|
|
|
|
} else {
|
2007-02-28 06:25:22 +00:00
|
|
|
|
notify(get_string('guestsnotallowed', '', format_string($COURSE->fullname)));
|
2007-01-19 09:44:26 +00:00
|
|
|
|
echo '<div class="notifyproblem">'.switchroles_form($COURSE->id).'</div>';
|
|
|
|
|
print_footer($COURSE);
|
2006-10-12 07:28:22 +00:00
|
|
|
|
exit;
|
|
|
|
|
}
|
2006-09-12 09:31:23 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// For non-guests, check if they have course view access
|
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
} else if (has_capability('moodle/course:view', $COURSE->context)) {
|
2006-09-12 09:31:23 +00:00
|
|
|
|
if (!empty($USER->realuser)) { // Make sure the REAL person can also access this course
|
2007-09-19 07:25:49 +00:00
|
|
|
|
if (!has_capability('moodle/course:view', $COURSE->context, $USER->realuser)) {
|
2006-09-12 09:31:23 +00:00
|
|
|
|
print_header_simple();
|
2004-09-22 14:39:15 +00:00
|
|
|
|
notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot .'/');
|
2002-11-05 16:38:02 +00:00
|
|
|
|
}
|
2002-08-11 05:07:15 +00:00
|
|
|
|
}
|
2006-09-12 09:31:23 +00:00
|
|
|
|
|
|
|
|
|
/// Make sure they can read this activity too, if specified
|
|
|
|
|
|
2007-09-19 07:25:49 +00:00
|
|
|
|
if (!empty($cm) and !$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $COURSE->context)) {
|
2005-02-16 10:40:48 +00:00
|
|
|
|
redirect($CFG->wwwroot.'/course/view.php?id='.$cm->course, get_string('activityiscurrentlyhidden'));
|
|
|
|
|
}
|
2008-04-15 21:46:04 +00:00
|
|
|
|
user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times
|
2006-09-12 09:31:23 +00:00
|
|
|
|
return; // User is allowed to see this course
|
|
|
|
|
|
2002-06-09 14:14:07 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2005-02-05 16:40:38 +00:00
|
|
|
|
|
2006-09-12 09:31:23 +00:00
|
|
|
|
/// Currently not enrolled in the course, so see if they want to enrol
|
2002-06-09 14:14:07 +00:00
|
|
|
|
$SESSION->wantsurl = $FULLME;
|
2007-01-19 09:44:26 +00:00
|
|
|
|
redirect($CFG->wwwroot .'/course/enrol.php?id='. $COURSE->id);
|
2002-06-09 14:14:07 +00:00
|
|
|
|
die;
|
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-03 08:10:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This function just makes sure a user is logged out.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $USER
|
|
|
|
|
*/
|
|
|
|
|
function require_logout() {
|
|
|
|
|
|
2007-01-20 13:39:38 +00:00
|
|
|
|
global $USER, $CFG, $SESSION;
|
2006-09-03 08:10:10 +00:00
|
|
|
|
|
2007-03-26 20:35:04 +00:00
|
|
|
|
if (isloggedin()) {
|
2006-09-03 08:10:10 +00:00
|
|
|
|
add_to_log(SITEID, "user", "logout", "view.php?id=$USER->id&course=".SITEID, $USER->id, 0, $USER->id);
|
|
|
|
|
|
2007-04-30 03:14:43 +00:00
|
|
|
|
$authsequence = get_enabled_auth_plugins(); // auths, in sequence
|
|
|
|
|
foreach($authsequence as $authname) {
|
|
|
|
|
$authplugin = get_auth_plugin($authname);
|
|
|
|
|
$authplugin->prelogout_hook();
|
2007-01-04 08:32:50 +00:00
|
|
|
|
}
|
2006-09-03 08:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-04-29 15:01:47 +00:00
|
|
|
|
// Initialize variable to pass-by-reference to headers_sent(&$file, &$line)
|
|
|
|
|
$file = $line = null;
|
|
|
|
|
if (headers_sent($file, $line)) {
|
|
|
|
|
error_log('MoodleSessionTest cookie could not be set in moodlelib.php:'.__LINE__);
|
|
|
|
|
error_log('Headers were already sent in file: '.$file.' on line '.$line);
|
|
|
|
|
} else {
|
2008-05-01 21:17:33 +00:00
|
|
|
|
setcookie('MoodleSessionTest'.$CFG->sessioncookie, '', time() - 3600, $CFG->sessioncookiepath, '', $CFG->cookiesecure, $CFG->cookiehttponly);
|
2007-04-29 15:01:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-03 08:10:10 +00:00
|
|
|
|
unset($_SESSION['USER']);
|
|
|
|
|
unset($_SESSION['SESSION']);
|
|
|
|
|
|
|
|
|
|
unset($SESSION);
|
|
|
|
|
unset($USER);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* This is a weaker version of {@link require_login()} which only requires login
|
|
|
|
|
* when called from within a course rather than the site page, unless
|
|
|
|
|
* the forcelogin option is turned on.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2007-01-19 09:44:26 +00:00
|
|
|
|
* @param mixed $courseorid The course object or id in question
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @param bool $autologinguest Allow autologin guests if that is wanted
|
2005-04-14 02:13:47 +00:00
|
|
|
|
* @param object $cm Course activity module if known
|
2008-04-25 18:55:36 +00:00
|
|
|
|
* @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to
|
|
|
|
|
* true. Used to avoid (=false) some scripts (file.php...) to set that variable,
|
|
|
|
|
* in order to keep redirects working properly. MDL-14495
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2008-04-25 18:55:36 +00:00
|
|
|
|
function require_course_login($courseorid, $autologinguest=true, $cm=null, $setwantsurltome=true) {
|
2004-08-22 14:38:47 +00:00
|
|
|
|
global $CFG;
|
2005-04-13 06:59:13 +00:00
|
|
|
|
if (!empty($CFG->forcelogin)) {
|
2007-01-19 09:44:26 +00:00
|
|
|
|
// login required for both SITE and courses
|
2008-04-25 18:55:36 +00:00
|
|
|
|
require_login($courseorid, $autologinguest, $cm, $setwantsurltome);
|
2007-05-10 09:02:41 +00:00
|
|
|
|
|
|
|
|
|
} else if (!empty($cm) and !$cm->visible) {
|
|
|
|
|
// always login for hidden activities
|
2008-04-25 18:55:36 +00:00
|
|
|
|
require_login($courseorid, $autologinguest, $cm, $setwantsurltome);
|
2007-05-10 09:02:41 +00:00
|
|
|
|
|
2007-01-30 21:23:29 +00:00
|
|
|
|
} else if ((is_object($courseorid) and $courseorid->id == SITEID)
|
|
|
|
|
or (!is_object($courseorid) and $courseorid == SITEID)) {
|
2007-01-19 09:44:26 +00:00
|
|
|
|
//login for SITE not required
|
2008-04-15 21:46:04 +00:00
|
|
|
|
user_accesstime_log(SITEID);
|
2007-05-10 09:02:41 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2007-01-19 09:44:26 +00:00
|
|
|
|
} else {
|
|
|
|
|
// course login always required
|
2008-04-25 18:55:36 +00:00
|
|
|
|
require_login($courseorid, $autologinguest, $cm, $setwantsurltome);
|
2004-08-22 14:38:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-08-28 08:29:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* Require key login. Function terminates with error if key not found or incorrect.
|
|
|
|
|
* @param string $script unique script identifier
|
|
|
|
|
* @param int $instance optional instance id
|
|
|
|
|
*/
|
|
|
|
|
function require_user_key_login($script, $instance=null) {
|
2007-09-25 12:31:39 +00:00
|
|
|
|
global $nomoodlecookie, $USER, $SESSION, $CFG;
|
2007-08-28 08:29:40 +00:00
|
|
|
|
|
|
|
|
|
if (empty($nomoodlecookie)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Incorrect use of require_key_login() - session cookies must be disabled!');
|
2007-08-28 08:29:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// extra safety
|
|
|
|
|
@session_write_close();
|
|
|
|
|
|
|
|
|
|
$keyvalue = required_param('key', PARAM_ALPHANUM);
|
|
|
|
|
|
|
|
|
|
if (!$key = get_record('user_private_key', 'script', $script, 'value', $keyvalue, 'instance', $instance)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Incorrect key');
|
2007-08-28 08:29:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!empty($key->validuntil) and $key->validuntil < time()) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Expired key');
|
2007-08-28 08:29:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-29 18:06:18 +00:00
|
|
|
|
if ($key->iprestriction) {
|
|
|
|
|
$remoteaddr = getremoteaddr();
|
|
|
|
|
if ($remoteaddr == '' or !address_in_subnet($remoteaddr, $key->iprestriction)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Client IP address mismatch');
|
2007-08-29 18:06:18 +00:00
|
|
|
|
}
|
2007-08-28 08:29:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$user = get_record('user', 'id', $key->userid)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Incorrect user record');
|
2007-08-28 08:29:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// emulate normal session
|
|
|
|
|
$SESSION = new object();
|
|
|
|
|
$USER = $user;
|
|
|
|
|
|
2007-09-25 12:31:39 +00:00
|
|
|
|
/// note we are not using normal login
|
|
|
|
|
if (!defined('USER_KEY_LOGIN')) {
|
|
|
|
|
define('USER_KEY_LOGIN', true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
load_all_capabilities();
|
|
|
|
|
|
2007-08-28 08:29:40 +00:00
|
|
|
|
/// return isntance id - it might be empty
|
|
|
|
|
return $key->instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a new private user access key.
|
|
|
|
|
* @param string $script unique target identifier
|
|
|
|
|
* @param int $userid
|
|
|
|
|
* @param instance $int optional instance id
|
|
|
|
|
* @param string $iprestriction optional ip restricted access
|
|
|
|
|
* @param timestamp $validuntil key valid only until given data
|
|
|
|
|
* @return string access key value
|
|
|
|
|
*/
|
|
|
|
|
function create_user_key($script, $userid, $instance=null, $iprestriction=null, $validuntil=null) {
|
|
|
|
|
$key = new object();
|
|
|
|
|
$key->script = $script;
|
|
|
|
|
$key->userid = $userid;
|
|
|
|
|
$key->instance = $instance;
|
|
|
|
|
$key->iprestriction = $iprestriction;
|
|
|
|
|
$key->validuntil = $validuntil;
|
|
|
|
|
$key->timecreated = time();
|
|
|
|
|
|
|
|
|
|
$key->value = md5($userid.'_'.time().random_string(40)); // something long and unique
|
|
|
|
|
while (record_exists('user_private_key', 'value', $key->value)) {
|
|
|
|
|
// must be unique
|
|
|
|
|
$key->value = md5($userid.'_'.time().random_string(40));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!insert_record('user_private_key', $key)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Can not insert new key');
|
2007-08-28 08:29:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $key->value;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Modify the user table by setting the currently logged in user's
|
|
|
|
|
* last login to now.
|
|
|
|
|
*
|
|
|
|
|
* @uses $USER
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-12-23 03:07:01 +00:00
|
|
|
|
function update_user_login_times() {
|
|
|
|
|
global $USER;
|
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$user = new object();
|
2002-12-23 03:07:01 +00:00
|
|
|
|
$USER->lastlogin = $user->lastlogin = $USER->currentlogin;
|
2004-08-29 15:00:08 +00:00
|
|
|
|
$USER->currentlogin = $user->lastaccess = $user->currentlogin = time();
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
|
|
|
|
$user->id = $USER->id;
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return update_record('user', $user);
|
2002-12-23 03:07:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Determines if a user has completed setting up their account.
|
|
|
|
|
*
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @param user $user A {@link $USER} object to test for the existance of a valid name and email
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-12-30 15:30:05 +00:00
|
|
|
|
function user_not_fully_set_up($user) {
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
return ($user->username != 'guest' and (empty($user->firstname) or empty($user->lastname) or empty($user->email) or over_bounce_threshold($user)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function over_bounce_threshold($user) {
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
global $CFG;
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
if (empty($CFG->handlebounces)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// set sensible defaults
|
|
|
|
|
if (empty($CFG->minbounces)) {
|
|
|
|
|
$CFG->minbounces = 10;
|
|
|
|
|
}
|
|
|
|
|
if (empty($CFG->bounceratio)) {
|
|
|
|
|
$CFG->bounceratio = .20;
|
|
|
|
|
}
|
|
|
|
|
$bouncecount = 0;
|
|
|
|
|
$sendcount = 0;
|
|
|
|
|
if ($bounce = get_record('user_preferences','userid',$user->id,'name','email_bounce_count')) {
|
|
|
|
|
$bouncecount = $bounce->value;
|
|
|
|
|
}
|
|
|
|
|
if ($send = get_record('user_preferences','userid',$user->id,'name','email_send_count')) {
|
|
|
|
|
$sendcount = $send->value;
|
|
|
|
|
}
|
|
|
|
|
return ($bouncecount >= $CFG->minbounces && $bouncecount/$sendcount >= $CFG->bounceratio);
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-25 06:08:40 +00:00
|
|
|
|
/**
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
* @param $user - object containing an id
|
|
|
|
|
* @param $reset - will reset the count to 0
|
|
|
|
|
*/
|
|
|
|
|
function set_send_count($user,$reset=false) {
|
2005-02-25 06:08:40 +00:00
|
|
|
|
if ($pref = get_record('user_preferences','userid',$user->id,'name','email_send_count')) {
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
$pref->value = (!empty($reset)) ? 0 : $pref->value+1;
|
|
|
|
|
update_record('user_preferences',$pref);
|
|
|
|
|
}
|
|
|
|
|
else if (!empty($reset)) { // if it's not there and we're resetting, don't bother.
|
|
|
|
|
// make a new one
|
|
|
|
|
$pref->name = 'email_send_count';
|
|
|
|
|
$pref->value = 1;
|
|
|
|
|
$pref->userid = $user->id;
|
2005-08-16 00:43:56 +00:00
|
|
|
|
insert_record('user_preferences',$pref, false);
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-25 06:08:40 +00:00
|
|
|
|
/**
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
* @param $user - object containing an id
|
|
|
|
|
* @param $reset - will reset the count to 0
|
|
|
|
|
*/
|
|
|
|
|
function set_bounce_count($user,$reset=false) {
|
2005-02-25 06:08:40 +00:00
|
|
|
|
if ($pref = get_record('user_preferences','userid',$user->id,'name','email_bounce_count')) {
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
$pref->value = (!empty($reset)) ? 0 : $pref->value+1;
|
|
|
|
|
update_record('user_preferences',$pref);
|
|
|
|
|
}
|
|
|
|
|
else if (!empty($reset)) { // if it's not there and we're resetting, don't bother.
|
|
|
|
|
// make a new one
|
|
|
|
|
$pref->name = 'email_bounce_count';
|
|
|
|
|
$pref->value = 1;
|
|
|
|
|
$pref->userid = $user->id;
|
2005-08-16 00:43:56 +00:00
|
|
|
|
insert_record('user_preferences',$pref, false);
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
}
|
2002-12-30 15:30:05 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Keeps track of login attempts
|
|
|
|
|
*
|
|
|
|
|
* @uses $SESSION
|
|
|
|
|
*/
|
2001-11-22 06:23:56 +00:00
|
|
|
|
function update_login_count() {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
|
2001-11-22 06:23:56 +00:00
|
|
|
|
global $SESSION;
|
|
|
|
|
|
|
|
|
|
$max_logins = 10;
|
|
|
|
|
|
|
|
|
|
if (empty($SESSION->logincount)) {
|
|
|
|
|
$SESSION->logincount = 1;
|
|
|
|
|
} else {
|
|
|
|
|
$SESSION->logincount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($SESSION->logincount > $max_logins) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
unset($SESSION->wantsurl);
|
2008-04-03 00:59:34 +00:00
|
|
|
|
print_error('errortoomanylogins');
|
2002-09-22 14:06:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Resets login attempts
|
|
|
|
|
*
|
|
|
|
|
* @uses $SESSION
|
|
|
|
|
*/
|
2002-12-20 14:44:14 +00:00
|
|
|
|
function reset_login_count() {
|
|
|
|
|
global $SESSION;
|
2002-09-22 14:06:38 +00:00
|
|
|
|
|
2002-12-20 14:44:14 +00:00
|
|
|
|
$SESSION->logincount = 0;
|
2002-09-22 14:06:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-24 22:21:28 +00:00
|
|
|
|
function sync_metacourses() {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2006-09-17 22:21:37 +00:00
|
|
|
|
if (!$courses = get_records('course', 'metacourse', 1)) {
|
2005-01-24 22:21:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
2005-01-24 22:21:28 +00:00
|
|
|
|
foreach ($courses as $course) {
|
2006-09-17 22:21:37 +00:00
|
|
|
|
sync_metacourse($course);
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Goes through all enrolment records for the courses inside the metacourse and sync with them.
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2006-11-20 16:45:24 +00:00
|
|
|
|
* @param mixed $course the metacourse to synch. Either the course object itself, or the courseid.
|
2005-02-25 06:08:40 +00:00
|
|
|
|
*/
|
2006-09-17 22:21:37 +00:00
|
|
|
|
function sync_metacourse($course) {
|
2005-08-23 05:43:02 +00:00
|
|
|
|
global $CFG;
|
2005-01-24 22:21:28 +00:00
|
|
|
|
|
2006-11-20 16:45:24 +00:00
|
|
|
|
// Check the course is valid.
|
2006-09-17 22:21:37 +00:00
|
|
|
|
if (!is_object($course)) {
|
|
|
|
|
if (!$course = get_record('course', 'id', $course)) {
|
|
|
|
|
return false; // invalid course id
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2006-11-20 16:45:24 +00:00
|
|
|
|
// Check that we actually have a metacourse.
|
2006-09-17 22:21:37 +00:00
|
|
|
|
if (empty($course->metacourse)) {
|
2006-11-20 16:45:24 +00:00
|
|
|
|
return false;
|
2005-08-23 05:43:02 +00:00
|
|
|
|
}
|
2005-02-18 02:42:33 +00:00
|
|
|
|
|
2007-01-12 18:03:36 +00:00
|
|
|
|
// Get a list of roles that should not be synced.
|
2007-04-05 08:43:06 +00:00
|
|
|
|
if (!empty($CFG->nonmetacoursesyncroleids)) {
|
2007-01-12 18:03:36 +00:00
|
|
|
|
$roleexclusions = 'ra.roleid NOT IN (' . $CFG->nonmetacoursesyncroleids . ') AND';
|
2007-07-18 05:17:45 +00:00
|
|
|
|
} else {
|
2007-01-12 18:03:36 +00:00
|
|
|
|
$roleexclusions = '';
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-20 16:45:24 +00:00
|
|
|
|
// Get the context of the metacourse.
|
2006-09-17 22:21:37 +00:00
|
|
|
|
$context = get_context_instance(CONTEXT_COURSE, $course->id); // SITEID can not be a metacourse
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2006-11-20 16:45:24 +00:00
|
|
|
|
// We do not ever want to unassign the list of metacourse manager, so get a list of them.
|
2006-09-19 06:35:52 +00:00
|
|
|
|
if ($users = get_users_by_capability($context, 'moodle/course:managemetacourse')) {
|
2006-09-17 22:21:37 +00:00
|
|
|
|
$managers = array_keys($users);
|
|
|
|
|
} else {
|
|
|
|
|
$managers = array();
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-11-20 16:45:24 +00:00
|
|
|
|
// Get assignments of a user to a role that exist in a child course, but
|
|
|
|
|
// not in the meta coure. That is, get a list of the assignments that need to be made.
|
|
|
|
|
if (!$assignments = get_records_sql("
|
|
|
|
|
SELECT
|
|
|
|
|
ra.id, ra.roleid, ra.userid
|
|
|
|
|
FROM
|
|
|
|
|
{$CFG->prefix}role_assignments ra,
|
|
|
|
|
{$CFG->prefix}context con,
|
|
|
|
|
{$CFG->prefix}course_meta cm
|
|
|
|
|
WHERE
|
|
|
|
|
ra.contextid = con.id AND
|
|
|
|
|
con.contextlevel = " . CONTEXT_COURSE . " AND
|
|
|
|
|
con.instanceid = cm.child_course AND
|
|
|
|
|
cm.parent_course = {$course->id} AND
|
2007-01-12 18:03:36 +00:00
|
|
|
|
$roleexclusions
|
2006-11-20 16:45:24 +00:00
|
|
|
|
NOT EXISTS (
|
|
|
|
|
SELECT 1 FROM
|
|
|
|
|
{$CFG->prefix}role_assignments ra2
|
|
|
|
|
WHERE
|
|
|
|
|
ra2.userid = ra.userid AND
|
|
|
|
|
ra2.roleid = ra.roleid AND
|
|
|
|
|
ra2.contextid = {$context->id}
|
|
|
|
|
)
|
|
|
|
|
")) {
|
|
|
|
|
$assignments = array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get assignments of a user to a role that exist in the meta course, but
|
|
|
|
|
// not in any child courses. That is, get a list of the unassignments that need to be made.
|
|
|
|
|
if (!$unassignments = get_records_sql("
|
|
|
|
|
SELECT
|
|
|
|
|
ra.id, ra.roleid, ra.userid
|
|
|
|
|
FROM
|
|
|
|
|
{$CFG->prefix}role_assignments ra
|
|
|
|
|
WHERE
|
|
|
|
|
ra.contextid = {$context->id} AND
|
2007-01-12 18:03:36 +00:00
|
|
|
|
$roleexclusions
|
2006-11-20 16:45:24 +00:00
|
|
|
|
NOT EXISTS (
|
|
|
|
|
SELECT 1 FROM
|
|
|
|
|
{$CFG->prefix}role_assignments ra2,
|
|
|
|
|
{$CFG->prefix}context con2,
|
|
|
|
|
{$CFG->prefix}course_meta cm
|
|
|
|
|
WHERE
|
|
|
|
|
ra2.userid = ra.userid AND
|
|
|
|
|
ra2.roleid = ra.roleid AND
|
|
|
|
|
ra2.contextid = con2.id AND
|
|
|
|
|
con2.contextlevel = " . CONTEXT_COURSE . " AND
|
|
|
|
|
con2.instanceid = cm.child_course AND
|
|
|
|
|
cm.parent_course = {$course->id}
|
|
|
|
|
)
|
|
|
|
|
")) {
|
|
|
|
|
$unassignments = array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$success = true;
|
|
|
|
|
|
|
|
|
|
// Make the unassignments, if they are not managers.
|
|
|
|
|
foreach ($unassignments as $unassignment) {
|
|
|
|
|
if (!in_array($unassignment->userid, $managers)) {
|
|
|
|
|
$success = role_unassign($unassignment->roleid, $unassignment->userid, 0, $context->id) && $success;
|
2006-09-17 22:21:37 +00:00
|
|
|
|
}
|
2005-08-23 05:43:02 +00:00
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2006-11-20 16:45:24 +00:00
|
|
|
|
// Make the assignments.
|
|
|
|
|
foreach ($assignments as $assignment) {
|
|
|
|
|
$success = role_assign($assignment->roleid, $assignment->userid, 0, $context->id) && $success;
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
2005-08-23 05:43:02 +00:00
|
|
|
|
|
2006-11-20 16:45:24 +00:00
|
|
|
|
return $success;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2006-09-17 22:21:37 +00:00
|
|
|
|
// TODO: finish timeend and timestart
|
|
|
|
|
// maybe we could rely on cron job to do the cleaning from time to time
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-02-25 06:08:40 +00:00
|
|
|
|
/**
|
2005-01-24 22:21:28 +00:00
|
|
|
|
* Adds a record to the metacourse table and calls sync_metacoures
|
|
|
|
|
*/
|
|
|
|
|
function add_to_metacourse ($metacourseid, $courseid) {
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
2005-01-24 22:21:28 +00:00
|
|
|
|
if (!$metacourse = get_record("course","id",$metacourseid)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
2005-01-24 22:21:28 +00:00
|
|
|
|
if (!$course = get_record("course","id",$courseid)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-25 04:33:02 +00:00
|
|
|
|
if (!$record = get_record("course_meta","parent_course",$metacourseid,"child_course",$courseid)) {
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$rec = new object();
|
2005-01-24 22:21:28 +00:00
|
|
|
|
$rec->parent_course = $metacourseid;
|
|
|
|
|
$rec->child_course = $courseid;
|
2005-01-25 04:33:02 +00:00
|
|
|
|
if (!insert_record('course_meta',$rec)) {
|
2005-01-24 22:21:28 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return sync_metacourse($metacourseid);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-02-25 06:08:40 +00:00
|
|
|
|
/**
|
2005-01-24 22:21:28 +00:00
|
|
|
|
* Removes the record from the metacourse table and calls sync_metacourse
|
|
|
|
|
*/
|
|
|
|
|
function remove_from_metacourse($metacourseid, $courseid) {
|
|
|
|
|
|
2005-01-25 04:33:02 +00:00
|
|
|
|
if (delete_records('course_meta','parent_course',$metacourseid,'child_course',$courseid)) {
|
2005-01-24 22:21:28 +00:00
|
|
|
|
return sync_metacourse($metacourseid);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-04-17 12:08:46 +00:00
|
|
|
|
/**
|
|
|
|
|
* Determines if a user is currently logged in
|
|
|
|
|
*
|
|
|
|
|
* @uses $USER
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2005-04-17 12:08:46 +00:00
|
|
|
|
*/
|
|
|
|
|
function isloggedin() {
|
|
|
|
|
global $USER;
|
|
|
|
|
|
|
|
|
|
return (!empty($USER->id));
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-01 13:36:42 +00:00
|
|
|
|
/**
|
|
|
|
|
* Determines if a user is logged in as real guest user with username 'guest'.
|
|
|
|
|
* This function is similar to original isguest() in 1.6 and earlier.
|
|
|
|
|
* Current isguest() is deprecated - do not use it anymore.
|
|
|
|
|
*
|
|
|
|
|
* @param $user mixed user object or id, $USER if not specified
|
|
|
|
|
* @return bool true if user is the real guest user, false if not logged in or other user
|
|
|
|
|
*/
|
|
|
|
|
function isguestuser($user=NULL) {
|
|
|
|
|
global $USER;
|
|
|
|
|
if ($user === NULL) {
|
|
|
|
|
$user = $USER;
|
|
|
|
|
} else if (is_numeric($user)) {
|
|
|
|
|
$user = get_record('user', 'id', $user, '', '', '', '', 'id, username');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($user->id)) {
|
|
|
|
|
return false; // not logged in, can not be guest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ($user->username == 'guest');
|
|
|
|
|
}
|
2005-04-17 12:08:46 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2007-08-25 11:28:37 +00:00
|
|
|
|
* Determines if the currently logged in user is in editing mode.
|
|
|
|
|
* Note: originally this function had $userid parameter - it was not usable anyway
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
2007-09-19 07:48:03 +00:00
|
|
|
|
* @uses $USER, $PAGE
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2007-09-19 07:48:03 +00:00
|
|
|
|
function isediting() {
|
|
|
|
|
global $USER, $PAGE;
|
2007-08-25 11:28:37 +00:00
|
|
|
|
|
|
|
|
|
if (empty($USER->editing)) {
|
2002-12-29 17:32:32 +00:00
|
|
|
|
return false;
|
2007-09-19 07:48:03 +00:00
|
|
|
|
} elseif (is_object($PAGE) && method_exists($PAGE,'user_allowed_editing')) {
|
|
|
|
|
return $PAGE->user_allowed_editing();
|
2002-12-29 17:32:32 +00:00
|
|
|
|
}
|
2007-09-19 07:48:03 +00:00
|
|
|
|
return true;//false;
|
2002-07-29 15:45:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Determines if the logged in user is currently moving an activity
|
|
|
|
|
*
|
|
|
|
|
* @uses $USER
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $courseid The id of the course being tested
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2003-07-14 13:08:38 +00:00
|
|
|
|
function ismoving($courseid) {
|
|
|
|
|
global $USER;
|
|
|
|
|
|
|
|
|
|
if (!empty($USER->activitycopy)) {
|
|
|
|
|
return ($USER->activitycopycourse == $courseid);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given an object containing firstname and lastname
|
|
|
|
|
* values, this function returns a string with the
|
|
|
|
|
* full name of the person.
|
|
|
|
|
* The result may depend on system settings
|
|
|
|
|
* or language. 'override' will force both names
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* to be used even if system settings specify one.
|
2005-07-12 03:09:25 +00:00
|
|
|
|
*
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $SESSION
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @param object $user A {@link $USER} object to get full name of
|
|
|
|
|
* @param bool $override If true then the name will be first name followed by last name rather than adhering to fullnamedisplay setting.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2003-11-19 15:59:45 +00:00
|
|
|
|
function fullname($user, $override=false) {
|
2003-11-30 14:02:01 +00:00
|
|
|
|
|
2003-12-30 17:18:06 +00:00
|
|
|
|
global $CFG, $SESSION;
|
|
|
|
|
|
2004-08-07 13:39:36 +00:00
|
|
|
|
if (!isset($user->firstname) and !isset($user->lastname)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-10 06:18:30 +00:00
|
|
|
|
if (!$override) {
|
|
|
|
|
if (!empty($CFG->forcefirstname)) {
|
|
|
|
|
$user->firstname = $CFG->forcefirstname;
|
|
|
|
|
}
|
|
|
|
|
if (!empty($CFG->forcelastname)) {
|
|
|
|
|
$user->lastname = $CFG->forcelastname;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-12-30 17:18:06 +00:00
|
|
|
|
if (!empty($SESSION->fullnamedisplay)) {
|
|
|
|
|
$CFG->fullnamedisplay = $SESSION->fullnamedisplay;
|
|
|
|
|
}
|
2003-11-19 15:59:45 +00:00
|
|
|
|
|
2003-11-30 14:02:01 +00:00
|
|
|
|
if ($CFG->fullnamedisplay == 'firstname lastname') {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return $user->firstname .' '. $user->lastname;
|
2003-11-30 14:02:01 +00:00
|
|
|
|
|
|
|
|
|
} else if ($CFG->fullnamedisplay == 'lastname firstname') {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return $user->lastname .' '. $user->firstname;
|
2003-11-19 15:59:45 +00:00
|
|
|
|
|
2003-11-30 14:02:01 +00:00
|
|
|
|
} else if ($CFG->fullnamedisplay == 'firstname') {
|
|
|
|
|
if ($override) {
|
|
|
|
|
return get_string('fullnamedisplay', '', $user);
|
|
|
|
|
} else {
|
|
|
|
|
return $user->firstname;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-11-19 15:59:45 +00:00
|
|
|
|
|
2003-11-30 14:02:01 +00:00
|
|
|
|
return get_string('fullnamedisplay', '', $user);
|
2003-11-19 15:59:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets a moodle cookie with an encrypted string
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* @uses DAYSECS
|
|
|
|
|
* @uses HOURSECS
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @param string $thing The string to encrypt and place in a cookie
|
|
|
|
|
*/
|
2001-11-22 06:23:56 +00:00
|
|
|
|
function set_moodle_cookie($thing) {
|
2002-12-24 10:07:45 +00:00
|
|
|
|
global $CFG;
|
2003-10-17 12:30:17 +00:00
|
|
|
|
|
2005-05-07 03:10:48 +00:00
|
|
|
|
if ($thing == 'guest') { // Ignore guest account
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-17 12:30:17 +00:00
|
|
|
|
$cookiename = 'MOODLEID_'.$CFG->sessioncookie;
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
|
|
|
|
$days = 60;
|
2004-09-28 05:53:08 +00:00
|
|
|
|
$seconds = DAYSECS*$days;
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2008-02-24 12:46:37 +00:00
|
|
|
|
// no need to set secure or http cookie only here - it is not secret
|
2007-10-28 14:20:20 +00:00
|
|
|
|
setCookie($cookiename, '', time() - HOURSECS, $CFG->sessioncookiepath);
|
|
|
|
|
setCookie($cookiename, rc4encrypt($thing), time()+$seconds, $CFG->sessioncookiepath);
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Gets a moodle cookie with an encrypted string
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2001-11-22 06:23:56 +00:00
|
|
|
|
function get_moodle_cookie() {
|
2002-12-24 10:07:45 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2003-10-17 12:30:17 +00:00
|
|
|
|
$cookiename = 'MOODLEID_'.$CFG->sessioncookie;
|
2002-12-24 10:07:45 +00:00
|
|
|
|
|
2003-01-08 09:07:07 +00:00
|
|
|
|
if (empty($_COOKIE[$cookiename])) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return '';
|
2003-01-08 09:07:07 +00:00
|
|
|
|
} else {
|
2005-05-07 03:10:48 +00:00
|
|
|
|
$thing = rc4decrypt($_COOKIE[$cookiename]);
|
|
|
|
|
return ($thing == 'guest') ? '': $thing; // Ignore guest account
|
2003-01-08 09:07:07 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2007-01-04 02:52:44 +00:00
|
|
|
|
* Returns whether a given authentication plugin exists.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2007-01-04 02:52:44 +00:00
|
|
|
|
* @param string $auth Form of authentication to check for. Defaults to the
|
|
|
|
|
* global setting in {@link $CFG}.
|
|
|
|
|
* @return boolean Whether the plugin is available.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2007-02-20 17:15:13 +00:00
|
|
|
|
function exists_auth_plugin($auth) {
|
2007-01-04 02:52:44 +00:00
|
|
|
|
global $CFG;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
if (file_exists("{$CFG->dirroot}/auth/$auth/auth.php")) {
|
|
|
|
|
return is_readable("{$CFG->dirroot}/auth/$auth/auth.php");
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2003-09-22 13:58:20 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Checks if a given plugin is in the list of enabled authentication plugins.
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2007-01-04 02:52:44 +00:00
|
|
|
|
* @param string $auth Authentication plugin.
|
|
|
|
|
* @return boolean Whether the plugin is enabled.
|
|
|
|
|
*/
|
2007-02-20 17:15:13 +00:00
|
|
|
|
function is_enabled_auth($auth) {
|
|
|
|
|
if (empty($auth)) {
|
|
|
|
|
return false;
|
2007-01-04 02:52:44 +00:00
|
|
|
|
}
|
2007-02-20 17:15:13 +00:00
|
|
|
|
|
2007-03-27 20:26:05 +00:00
|
|
|
|
$enabled = get_enabled_auth_plugins();
|
|
|
|
|
|
|
|
|
|
return in_array($auth, $enabled);
|
2007-01-04 02:52:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns an authentication plugin instance.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2007-02-21 21:48:48 +00:00
|
|
|
|
* @param string $auth name of authentication plugin
|
2007-01-04 02:52:44 +00:00
|
|
|
|
* @return object An instance of the required authentication plugin.
|
|
|
|
|
*/
|
2007-02-21 21:48:48 +00:00
|
|
|
|
function get_auth_plugin($auth) {
|
2007-01-04 02:52:44 +00:00
|
|
|
|
global $CFG;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
// check the plugin exists first
|
|
|
|
|
if (! exists_auth_plugin($auth)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error("Authentication plugin '$auth' not found.");
|
2007-01-04 02:52:44 +00:00
|
|
|
|
}
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
// return auth plugin instance
|
|
|
|
|
require_once "{$CFG->dirroot}/auth/$auth/auth.php";
|
|
|
|
|
$class = "auth_plugin_$auth";
|
|
|
|
|
return new $class;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-27 20:26:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns array of active auth plugins.
|
|
|
|
|
*
|
|
|
|
|
* @param bool $fix fix $CFG->auth if needed
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
function get_enabled_auth_plugins($fix=false) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$default = array('manual', 'nologin');
|
|
|
|
|
|
|
|
|
|
if (empty($CFG->auth)) {
|
|
|
|
|
$auths = array();
|
|
|
|
|
} else {
|
|
|
|
|
$auths = explode(',', $CFG->auth);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($fix) {
|
|
|
|
|
$auths = array_unique($auths);
|
|
|
|
|
foreach($auths as $k=>$authname) {
|
|
|
|
|
if (!exists_auth_plugin($authname) or in_array($authname, $default)) {
|
|
|
|
|
unset($auths[$k]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$newconfig = implode(',', $auths);
|
|
|
|
|
if (!isset($CFG->auth) or $newconfig != $CFG->auth) {
|
|
|
|
|
set_config('auth', $newconfig);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (array_merge($default, $auths));
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns true if an internal authentication method is being used.
|
|
|
|
|
* if method not specified then, global default is assumed
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param string $auth Form of authentication required
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2007-02-20 17:15:13 +00:00
|
|
|
|
function is_internal_auth($auth) {
|
2007-01-04 02:52:44 +00:00
|
|
|
|
$authplugin = get_auth_plugin($auth); // throws error if bad $auth
|
|
|
|
|
return $authplugin->is_internal();
|
2004-09-23 03:56:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an array of user fields
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $db
|
|
|
|
|
* @return array User field/column names
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-09-23 03:56:53 +00:00
|
|
|
|
function get_user_fieldnames() {
|
|
|
|
|
|
|
|
|
|
global $CFG, $db;
|
|
|
|
|
|
|
|
|
|
$fieldarray = $db->MetaColumnNames($CFG->prefix.'user');
|
|
|
|
|
unset($fieldarray['ID']);
|
|
|
|
|
|
|
|
|
|
return $fieldarray;
|
2003-09-22 13:58:20 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2007-07-07 14:18:30 +12:00
|
|
|
|
/**
|
|
|
|
|
* Creates the default "guest" user. Used both from
|
|
|
|
|
* admin/index.php and login/index.php
|
|
|
|
|
* @return mixed user object created or boolean false if the creation has failed
|
|
|
|
|
*/
|
|
|
|
|
function create_guest_record() {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-09-12 03:25:43 +00:00
|
|
|
|
$guest = new stdClass();
|
2007-07-07 14:18:30 +12:00
|
|
|
|
$guest->auth = 'manual';
|
|
|
|
|
$guest->username = 'guest';
|
|
|
|
|
$guest->password = hash_internal_user_password('guest');
|
|
|
|
|
$guest->firstname = addslashes(get_string('guestuser'));
|
|
|
|
|
$guest->lastname = ' ';
|
|
|
|
|
$guest->email = 'root@localhost';
|
|
|
|
|
$guest->description = addslashes(get_string('guestuserinfo'));
|
|
|
|
|
$guest->mnethostid = $CFG->mnet_localhost_id;
|
|
|
|
|
$guest->confirmed = 1;
|
|
|
|
|
$guest->lang = $CFG->lang;
|
|
|
|
|
$guest->timemodified= time();
|
|
|
|
|
|
|
|
|
|
if (! $guest->id = insert_record("user", $guest)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $guest;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Creates a bare-bones user record
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param string $username New user's username to add to record
|
|
|
|
|
* @param string $password New user's password to add to record
|
|
|
|
|
* @param string $auth Form of authentication required
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @return object A {@link $USER} object
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @todo Outline auth types and provide code example
|
|
|
|
|
*/
|
2007-04-04 09:19:31 +00:00
|
|
|
|
function create_user_record($username, $password, $auth='manual') {
|
2004-09-27 14:35:37 +00:00
|
|
|
|
global $CFG;
|
2004-08-31 12:33:20 +00:00
|
|
|
|
|
2003-04-24 20:06:40 +00:00
|
|
|
|
//just in case check text case
|
|
|
|
|
$username = trim(moodle_strtolower($username));
|
2004-08-31 12:33:20 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
$authplugin = get_auth_plugin($auth);
|
|
|
|
|
|
2007-03-22 12:27:52 +00:00
|
|
|
|
if ($newinfo = $authplugin->get_userinfo($username)) {
|
|
|
|
|
$newinfo = truncate_userinfo($newinfo);
|
|
|
|
|
foreach ($newinfo as $key => $value){
|
|
|
|
|
$newuser->$key = addslashes($value);
|
2002-10-05 16:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-06 15:21:22 +00:00
|
|
|
|
if (!empty($newuser->email)) {
|
|
|
|
|
if (email_is_not_allowed($newuser->email)) {
|
|
|
|
|
unset($newuser->email);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-04 09:19:31 +00:00
|
|
|
|
$newuser->auth = $auth;
|
2002-09-26 07:03:22 +00:00
|
|
|
|
$newuser->username = $username;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-02-13 03:08:27 +00:00
|
|
|
|
// fix for MDL-8480
|
|
|
|
|
// user CFG lang for user if $newuser->lang is empty
|
|
|
|
|
// or $user->lang is not an installed language
|
|
|
|
|
$sitelangs = array_keys(get_list_of_languages());
|
|
|
|
|
if (empty($newuser->lang) || !in_array($newuser->lang, $sitelangs)) {
|
|
|
|
|
$newuser -> lang = $CFG->lang;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
}
|
2002-09-26 07:03:22 +00:00
|
|
|
|
$newuser->confirmed = 1;
|
2006-06-09 10:04:43 +00:00
|
|
|
|
$newuser->lastip = getremoteaddr();
|
2002-09-26 07:03:22 +00:00
|
|
|
|
$newuser->timemodified = time();
|
2007-01-04 02:52:44 +00:00
|
|
|
|
$newuser->mnethostid = $CFG->mnet_localhost_id;
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (insert_record('user', $newuser)) {
|
2007-02-20 17:15:13 +00:00
|
|
|
|
$user = get_complete_user_data('username', $newuser->username);
|
2007-03-20 08:08:22 +00:00
|
|
|
|
if(!empty($CFG->{'auth_'.$newuser->auth.'_forcechangepassword'})){
|
2007-02-20 17:15:13 +00:00
|
|
|
|
set_user_preference('auth_forcepasswordchange', 1, $user->id);
|
|
|
|
|
}
|
|
|
|
|
update_internal_user_password($user, $password);
|
|
|
|
|
return $user;
|
2002-09-26 07:03:22 +00:00
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Will update a local user record from an external source
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param string $username New user's username to add to record
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @return user A {@link $USER} object
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2007-01-04 02:52:44 +00:00
|
|
|
|
function update_user_record($username, $authplugin) {
|
2007-03-22 12:27:52 +00:00
|
|
|
|
$username = trim(moodle_strtolower($username)); /// just in case check text case
|
|
|
|
|
|
|
|
|
|
$oldinfo = get_record('user', 'username', $username, '','','','', 'username, auth');
|
|
|
|
|
$userauth = get_auth_plugin($oldinfo->auth);
|
|
|
|
|
|
|
|
|
|
if ($newinfo = $userauth->get_userinfo($username)) {
|
|
|
|
|
$newinfo = truncate_userinfo($newinfo);
|
|
|
|
|
foreach ($newinfo as $key => $value){
|
|
|
|
|
$confkey = 'field_updatelocal_' . $key;
|
|
|
|
|
if (!empty($userauth->config->$confkey) and $userauth->config->$confkey === 'onlogin') {
|
|
|
|
|
$value = addslashes(stripslashes($value)); // Just in case
|
|
|
|
|
set_field('user', $key, $value, 'username', $username)
|
|
|
|
|
or error_log("Error updating $key for $username");
|
2004-09-20 09:08:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-03-22 12:27:52 +00:00
|
|
|
|
|
2005-04-17 12:08:46 +00:00
|
|
|
|
return get_complete_user_data('username', $username);
|
2004-09-20 09:08:57 +00:00
|
|
|
|
}
|
2004-01-25 09:35:45 +00:00
|
|
|
|
|
Auth/LDAP
Bugfix - value truncation to fit Moodle database
- Added truncate_userinfo() to cleanup data coming from external auth
- Fixed auth_user_create() to truncate user info as appropriate
Auth_ldap_user_sync
- created external script that calls the function
- much faster update strategy on postgres and mysql: auth_sync_users now to uses bulk inserts into a temp table, and then use LEFT JOINs and plain old SELECTs to determine what users it has to insert.
- we now loop over smaller sets of data -- we are still memory-bound, but (a) it'll be easy to use LIMIT to manage that and (b) memory use is much lower now in all cases.
- postgres: phased commits in auth_user_sync() for the batch user upload phase
- Several feature and performance enhancements:
- if a value is removed from ldap, it will be cleared from moodle
- no-op updates (where the data does not change) are skipped
- if a user disappears and then reappears in LDAP in two separate calls to auth_user_sync(),the account will be marked deleted and then be revived. before, the account would have been deleted and created anew.
Multi-source ldap values:
The LDAP auth module now accepts a comma separated set of LDAP field names. When creating or updating a user record, auth/ldap will retrieve all the relevant fields. The right-most values overwrites all the others.
This is particularly useful when updating the user's email address from an LDAP source, which may contain the email address in one of several fields (traditionally: mail, mailForwardingAddress, mailAlternateAddress).
If a value is updated and is set to update external auth and this field is using this multi-source ldap configuration, the auth/ldap module will retrieve the old value, find which field it was sourced from, and update that field in LDAP. If it fails to find the original source of the value, it will log it in error_log.
Log of patchsets applied:
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-131
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-137
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-139
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-172
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-173
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-189
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-190
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-208
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-212
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-216
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-279
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-282
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-287
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-294
2004-11-22 07:46:10 +00:00
|
|
|
|
function truncate_userinfo($info) {
|
|
|
|
|
/// will truncate userinfo as it comes from auth_get_userinfo (from external auth)
|
|
|
|
|
/// which may have large fields
|
|
|
|
|
|
|
|
|
|
// define the limits
|
|
|
|
|
$limit = array(
|
|
|
|
|
'username' => 100,
|
2008-05-12 14:38:45 +00:00
|
|
|
|
'idnumber' => 255,
|
2006-04-19 08:18:35 +00:00
|
|
|
|
'firstname' => 100,
|
|
|
|
|
'lastname' => 100,
|
Auth/LDAP
Bugfix - value truncation to fit Moodle database
- Added truncate_userinfo() to cleanup data coming from external auth
- Fixed auth_user_create() to truncate user info as appropriate
Auth_ldap_user_sync
- created external script that calls the function
- much faster update strategy on postgres and mysql: auth_sync_users now to uses bulk inserts into a temp table, and then use LEFT JOINs and plain old SELECTs to determine what users it has to insert.
- we now loop over smaller sets of data -- we are still memory-bound, but (a) it'll be easy to use LIMIT to manage that and (b) memory use is much lower now in all cases.
- postgres: phased commits in auth_user_sync() for the batch user upload phase
- Several feature and performance enhancements:
- if a value is removed from ldap, it will be cleared from moodle
- no-op updates (where the data does not change) are skipped
- if a user disappears and then reappears in LDAP in two separate calls to auth_user_sync(),the account will be marked deleted and then be revived. before, the account would have been deleted and created anew.
Multi-source ldap values:
The LDAP auth module now accepts a comma separated set of LDAP field names. When creating or updating a user record, auth/ldap will retrieve all the relevant fields. The right-most values overwrites all the others.
This is particularly useful when updating the user's email address from an LDAP source, which may contain the email address in one of several fields (traditionally: mail, mailForwardingAddress, mailAlternateAddress).
If a value is updated and is set to update external auth and this field is using this multi-source ldap configuration, the auth/ldap module will retrieve the old value, find which field it was sourced from, and update that field in LDAP. If it fails to find the original source of the value, it will log it in error_log.
Log of patchsets applied:
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-131
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-137
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-139
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-172
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-173
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-189
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-190
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-208
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-212
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-216
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-279
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-282
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-287
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-294
2004-11-22 07:46:10 +00:00
|
|
|
|
'email' => 100,
|
|
|
|
|
'icq' => 15,
|
|
|
|
|
'phone1' => 20,
|
|
|
|
|
'phone2' => 20,
|
|
|
|
|
'institution' => 40,
|
|
|
|
|
'department' => 30,
|
|
|
|
|
'address' => 70,
|
|
|
|
|
'city' => 20,
|
|
|
|
|
'country' => 2,
|
|
|
|
|
'url' => 255,
|
|
|
|
|
);
|
2004-11-22 18:38:33 +00:00
|
|
|
|
|
Auth/LDAP
Bugfix - value truncation to fit Moodle database
- Added truncate_userinfo() to cleanup data coming from external auth
- Fixed auth_user_create() to truncate user info as appropriate
Auth_ldap_user_sync
- created external script that calls the function
- much faster update strategy on postgres and mysql: auth_sync_users now to uses bulk inserts into a temp table, and then use LEFT JOINs and plain old SELECTs to determine what users it has to insert.
- we now loop over smaller sets of data -- we are still memory-bound, but (a) it'll be easy to use LIMIT to manage that and (b) memory use is much lower now in all cases.
- postgres: phased commits in auth_user_sync() for the batch user upload phase
- Several feature and performance enhancements:
- if a value is removed from ldap, it will be cleared from moodle
- no-op updates (where the data does not change) are skipped
- if a user disappears and then reappears in LDAP in two separate calls to auth_user_sync(),the account will be marked deleted and then be revived. before, the account would have been deleted and created anew.
Multi-source ldap values:
The LDAP auth module now accepts a comma separated set of LDAP field names. When creating or updating a user record, auth/ldap will retrieve all the relevant fields. The right-most values overwrites all the others.
This is particularly useful when updating the user's email address from an LDAP source, which may contain the email address in one of several fields (traditionally: mail, mailForwardingAddress, mailAlternateAddress).
If a value is updated and is set to update external auth and this field is using this multi-source ldap configuration, the auth/ldap module will retrieve the old value, find which field it was sourced from, and update that field in LDAP. If it fails to find the original source of the value, it will log it in error_log.
Log of patchsets applied:
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-131
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-137
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-139
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-172
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-173
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-189
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-190
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-208
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-212
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-216
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-279
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-282
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-287
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-294
2004-11-22 07:46:10 +00:00
|
|
|
|
// apply where needed
|
|
|
|
|
foreach (array_keys($info) as $key) {
|
|
|
|
|
if (!empty($limit[$key])) {
|
2005-02-14 01:30:57 +00:00
|
|
|
|
$info[$key] = trim(substr($info[$key],0, $limit[$key]));
|
2004-11-22 18:38:33 +00:00
|
|
|
|
}
|
Auth/LDAP
Bugfix - value truncation to fit Moodle database
- Added truncate_userinfo() to cleanup data coming from external auth
- Fixed auth_user_create() to truncate user info as appropriate
Auth_ldap_user_sync
- created external script that calls the function
- much faster update strategy on postgres and mysql: auth_sync_users now to uses bulk inserts into a temp table, and then use LEFT JOINs and plain old SELECTs to determine what users it has to insert.
- we now loop over smaller sets of data -- we are still memory-bound, but (a) it'll be easy to use LIMIT to manage that and (b) memory use is much lower now in all cases.
- postgres: phased commits in auth_user_sync() for the batch user upload phase
- Several feature and performance enhancements:
- if a value is removed from ldap, it will be cleared from moodle
- no-op updates (where the data does not change) are skipped
- if a user disappears and then reappears in LDAP in two separate calls to auth_user_sync(),the account will be marked deleted and then be revived. before, the account would have been deleted and created anew.
Multi-source ldap values:
The LDAP auth module now accepts a comma separated set of LDAP field names. When creating or updating a user record, auth/ldap will retrieve all the relevant fields. The right-most values overwrites all the others.
This is particularly useful when updating the user's email address from an LDAP source, which may contain the email address in one of several fields (traditionally: mail, mailForwardingAddress, mailAlternateAddress).
If a value is updated and is set to update external auth and this field is using this multi-source ldap configuration, the auth/ldap module will retrieve the old value, find which field it was sourced from, and update that field in LDAP. If it fails to find the original source of the value, it will log it in error_log.
Log of patchsets applied:
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-131
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-137
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-139
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-172
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-173
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-189
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-190
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-208
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-212
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-216
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-279
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-282
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-287
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-294
2004-11-22 07:46:10 +00:00
|
|
|
|
}
|
2004-11-22 18:38:33 +00:00
|
|
|
|
|
Auth/LDAP
Bugfix - value truncation to fit Moodle database
- Added truncate_userinfo() to cleanup data coming from external auth
- Fixed auth_user_create() to truncate user info as appropriate
Auth_ldap_user_sync
- created external script that calls the function
- much faster update strategy on postgres and mysql: auth_sync_users now to uses bulk inserts into a temp table, and then use LEFT JOINs and plain old SELECTs to determine what users it has to insert.
- we now loop over smaller sets of data -- we are still memory-bound, but (a) it'll be easy to use LIMIT to manage that and (b) memory use is much lower now in all cases.
- postgres: phased commits in auth_user_sync() for the batch user upload phase
- Several feature and performance enhancements:
- if a value is removed from ldap, it will be cleared from moodle
- no-op updates (where the data does not change) are skipped
- if a user disappears and then reappears in LDAP in two separate calls to auth_user_sync(),the account will be marked deleted and then be revived. before, the account would have been deleted and created anew.
Multi-source ldap values:
The LDAP auth module now accepts a comma separated set of LDAP field names. When creating or updating a user record, auth/ldap will retrieve all the relevant fields. The right-most values overwrites all the others.
This is particularly useful when updating the user's email address from an LDAP source, which may contain the email address in one of several fields (traditionally: mail, mailForwardingAddress, mailAlternateAddress).
If a value is updated and is set to update external auth and this field is using this multi-source ldap configuration, the auth/ldap module will retrieve the old value, find which field it was sourced from, and update that field in LDAP. If it fails to find the original source of the value, it will log it in error_log.
Log of patchsets applied:
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-131
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-137
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-139
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-172
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-173
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-189
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-190
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-208
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-212
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-216
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-279
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-282
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-287
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-294
2004-11-22 07:46:10 +00:00
|
|
|
|
return $info;
|
2007-08-21 20:52:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Marks user deleted in internal user database and notifies the auth plugin.
|
|
|
|
|
* Also unenrols user from all roles and does other cleanup.
|
|
|
|
|
* @param object $user Userobject before delete (without system magic quotes)
|
|
|
|
|
* @return boolean success
|
|
|
|
|
*/
|
|
|
|
|
function delete_user($user) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
require_once($CFG->libdir.'/grouplib.php');
|
2007-10-03 12:22:25 +00:00
|
|
|
|
require_once($CFG->libdir.'/gradelib.php');
|
2007-08-21 20:52:36 +00:00
|
|
|
|
|
|
|
|
|
begin_sql();
|
|
|
|
|
|
|
|
|
|
// delete all grades - backup is kept in grade_grades_history table
|
|
|
|
|
if ($grades = grade_grade::fetch_all(array('userid'=>$user->id))) {
|
|
|
|
|
foreach ($grades as $grade) {
|
|
|
|
|
$grade->delete('userdelete');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// remove from all groups
|
|
|
|
|
delete_records('groups_members', 'userid', $user->id);
|
|
|
|
|
|
|
|
|
|
// unenrol from all roles in all contexts
|
|
|
|
|
role_unassign(0, $user->id); // this might be slow but it is really needed - modules might do some extra cleanup!
|
|
|
|
|
|
|
|
|
|
// now do a final accesslib cleanup - removes all role assingments in user context and context itself
|
|
|
|
|
delete_context(CONTEXT_USER, $user->id);
|
|
|
|
|
|
2008-04-28 08:35:21 +00:00
|
|
|
|
require_once($CFG->dirroot.'/tag/lib.php');
|
|
|
|
|
tag_set('user', $user->id, array());
|
|
|
|
|
|
2007-11-04 13:51:26 +00:00
|
|
|
|
// workaround for bulk deletes of users with the same email address
|
|
|
|
|
$delname = addslashes("$user->email.".time());
|
|
|
|
|
while (record_exists('user', 'username', $delname)) { // no need to use mnethostid here
|
|
|
|
|
$delname++;
|
|
|
|
|
}
|
|
|
|
|
|
2007-08-21 20:52:36 +00:00
|
|
|
|
// mark internal user record as "deleted"
|
|
|
|
|
$updateuser = new object();
|
|
|
|
|
$updateuser->id = $user->id;
|
|
|
|
|
$updateuser->deleted = 1;
|
2007-11-04 13:51:26 +00:00
|
|
|
|
$updateuser->username = $delname; // Remember it just in case
|
2007-08-21 20:52:36 +00:00
|
|
|
|
$updateuser->email = ''; // Clear this field to free it up
|
|
|
|
|
$updateuser->idnumber = ''; // Clear this field to free it up
|
|
|
|
|
$updateuser->timemodified = time();
|
|
|
|
|
|
|
|
|
|
if (update_record('user', $updateuser)) {
|
|
|
|
|
commit_sql();
|
|
|
|
|
// notify auth plugin - do not block the delete even when plugin fails
|
|
|
|
|
$authplugin = get_auth_plugin($user->auth);
|
|
|
|
|
$authplugin->user_delete($user);
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
rollback_sql();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
Auth/LDAP
Bugfix - value truncation to fit Moodle database
- Added truncate_userinfo() to cleanup data coming from external auth
- Fixed auth_user_create() to truncate user info as appropriate
Auth_ldap_user_sync
- created external script that calls the function
- much faster update strategy on postgres and mysql: auth_sync_users now to uses bulk inserts into a temp table, and then use LEFT JOINs and plain old SELECTs to determine what users it has to insert.
- we now loop over smaller sets of data -- we are still memory-bound, but (a) it'll be easy to use LIMIT to manage that and (b) memory use is much lower now in all cases.
- postgres: phased commits in auth_user_sync() for the batch user upload phase
- Several feature and performance enhancements:
- if a value is removed from ldap, it will be cleared from moodle
- no-op updates (where the data does not change) are skipped
- if a user disappears and then reappears in LDAP in two separate calls to auth_user_sync(),the account will be marked deleted and then be revived. before, the account would have been deleted and created anew.
Multi-source ldap values:
The LDAP auth module now accepts a comma separated set of LDAP field names. When creating or updating a user record, auth/ldap will retrieve all the relevant fields. The right-most values overwrites all the others.
This is particularly useful when updating the user's email address from an LDAP source, which may contain the email address in one of several fields (traditionally: mail, mailForwardingAddress, mailAlternateAddress).
If a value is updated and is set to update external auth and this field is using this multi-source ldap configuration, the auth/ldap module will retrieve the old value, find which field it was sourced from, and update that field in LDAP. If it fails to find the original source of the value, it will log it in error_log.
Log of patchsets applied:
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-131
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-137
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-139
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-172
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-173
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-189
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-190
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-208
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-212
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-216
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-279
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-282
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-287
arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-294
2004-11-22 07:46:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Retrieve the guest user object
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @return user A {@link $USER} object
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2004-01-25 09:35:45 +00:00
|
|
|
|
function guest_user() {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-03-23 15:57:46 +00:00
|
|
|
|
if ($newuser = get_record('user', 'username', 'guest', 'mnethostid', $CFG->mnet_localhost_id)) {
|
2004-01-25 09:35:45 +00:00
|
|
|
|
$newuser->confirmed = 1;
|
|
|
|
|
$newuser->lang = $CFG->lang;
|
2006-06-09 10:04:43 +00:00
|
|
|
|
$newuser->lastip = getremoteaddr();
|
2004-01-25 09:35:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $newuser;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given a username and password, this function looks them
|
|
|
|
|
* up using the currently selected authentication mechanism,
|
|
|
|
|
* and if the authentication is successful, it returns a
|
|
|
|
|
* valid $user object from the 'user' table.
|
2004-11-22 18:38:33 +00:00
|
|
|
|
*
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* Uses auth_ functions from the currently active auth module
|
|
|
|
|
*
|
2007-11-14 22:03:46 +00:00
|
|
|
|
* After authenticate_user_login() returns success, you will need to
|
|
|
|
|
* log that the user has logged in, and call complete_user_login() to set
|
|
|
|
|
* the session up.
|
|
|
|
|
*
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @uses $CFG
|
2007-03-28 08:28:02 +00:00
|
|
|
|
* @param string $username User's username (with system magic quotes)
|
|
|
|
|
* @param string $password User's password (with system magic quotes)
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @return user|flase A {@link $USER} object or false if error
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-09-26 07:03:22 +00:00
|
|
|
|
function authenticate_user_login($username, $password) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-03-27 20:26:05 +00:00
|
|
|
|
$authsenabled = get_enabled_auth_plugins();
|
2004-08-16 15:41:57 +00:00
|
|
|
|
|
2007-02-20 17:15:13 +00:00
|
|
|
|
if ($user = get_complete_user_data('username', $username)) {
|
|
|
|
|
$auth = empty($user->auth) ? 'manual' : $user->auth; // use manual if auth not set
|
|
|
|
|
if ($auth=='nologin' or !is_enabled_auth($auth)) {
|
|
|
|
|
add_to_log(0, 'login', 'error', 'index.php', $username);
|
|
|
|
|
error_log('[client '.$_SERVER['REMOTE_ADDR']."] $CFG->wwwroot Disabled Login: $username ".$_SERVER['HTTP_USER_AGENT']);
|
|
|
|
|
return false;
|
2004-08-29 05:48:15 +00:00
|
|
|
|
}
|
2007-02-20 17:15:13 +00:00
|
|
|
|
if (!empty($user->deleted)) {
|
|
|
|
|
add_to_log(0, 'login', 'error', 'index.php', $username);
|
|
|
|
|
error_log('[client '.$_SERVER['REMOTE_ADDR']."] $CFG->wwwroot Deleted Login: $username ".$_SERVER['HTTP_USER_AGENT']);
|
|
|
|
|
return false;
|
2004-09-20 09:08:57 +00:00
|
|
|
|
}
|
2007-02-20 17:15:13 +00:00
|
|
|
|
$auths = array($auth);
|
|
|
|
|
|
2004-08-31 12:33:20 +00:00
|
|
|
|
} else {
|
2007-02-20 17:15:13 +00:00
|
|
|
|
$auths = $authsenabled;
|
|
|
|
|
$user = new object();
|
|
|
|
|
$user->id = 0; // User does not exist
|
2004-08-29 05:48:15 +00:00
|
|
|
|
}
|
2004-09-21 11:41:58 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
foreach ($auths as $auth) {
|
|
|
|
|
$authplugin = get_auth_plugin($auth);
|
2002-11-22 08:43:35 +00:00
|
|
|
|
|
2007-02-20 17:15:13 +00:00
|
|
|
|
// on auth fail fall through to the next plugin
|
2007-01-04 02:52:44 +00:00
|
|
|
|
if (!$authplugin->user_login($username, $password)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2002-09-26 07:03:22 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
// successful authentication
|
2005-02-17 09:28:27 +00:00
|
|
|
|
if ($user->id) { // User already exists in database
|
2004-08-31 12:33:20 +00:00
|
|
|
|
if (empty($user->auth)) { // For some reason auth isn't set yet
|
|
|
|
|
set_field('user', 'auth', $auth, 'username', $username);
|
2007-02-20 17:15:13 +00:00
|
|
|
|
$user->auth = $auth;
|
2004-08-31 12:33:20 +00:00
|
|
|
|
}
|
2007-02-20 17:15:13 +00:00
|
|
|
|
|
|
|
|
|
update_internal_user_password($user, $password); // just in case salt or encoding were changed (magic quotes too one day)
|
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
if (!$authplugin->is_internal()) { // update user record from external DB
|
|
|
|
|
$user = update_user_record($username, get_auth_plugin($user->auth));
|
2004-09-20 09:08:57 +00:00
|
|
|
|
}
|
2002-09-26 07:03:22 +00:00
|
|
|
|
} else {
|
2007-02-20 17:15:13 +00:00
|
|
|
|
// if user not found, create him
|
2004-08-31 12:33:20 +00:00
|
|
|
|
$user = create_user_record($username, $password, $auth);
|
2002-09-26 07:03:22 +00:00
|
|
|
|
}
|
2005-07-15 04:26:18 +00:00
|
|
|
|
|
2007-03-22 12:27:52 +00:00
|
|
|
|
$authplugin->sync_roles($user);
|
|
|
|
|
|
2007-03-28 08:28:02 +00:00
|
|
|
|
foreach ($authsenabled as $hau) {
|
|
|
|
|
$hauth = get_auth_plugin($hau);
|
|
|
|
|
$hauth->user_authenticated_hook($user, $username, $password);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Log in to a second system if necessary
|
|
|
|
|
/// NOTICE: /sso/ will be moved to auth and deprecated soon; use user_authenticated_hook() instead
|
|
|
|
|
if (!empty($CFG->sso)) {
|
|
|
|
|
include_once($CFG->dirroot .'/sso/'. $CFG->sso .'/lib.php');
|
|
|
|
|
if (function_exists('sso_user_login')) {
|
|
|
|
|
if (!sso_user_login($username, $password)) { // Perform the signon process
|
|
|
|
|
notify('Second sign-on failed');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-07-15 04:26:18 +00:00
|
|
|
|
|
2008-02-27 02:56:48 +00:00
|
|
|
|
if ($user->id===0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2003-03-14 21:34:39 +00:00
|
|
|
|
return $user;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
// failed if all the plugins have failed
|
|
|
|
|
add_to_log(0, 'login', 'error', 'index.php', $username);
|
2008-02-25 07:17:04 +00:00
|
|
|
|
if (debugging('', DEBUG_ALL)) {
|
|
|
|
|
error_log('[client '.$_SERVER['REMOTE_ADDR']."] $CFG->wwwroot Failed Login: $username ".$_SERVER['HTTP_USER_AGENT']);
|
|
|
|
|
}
|
2007-01-04 02:52:44 +00:00
|
|
|
|
return false;
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-11-14 22:03:46 +00:00
|
|
|
|
/**
|
|
|
|
|
* Call to complete the user login process after authenticate_user_login()
|
|
|
|
|
* has succeeded. It will setup the $USER variable and other required bits
|
|
|
|
|
* and pieces.
|
|
|
|
|
*
|
|
|
|
|
* NOTE:
|
|
|
|
|
* - It will NOT log anything -- up to the caller to decide what to log.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG, $USER
|
|
|
|
|
* @param string $user obj
|
|
|
|
|
* @return user|flase A {@link $USER} object or false if error
|
|
|
|
|
*/
|
|
|
|
|
function complete_user_login($user) {
|
|
|
|
|
global $CFG, $USER;
|
|
|
|
|
|
2008-01-19 20:05:21 +00:00
|
|
|
|
$USER = $user; // this is required because we need to access preferences here!
|
|
|
|
|
|
|
|
|
|
reload_user_preferences();
|
2007-11-14 22:03:46 +00:00
|
|
|
|
|
|
|
|
|
update_user_login_times();
|
|
|
|
|
if (empty($CFG->nolastloggedin)) {
|
|
|
|
|
set_moodle_cookie($USER->username);
|
|
|
|
|
} else {
|
|
|
|
|
// do not store last logged in user in cookie
|
|
|
|
|
// auth plugins can temporarily override this from loginpage_hook()
|
|
|
|
|
// do not save $CFG->nolastloggedin in database!
|
|
|
|
|
set_moodle_cookie('nobody');
|
|
|
|
|
}
|
|
|
|
|
set_login_session_preferences();
|
|
|
|
|
|
2007-11-14 22:04:05 +00:00
|
|
|
|
// Call enrolment plugins
|
|
|
|
|
check_enrolment_plugins($user);
|
|
|
|
|
|
2007-11-14 22:03:46 +00:00
|
|
|
|
/// This is what lets the user do anything on the site :-)
|
|
|
|
|
load_all_capabilities();
|
|
|
|
|
|
|
|
|
|
/// Select password change url
|
|
|
|
|
$userauth = get_auth_plugin($USER->auth);
|
|
|
|
|
|
|
|
|
|
/// check whether the user should be changing password
|
|
|
|
|
if (get_user_preferences('auth_forcepasswordchange', false)){
|
|
|
|
|
if ($userauth->can_change_password()) {
|
|
|
|
|
if ($changeurl = $userauth->change_password_url()) {
|
|
|
|
|
redirect($changeurl);
|
|
|
|
|
} else {
|
|
|
|
|
redirect($CFG->httpswwwroot.'/login/change_password.php');
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2008-04-03 00:59:34 +00:00
|
|
|
|
print_error('nopasswordchangeforced', 'auth');
|
2007-11-14 22:03:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $USER;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-11 11:26:36 +00:00
|
|
|
|
/**
|
2006-04-30 21:02:28 +00:00
|
|
|
|
* Compare password against hash stored in internal user table.
|
2006-03-11 11:26:36 +00:00
|
|
|
|
* If necessary it also updates the stored hash to new format.
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2006-03-11 11:26:36 +00:00
|
|
|
|
* @param object user
|
|
|
|
|
* @param string plain text password
|
|
|
|
|
* @return bool is password valid?
|
|
|
|
|
*/
|
|
|
|
|
function validate_internal_user_password(&$user, $password) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2006-04-30 21:02:28 +00:00
|
|
|
|
if (!isset($CFG->passwordsaltmain)) {
|
|
|
|
|
$CFG->passwordsaltmain = '';
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-11 11:26:36 +00:00
|
|
|
|
$validated = false;
|
|
|
|
|
|
2007-05-08 15:07:25 +00:00
|
|
|
|
// get password original encoding in case it was not updated to unicode yet
|
2006-11-11 16:07:53 +00:00
|
|
|
|
$textlib = textlib_get_instance();
|
2006-11-11 17:23:20 +00:00
|
|
|
|
$convpassword = $textlib->convert($password, 'utf-8', get_string('oldcharset'));
|
2006-03-11 11:26:36 +00:00
|
|
|
|
|
2006-04-30 21:02:28 +00:00
|
|
|
|
if ($user->password == md5($password.$CFG->passwordsaltmain) or $user->password == md5($password)
|
|
|
|
|
or $user->password == md5($convpassword.$CFG->passwordsaltmain) or $user->password == md5($convpassword)) {
|
2006-03-11 11:26:36 +00:00
|
|
|
|
$validated = true;
|
2006-04-30 21:02:28 +00:00
|
|
|
|
} else {
|
2006-05-01 21:32:49 +00:00
|
|
|
|
for ($i=1; $i<=20; $i++) { //20 alternative salts should be enough, right?
|
2006-04-30 21:02:28 +00:00
|
|
|
|
$alt = 'passwordsaltalt'.$i;
|
|
|
|
|
if (!empty($CFG->$alt)) {
|
|
|
|
|
if ($user->password == md5($password.$CFG->$alt) or $user->password == md5($convpassword.$CFG->$alt)) {
|
|
|
|
|
$validated = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-03-11 11:26:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($validated) {
|
2006-04-30 21:02:28 +00:00
|
|
|
|
// force update of password hash using latest main password salt and encoding if needed
|
2006-03-11 11:26:36 +00:00
|
|
|
|
update_internal_user_password($user, $password);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $validated;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calculate hashed value from password using current hash mechanism.
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2006-03-11 11:26:36 +00:00
|
|
|
|
* @param string password
|
|
|
|
|
* @return string password hash
|
|
|
|
|
*/
|
|
|
|
|
function hash_internal_user_password($password) {
|
2006-04-30 21:02:28 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (isset($CFG->passwordsaltmain)) {
|
|
|
|
|
return md5($password.$CFG->passwordsaltmain);
|
|
|
|
|
} else {
|
|
|
|
|
return md5($password);
|
|
|
|
|
}
|
2006-03-11 11:26:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Update pssword hash in user object.
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2006-03-11 11:26:36 +00:00
|
|
|
|
* @param object user
|
|
|
|
|
* @param string plain text password
|
|
|
|
|
* @param bool store changes also in db, default true
|
|
|
|
|
* @return true if hash changed
|
|
|
|
|
*/
|
2007-02-20 17:15:13 +00:00
|
|
|
|
function update_internal_user_password(&$user, $password) {
|
2006-03-11 11:26:36 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
$authplugin = get_auth_plugin($user->auth);
|
2007-02-20 17:15:13 +00:00
|
|
|
|
if (!empty($authplugin->config->preventpassindb)) {
|
2006-03-11 11:26:36 +00:00
|
|
|
|
$hashedpassword = 'not cached';
|
|
|
|
|
} else {
|
|
|
|
|
$hashedpassword = hash_internal_user_password($password);
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-10 00:50:59 +00:00
|
|
|
|
return set_field('user', 'password', $hashedpassword, 'id', $user->id);
|
2006-03-11 11:26:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-04-17 12:08:46 +00:00
|
|
|
|
/**
|
|
|
|
|
* Get a complete user record, which includes all the info
|
2006-09-16 13:59:38 +00:00
|
|
|
|
* in the user record
|
2005-04-17 12:08:46 +00:00
|
|
|
|
* Intended for setting as $USER session variable
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses SITEID
|
2006-03-04 16:53:02 +00:00
|
|
|
|
* @param string $field The user field to be checked for a given value.
|
2005-04-17 12:08:46 +00:00
|
|
|
|
* @param string $value The value to match for $field.
|
|
|
|
|
* @return user A {@link $USER} object.
|
|
|
|
|
*/
|
2007-01-10 00:50:59 +00:00
|
|
|
|
function get_complete_user_data($field, $value, $mnethostid=null) {
|
2005-04-17 12:08:46 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (!$field || !$value) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-10 00:50:59 +00:00
|
|
|
|
/// Build the WHERE clause for an SQL query
|
|
|
|
|
|
|
|
|
|
$constraints = $field .' = \''. $value .'\' AND deleted <> \'1\'';
|
|
|
|
|
|
2007-03-16 03:37:52 +00:00
|
|
|
|
if (is_null($mnethostid)) {
|
|
|
|
|
// if null, we restrict to local users
|
|
|
|
|
// ** testing for local user can be done with
|
2007-07-18 05:17:45 +00:00
|
|
|
|
// mnethostid = $CFG->mnet_localhost_id
|
2007-03-16 03:37:52 +00:00
|
|
|
|
// or with
|
2007-07-18 05:17:45 +00:00
|
|
|
|
// auth != 'mnet'
|
2007-03-16 03:37:52 +00:00
|
|
|
|
// but the first one is FAST with our indexes
|
|
|
|
|
$mnethostid = $CFG->mnet_localhost_id;
|
|
|
|
|
}
|
|
|
|
|
$mnethostid = (int)$mnethostid;
|
|
|
|
|
$constraints .= ' AND mnethostid = \''.$mnethostid.'\'';
|
2007-01-10 00:50:59 +00:00
|
|
|
|
|
2005-04-17 12:08:46 +00:00
|
|
|
|
/// Get all the basic user data
|
|
|
|
|
|
2007-01-10 00:50:59 +00:00
|
|
|
|
if (! $user = get_record_select('user', $constraints)) {
|
2005-04-17 12:08:46 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Get various settings and preferences
|
|
|
|
|
|
|
|
|
|
if ($displays = get_records('course_display', 'userid', $user->id)) {
|
|
|
|
|
foreach ($displays as $display) {
|
|
|
|
|
$user->display[$display->course] = $display->display;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-05 20:02:27 +00:00
|
|
|
|
$user->preference = get_user_preferences(null, null, $user->id);
|
2005-04-17 12:08:46 +00:00
|
|
|
|
|
2008-04-15 21:46:04 +00:00
|
|
|
|
$user->lastcourseaccess = array(); // during last session
|
|
|
|
|
$user->currentcourseaccess = array(); // during current session
|
2006-10-22 07:42:04 +00:00
|
|
|
|
if ($lastaccesses = get_records('user_lastaccess', 'userid', $user->id)) {
|
|
|
|
|
foreach ($lastaccesses as $lastaccess) {
|
|
|
|
|
$user->lastcourseaccess[$lastaccess->courseid] = $lastaccess->timeaccess;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-08-16 11:06:48 +00:00
|
|
|
|
$sql = "SELECT g.id, g.courseid
|
|
|
|
|
FROM {$CFG->prefix}groups g, {$CFG->prefix}groups_members gm
|
|
|
|
|
WHERE gm.groupid=g.id AND gm.userid={$user->id}";
|
|
|
|
|
|
|
|
|
|
// this is a special hack to speedup calendar display
|
|
|
|
|
$user->groupmember = array();
|
|
|
|
|
if ($groups = get_records_sql($sql)) {
|
|
|
|
|
foreach ($groups as $group) {
|
|
|
|
|
if (!array_key_exists($group->courseid, $user->groupmember)) {
|
|
|
|
|
$user->groupmember[$group->courseid] = array();
|
|
|
|
|
}
|
|
|
|
|
$user->groupmember[$group->courseid][$group->id] = $group->id;
|
2005-04-17 12:08:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-08 07:23:18 +00:00
|
|
|
|
/// Add the custom profile fields to the user record
|
|
|
|
|
include_once($CFG->dirroot.'/user/profile/lib.php');
|
|
|
|
|
$customfields = (array)profile_user_record($user->id);
|
|
|
|
|
foreach ($customfields as $cname=>$cvalue) {
|
|
|
|
|
if (!isset($user->$cname)) { // Don't overwrite any standard fields
|
|
|
|
|
$user->$cname = $cvalue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-17 12:08:46 +00:00
|
|
|
|
/// Rewrite some variables if necessary
|
|
|
|
|
if (!empty($user->description)) {
|
|
|
|
|
$user->description = true; // No need to cart all of it around
|
|
|
|
|
}
|
|
|
|
|
if ($user->username == 'guest') {
|
|
|
|
|
$user->lang = $CFG->lang; // Guest language always same as site
|
|
|
|
|
$user->firstname = get_string('guestuser'); // Name always in current language
|
|
|
|
|
$user->lastname = ' ';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$user->sesskey = random_string(10);
|
|
|
|
|
$user->sessionIP = md5(getremoteaddr()); // Store the current IP in the session
|
|
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-25 19:36:47 +00:00
|
|
|
|
/**
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param string $password the password to be checked agains the password policy
|
|
|
|
|
* @param string $errmsg the error message to display when the password doesn't comply with the policy.
|
|
|
|
|
* @return bool true if the password is valid according to the policy. false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
function check_password_policy($password, &$errmsg) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (empty($CFG->passwordpolicy)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-16 18:49:41 +00:00
|
|
|
|
$textlib = textlib_get_instance();
|
2007-04-25 19:36:47 +00:00
|
|
|
|
$errmsg = '';
|
|
|
|
|
if ($textlib->strlen($password) < $CFG->minpasswordlength) {
|
|
|
|
|
$errmsg = get_string('errorminpasswordlength', 'auth', $CFG->minpasswordlength);
|
|
|
|
|
|
|
|
|
|
} else if (preg_match_all('/[[:digit:]]/u', $password, $matches) < $CFG->minpassworddigits) {
|
|
|
|
|
$errmsg = get_string('errorminpassworddigits', 'auth', $CFG->minpassworddigits);
|
|
|
|
|
|
|
|
|
|
} else if (preg_match_all('/[[:lower:]]/u', $password, $matches) < $CFG->minpasswordlower) {
|
|
|
|
|
$errmsg = get_string('errorminpasswordlower', 'auth', $CFG->minpasswordlower);
|
|
|
|
|
|
|
|
|
|
} else if (preg_match_all('/[[:upper:]]/u', $password, $matches) < $CFG->minpasswordupper) {
|
|
|
|
|
$errmsg = get_string('errorminpasswordupper', 'auth', $CFG->minpasswordupper);
|
2005-04-17 12:08:46 +00:00
|
|
|
|
|
2007-04-25 19:36:47 +00:00
|
|
|
|
} else if (preg_match_all('/[^[:upper:][:lower:][:digit:]]/u', $password, $matches) < $CFG->minpasswordnonalphanum) {
|
|
|
|
|
$errmsg = get_string('errorminpasswordnonalphanum', 'auth', $CFG->minpasswordnonalphanum);
|
2006-09-16 13:59:38 +00:00
|
|
|
|
|
2007-04-25 19:36:47 +00:00
|
|
|
|
} else if ($password == 'admin' or $password == 'password') {
|
|
|
|
|
$errmsg = get_string('unsafepassword');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($errmsg == '') {
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2005-04-17 12:08:46 +00:00
|
|
|
|
* When logging in, this function is run to set certain preferences
|
|
|
|
|
* for the current SESSION
|
|
|
|
|
*/
|
|
|
|
|
function set_login_session_preferences() {
|
2005-05-28 06:39:38 +00:00
|
|
|
|
global $SESSION, $CFG;
|
2005-04-17 12:08:46 +00:00
|
|
|
|
|
|
|
|
|
$SESSION->justloggedin = true;
|
|
|
|
|
|
|
|
|
|
unset($SESSION->lang);
|
|
|
|
|
|
|
|
|
|
// Restore the calendar filters, if saved
|
|
|
|
|
if (intval(get_user_preferences('calendar_persistflt', 0))) {
|
|
|
|
|
include_once($CFG->dirroot.'/calendar/lib.php');
|
2005-12-02 02:26:39 +00:00
|
|
|
|
calendar_set_filters_status(get_user_preferences('calendav_savedflt', 0xff));
|
2005-04-17 12:08:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-03-02 11:58:43 +00:00
|
|
|
|
/**
|
|
|
|
|
* Delete a course, including all related data from the database,
|
|
|
|
|
* and any associated files from the moodledata folder.
|
2006-03-04 16:53:02 +00:00
|
|
|
|
*
|
2006-03-02 11:58:43 +00:00
|
|
|
|
* @param int $courseid The id of the course to delete.
|
|
|
|
|
* @param bool $showfeedback Whether to display notifications of each action the function performs.
|
|
|
|
|
* @return bool true if all the removals succeeded. false if there were any failures. If this
|
|
|
|
|
* method returns false, some of the removals will probably have succeeded, and others
|
|
|
|
|
* failed, but you have no way of knowing which.
|
|
|
|
|
*/
|
|
|
|
|
function delete_course($courseid, $showfeedback = true) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
$result = true;
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2007-10-09 16:07:15 +00:00
|
|
|
|
// frontpage course can not be deleted!!
|
|
|
|
|
if ($courseid == SITEID) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-02 11:58:43 +00:00
|
|
|
|
if (!remove_course_contents($courseid, $showfeedback)) {
|
|
|
|
|
if ($showfeedback) {
|
|
|
|
|
notify("An error occurred while deleting some of the course contents.");
|
|
|
|
|
}
|
|
|
|
|
$result = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!delete_records("course", "id", $courseid)) {
|
|
|
|
|
if ($showfeedback) {
|
|
|
|
|
notify("An error occurred while deleting the main course record.");
|
|
|
|
|
}
|
|
|
|
|
$result = false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-09 16:07:15 +00:00
|
|
|
|
/// Delete all roles and overiddes in the course context
|
|
|
|
|
if (!delete_context(CONTEXT_COURSE, $courseid)) {
|
2006-09-22 17:49:45 +00:00
|
|
|
|
if ($showfeedback) {
|
2007-10-09 16:07:15 +00:00
|
|
|
|
notify("An error occurred while deleting the main course context.");
|
2006-09-22 17:49:45 +00:00
|
|
|
|
}
|
|
|
|
|
$result = false;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-02 11:58:43 +00:00
|
|
|
|
if (!fulldelete($CFG->dataroot.'/'.$courseid)) {
|
|
|
|
|
if ($showfeedback) {
|
|
|
|
|
notify("An error occurred while deleting the course files.");
|
|
|
|
|
}
|
|
|
|
|
$result = false;
|
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2006-03-02 11:58:43 +00:00
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Clear a course out completely, deleting all content
|
|
|
|
|
* but don't delete the course itself
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2006-03-01 12:15:57 +00:00
|
|
|
|
* @param int $courseid The id of the course that is being deleted
|
|
|
|
|
* @param bool $showfeedback Whether to display notifications of each action the function performs.
|
2006-03-02 11:58:43 +00:00
|
|
|
|
* @return bool true if all the removals succeeded. false if there were any failures. If this
|
|
|
|
|
* method returns false, some of the removals will probably have succeeded, and others
|
|
|
|
|
* failed, but you have no way of knowing which.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2003-08-02 11:32:59 +00:00
|
|
|
|
function remove_course_contents($courseid, $showfeedback=true) {
|
|
|
|
|
|
2006-03-01 12:15:57 +00:00
|
|
|
|
global $CFG;
|
2008-02-18 23:10:52 +00:00
|
|
|
|
require_once($CFG->libdir.'/questionlib.php');
|
|
|
|
|
require_once($CFG->libdir.'/gradelib.php');
|
2003-08-02 11:32:59 +00:00
|
|
|
|
|
|
|
|
|
$result = true;
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (! $course = get_record('course', 'id', $courseid)) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('Course ID was incorrect (can\'t find it)');
|
2003-08-02 11:32:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$strdeleted = get_string('deleted');
|
2003-08-02 11:32:59 +00:00
|
|
|
|
|
2006-09-23 06:10:48 +00:00
|
|
|
|
/// First delete every instance of every module
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($allmods = get_records('modules') ) {
|
2003-08-02 11:32:59 +00:00
|
|
|
|
foreach ($allmods as $mod) {
|
|
|
|
|
$modname = $mod->name;
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$modfile = $CFG->dirroot .'/mod/'. $modname .'/lib.php';
|
|
|
|
|
$moddelete = $modname .'_delete_instance'; // Delete everything connected to an instance
|
|
|
|
|
$moddeletecourse = $modname .'_delete_course'; // Delete other stray stuff (uncommon)
|
2003-08-02 11:32:59 +00:00
|
|
|
|
$count=0;
|
|
|
|
|
if (file_exists($modfile)) {
|
|
|
|
|
include_once($modfile);
|
|
|
|
|
if (function_exists($moddelete)) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($instances = get_records($modname, 'course', $course->id)) {
|
2003-08-02 11:32:59 +00:00
|
|
|
|
foreach ($instances as $instance) {
|
2006-09-22 17:49:45 +00:00
|
|
|
|
if ($cm = get_coursemodule_from_instance($modname, $instance->id, $course->id)) {
|
2007-08-09 21:50:59 +00:00
|
|
|
|
/// Delete activity context questions and question categories
|
|
|
|
|
question_delete_activity($cm, $showfeedback);
|
2006-09-22 17:49:45 +00:00
|
|
|
|
}
|
2003-08-02 11:32:59 +00:00
|
|
|
|
if ($moddelete($instance->id)) {
|
|
|
|
|
$count++;
|
2006-09-22 17:49:45 +00:00
|
|
|
|
|
2003-08-02 11:32:59 +00:00
|
|
|
|
} else {
|
2005-05-29 17:27:00 +00:00
|
|
|
|
notify('Could not delete '. $modname .' instance '. $instance->id .' ('. format_string($instance->name) .')');
|
2003-08-02 11:32:59 +00:00
|
|
|
|
$result = false;
|
|
|
|
|
}
|
2007-10-09 16:07:15 +00:00
|
|
|
|
if ($cm) {
|
|
|
|
|
// delete cm and its context in correct order
|
|
|
|
|
delete_records('course_modules', 'id', $cm->id);
|
|
|
|
|
delete_context(CONTEXT_MODULE, $cm->id);
|
|
|
|
|
}
|
2003-08-02 11:32:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2008-01-25 21:09:36 +00:00
|
|
|
|
notify('Function '.$moddelete.'() doesn\'t exist!');
|
2003-08-02 11:32:59 +00:00
|
|
|
|
$result = false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-01-21 16:15:03 +00:00
|
|
|
|
if (function_exists($moddeletecourse)) {
|
2006-03-21 09:06:34 +00:00
|
|
|
|
$moddeletecourse($course, $showfeedback);
|
2004-01-21 16:15:03 +00:00
|
|
|
|
}
|
2003-08-02 11:32:59 +00:00
|
|
|
|
}
|
|
|
|
|
if ($showfeedback) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
notify($strdeleted .' '. $count .' x '. $modname);
|
2003-08-02 11:32:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error('No modules are installed!');
|
2003-08-02 11:32:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-23 06:10:48 +00:00
|
|
|
|
/// Give local code a chance to delete its references to this course.
|
2006-03-06 12:19:58 +00:00
|
|
|
|
require_once('locallib.php');
|
|
|
|
|
notify_local_delete_course($courseid, $showfeedback);
|
|
|
|
|
|
2006-09-23 06:10:48 +00:00
|
|
|
|
/// Delete course blocks
|
2006-10-04 02:43:11 +00:00
|
|
|
|
|
2007-07-18 05:17:45 +00:00
|
|
|
|
if ($blocks = get_records_sql("SELECT *
|
2006-10-04 02:43:11 +00:00
|
|
|
|
FROM {$CFG->prefix}block_instance
|
|
|
|
|
WHERE pagetype = '".PAGE_COURSE_VIEW."'
|
|
|
|
|
AND pageid = $course->id")) {
|
2006-09-22 17:49:45 +00:00
|
|
|
|
if (delete_records('block_instance', 'pagetype', PAGE_COURSE_VIEW, 'pageid', $course->id)) {
|
|
|
|
|
if ($showfeedback) {
|
|
|
|
|
notify($strdeleted .' block_instance');
|
|
|
|
|
}
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-03-22 02:11:51 +00:00
|
|
|
|
require_once($CFG->libdir.'/blocklib.php');
|
2006-09-23 06:10:48 +00:00
|
|
|
|
foreach ($blocks as $block) { /// Delete any associated contexts for this block
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-10-09 16:07:15 +00:00
|
|
|
|
delete_context(CONTEXT_BLOCK, $block->id);
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
|
|
|
|
// fix for MDL-7164
|
2007-03-22 02:11:51 +00:00
|
|
|
|
// Get the block object and call instance_delete()
|
|
|
|
|
if (!$record = blocks_get_record($block->blockid)) {
|
|
|
|
|
$result = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!$obj = block_instance($record->name, $block)) {
|
|
|
|
|
$result = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// Return value ignored, in core mods this does not do anything, but just in case
|
|
|
|
|
// third party blocks might have stuff to clean up
|
|
|
|
|
// we execute this anyway
|
|
|
|
|
$obj->instance_delete();
|
2007-10-09 16:07:15 +00:00
|
|
|
|
|
2006-09-23 06:10:48 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$result = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-20 10:57:47 +00:00
|
|
|
|
/// Delete any groups, removing members and grouping/course links first.
|
2007-08-16 11:06:48 +00:00
|
|
|
|
require_once($CFG->dirroot.'/group/lib.php');
|
2008-02-02 20:43:18 +00:00
|
|
|
|
groups_delete_groupings($courseid, $showfeedback);
|
|
|
|
|
groups_delete_groups($courseid, $showfeedback);
|
2005-02-28 04:35:32 +00:00
|
|
|
|
|
2006-09-23 06:10:48 +00:00
|
|
|
|
/// Delete all related records in other tables that may have a courseid
|
|
|
|
|
/// This array stores the tables that need to be cleared, as
|
|
|
|
|
/// table_name => column_name that contains the course id.
|
|
|
|
|
|
2006-03-08 16:10:24 +00:00
|
|
|
|
$tablestoclear = array(
|
|
|
|
|
'event' => 'courseid', // Delete events
|
|
|
|
|
'log' => 'course', // Delete logs
|
|
|
|
|
'course_sections' => 'course', // Delete any course stuff
|
|
|
|
|
'course_modules' => 'course',
|
2007-02-09 00:13:18 +00:00
|
|
|
|
'backup_courses' => 'courseid', // Delete scheduled backup stuff
|
2007-10-09 16:07:15 +00:00
|
|
|
|
'user_lastaccess' => 'courseid',
|
2007-02-09 00:13:18 +00:00
|
|
|
|
'backup_log' => 'courseid'
|
2006-03-08 16:10:24 +00:00
|
|
|
|
);
|
|
|
|
|
foreach ($tablestoclear as $table => $col) {
|
|
|
|
|
if (delete_records($table, $col, $course->id)) {
|
|
|
|
|
if ($showfeedback) {
|
|
|
|
|
notify($strdeleted . ' ' . $table);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$result = false;
|
2003-08-02 11:32:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-23 06:10:48 +00:00
|
|
|
|
|
|
|
|
|
/// Clean up metacourse stuff
|
2004-02-15 05:08:00 +00:00
|
|
|
|
|
2005-01-25 04:33:02 +00:00
|
|
|
|
if ($course->metacourse) {
|
|
|
|
|
delete_records("course_meta","parent_course",$course->id);
|
2005-01-24 22:21:28 +00:00
|
|
|
|
sync_metacourse($course->id); // have to do it here so the enrolments get nuked. sync_metacourses won't find it without the id.
|
|
|
|
|
if ($showfeedback) {
|
2005-01-25 04:33:02 +00:00
|
|
|
|
notify("$strdeleted course_meta");
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
2005-03-13 13:50:23 +00:00
|
|
|
|
} else {
|
2005-01-25 04:33:02 +00:00
|
|
|
|
if ($parents = get_records("course_meta","child_course",$course->id)) {
|
2005-01-24 22:21:28 +00:00
|
|
|
|
foreach ($parents as $parent) {
|
|
|
|
|
remove_from_metacourse($parent->parent_course,$parent->child_course); // this will do the unenrolments as well.
|
|
|
|
|
}
|
|
|
|
|
if ($showfeedback) {
|
2005-01-25 04:33:02 +00:00
|
|
|
|
notify("$strdeleted course_meta");
|
2005-01-24 22:21:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-23 06:10:48 +00:00
|
|
|
|
/// Delete questions and question categories
|
2006-03-21 09:06:34 +00:00
|
|
|
|
question_delete_course($course, $showfeedback);
|
|
|
|
|
|
2008-02-18 23:10:52 +00:00
|
|
|
|
/// Remove all data from gradebook
|
|
|
|
|
$context = get_context_instance(CONTEXT_COURSE, $courseid);
|
|
|
|
|
remove_course_grades($courseid, $showfeedback);
|
|
|
|
|
remove_grade_letters($context, $showfeedback);
|
|
|
|
|
|
2003-08-02 11:32:59 +00:00
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2007-11-29 14:43:04 +00:00
|
|
|
|
* Change dates in module - used from course reset.
|
|
|
|
|
* @param strin $modname forum, assignent, etc
|
|
|
|
|
* @param array $fields array of date fields from mod table
|
|
|
|
|
* @param int $timeshift time difference
|
|
|
|
|
* @return success
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2007-11-29 14:43:04 +00:00
|
|
|
|
function shift_course_mod_dates($modname, $fields, $timeshift, $courseid) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
include_once($CFG->dirroot.'/mod/'.$modname.'/lib.php');
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
$return = true;
|
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
|
$updatesql = "UPDATE {$CFG->prefix}$modname
|
|
|
|
|
SET $field = $field + ($timeshift)
|
|
|
|
|
WHERE course=$courseid AND $field<>0 AND $field<>0";
|
|
|
|
|
$return = execute_sql($updatesql, false) && $return;
|
|
|
|
|
}
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
$refreshfunction = $modname.'_refresh_events';
|
|
|
|
|
if (function_exists($refreshfunction)) {
|
|
|
|
|
$refreshfunction($courseid);
|
|
|
|
|
}
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
return $return;
|
|
|
|
|
}
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function will empty a course of user data.
|
|
|
|
|
* It will retain the activities and the structure of the course.
|
|
|
|
|
* @param object $data an object containing all the settings including courseid (without magic quotes)
|
|
|
|
|
* @return array status array of array component, item, error
|
|
|
|
|
*/
|
|
|
|
|
function reset_course_userdata($data) {
|
|
|
|
|
global $CFG, $USER;
|
|
|
|
|
require_once($CFG->libdir.'/gradelib.php');
|
|
|
|
|
require_once($CFG->dirroot.'/group/lib.php');
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
$data->courseid = $data->id;
|
|
|
|
|
$context = get_context_instance(CONTEXT_COURSE, $data->courseid);
|
|
|
|
|
|
|
|
|
|
// calculate the time shift of dates
|
|
|
|
|
if (!empty($data->reset_start_date)) {
|
|
|
|
|
// time part of course startdate should be zero
|
|
|
|
|
$data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old);
|
2004-08-01 07:34:39 +00:00
|
|
|
|
} else {
|
2007-11-29 14:43:04 +00:00
|
|
|
|
$data->timeshift = 0;
|
2004-08-01 07:34:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
// result array: component, item, error
|
|
|
|
|
$status = array();
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
// start the resetting
|
|
|
|
|
$componentstr = get_string('general');
|
2006-10-18 09:20:16 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
// move the course start time
|
|
|
|
|
if (!empty($data->reset_start_date) and $data->timeshift) {
|
|
|
|
|
// change course start data
|
|
|
|
|
set_field('course', 'startdate', $data->reset_start_date, 'id', $data->courseid);
|
|
|
|
|
// update all course and group events - do not move activity events
|
|
|
|
|
$updatesql = "UPDATE {$CFG->prefix}event
|
|
|
|
|
SET timestart = timestart + ({$data->timeshift})
|
|
|
|
|
WHERE courseid={$data->courseid} AND instance=0";
|
|
|
|
|
execute_sql($updatesql, false);
|
|
|
|
|
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!empty($data->reset_logs)) {
|
|
|
|
|
delete_records('log', 'course', $data->courseid);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletelogs'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!empty($data->reset_events)) {
|
|
|
|
|
delete_records('event', 'courseid', $data->courseid);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteevents', 'calendar'), 'error'=>false);
|
|
|
|
|
}
|
2006-09-19 01:44:33 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
if (!empty($data->reset_notes)) {
|
|
|
|
|
require_once($CFG->dirroot.'/notes/lib.php');
|
|
|
|
|
note_delete_all($data->courseid);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotes', 'notes'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$componentstr = get_string('roles');
|
|
|
|
|
|
|
|
|
|
if (!empty($data->reset_roles_overrides)) {
|
|
|
|
|
$children = get_child_contexts($context);
|
|
|
|
|
foreach ($children as $child) {
|
|
|
|
|
delete_records('role_capabilities', 'contextid', $child->id);
|
2004-08-01 07:34:39 +00:00
|
|
|
|
}
|
2007-11-29 14:43:04 +00:00
|
|
|
|
delete_records('role_capabilities', 'contextid', $context->id);
|
|
|
|
|
//force refresh for logged in users
|
|
|
|
|
mark_context_dirty($context->path);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletecourseoverrides', 'role'), 'error'=>false);
|
|
|
|
|
}
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
if (!empty($data->reset_roles_local)) {
|
|
|
|
|
$children = get_child_contexts($context);
|
|
|
|
|
foreach ($children as $child) {
|
|
|
|
|
role_unassign(0, 0, 0, $child->id);
|
|
|
|
|
}
|
|
|
|
|
//force refresh for logged in users
|
|
|
|
|
mark_context_dirty($context->path);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletelocalroles', 'role'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc.
|
|
|
|
|
$data->unenrolled = array();
|
|
|
|
|
if (!empty($data->reset_roles)) {
|
|
|
|
|
foreach($data->reset_roles as $roleid) {
|
|
|
|
|
if ($users = get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')) {
|
|
|
|
|
foreach ($users as $user) {
|
|
|
|
|
role_unassign($roleid, $user->id, 0, $context->id);
|
|
|
|
|
if (!has_capability('moodle/course:view', $context, $user->id)) {
|
|
|
|
|
$data->unenrolled[$user->id] = $user->id;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-08-01 07:34:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-11-29 14:43:04 +00:00
|
|
|
|
if (!empty($data->unenrolled)) {
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('unenrol').' ('.count($data->unenrolled).')', 'error'=>false);
|
|
|
|
|
}
|
2004-08-01 07:34:39 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
|
|
|
|
|
$componentstr = get_string('groups');
|
|
|
|
|
|
|
|
|
|
// remove all group members
|
|
|
|
|
if (!empty($data->reset_groups_members)) {
|
|
|
|
|
groups_delete_group_members($data->courseid, false);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('removegroupsmembers', 'group'), 'error'=>false);
|
2004-08-01 07:34:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
// remove all groups
|
|
|
|
|
if (!empty($data->reset_groups_remove)) {
|
|
|
|
|
groups_delete_groups($data->courseid, false);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallgroups', 'group'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// remove all grouping members
|
|
|
|
|
if (!empty($data->reset_groupings_members)) {
|
|
|
|
|
groups_delete_groupings_groups($data->courseid, false);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('removegroupingsmembers', 'group'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// remove all groupings
|
|
|
|
|
if (!empty($data->reset_groupings_remove)) {
|
|
|
|
|
groups_delete_groupings($data->courseid, false);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallgroupings', 'group'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look in every instance of every module for data to delete
|
|
|
|
|
$unsupported_mods = array();
|
|
|
|
|
if ($allmods = get_records('modules') ) {
|
|
|
|
|
foreach ($allmods as $mod) {
|
|
|
|
|
$modname = $mod->name;
|
|
|
|
|
if (!count_records($modname, 'course', $data->courseid)) {
|
|
|
|
|
continue; // skip mods with no instances
|
|
|
|
|
}
|
|
|
|
|
$modfile = $CFG->dirroot.'/mod/'. $modname.'/lib.php';
|
|
|
|
|
$moddeleteuserdata = $modname.'_reset_userdata'; // Function to delete user data
|
|
|
|
|
if (file_exists($modfile)) {
|
|
|
|
|
include_once($modfile);
|
|
|
|
|
if (function_exists($moddeleteuserdata)) {
|
|
|
|
|
$modstatus = $moddeleteuserdata($data);
|
|
|
|
|
if (is_array($modstatus)) {
|
|
|
|
|
$status = array_merge($status, $modstatus);
|
|
|
|
|
} else {
|
|
|
|
|
debugging('Module '.$modname.' returned incorrect staus - must be an array!');
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$unsupported_mods[] = $mod;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
debugging('Missing lib.php in '.$modname.' module!');
|
2004-08-01 07:34:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
// mention unsupported mods
|
|
|
|
|
if (!empty($unsupported_mods)) {
|
|
|
|
|
foreach($unsupported_mods as $mod) {
|
|
|
|
|
$status[] = array('component'=>get_string('modulenameplural', $mod->name), 'item'=>'', 'error'=>get_string('resetnotimplemented'));
|
2004-08-01 07:34:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-10-18 09:20:16 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
$componentstr = get_string('gradebook', 'grades');
|
|
|
|
|
// reset gradebook
|
|
|
|
|
if (!empty($data->reset_gradebook_items)) {
|
|
|
|
|
remove_course_grades($data->courseid, false);
|
|
|
|
|
grade_grab_course_grades($data->courseid);
|
|
|
|
|
grade_regrade_final_grades($data->courseid);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('removeallcourseitems', 'grades'), 'error'=>false);
|
2007-09-19 07:11:42 +00:00
|
|
|
|
|
2007-11-29 14:43:04 +00:00
|
|
|
|
} else if (!empty($data->reset_gradebook_grades)) {
|
|
|
|
|
grade_course_reset($data->courseid);
|
|
|
|
|
$status[] = array('component'=>$componentstr, 'item'=>get_string('removeallcoursegrades', 'grades'), 'error'=>false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $status;
|
2004-08-01 07:34:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
function generate_email_processing_address($modid,$modargs) {
|
|
|
|
|
global $CFG;
|
2005-02-10 07:53:52 +00:00
|
|
|
|
|
|
|
|
|
if (empty($CFG->siteidentifier)) { // Unique site identification code
|
|
|
|
|
set_config('siteidentifier', random_string(32));
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
}
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
$header = $CFG->mailprefix . substr(base64_encode(pack('C',$modid)),0,2).$modargs;
|
2005-05-30 23:26:17 +00:00
|
|
|
|
return $header . substr(md5($header.$CFG->siteidentifier),0,16).'@'.$CFG->maildomain;
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-12-30 17:18:06 +00:00
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
function moodle_process_email($modargs,$body) {
|
|
|
|
|
// the first char should be an unencoded letter. We'll take this as an action
|
|
|
|
|
switch ($modargs{0}) {
|
|
|
|
|
case 'B': { // bounce
|
|
|
|
|
list(,$userid) = unpack('V',base64_decode(substr($modargs,1,8)));
|
|
|
|
|
if ($user = get_record_select("user","id=$userid","id,email")) {
|
|
|
|
|
// check the half md5 of their email
|
|
|
|
|
$md5check = substr(md5($user->email),0,16);
|
2005-06-13 00:17:16 +00:00
|
|
|
|
if ($md5check == substr($modargs, -16)) {
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
set_bounce_count($user);
|
|
|
|
|
}
|
|
|
|
|
// else maybe they've already changed it?
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
// maybe more later?
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-12-30 17:18:06 +00:00
|
|
|
|
|
2001-11-22 06:23:56 +00:00
|
|
|
|
/// CORRESPONDENCE ////////////////////////////////////////////////
|
|
|
|
|
|
2008-02-01 07:05:58 +00:00
|
|
|
|
/**
|
|
|
|
|
* Get mailer instance, enable buffering, flush buffer or disable buffering.
|
|
|
|
|
* @param $action string 'get', 'buffer', 'close' or 'flush'
|
|
|
|
|
* @return reference to mailer instance if 'get' used or nothing
|
|
|
|
|
*/
|
|
|
|
|
function &get_mailer($action='get') {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
static $mailer = null;
|
|
|
|
|
static $counter = 0;
|
|
|
|
|
|
|
|
|
|
if (!isset($CFG->smtpmaxbulk)) {
|
2008-02-02 16:22:47 +00:00
|
|
|
|
$CFG->smtpmaxbulk = 1;
|
2008-02-01 07:05:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($action == 'get') {
|
|
|
|
|
$prevkeepalive = false;
|
|
|
|
|
|
|
|
|
|
if (isset($mailer) and $mailer->Mailer == 'smtp') {
|
|
|
|
|
if ($counter < $CFG->smtpmaxbulk and empty($mailer->error_count)) {
|
|
|
|
|
$counter++;
|
|
|
|
|
// reset the mailer
|
|
|
|
|
$mailer->Priority = 3;
|
|
|
|
|
$mailer->CharSet = 'UTF-8'; // our default
|
|
|
|
|
$mailer->ContentType = "text/plain";
|
|
|
|
|
$mailer->Encoding = "8bit";
|
|
|
|
|
$mailer->From = "root@localhost";
|
|
|
|
|
$mailer->FromName = "Root User";
|
|
|
|
|
$mailer->Sender = "";
|
|
|
|
|
$mailer->Subject = "";
|
|
|
|
|
$mailer->Body = "";
|
|
|
|
|
$mailer->AltBody = "";
|
|
|
|
|
$mailer->ConfirmReadingTo = "";
|
|
|
|
|
|
|
|
|
|
$mailer->ClearAllRecipients();
|
|
|
|
|
$mailer->ClearReplyTos();
|
|
|
|
|
$mailer->ClearAttachments();
|
|
|
|
|
$mailer->ClearCustomHeaders();
|
|
|
|
|
return $mailer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$prevkeepalive = $mailer->SMTPKeepAlive;
|
|
|
|
|
get_mailer('flush');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
include_once($CFG->libdir.'/phpmailer/class.phpmailer.php');
|
|
|
|
|
$mailer = new phpmailer();
|
|
|
|
|
|
2008-02-02 16:22:47 +00:00
|
|
|
|
$counter = 1;
|
2008-02-01 07:05:58 +00:00
|
|
|
|
|
|
|
|
|
$mailer->Version = 'Moodle '.$CFG->version; // mailer version
|
|
|
|
|
$mailer->PluginDir = $CFG->libdir.'/phpmailer/'; // plugin directory (eg smtp plugin)
|
|
|
|
|
$mailer->CharSet = 'UTF-8';
|
|
|
|
|
|
|
|
|
|
// some MTAs may do double conversion of LF if CRLF used, CRLF is required line ending in RFC 822bis
|
|
|
|
|
// hmm, this is a bit hacky because LE should be private
|
|
|
|
|
if (isset($CFG->mailnewline) and $CFG->mailnewline == 'CRLF') {
|
|
|
|
|
$mailer->LE = "\r\n";
|
|
|
|
|
} else {
|
|
|
|
|
$mailer->LE = "\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($CFG->smtphosts == 'qmail') {
|
|
|
|
|
$mailer->IsQmail(); // use Qmail system
|
|
|
|
|
|
|
|
|
|
} else if (empty($CFG->smtphosts)) {
|
|
|
|
|
$mailer->IsMail(); // use PHP mail() = sendmail
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
$mailer->IsSMTP(); // use SMTP directly
|
|
|
|
|
if (!empty($CFG->debugsmtp)) {
|
|
|
|
|
$mailer->SMTPDebug = true;
|
|
|
|
|
}
|
|
|
|
|
$mailer->Host = $CFG->smtphosts; // specify main and backup servers
|
|
|
|
|
$mailer->SMTPKeepAlive = $prevkeepalive; // use previous keepalive
|
|
|
|
|
|
|
|
|
|
if ($CFG->smtpuser) { // Use SMTP authentication
|
|
|
|
|
$mailer->SMTPAuth = true;
|
|
|
|
|
$mailer->Username = $CFG->smtpuser;
|
|
|
|
|
$mailer->Password = $CFG->smtppass;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $mailer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$nothing = null;
|
|
|
|
|
|
|
|
|
|
// keep smtp session open after sending
|
|
|
|
|
if ($action == 'buffer') {
|
|
|
|
|
if (!empty($CFG->smtpmaxbulk)) {
|
|
|
|
|
get_mailer('flush');
|
|
|
|
|
$m =& get_mailer();
|
|
|
|
|
if ($m->Mailer == 'smtp') {
|
|
|
|
|
$m->SMTPKeepAlive = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $nothing;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// close smtp session, but continue buffering
|
|
|
|
|
if ($action == 'flush') {
|
|
|
|
|
if (isset($mailer) and $mailer->Mailer == 'smtp') {
|
|
|
|
|
if (!empty($mailer->SMTPDebug)) {
|
|
|
|
|
echo '<pre>'."\n";
|
|
|
|
|
}
|
|
|
|
|
$mailer->SmtpClose();
|
|
|
|
|
if (!empty($mailer->SMTPDebug)) {
|
|
|
|
|
echo '</pre>';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $nothing;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// close smtp session, do not buffer anymore
|
|
|
|
|
if ($action == 'close') {
|
|
|
|
|
if (isset($mailer) and $mailer->Mailer == 'smtp') {
|
|
|
|
|
get_mailer('flush');
|
|
|
|
|
$mailer->SMTPKeepAlive = false;
|
|
|
|
|
}
|
|
|
|
|
$mailer = null; // better force new instance
|
|
|
|
|
return $nothing;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Send an email to a specified user
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @uses $FULLME
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses SITEID
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @param user $user A {@link $USER} object
|
|
|
|
|
* @param user $from A {@link $USER} object
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @param string $subject plain text subject line of the email
|
|
|
|
|
* @param string $messagetext plain text version of the message
|
|
|
|
|
* @param string $messagehtml complete html version of the message (optional)
|
|
|
|
|
* @param string $attachment a file on the filesystem, relative to $CFG->dataroot
|
|
|
|
|
* @param string $attachname the name of the file (extension indicates MIME)
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @param bool $usetrueaddress determines whether $from email address should
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* be sent out. Will be overruled by user profile setting for maildisplay
|
2008-03-15 17:04:36 +00:00
|
|
|
|
* @param int $wordwrapwidth custom word wrap width
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool|string Returns "true" if mail was sent OK, "emailstop" if email
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* was blocked by user and "false" if there was another sort of error.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2008-03-15 17:04:36 +00:00
|
|
|
|
function email_to_user($user, $from, $subject, $messagetext, $messagehtml='', $attachment='', $attachname='', $usetrueaddress=true, $replyto='', $replytoname='', $wordwrapwidth=79) {
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2007-01-27 19:56:08 +00:00
|
|
|
|
global $CFG, $FULLME;
|
2004-02-09 08:49:54 +00:00
|
|
|
|
|
2004-02-20 10:27:24 +00:00
|
|
|
|
if (empty($user)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-15 10:47:02 +00:00
|
|
|
|
if (!empty($CFG->noemailever)) {
|
|
|
|
|
// hidden setting for development sites, set in config.php if needed
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-20 17:15:13 +00:00
|
|
|
|
// skip mail to suspended users
|
2007-03-05 04:47:49 +00:00
|
|
|
|
if (isset($user->auth) && $user->auth=='nologin') {
|
2007-02-20 17:15:13 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2004-02-20 10:27:24 +00:00
|
|
|
|
if (!empty($user->emailstop)) {
|
2004-08-03 04:03:01 +00:00
|
|
|
|
return 'emailstop';
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
if (over_bounce_threshold($user)) {
|
|
|
|
|
error_log("User $user->id (".fullname($user).") is over bounce threshold! Not sending.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2008-02-01 07:05:58 +00:00
|
|
|
|
$mail =& get_mailer();
|
2002-09-21 08:39:54 +00:00
|
|
|
|
|
2008-02-01 07:05:58 +00:00
|
|
|
|
if (!empty($mail->SMTPDebug)) {
|
|
|
|
|
echo '<pre>' . "\n";
|
2007-12-17 23:44:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-02-01 07:05:58 +00:00
|
|
|
|
/// We are going to use textlib services here
|
|
|
|
|
$textlib = textlib_get_instance();
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$supportuser = generate_email_supportuser();
|
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
// make up an email address for handling bounces
|
|
|
|
|
if (!empty($CFG->handlebounces)) {
|
|
|
|
|
$modargs = 'B'.base64_encode(pack('V',$user->id)).substr(md5($user->email),0,16);
|
|
|
|
|
$mail->Sender = generate_email_processing_address(0,$modargs);
|
2007-08-01 09:00:21 +00:00
|
|
|
|
} else {
|
2008-02-01 07:05:58 +00:00
|
|
|
|
$mail->Sender = $supportuser->email;
|
2005-02-25 06:08:40 +00:00
|
|
|
|
}
|
2003-07-27 13:14:00 +00:00
|
|
|
|
|
2004-06-25 07:38:44 +00:00
|
|
|
|
if (is_string($from)) { // So we can pass whatever we want if there is need
|
|
|
|
|
$mail->From = $CFG->noreplyaddress;
|
2004-06-29 07:01:34 +00:00
|
|
|
|
$mail->FromName = $from;
|
2004-06-25 07:38:44 +00:00
|
|
|
|
} else if ($usetrueaddress and $from->maildisplay) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$mail->From = $from->email;
|
2004-06-06 12:49:55 +00:00
|
|
|
|
$mail->FromName = fullname($from);
|
|
|
|
|
} else {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$mail->From = $CFG->noreplyaddress;
|
2004-06-29 07:01:34 +00:00
|
|
|
|
$mail->FromName = fullname($from);
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
if (empty($replyto)) {
|
|
|
|
|
$mail->AddReplyTo($CFG->noreplyaddress,get_string('noreplyname'));
|
|
|
|
|
}
|
2004-06-06 12:49:55 +00:00
|
|
|
|
}
|
2005-02-25 06:08:40 +00:00
|
|
|
|
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
if (!empty($replyto)) {
|
|
|
|
|
$mail->AddReplyTo($replyto,$replytoname);
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-30 18:10:57 +00:00
|
|
|
|
$mail->Subject = substr(stripslashes($subject), 0, 900);
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$mail->AddAddress($user->email, fullname($user) );
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2008-03-15 17:04:36 +00:00
|
|
|
|
$mail->WordWrap = $wordwrapwidth; // set word wrap
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-07 14:04:33 +00:00
|
|
|
|
if (!empty($from->customheaders)) { // Add custom headers
|
|
|
|
|
if (is_array($from->customheaders)) {
|
|
|
|
|
foreach ($from->customheaders as $customheader) {
|
|
|
|
|
$mail->AddCustomHeader($customheader);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$mail->AddCustomHeader($from->customheaders);
|
|
|
|
|
}
|
2004-05-07 03:29:11 +00:00
|
|
|
|
}
|
2004-09-21 11:41:58 +00:00
|
|
|
|
|
2005-03-02 17:56:46 +00:00
|
|
|
|
if (!empty($from->priority)) {
|
|
|
|
|
$mail->Priority = $from->priority;
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-05 01:36:55 +00:00
|
|
|
|
if ($messagehtml && $user->mailformat == 1) { // Don't ever send HTML to users who don't want it
|
2002-05-24 06:38:37 +00:00
|
|
|
|
$mail->IsHTML(true);
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$mail->Encoding = 'quoted-printable'; // Encoding to use
|
2002-05-24 06:38:37 +00:00
|
|
|
|
$mail->Body = $messagehtml;
|
2002-06-07 03:54:39 +00:00
|
|
|
|
$mail->AltBody = "\n$messagetext\n";
|
2002-05-24 06:38:37 +00:00
|
|
|
|
} else {
|
|
|
|
|
$mail->IsHTML(false);
|
2002-06-07 03:54:39 +00:00
|
|
|
|
$mail->Body = "\n$messagetext\n";
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-05-24 06:38:37 +00:00
|
|
|
|
if ($attachment && $attachname) {
|
|
|
|
|
if (ereg( "\\.\\." ,$attachment )) { // Security check for ".." in dir path
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$mail->AddAddress($supportuser->email, fullname($supportuser, true) );
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$mail->AddStringAttachment('Error in attachment. User attempted to attach a filename with a unsafe name.', 'error.txt', '8bit', 'text/plain');
|
2002-05-24 06:38:37 +00:00
|
|
|
|
} else {
|
2005-03-07 11:32:03 +00:00
|
|
|
|
require_once($CFG->libdir.'/filelib.php');
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$mimetype = mimeinfo('type', $attachname);
|
|
|
|
|
$mail->AddAttachment($CFG->dataroot .'/'. $attachment, $attachname, 'base64', $mimetype);
|
2002-05-24 06:38:37 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-18 17:48:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// If we are running under Unicode and sitemailcharset or allowusermailcharset are set, convert the email
|
|
|
|
|
/// encoding to the specified one
|
2006-11-11 16:07:53 +00:00
|
|
|
|
if ((!empty($CFG->sitemailcharset) || !empty($CFG->allowusermailcharset))) {
|
2006-03-18 17:48:52 +00:00
|
|
|
|
/// Set it to site mail charset
|
|
|
|
|
$charset = $CFG->sitemailcharset;
|
|
|
|
|
/// Overwrite it with the user mail charset
|
|
|
|
|
if (!empty($CFG->allowusermailcharset)) {
|
|
|
|
|
if ($useremailcharset = get_user_preferences('mailcharset', '0', $user->id)) {
|
|
|
|
|
$charset = $useremailcharset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// If it has changed, convert all the necessary strings
|
2007-03-08 00:10:49 +00:00
|
|
|
|
$charsets = get_list_of_charsets();
|
|
|
|
|
unset($charsets['UTF-8']);
|
|
|
|
|
if (in_array($charset, $charsets)) {
|
2006-03-18 17:48:52 +00:00
|
|
|
|
/// Save the new mail charset
|
|
|
|
|
$mail->CharSet = $charset;
|
|
|
|
|
/// And convert some strings
|
|
|
|
|
$mail->FromName = $textlib->convert($mail->FromName, 'utf-8', $mail->CharSet); //From Name
|
|
|
|
|
foreach ($mail->ReplyTo as $key => $rt) { //ReplyTo Names
|
|
|
|
|
$mail->ReplyTo[$key][1] = $textlib->convert($rt, 'utf-8', $mail->CharSet);
|
|
|
|
|
}
|
|
|
|
|
$mail->Subject = $textlib->convert($mail->Subject, 'utf-8', $mail->CharSet); //Subject
|
|
|
|
|
foreach ($mail->to as $key => $to) {
|
|
|
|
|
$mail->to[$key][1] = $textlib->convert($to, 'utf-8', $mail->CharSet); //To Names
|
|
|
|
|
}
|
|
|
|
|
$mail->Body = $textlib->convert($mail->Body, 'utf-8', $mail->CharSet); //Body
|
|
|
|
|
$mail->AltBody = $textlib->convert($mail->AltBody, 'utf-8', $mail->CharSet); //Subject
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-05-24 06:38:37 +00:00
|
|
|
|
if ($mail->Send()) {
|
First cut of email to module (or core) processing.
This patch contains:
* email_to_user will set the envelope sender to a special bounce processing address (based on $CFG settings)
* email_to_user will accept (and set) a reply-to header, to be generated by the module calling the function.
* new functions:
* generate_email_processing_address - ALWAYS use this to generate the reply-to header. reply-to header will look like this:
(LIMIT: 64 chars total)
prefix - EXACTLY four chars
encodeded, packed, moduleid (0 for core) (2 chars)
up to 42 chars for the modules to put anything they want it (can contain userid (or, eg for forum, postids to reply to), or anything really. 42 chars is ABSOLUTE LIMIT)
16 char hash (half an md5) of the first part of the address, together with a site "secret"
* moodle_process_email - any non-module email processing goes here (currently used for processing bounces)
* bounce handling:
* config settings for bounce threshold and ratio (and whether to handle bounces at all)
* if too many bounces occur against any given user, user_not_fully_set_up will force an email address change
* associated functions (over_bounce_threshold, set_send_count, set_bounce_count)
* handling emails to noreply address (see below)
* new script - admin/process_email.php
This script needs to be called from your mail program for anything starting with the 4 char prefix described above (and optionally, the noreply address)
It will bounce emails to the noreplyaddress, with a friendly "this is not a real email address" message
It will break down and unencode the email address into moduleid and validate the half md5 hash, and call $modname_process_email (if it exists). Arguments to these functions are: $modargs (any part of the email address that isn't the prefix, modid or the hash) and the contents of the email (read from STDIN).
* associated string changes/additions
* changes in config-dist.php to give clues as to how to set this up.
MODULE WRITERS!
take a look at new functions moodle_process_email and generate_email_processing_address in moodlelib.php for ideas about how to
* encode and unencode the arguments your module needs to do the processing
* how to deal with multiple "actions" for any given module.
Martin Langhoff <martin@catalyst.net.nz> will be writing up some PROPER documentation, containing amongst other things config settings for different mail servers (this was developed against Postfix). Feel free to email me with any feedback on the code or design, penny@catalyst.net.nz. Or post on the developer fourm.
2005-02-08 02:57:14 +00:00
|
|
|
|
set_send_count($user);
|
2007-03-09 20:16:48 +00:00
|
|
|
|
$mail->IsSMTP(); // use SMTP directly
|
2008-02-01 07:05:58 +00:00
|
|
|
|
if (!empty($mail->SMTPDebug)) {
|
2007-03-09 20:16:48 +00:00
|
|
|
|
echo '</pre>';
|
|
|
|
|
}
|
2002-05-24 06:38:37 +00:00
|
|
|
|
return true;
|
|
|
|
|
} else {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
mtrace('ERROR: '. $mail->ErrorInfo);
|
2004-12-12 06:49:26 +00:00
|
|
|
|
add_to_log(SITEID, 'library', 'mailer', $FULLME, 'ERROR: '. $mail->ErrorInfo);
|
2008-02-01 07:05:58 +00:00
|
|
|
|
if (!empty($mail->SMTPDebug)) {
|
2007-03-09 20:16:48 +00:00
|
|
|
|
echo '</pre>';
|
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-08-01 09:00:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Generate a signoff for emails based on support settings
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function generate_email_signoff() {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$signoff = "\n";
|
|
|
|
|
if (!empty($CFG->supportname)) {
|
|
|
|
|
$signoff .= $CFG->supportname."\n";
|
|
|
|
|
}
|
|
|
|
|
if (!empty($CFG->supportemail)) {
|
|
|
|
|
$signoff .= $CFG->supportemail."\n";
|
|
|
|
|
}
|
|
|
|
|
if (!empty($CFG->supportpage)) {
|
|
|
|
|
$signoff .= $CFG->supportpage."\n";
|
|
|
|
|
}
|
|
|
|
|
return $signoff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate a fake user for emails based on support settings
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function generate_email_supportuser() {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
static $supportuser;
|
|
|
|
|
|
|
|
|
|
if (!empty($supportuser)) {
|
|
|
|
|
return $supportuser;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$supportuser = new object;
|
|
|
|
|
$supportuser->email = $CFG->supportemail ? $CFG->supportemail : $CFG->noreplyaddress;
|
|
|
|
|
$supportuser->firstname = $CFG->supportname ? $CFG->supportname : get_string('noreplyname');
|
|
|
|
|
$supportuser->lastname = '';
|
2007-09-27 12:38:40 +00:00
|
|
|
|
$supportuser->maildisplay = true;
|
2007-08-01 09:00:21 +00:00
|
|
|
|
|
|
|
|
|
return $supportuser;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-01-16 02:51:02 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets specified user's password and send the new password to the user via email.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param user $user A {@link $USER} object
|
|
|
|
|
* @return boolean|string Returns "true" if mail was sent OK, "emailstop" if email
|
|
|
|
|
* was blocked by user and "false" if there was another sort of error.
|
|
|
|
|
*/
|
|
|
|
|
function setnew_password_and_mail($user) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$site = get_site();
|
2007-08-01 09:00:21 +00:00
|
|
|
|
|
|
|
|
|
$supportuser = generate_email_supportuser();
|
2006-01-16 02:51:02 +00:00
|
|
|
|
|
|
|
|
|
$newpassword = generate_password();
|
|
|
|
|
|
|
|
|
|
if (! set_field('user', 'password', md5($newpassword), 'id', $user->id) ) {
|
|
|
|
|
trigger_error('Could not set user password!');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$a = new object();
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$a->firstname = fullname($user, true);
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$a->sitename = format_string($site->fullname);
|
2006-01-16 02:51:02 +00:00
|
|
|
|
$a->username = $user->username;
|
|
|
|
|
$a->newpassword = $newpassword;
|
|
|
|
|
$a->link = $CFG->wwwroot .'/login/';
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$a->signoff = generate_email_signoff();
|
2006-01-16 02:51:02 +00:00
|
|
|
|
|
|
|
|
|
$message = get_string('newusernewpasswordtext', '', $a);
|
|
|
|
|
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$subject = format_string($site->fullname) .': '. get_string('newusernewpasswordsubj');
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2007-08-01 09:00:21 +00:00
|
|
|
|
return email_to_user($user, $supportuser, $subject, $message);
|
2006-01-16 02:51:02 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Resets specified user's password and send the new password to the user via email.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @param user $user A {@link $USER} object
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool|string Returns "true" if mail was sent OK, "emailstop" if email
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* was blocked by user and "false" if there was another sort of error.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-12-23 03:07:01 +00:00
|
|
|
|
function reset_password_and_mail($user) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$site = get_site();
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$supportuser = generate_email_supportuser();
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
$userauth = get_auth_plugin($user->auth);
|
2007-04-26 21:41:08 +00:00
|
|
|
|
if (!$userauth->can_reset_password() or !is_enabled_auth($user->auth)) {
|
2007-01-04 02:52:44 +00:00
|
|
|
|
trigger_error("Attempt to reset user password for user $user->username with Auth $user->auth.");
|
|
|
|
|
return false;
|
2005-08-15 23:19:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-23 03:07:01 +00:00
|
|
|
|
$newpassword = generate_password();
|
|
|
|
|
|
2007-02-22 22:20:51 +00:00
|
|
|
|
if (!$userauth->user_update_password(addslashes_recursive($user), addslashes($newpassword))) {
|
2008-04-04 02:54:20 +00:00
|
|
|
|
print_error("Could not set user password!");
|
2002-12-23 03:07:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$a = new object();
|
2002-12-23 03:07:01 +00:00
|
|
|
|
$a->firstname = $user->firstname;
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$a->sitename = format_string($site->fullname);
|
2002-12-23 03:07:01 +00:00
|
|
|
|
$a->username = $user->username;
|
|
|
|
|
$a->newpassword = $newpassword;
|
2005-07-15 00:04:51 +00:00
|
|
|
|
$a->link = $CFG->httpswwwroot .'/login/change_password.php';
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$a->signoff = generate_email_signoff();
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$message = get_string('newpasswordtext', '', $a);
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$subject = format_string($site->fullname) .': '. get_string('changedpassword');
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2007-08-01 09:00:21 +00:00
|
|
|
|
return email_to_user($user, $supportuser, $subject, $message);
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Send email to specified user with confirmation text and activation link.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @param user $user A {@link $USER} object
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool|string Returns "true" if mail was sent OK, "emailstop" if email
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* was blocked by user and "false" if there was another sort of error.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
|
|
|
|
function send_confirmation_email($user) {
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$site = get_site();
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$supportuser = generate_email_supportuser();
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$data = new object();
|
2005-01-29 04:54:17 +00:00
|
|
|
|
$data->firstname = fullname($user);
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$data->sitename = format_string($site->fullname);
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$data->admin = generate_email_signoff();
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$subject = get_string('emailconfirmationsubject', '', format_string($site->fullname));
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2007-03-21 22:00:10 +00:00
|
|
|
|
$data->link = $CFG->wwwroot .'/login/confirm.php?data='. $user->secret .'/'. urlencode($user->username);
|
2006-09-04 02:30:52 +00:00
|
|
|
|
$message = get_string('emailconfirmation', '', $data);
|
2005-03-01 07:06:42 +00:00
|
|
|
|
$messagehtml = text_to_html(get_string('emailconfirmation', '', $data), false, false, true);
|
|
|
|
|
|
|
|
|
|
$user->mailformat = 1; // Always send HTML version as well
|
2004-05-13 03:09:47 +00:00
|
|
|
|
|
2007-08-01 09:00:21 +00:00
|
|
|
|
return email_to_user($user, $supportuser, $subject, $message, $messagehtml);
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* send_password_change_confirmation_email.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @param user $user A {@link $USER} object
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool|string Returns "true" if mail was sent OK, "emailstop" if email
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* was blocked by user and "false" if there was another sort of error.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2003-05-04 03:00:52 +00:00
|
|
|
|
function send_password_change_confirmation_email($user) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$site = get_site();
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$supportuser = generate_email_supportuser();
|
2003-05-04 03:00:52 +00:00
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$data = new object();
|
2003-05-04 03:00:52 +00:00
|
|
|
|
$data->firstname = $user->firstname;
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$data->sitename = format_string($site->fullname);
|
2007-03-21 22:00:10 +00:00
|
|
|
|
$data->link = $CFG->httpswwwroot .'/login/forgot_password.php?p='. $user->secret .'&s='. urlencode($user->username);
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$data->admin = generate_email_signoff();
|
2003-05-04 03:00:52 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$message = get_string('emailpasswordconfirmation', '', $data);
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$subject = get_string('emailpasswordconfirmationsubject', '', format_string($site->fullname));
|
2003-05-04 03:00:52 +00:00
|
|
|
|
|
2007-08-01 09:00:21 +00:00
|
|
|
|
return email_to_user($user, $supportuser, $subject, $message);
|
2003-05-04 03:00:52 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-21 21:48:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* send_password_change_info.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param user $user A {@link $USER} object
|
|
|
|
|
* @return bool|string Returns "true" if mail was sent OK, "emailstop" if email
|
|
|
|
|
* was blocked by user and "false" if there was another sort of error.
|
|
|
|
|
*/
|
|
|
|
|
function send_password_change_info($user) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$site = get_site();
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$supportuser = generate_email_supportuser();
|
2007-04-26 21:41:08 +00:00
|
|
|
|
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
|
2007-02-21 21:48:48 +00:00
|
|
|
|
|
|
|
|
|
$data = new object();
|
|
|
|
|
$data->firstname = $user->firstname;
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$data->sitename = format_string($site->fullname);
|
2007-08-01 09:00:21 +00:00
|
|
|
|
$data->admin = generate_email_signoff();
|
2007-02-21 21:48:48 +00:00
|
|
|
|
|
2007-04-26 21:41:08 +00:00
|
|
|
|
$userauth = get_auth_plugin($user->auth);
|
|
|
|
|
|
|
|
|
|
if (!is_enabled_auth($user->auth) or $user->auth == 'nologin') {
|
|
|
|
|
$message = get_string('emailpasswordchangeinfodisabled', '', $data);
|
|
|
|
|
$subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
|
2007-08-01 09:00:21 +00:00
|
|
|
|
return email_to_user($user, $supportuser, $subject, $message);
|
2007-04-26 21:41:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-03-22 12:27:52 +00:00
|
|
|
|
if ($userauth->can_change_password() and $userauth->change_password_url()) {
|
2007-04-26 21:41:08 +00:00
|
|
|
|
// we have some external url for password changing
|
2007-02-21 21:48:48 +00:00
|
|
|
|
$data->link .= $userauth->change_password_url();
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
//no way to change password, sorry
|
|
|
|
|
$data->link = '';
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-26 21:41:08 +00:00
|
|
|
|
if (!empty($data->link) and has_capability('moodle/user:changeownpassword', $systemcontext, $user->id)) {
|
2007-02-21 21:48:48 +00:00
|
|
|
|
$message = get_string('emailpasswordchangeinfo', '', $data);
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
|
2007-02-21 21:48:48 +00:00
|
|
|
|
} else {
|
|
|
|
|
$message = get_string('emailpasswordchangeinfofail', '', $data);
|
2007-03-20 07:42:41 +00:00
|
|
|
|
$subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
|
2007-02-21 21:48:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-01 09:00:21 +00:00
|
|
|
|
return email_to_user($user, $supportuser, $subject, $message);
|
2007-02-21 21:48:48 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Check that an email is allowed. It returns an error message if there
|
|
|
|
|
* was a problem.
|
|
|
|
|
*
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param string $email Content of email
|
|
|
|
|
* @return string|false
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2004-09-06 15:21:22 +00:00
|
|
|
|
function email_is_not_allowed($email) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (!empty($CFG->allowemailaddresses)) {
|
|
|
|
|
$allowed = explode(' ', $CFG->allowemailaddresses);
|
|
|
|
|
foreach ($allowed as $allowedpattern) {
|
|
|
|
|
$allowedpattern = trim($allowedpattern);
|
|
|
|
|
if (!$allowedpattern) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2007-10-29 20:04:14 +00:00
|
|
|
|
if (strpos($allowedpattern, '.') === 0) {
|
|
|
|
|
if (strpos(strrev($email), strrev($allowedpattern)) === 0) {
|
|
|
|
|
// subdomains are in a form ".example.com" - matches "xxx@anything.example.com"
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (strpos(strrev($email), strrev('@'.$allowedpattern)) === 0) { // Match! (bug 5250)
|
2004-09-06 15:21:22 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return get_string('emailonlyallowed', '', $CFG->allowemailaddresses);
|
2004-09-06 15:21:22 +00:00
|
|
|
|
|
|
|
|
|
} else if (!empty($CFG->denyemailaddresses)) {
|
|
|
|
|
$denied = explode(' ', $CFG->denyemailaddresses);
|
|
|
|
|
foreach ($denied as $deniedpattern) {
|
|
|
|
|
$deniedpattern = trim($deniedpattern);
|
|
|
|
|
if (!$deniedpattern) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2007-10-29 20:04:14 +00:00
|
|
|
|
if (strpos($deniedpattern, '.') === 0) {
|
|
|
|
|
if (strpos(strrev($email), strrev($deniedpattern)) === 0) {
|
|
|
|
|
// subdomains are in a form ".example.com" - matches "xxx@anything.example.com"
|
|
|
|
|
return get_string('emailnotallowed', '', $CFG->denyemailaddresses);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (strpos(strrev($email), strrev('@'.$deniedpattern)) === 0) { // Match! (bug 5250)
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return get_string('emailnotallowed', '', $CFG->denyemailaddresses);
|
2004-09-06 15:21:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
2006-09-17 16:04:15 +00:00
|
|
|
|
function email_welcome_message_to_user($course, $user=NULL) {
|
|
|
|
|
global $CFG, $USER;
|
|
|
|
|
|
|
|
|
|
if (empty($user)) {
|
|
|
|
|
if (!isloggedin()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$user = $USER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!empty($course->welcomemessage)) {
|
2007-12-28 17:14:01 +00:00
|
|
|
|
$message = $course->welcomemessage;
|
|
|
|
|
} else {
|
|
|
|
|
$a = new Object();
|
2006-09-17 16:04:15 +00:00
|
|
|
|
$a->coursename = $course->fullname;
|
|
|
|
|
$a->profileurl = "$CFG->wwwroot/user/view.php?id=$USER->id&course=$course->id";
|
2007-12-28 17:14:01 +00:00
|
|
|
|
$message = get_string("welcometocoursetext", "", $a);
|
|
|
|
|
}
|
2006-09-17 16:04:15 +00:00
|
|
|
|
|
2007-12-28 17:14:01 +00:00
|
|
|
|
/// If you don't want a welcome message sent, then make the message string blank.
|
|
|
|
|
if (!empty($message)) {
|
|
|
|
|
$subject = get_string('welcometocourse', '', format_string($course->fullname));
|
|
|
|
|
|
2006-09-17 16:04:15 +00:00
|
|
|
|
if (! $teacher = get_teacher($course->id)) {
|
|
|
|
|
$teacher = get_admin();
|
|
|
|
|
}
|
|
|
|
|
email_to_user($user, $teacher, $subject, $message);
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-05-24 06:38:37 +00:00
|
|
|
|
|
2001-11-22 06:23:56 +00:00
|
|
|
|
/// FILE HANDLING /////////////////////////////////////////////
|
|
|
|
|
|
2004-02-20 14:12:49 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Makes an upload directory for a particular module.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $courseid The id of the course in question - maps to id field of 'course' table.
|
|
|
|
|
* @return string|false Returns full path to directory if successful, false if not
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-08-28 13:07:10 +00:00
|
|
|
|
function make_mod_upload_directory($courseid) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (! $moddata = make_upload_directory($courseid .'/'. $CFG->moddata)) {
|
2002-08-28 13:07:10 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$strreadme = get_string('readme');
|
2002-08-28 13:07:10 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/lang/'. $CFG->lang .'/docs/module_files.txt')) {
|
|
|
|
|
copy($CFG->dirroot .'/lang/'. $CFG->lang .'/docs/module_files.txt', $moddata .'/'. $strreadme .'.txt');
|
2002-08-28 13:07:10 +00:00
|
|
|
|
} else {
|
2006-03-21 16:57:32 +00:00
|
|
|
|
copy($CFG->dirroot .'/lang/en_utf8/docs/module_files.txt', $moddata .'/'. $strreadme .'.txt');
|
2002-08-28 13:07:10 +00:00
|
|
|
|
}
|
|
|
|
|
return $moddata;
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-11 09:01:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* Makes a directory for a particular user.
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param int $userid The id of the user in question - maps to id field of 'user' table.
|
|
|
|
|
* @param bool $test Whether we are only testing the return value (do not create the directory)
|
|
|
|
|
* @return string|false Returns full path to directory if successful, false if not
|
|
|
|
|
*/
|
|
|
|
|
function make_user_directory($userid, $test=false) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (is_bool($userid) || $userid < 0 || !ereg('^[0-9]{1,10}$', $userid) || $userid > 2147483647) {
|
|
|
|
|
if (!$test) {
|
|
|
|
|
notify("Given userid was not a valid integer! (" . gettype($userid) . " $userid)");
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate a two-level path for the userid. First level groups them by slices of 1000 users, second level is userid
|
|
|
|
|
$level1 = floor($userid / 1000) * 1000;
|
|
|
|
|
|
|
|
|
|
$userdir = "user/$level1/$userid";
|
|
|
|
|
if ($test) {
|
|
|
|
|
return $CFG->dataroot . '/' . $userdir;
|
|
|
|
|
} else {
|
|
|
|
|
return make_upload_directory($userdir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-12 19:13:18 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an array of full paths to user directories, indexed by their userids.
|
|
|
|
|
*
|
|
|
|
|
* @param bool $only_non_empty Only return directories that contain files
|
|
|
|
|
* @param bool $legacy Search for user directories in legacy location (dataroot/users/userid) instead of (dataroot/user/section/userid)
|
|
|
|
|
* @return array An associative array: userid=>array(basedir => $basedir, userfolder => $userfolder)
|
|
|
|
|
*/
|
|
|
|
|
function get_user_directories($only_non_empty=true, $legacy=false) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$rootdir = $CFG->dataroot."/user";
|
|
|
|
|
|
|
|
|
|
if ($legacy) {
|
|
|
|
|
$rootdir = $CFG->dataroot."/users";
|
|
|
|
|
}
|
|
|
|
|
$dirlist = array();
|
|
|
|
|
|
|
|
|
|
//Check if directory exists
|
2007-11-01 08:45:30 +00:00
|
|
|
|
if (check_dir_exists($rootdir, true)) {
|
2007-10-12 19:13:18 +00:00
|
|
|
|
if ($legacy) {
|
|
|
|
|
if ($userlist = get_directory_list($rootdir, '', true, true, false)) {
|
|
|
|
|
foreach ($userlist as $userid) {
|
|
|
|
|
$dirlist[$userid] = array('basedir' => $rootdir, 'userfolder' => $userid);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
notify("no directories found under $rootdir");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ($grouplist =get_directory_list($rootdir, '', true, true, false)) { // directories will be in the form 0, 1000, 2000 etc...
|
|
|
|
|
foreach ($grouplist as $group) {
|
|
|
|
|
if ($userlist = get_directory_list("$rootdir/$group", '', true, true, false)) {
|
|
|
|
|
foreach ($userlist as $userid) {
|
|
|
|
|
$dirlist[$userid] = array('basedir' => $rootdir, 'userfolder' => $group . '/' . $userid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
notify("$rootdir does not exist!");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return $dirlist;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Returns current name of file on disk if it exists.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $newfile File to be verified
|
|
|
|
|
* @return string Current name of file on disk if true
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-09-01 14:29:17 +00:00
|
|
|
|
function valid_uploaded_file($newfile) {
|
2002-12-29 17:32:32 +00:00
|
|
|
|
if (empty($newfile)) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return '';
|
2002-12-29 17:32:32 +00:00
|
|
|
|
}
|
2002-09-01 14:29:17 +00:00
|
|
|
|
if (is_uploaded_file($newfile['tmp_name']) and $newfile['size'] > 0) {
|
|
|
|
|
return $newfile['tmp_name'];
|
|
|
|
|
} else {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return '';
|
2002-09-01 14:29:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the maximum size for uploading files.
|
|
|
|
|
*
|
|
|
|
|
* There are seven possible upload limits:
|
|
|
|
|
* 1. in Apache using LimitRequestBody (no way of checking or changing this)
|
|
|
|
|
* 2. in php.ini for 'upload_max_filesize' (can not be changed inside PHP)
|
|
|
|
|
* 3. in .htaccess for 'upload_max_filesize' (can not be changed inside PHP)
|
|
|
|
|
* 4. in php.ini for 'post_max_size' (can not be changed inside PHP)
|
|
|
|
|
* 5. by the Moodle admin in $CFG->maxbytes
|
|
|
|
|
* 6. by the teacher in the current course $course->maxbytes
|
|
|
|
|
* 7. by the teacher for the current module, eg $assignment->maxbytes
|
|
|
|
|
*
|
|
|
|
|
* These last two are passed to this function as arguments (in bytes).
|
|
|
|
|
* Anything defined as 0 is ignored.
|
|
|
|
|
* The smallest of all the non-zero numbers is returned.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $sizebytes ?
|
|
|
|
|
* @param int $coursebytes Current course $course->maxbytes (in bytes)
|
|
|
|
|
* @param int $modulebytes Current module ->maxbytes (in bytes)
|
|
|
|
|
* @return int The maximum size for uploading files.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2003-10-06 18:02:35 +00:00
|
|
|
|
function get_max_upload_file_size($sitebytes=0, $coursebytes=0, $modulebytes=0) {
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (! $filesize = ini_get('upload_max_filesize')) {
|
|
|
|
|
$filesize = '5M';
|
2002-09-01 14:29:17 +00:00
|
|
|
|
}
|
2003-10-06 18:02:35 +00:00
|
|
|
|
$minimumsize = get_real_size($filesize);
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($postsize = ini_get('post_max_size')) {
|
2003-12-02 14:34:24 +00:00
|
|
|
|
$postsize = get_real_size($postsize);
|
|
|
|
|
if ($postsize < $minimumsize) {
|
|
|
|
|
$minimumsize = $postsize;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 18:02:35 +00:00
|
|
|
|
if ($sitebytes and $sitebytes < $minimumsize) {
|
|
|
|
|
$minimumsize = $sitebytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($coursebytes and $coursebytes < $minimumsize) {
|
|
|
|
|
$minimumsize = $coursebytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($modulebytes and $modulebytes < $minimumsize) {
|
|
|
|
|
$minimumsize = $modulebytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $minimumsize;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* Related to {@link get_max_upload_file_size()} - this function returns an
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* array of possible sizes in an array, translated to the
|
|
|
|
|
* local language.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses SORT_NUMERIC
|
|
|
|
|
* @param int $sizebytes ?
|
|
|
|
|
* @param int $coursebytes Current course $course->maxbytes (in bytes)
|
|
|
|
|
* @param int $modulebytes Current module ->maxbytes (in bytes)
|
|
|
|
|
* @return int
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2003-10-06 18:02:35 +00:00
|
|
|
|
function get_max_upload_sizes($sitebytes=0, $coursebytes=0, $modulebytes=0) {
|
2007-04-16 15:56:38 +00:00
|
|
|
|
global $CFG;
|
2003-10-06 18:02:35 +00:00
|
|
|
|
|
|
|
|
|
if (!$maxsize = get_max_upload_file_size($sitebytes, $coursebytes, $modulebytes)) {
|
|
|
|
|
return array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$filesize[$maxsize] = display_size($maxsize);
|
|
|
|
|
|
2004-04-01 10:11:20 +00:00
|
|
|
|
$sizelist = array(10240, 51200, 102400, 512000, 1048576, 2097152,
|
2003-10-06 18:02:35 +00:00
|
|
|
|
5242880, 10485760, 20971520, 52428800, 104857600);
|
|
|
|
|
|
2007-04-16 15:56:38 +00:00
|
|
|
|
// Allow maxbytes to be selected if it falls outside the above boundaries
|
|
|
|
|
if( isset($CFG->maxbytes) && !in_array($CFG->maxbytes, $sizelist) ){
|
|
|
|
|
$sizelist[] = $CFG->maxbytes;
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 18:02:35 +00:00
|
|
|
|
foreach ($sizelist as $sizebytes) {
|
|
|
|
|
if ($sizebytes < $maxsize) {
|
|
|
|
|
$filesize[$sizebytes] = display_size($sizebytes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
krsort($filesize, SORT_NUMERIC);
|
|
|
|
|
|
|
|
|
|
return $filesize;
|
2002-09-01 14:29:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* If there has been an error uploading a file, print the appropriate error message
|
|
|
|
|
* Numerical constants used as constant definitions not added until PHP version 4.2.0
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* $filearray is a 1-dimensional sub-array of the $_FILES array
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* eg $filearray = $_FILES['userfile1']
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* If left empty then the first element of the $_FILES array will be used
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $_FILES
|
|
|
|
|
* @param array $filearray A 1-dimensional sub-array of the $_FILES array
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @param bool $returnerror If true then a string error message will be returned. Otherwise the user will be notified of the error in a notify() call.
|
|
|
|
|
* @return bool|string
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2004-09-06 04:28:07 +00:00
|
|
|
|
function print_file_upload_error($filearray = '', $returnerror = false) {
|
|
|
|
|
|
|
|
|
|
if ($filearray == '' or !isset($filearray['error'])) {
|
|
|
|
|
|
|
|
|
|
if (empty($_FILES)) return false;
|
|
|
|
|
|
|
|
|
|
$files = $_FILES; /// so we don't mess up the _FILES array for subsequent code
|
|
|
|
|
$filearray = array_shift($files); /// use first element of array
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch ($filearray['error']) {
|
|
|
|
|
|
|
|
|
|
case 0: // UPLOAD_ERR_OK
|
|
|
|
|
if ($filearray['size'] > 0) {
|
|
|
|
|
$errmessage = get_string('uploadproblem', $filearray['name']);
|
|
|
|
|
} else {
|
|
|
|
|
$errmessage = get_string('uploadnofilefound'); /// probably a dud file name
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1: // UPLOAD_ERR_INI_SIZE
|
|
|
|
|
$errmessage = get_string('uploadserverlimit');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2: // UPLOAD_ERR_FORM_SIZE
|
|
|
|
|
$errmessage = get_string('uploadformlimit');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3: // UPLOAD_ERR_PARTIAL
|
|
|
|
|
$errmessage = get_string('uploadpartialfile');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 4: // UPLOAD_ERR_NO_FILE
|
|
|
|
|
$errmessage = get_string('uploadnofilefound');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
$errmessage = get_string('uploadproblem', $filearray['name']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($returnerror) {
|
|
|
|
|
return $errmessage;
|
|
|
|
|
} else {
|
|
|
|
|
notify($errmessage);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-06 00:36:06 +00:00
|
|
|
|
/**
|
|
|
|
|
* handy function to loop through an array of files and resolve any filename conflicts
|
|
|
|
|
* both in the array of filenames and for what is already on disk.
|
|
|
|
|
* not really compatible with the similar function in uploadlib.php
|
|
|
|
|
* but this could be used for files/index.php for moving files around.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
function resolve_filename_collisions($destination,$files,$format='%s_%d.%s') {
|
|
|
|
|
foreach ($files as $k => $f) {
|
|
|
|
|
if (check_potential_filename($destination,$f,$files)) {
|
|
|
|
|
$bits = explode('.', $f);
|
|
|
|
|
for ($i = 1; true; $i++) {
|
|
|
|
|
$try = sprintf($format, $bits[0], $i, $bits[1]);
|
|
|
|
|
if (!check_potential_filename($destination,$try,$files)) {
|
|
|
|
|
$files[$k] = $try;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $files;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @used by resolve_filename_collisions
|
|
|
|
|
*/
|
|
|
|
|
function check_potential_filename($destination,$filename,$files) {
|
|
|
|
|
if (file_exists($destination.'/'.$filename)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (count(array_keys($files,$filename)) > 1) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an array with all the filenames in
|
|
|
|
|
* all subdirectories, relative to the given rootdir.
|
|
|
|
|
* If excludefile is defined, then that file/directory is ignored
|
|
|
|
|
* If getdirs is true, then (sub)directories are included in the output
|
|
|
|
|
* If getfiles is true, then files are included in the output
|
|
|
|
|
* (at least one of these must be true!)
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $rootdir ?
|
|
|
|
|
* @param string $excludefile If defined then the specified file/directory is ignored
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @param bool $descend ?
|
|
|
|
|
* @param bool $getdirs If true then (sub)directories are included in the output
|
|
|
|
|
* @param bool $getfiles If true then files are included in the output
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return array An array with all the filenames in
|
|
|
|
|
* all subdirectories, relative to the given rootdir
|
|
|
|
|
* @todo Finish documenting this function. Add examples of $excludefile usage.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2006-09-17 06:49:26 +00:00
|
|
|
|
function get_directory_list($rootdir, $excludefiles='', $descend=true, $getdirs=false, $getfiles=true) {
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
|
|
|
|
$dirs = array();
|
|
|
|
|
|
2004-05-16 08:52:32 +00:00
|
|
|
|
if (!$getdirs and !$getfiles) { // Nothing to show
|
2003-08-17 14:16:08 +00:00
|
|
|
|
return $dirs;
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-16 08:52:32 +00:00
|
|
|
|
if (!is_dir($rootdir)) { // Must be a directory
|
|
|
|
|
return $dirs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$dir = opendir($rootdir)) { // Can't open it for some reason
|
2002-11-10 07:37:15 +00:00
|
|
|
|
return $dirs;
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-17 06:49:26 +00:00
|
|
|
|
if (!is_array($excludefiles)) {
|
|
|
|
|
$excludefiles = array($excludefiles);
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-17 14:01:53 +00:00
|
|
|
|
while (false !== ($file = readdir($dir))) {
|
2003-01-28 03:34:26 +00:00
|
|
|
|
$firstchar = substr($file, 0, 1);
|
2006-09-17 06:49:26 +00:00
|
|
|
|
if ($firstchar == '.' or $file == 'CVS' or in_array($file, $excludefiles)) {
|
2003-01-28 03:34:26 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$fullfile = $rootdir .'/'. $file;
|
|
|
|
|
if (filetype($fullfile) == 'dir') {
|
2004-05-16 08:52:32 +00:00
|
|
|
|
if ($getdirs) {
|
2004-05-02 15:31:23 +00:00
|
|
|
|
$dirs[] = $file;
|
|
|
|
|
}
|
2004-05-04 01:21:17 +00:00
|
|
|
|
if ($descend) {
|
2006-09-17 06:49:26 +00:00
|
|
|
|
$subdirs = get_directory_list($fullfile, $excludefiles, $descend, $getdirs, $getfiles);
|
2004-05-04 01:21:17 +00:00
|
|
|
|
foreach ($subdirs as $subdir) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$dirs[] = $file .'/'. $subdir;
|
2004-05-04 01:21:17 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
2004-05-16 08:52:32 +00:00
|
|
|
|
} else if ($getfiles) {
|
2003-01-28 03:34:26 +00:00
|
|
|
|
$dirs[] = $file;
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-09-01 14:29:17 +00:00
|
|
|
|
closedir($dir);
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2002-09-07 14:57:33 +00:00
|
|
|
|
asort($dirs);
|
|
|
|
|
|
2001-11-22 06:23:56 +00:00
|
|
|
|
return $dirs;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-19 15:11:44 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Adds up all the files in a directory and works out the size.
|
|
|
|
|
*
|
|
|
|
|
* @param string $rootdir ?
|
|
|
|
|
* @param string $excludefile ?
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return array
|
2004-09-23 02:48:41 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-09-22 14:39:15 +00:00
|
|
|
|
function get_directory_size($rootdir, $excludefile='') {
|
2004-05-16 08:52:32 +00:00
|
|
|
|
|
2005-09-05 05:33:02 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
// do it this way if we can, it's much faster
|
|
|
|
|
if (!empty($CFG->pathtodu) && is_executable(trim($CFG->pathtodu))) {
|
2005-11-13 21:19:23 +00:00
|
|
|
|
$command = trim($CFG->pathtodu).' -sk --apparent-size '.escapeshellarg($rootdir);
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$output = null;
|
|
|
|
|
$return = null;
|
2005-09-05 05:33:02 +00:00
|
|
|
|
exec($command,$output,$return);
|
|
|
|
|
if (is_array($output)) {
|
|
|
|
|
return get_real_size(intval($output[0]).'k'); // we told it to return k.
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2004-05-16 08:52:32 +00:00
|
|
|
|
if (!is_dir($rootdir)) { // Must be a directory
|
2006-04-22 16:45:12 +00:00
|
|
|
|
return 0;
|
2004-05-16 08:52:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-05-22 04:02:02 +00:00
|
|
|
|
if (!$dir = @opendir($rootdir)) { // Can't open it for some reason
|
2006-04-22 16:45:12 +00:00
|
|
|
|
return 0;
|
2004-05-16 08:52:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-04-22 16:45:12 +00:00
|
|
|
|
$size = 0;
|
|
|
|
|
|
2004-05-16 08:52:32 +00:00
|
|
|
|
while (false !== ($file = readdir($dir))) {
|
|
|
|
|
$firstchar = substr($file, 0, 1);
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($firstchar == '.' or $file == 'CVS' or $file == $excludefile) {
|
2004-05-16 08:52:32 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$fullfile = $rootdir .'/'. $file;
|
|
|
|
|
if (filetype($fullfile) == 'dir') {
|
2004-05-16 08:52:32 +00:00
|
|
|
|
$size += get_directory_size($fullfile, $excludefile);
|
|
|
|
|
} else {
|
|
|
|
|
$size += filesize($fullfile);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
closedir($dir);
|
|
|
|
|
|
|
|
|
|
return $size;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Converts bytes into display form
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $size ?
|
|
|
|
|
* @return string
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @staticvar string $gb Localized string for size in gigabytes
|
|
|
|
|
* @staticvar string $mb Localized string for size in megabytes
|
|
|
|
|
* @staticvar string $kb Localized string for size in kilobytes
|
|
|
|
|
* @staticvar string $b Localized string for size in bytes
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @todo Finish documenting this function. Verify return type.
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-09-01 14:29:17 +00:00
|
|
|
|
function display_size($size) {
|
2003-10-06 18:02:35 +00:00
|
|
|
|
|
2004-09-23 02:48:41 +00:00
|
|
|
|
static $gb, $mb, $kb, $b;
|
2003-10-06 18:02:35 +00:00
|
|
|
|
|
|
|
|
|
if (empty($gb)) {
|
|
|
|
|
$gb = get_string('sizegb');
|
|
|
|
|
$mb = get_string('sizemb');
|
|
|
|
|
$kb = get_string('sizekb');
|
|
|
|
|
$b = get_string('sizeb');
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-01 14:29:17 +00:00
|
|
|
|
if ($size >= 1073741824) {
|
2003-10-06 18:02:35 +00:00
|
|
|
|
$size = round($size / 1073741824 * 10) / 10 . $gb;
|
2002-09-01 14:29:17 +00:00
|
|
|
|
} else if ($size >= 1048576) {
|
2003-10-06 18:02:35 +00:00
|
|
|
|
$size = round($size / 1048576 * 10) / 10 . $mb;
|
2002-09-01 14:29:17 +00:00
|
|
|
|
} else if ($size >= 1024) {
|
2003-10-06 18:02:35 +00:00
|
|
|
|
$size = round($size / 1024 * 10) / 10 . $kb;
|
2004-04-01 10:11:20 +00:00
|
|
|
|
} else {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$size = $size .' '. $b;
|
2002-09-01 14:29:17 +00:00
|
|
|
|
}
|
|
|
|
|
return $size;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 11:35:08 +00:00
|
|
|
|
/**
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* Cleans a given filename by removing suspicious or troublesome characters
|
2006-03-04 11:35:08 +00:00
|
|
|
|
* Only these are allowed: alphanumeric _ - .
|
|
|
|
|
* Unicode characters can be enabled by setting $CFG->unicodecleanfilename = true in config.php
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*
|
2006-03-04 11:35:08 +00:00
|
|
|
|
* WARNING: unicode characters may not be compatible with zip compression in backup/restore,
|
|
|
|
|
* because native zip binaries do weird character conversions. Use PHP zipping instead.
|
|
|
|
|
*
|
|
|
|
|
* @param string $string file name
|
|
|
|
|
* @return string cleaned file name
|
2004-09-23 02:48:41 +00:00
|
|
|
|
*/
|
2002-08-04 16:20:30 +00:00
|
|
|
|
function clean_filename($string) {
|
2006-03-04 11:35:08 +00:00
|
|
|
|
global $CFG;
|
2006-11-11 16:07:53 +00:00
|
|
|
|
if (empty($CFG->unicodecleanfilename)) {
|
2006-03-06 00:39:51 +00:00
|
|
|
|
$textlib = textlib_get_instance();
|
2006-11-11 16:07:53 +00:00
|
|
|
|
$string = $textlib->specialtoascii($string);
|
2006-03-04 11:35:08 +00:00
|
|
|
|
$string = preg_replace('/[^\.a-zA-Z\d\_-]/','_', $string ); // only allowed chars
|
|
|
|
|
} else {
|
|
|
|
|
//clean only ascii range
|
|
|
|
|
$string = preg_replace("/[\\000-\\x2c\\x2f\\x3a-\\x40\\x5b-\\x5e\\x60\\x7b-\\177]/s", '_', $string);
|
|
|
|
|
}
|
|
|
|
|
$string = preg_replace("/_+/", '_', $string);
|
|
|
|
|
$string = preg_replace("/\.\.+/", '.', $string);
|
2004-09-25 01:29:37 +00:00
|
|
|
|
return $string;
|
2002-08-04 16:20:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-06-27 08:47:27 +00:00
|
|
|
|
/// STRING TRANSLATION ////////////////////////////////////////
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the code for the current language
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param $USER
|
|
|
|
|
* @param $SESSION
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2002-10-02 10:33:05 +00:00
|
|
|
|
function current_language() {
|
2007-01-28 21:18:08 +00:00
|
|
|
|
global $CFG, $USER, $SESSION, $COURSE;
|
2002-10-02 10:33:05 +00:00
|
|
|
|
|
2007-02-23 20:25:16 +00:00
|
|
|
|
if (!empty($COURSE->id) and $COURSE->id != SITEID and !empty($COURSE->lang)) { // Course language can override all other settings for this page
|
2007-02-21 21:48:48 +00:00
|
|
|
|
$return = $COURSE->lang;
|
2004-02-09 07:31:04 +00:00
|
|
|
|
|
2004-02-15 14:33:13 +00:00
|
|
|
|
} else if (!empty($SESSION->lang)) { // Session language can override other settings
|
2006-09-25 06:04:02 +00:00
|
|
|
|
$return = $SESSION->lang;
|
2003-01-19 12:32:55 +00:00
|
|
|
|
|
2007-07-18 05:17:45 +00:00
|
|
|
|
} else if (!empty($USER->lang)) {
|
2006-09-25 06:04:02 +00:00
|
|
|
|
$return = $USER->lang;
|
2003-01-19 12:32:55 +00:00
|
|
|
|
|
2002-10-02 10:33:05 +00:00
|
|
|
|
} else {
|
2006-09-25 06:04:02 +00:00
|
|
|
|
$return = $CFG->lang;
|
2002-10-02 10:33:05 +00:00
|
|
|
|
}
|
2006-09-25 06:04:02 +00:00
|
|
|
|
|
|
|
|
|
if ($return == 'en') {
|
|
|
|
|
$return = 'en_utf8';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $return;
|
2002-10-02 10:33:05 +00:00
|
|
|
|
}
|
2002-07-04 07:49:38 +00:00
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* Prints out a translated string.
|
|
|
|
|
*
|
|
|
|
|
* Prints out a translated string using the return value from the {@link get_string()} function.
|
|
|
|
|
*
|
2007-01-04 23:38:17 +00:00
|
|
|
|
* Example usage of this function when the string is in the moodle.php file:<br/>
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* <code>
|
|
|
|
|
* echo '<strong>';
|
|
|
|
|
* print_string('wordforstudent');
|
|
|
|
|
* echo '</strong>';
|
|
|
|
|
* </code>
|
|
|
|
|
*
|
2007-01-04 23:38:17 +00:00
|
|
|
|
* Example usage of this function when the string is not in the moodle.php file:<br/>
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* <code>
|
|
|
|
|
* echo '<h1>';
|
|
|
|
|
* print_string('typecourse', 'calendar');
|
|
|
|
|
* echo '</h1>';
|
|
|
|
|
* </code>
|
|
|
|
|
*
|
|
|
|
|
* @param string $identifier The key identifier for the localized string
|
|
|
|
|
* @param string $module The module where the key identifier is stored. If none is specified then moodle.php is used.
|
|
|
|
|
* @param mixed $a An object, string or number that can be used
|
|
|
|
|
* within translation strings
|
2004-11-22 18:38:33 +00:00
|
|
|
|
*/
|
2004-09-22 14:39:15 +00:00
|
|
|
|
function print_string($identifier, $module='', $a=NULL) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
echo get_string($identifier, $module, $a);
|
|
|
|
|
}
|
|
|
|
|
|
2005-06-21 12:30:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* fix up the optional data in get_string()/print_string() etc
|
|
|
|
|
* ensure possible sprintf() format characters are escaped correctly
|
|
|
|
|
* needs to handle arbitrary strings and objects
|
|
|
|
|
* @param mixed $a An object, string or number that can be used
|
|
|
|
|
* @return mixed the supplied parameter 'cleaned'
|
|
|
|
|
*/
|
2005-06-23 09:04:16 +00:00
|
|
|
|
function clean_getstring_data( $a ) {
|
2005-06-21 12:30:34 +00:00
|
|
|
|
if (is_string($a)) {
|
|
|
|
|
return str_replace( '%','%%',$a );
|
|
|
|
|
}
|
|
|
|
|
elseif (is_object($a)) {
|
|
|
|
|
$a_vars = get_object_vars( $a );
|
|
|
|
|
$new_a_vars = array();
|
|
|
|
|
foreach ($a_vars as $fname => $a_var) {
|
2005-06-23 09:04:16 +00:00
|
|
|
|
$new_a_vars[$fname] = clean_getstring_data( $a_var );
|
2005-06-21 12:30:34 +00:00
|
|
|
|
}
|
|
|
|
|
return (object)$new_a_vars;
|
2006-03-04 16:53:02 +00:00
|
|
|
|
}
|
2005-06-21 12:30:34 +00:00
|
|
|
|
else {
|
|
|
|
|
return $a;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-18 05:17:45 +00:00
|
|
|
|
/**
|
|
|
|
|
* @return array places to look for lang strings based on the prefix to the
|
|
|
|
|
* module name. For example qtype_ in question/type. Used by get_string and
|
2007-03-14 20:15:20 +00:00
|
|
|
|
* help.php.
|
|
|
|
|
*/
|
|
|
|
|
function places_to_search_for_lang_strings() {
|
2007-03-14 21:56:09 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-03-14 20:15:20 +00:00
|
|
|
|
return array(
|
|
|
|
|
'__exceptions' => array('moodle', 'langconfig'),
|
|
|
|
|
'assignment_' => array('mod/assignment/type'),
|
|
|
|
|
'auth_' => array('auth'),
|
|
|
|
|
'block_' => array('blocks'),
|
|
|
|
|
'datafield_' => array('mod/data/field'),
|
|
|
|
|
'datapreset_' => array('mod/data/preset'),
|
|
|
|
|
'enrol_' => array('enrol'),
|
2007-12-04 11:47:28 +00:00
|
|
|
|
'filter_' => array('filter'),
|
2007-03-14 20:15:20 +00:00
|
|
|
|
'format_' => array('course/format'),
|
|
|
|
|
'qtype_' => array('question/type'),
|
|
|
|
|
'report_' => array($CFG->admin.'/report', 'course/report', 'mod/quiz/report'),
|
|
|
|
|
'resource_' => array('mod/resource/type'),
|
2007-08-10 12:21:55 +00:00
|
|
|
|
'gradereport_' => array('grade/report'),
|
|
|
|
|
'gradeimport_' => array('grade/import'),
|
|
|
|
|
'gradeexport_' => array('grade/export'),
|
2007-11-09 19:11:40 +00:00
|
|
|
|
'profilefield_' => array('user/profile/field'),
|
2007-03-14 20:15:20 +00:00
|
|
|
|
'' => array('mod')
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* Returns a localized string.
|
|
|
|
|
*
|
|
|
|
|
* Returns the translated string specified by $identifier as
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* for $module. Uses the same format files as STphp.
|
|
|
|
|
* $a is an object, string or number that can be used
|
|
|
|
|
* within translation strings
|
|
|
|
|
*
|
|
|
|
|
* eg "hello \$a->firstname \$a->lastname"
|
|
|
|
|
* or "hello \$a"
|
|
|
|
|
*
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* If you would like to directly echo the localized string use
|
|
|
|
|
* the function {@link print_string()}
|
|
|
|
|
*
|
|
|
|
|
* Example usage of this function involves finding the string you would
|
|
|
|
|
* like a local equivalent of and using its identifier and module information
|
2007-01-04 23:38:17 +00:00
|
|
|
|
* to retrive it.<br/>
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* If you open moodle/lang/en/moodle.php and look near line 1031
|
|
|
|
|
* you will find a string to prompt a user for their word for student
|
|
|
|
|
* <code>
|
|
|
|
|
* $string['wordforstudent'] = 'Your word for Student';
|
|
|
|
|
* </code>
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* So if you want to display the string 'Your word for student'
|
|
|
|
|
* in any language that supports it on your site
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* you just need to use the identifier 'wordforstudent'
|
|
|
|
|
* <code>
|
|
|
|
|
* $mystring = '<strong>'. get_string('wordforstudent') .'</strong>';
|
|
|
|
|
or
|
|
|
|
|
* </code>
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* If the string you want is in another file you'd take a slightly
|
|
|
|
|
* different approach. Looking in moodle/lang/en/calendar.php you find
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* around line 75:
|
|
|
|
|
* <code>
|
|
|
|
|
* $string['typecourse'] = 'Course event';
|
|
|
|
|
* </code>
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* If you want to display the string "Course event" in any language
|
|
|
|
|
* supported you would use the identifier 'typecourse' and the module 'calendar'
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* (because it is in the file calendar.php):
|
|
|
|
|
* <code>
|
|
|
|
|
* $mystring = '<h1>'. get_string('typecourse', 'calendar') .'</h1>';
|
|
|
|
|
* </code>
|
|
|
|
|
*
|
|
|
|
|
* As a last resort, should the identifier fail to map to a string
|
|
|
|
|
* the returned string will be [[ $identifier ]]
|
|
|
|
|
*
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @uses $CFG
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* @param string $identifier The key identifier for the localized string
|
|
|
|
|
* @param string $module The module where the key identifier is stored. If none is specified then moodle.php is used.
|
|
|
|
|
* @param mixed $a An object, string or number that can be used
|
|
|
|
|
* within translation strings
|
2006-10-02 15:08:25 +00:00
|
|
|
|
* @param array $extralocations An array of strings with other locations to look for string files
|
2004-10-04 16:44:54 +00:00
|
|
|
|
* @return string The localized string.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2006-10-02 15:08:25 +00:00
|
|
|
|
function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
|
2002-06-27 08:47:27 +00:00
|
|
|
|
|
2002-10-02 10:33:05 +00:00
|
|
|
|
global $CFG;
|
2002-06-27 08:47:27 +00:00
|
|
|
|
|
2006-11-11 16:07:53 +00:00
|
|
|
|
/// originally these special strings were stored in moodle.php now we are only in langconfig.php
|
2007-08-10 15:00:35 +00:00
|
|
|
|
$langconfigstrs = array('alphabet', 'backupnameformat', 'decsep', 'firstdayofweek', 'listsep', 'locale',
|
2006-03-25 12:26:33 +00:00
|
|
|
|
'localewin', 'localewincharset', 'oldcharset',
|
2006-01-04 08:23:42 +00:00
|
|
|
|
'parentlanguage', 'strftimedate', 'strftimedateshort', 'strftimedatetime',
|
|
|
|
|
'strftimedaydate', 'strftimedaydatetime', 'strftimedayshort', 'strftimedaytime',
|
|
|
|
|
'strftimemonthyear', 'strftimerecent', 'strftimerecentfull', 'strftimetime',
|
2008-05-08 03:49:51 +00:00
|
|
|
|
'thischarset', 'thisdirection', 'thislanguage', 'strftimedatetimeshort');
|
2006-01-04 08:23:42 +00:00
|
|
|
|
|
2006-11-11 16:07:53 +00:00
|
|
|
|
$filetocheck = 'langconfig.php';
|
|
|
|
|
$defaultlang = 'en_utf8';
|
|
|
|
|
if (in_array($identifier, $langconfigstrs)) {
|
|
|
|
|
$module = 'langconfig'; //This strings are under langconfig.php for 1.6 lang packs
|
2006-01-04 08:23:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-10-02 10:33:05 +00:00
|
|
|
|
$lang = current_language();
|
2002-06-27 08:47:27 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($module == '') {
|
|
|
|
|
$module = 'moodle';
|
2002-06-27 08:47:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-06-20 09:15:30 +00:00
|
|
|
|
// if $a happens to have % in it, double it so sprintf() doesn't break
|
2005-06-23 09:04:16 +00:00
|
|
|
|
if ($a) {
|
|
|
|
|
$a = clean_getstring_data( $a );
|
|
|
|
|
}
|
2005-06-20 09:15:30 +00:00
|
|
|
|
|
2005-01-10 14:11:13 +00:00
|
|
|
|
/// Define the two or three major locations of language strings for this module
|
2006-10-02 15:08:25 +00:00
|
|
|
|
$locations = array();
|
|
|
|
|
|
|
|
|
|
if (!empty($extralocations)) { // Calling code has a good idea where to look
|
2006-10-02 15:15:23 +00:00
|
|
|
|
if (is_array($extralocations)) {
|
|
|
|
|
$locations += $extralocations;
|
|
|
|
|
} else if (is_string($extralocations)) {
|
|
|
|
|
$locations[] = $extralocations;
|
|
|
|
|
} else {
|
|
|
|
|
debugging('Bad lang path provided');
|
|
|
|
|
}
|
2006-10-02 15:08:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-09 17:43:14 +00:00
|
|
|
|
if (isset($CFG->running_installer)) {
|
|
|
|
|
$module = 'installer';
|
|
|
|
|
$filetocheck = 'installer.php';
|
2007-08-24 06:01:15 +00:00
|
|
|
|
$locations[] = $CFG->dirroot.'/install/lang/';
|
|
|
|
|
$locations[] = $CFG->dataroot.'/lang/';
|
|
|
|
|
$locations[] = $CFG->dirroot.'/lang/';
|
2006-03-09 17:43:14 +00:00
|
|
|
|
$defaultlang = 'en_utf8';
|
2005-07-25 11:26:03 +00:00
|
|
|
|
} else {
|
2007-08-24 06:01:15 +00:00
|
|
|
|
$locations[] = $CFG->dataroot.'/lang/';
|
|
|
|
|
$locations[] = $CFG->dirroot.'/lang/';
|
2008-01-15 01:40:02 +00:00
|
|
|
|
$locations[] = $CFG->dirroot.'/local/lang/';
|
2005-07-25 11:26:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-03-06 07:57:22 +00:00
|
|
|
|
/// Add extra places to look for strings for particular plugin types.
|
2007-03-14 20:15:20 +00:00
|
|
|
|
$rules = places_to_search_for_lang_strings();
|
|
|
|
|
$exceptions = $rules['__exceptions'];
|
|
|
|
|
unset($rules['__exceptions']);
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-03-14 20:15:20 +00:00
|
|
|
|
if (!in_array($module, $exceptions)) {
|
|
|
|
|
$dividerpos = strpos($module, '_');
|
|
|
|
|
if ($dividerpos === false) {
|
|
|
|
|
$type = '';
|
|
|
|
|
$plugin = $module;
|
|
|
|
|
} else {
|
|
|
|
|
$type = substr($module, 0, $dividerpos + 1);
|
|
|
|
|
$plugin = substr($module, $dividerpos + 1);
|
|
|
|
|
}
|
|
|
|
|
if (!empty($rules[$type])) {
|
|
|
|
|
foreach ($rules[$type] as $location) {
|
|
|
|
|
$locations[] = $CFG->dirroot . "/$location/$plugin/lang/";
|
|
|
|
|
}
|
2005-03-14 13:08:16 +00:00
|
|
|
|
}
|
2002-06-27 08:47:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-10 14:11:13 +00:00
|
|
|
|
/// First check all the normal locations for the string in the current language
|
2007-03-06 07:57:22 +00:00
|
|
|
|
$resultstring = '';
|
2005-01-10 14:11:13 +00:00
|
|
|
|
foreach ($locations as $location) {
|
2005-12-21 02:06:25 +00:00
|
|
|
|
$locallangfile = $location.$lang.'_local'.'/'.$module.'.php'; //first, see if there's a local file
|
|
|
|
|
if (file_exists($locallangfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
|
2008-02-21 06:01:01 +00:00
|
|
|
|
if (eval($result) === FALSE) {
|
|
|
|
|
trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
|
|
|
|
|
}
|
2005-12-21 02:06:25 +00:00
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//if local directory not found, or particular string does not exist in local direcotry
|
2005-01-11 12:24:37 +00:00
|
|
|
|
$langfile = $location.$lang.'/'.$module.'.php';
|
2004-05-24 09:19:59 +00:00
|
|
|
|
if (file_exists($langfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
|
2008-02-21 06:01:01 +00:00
|
|
|
|
if (eval($result) === FALSE) {
|
|
|
|
|
trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
|
|
|
|
|
}
|
2004-05-24 09:19:59 +00:00
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
2007-08-24 06:01:15 +00:00
|
|
|
|
}
|
2004-05-24 09:19:59 +00:00
|
|
|
|
}
|
2002-06-27 08:47:27 +00:00
|
|
|
|
|
2006-02-06 13:45:00 +00:00
|
|
|
|
/// If the preferred language was English (utf8) we can abort now
|
|
|
|
|
/// saving some checks beacuse it's the only "root" lang
|
|
|
|
|
if ($lang == 'en_utf8') {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return '[['. $identifier .']]';
|
2003-06-12 03:27:24 +00:00
|
|
|
|
}
|
2002-06-27 08:47:27 +00:00
|
|
|
|
|
2005-01-10 14:11:13 +00:00
|
|
|
|
/// Is a parent language defined? If so, try to find this string in a parent language file
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2005-01-10 14:11:13 +00:00
|
|
|
|
foreach ($locations as $location) {
|
2006-01-04 08:23:42 +00:00
|
|
|
|
$langfile = $location.$lang.'/'.$filetocheck;
|
2005-01-11 12:24:37 +00:00
|
|
|
|
if (file_exists($langfile)) {
|
|
|
|
|
if ($result = get_string_from_file('parentlanguage', $langfile, "\$parentlang")) {
|
|
|
|
|
eval($result);
|
|
|
|
|
if (!empty($parentlang)) { // found it!
|
2005-12-21 02:06:25 +00:00
|
|
|
|
|
|
|
|
|
//first, see if there's a local file for parent
|
2006-03-04 16:53:02 +00:00
|
|
|
|
$locallangfile = $location.$parentlang.'_local'.'/'.$module.'.php';
|
2005-12-21 02:06:25 +00:00
|
|
|
|
if (file_exists($locallangfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
|
|
|
|
|
eval($result);
|
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//if local directory not found, or particular string does not exist in local direcotry
|
2005-01-11 12:24:37 +00:00
|
|
|
|
$langfile = $location.$parentlang.'/'.$module.'.php';
|
|
|
|
|
if (file_exists($langfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
|
|
|
|
|
eval($result);
|
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
2005-01-10 14:11:13 +00:00
|
|
|
|
}
|
2003-06-12 03:27:24 +00:00
|
|
|
|
}
|
2002-06-27 08:47:27 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-06-12 03:27:24 +00:00
|
|
|
|
|
2005-01-10 14:11:13 +00:00
|
|
|
|
/// Our only remaining option is to try English
|
2003-06-12 03:27:24 +00:00
|
|
|
|
|
2005-01-10 14:11:13 +00:00
|
|
|
|
foreach ($locations as $location) {
|
2006-01-04 08:23:42 +00:00
|
|
|
|
$locallangfile = $location.$defaultlang.'_local/'.$module.'.php'; //first, see if there's a local file
|
2005-12-21 02:06:25 +00:00
|
|
|
|
if (file_exists($locallangfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
|
|
|
|
|
eval($result);
|
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-06-12 03:27:24 +00:00
|
|
|
|
|
2005-12-21 02:06:25 +00:00
|
|
|
|
//if local_en not found, or string not found in local_en
|
2006-01-04 08:23:42 +00:00
|
|
|
|
$langfile = $location.$defaultlang.'/'.$module.'.php';
|
|
|
|
|
|
2004-05-24 09:19:59 +00:00
|
|
|
|
if (file_exists($langfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
|
|
|
|
|
eval($result);
|
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 16:53:02 +00:00
|
|
|
|
/// And, because under 1.6 en is defined as en_utf8 child, me must try
|
2006-02-07 00:08:47 +00:00
|
|
|
|
/// if it hasn't been queried before.
|
|
|
|
|
if ($defaultlang == 'en') {
|
|
|
|
|
$defaultlang = 'en_utf8';
|
|
|
|
|
foreach ($locations as $location) {
|
|
|
|
|
$locallangfile = $location.$defaultlang.'_local/'.$module.'.php'; //first, see if there's a local file
|
|
|
|
|
if (file_exists($locallangfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
|
|
|
|
|
eval($result);
|
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//if local_en not found, or string not found in local_en
|
|
|
|
|
$langfile = $location.$defaultlang.'/'.$module.'.php';
|
|
|
|
|
|
|
|
|
|
if (file_exists($langfile)) {
|
|
|
|
|
if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
|
|
|
|
|
eval($result);
|
|
|
|
|
return $resultstring;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-10 14:11:13 +00:00
|
|
|
|
return '[['.$identifier.']]'; // Last resort
|
2002-06-27 08:47:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* This function is only used from {@link get_string()}.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2004-09-28 16:40:26 +00:00
|
|
|
|
* @internal Only used from get_string, not meant to be public API
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $identifier ?
|
|
|
|
|
* @param string $langfile ?
|
|
|
|
|
* @param string $destination ?
|
|
|
|
|
* @return string|false ?
|
2004-09-25 05:29:21 +00:00
|
|
|
|
* @staticvar array $strings Localized strings
|
2004-09-28 16:40:26 +00:00
|
|
|
|
* @access private
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @todo Finish documenting this function.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2002-06-27 08:47:27 +00:00
|
|
|
|
function get_string_from_file($identifier, $langfile, $destination) {
|
2003-07-03 12:19:54 +00:00
|
|
|
|
|
|
|
|
|
static $strings; // Keep the strings cached in memory.
|
|
|
|
|
|
|
|
|
|
if (empty($strings[$langfile])) {
|
2004-05-16 09:28:41 +00:00
|
|
|
|
$string = array();
|
2003-07-03 12:19:54 +00:00
|
|
|
|
include ($langfile);
|
|
|
|
|
$strings[$langfile] = $string;
|
|
|
|
|
} else {
|
|
|
|
|
$string = &$strings[$langfile];
|
|
|
|
|
}
|
2002-06-27 08:47:27 +00:00
|
|
|
|
|
|
|
|
|
if (!isset ($string[$identifier])) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return $destination .'= sprintf("'. $string[$identifier] .'");';
|
2002-06-27 08:47:27 +00:00
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Converts an array of strings to their localized value.
|
|
|
|
|
*
|
|
|
|
|
* @param array $array An array of strings
|
|
|
|
|
* @param string $module The language module that these strings can be found in.
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2004-07-25 13:48:55 +00:00
|
|
|
|
function get_strings($array, $module='') {
|
|
|
|
|
|
|
|
|
|
$string = NULL;
|
|
|
|
|
foreach ($array as $item) {
|
|
|
|
|
$string->$item = get_string($item, $module);
|
|
|
|
|
}
|
|
|
|
|
return $string;
|
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a list of language codes and their full names
|
2005-12-21 02:06:25 +00:00
|
|
|
|
* hides the _local files from everyone.
|
2007-04-24 16:14:16 +00:00
|
|
|
|
* @param bool refreshcache force refreshing of lang cache
|
2007-04-24 16:33:06 +00:00
|
|
|
|
* @param bool returnall ignore langlist, return all languages available
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return array An associative array with contents in the form of LanguageCode => LanguageName
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2007-04-24 16:33:06 +00:00
|
|
|
|
function get_list_of_languages($refreshcache=false, $returnall=false) {
|
2006-02-06 04:03:30 +00:00
|
|
|
|
|
2002-09-14 03:43:24 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2003-05-03 06:50:29 +00:00
|
|
|
|
$languages = array();
|
|
|
|
|
|
2006-11-11 16:07:53 +00:00
|
|
|
|
$filetocheck = 'langconfig.php';
|
2006-01-04 08:23:42 +00:00
|
|
|
|
|
2007-04-24 16:33:06 +00:00
|
|
|
|
if (!$refreshcache && !$returnall && !empty($CFG->langcache) && file_exists($CFG->dataroot .'/cache/languages')) {
|
2007-04-24 16:14:16 +00:00
|
|
|
|
/// read available langs from cache
|
2006-02-06 04:03:30 +00:00
|
|
|
|
|
2005-04-11 06:41:08 +00:00
|
|
|
|
$lines = file($CFG->dataroot .'/cache/languages');
|
|
|
|
|
foreach ($lines as $line) {
|
|
|
|
|
$line = trim($line);
|
|
|
|
|
if (preg_match('/^(\w+)\s+(.+)/', $line, $matches)) {
|
|
|
|
|
$languages[$matches[1]] = $matches[2];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unset($lines); unset($line); unset($matches);
|
|
|
|
|
return $languages;
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-24 16:33:06 +00:00
|
|
|
|
if (!$returnall && !empty($CFG->langlist)) {
|
2007-04-24 16:14:16 +00:00
|
|
|
|
/// return only languages allowed in langlist admin setting
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2003-05-03 06:50:29 +00:00
|
|
|
|
$langlist = explode(',', $CFG->langlist);
|
2007-04-24 14:58:43 +00:00
|
|
|
|
// fix short lang names first - non existing langs are skipped anyway...
|
|
|
|
|
foreach ($langlist as $lang) {
|
|
|
|
|
if (strpos($lang, '_utf8') === false) {
|
|
|
|
|
$langlist[] = $lang.'_utf8';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// find existing langs from langlist
|
2003-05-03 06:50:29 +00:00
|
|
|
|
foreach ($langlist as $lang) {
|
2006-01-04 08:23:42 +00:00
|
|
|
|
$lang = trim($lang); //Just trim spaces to be a bit more permissive
|
2006-04-15 17:30:23 +00:00
|
|
|
|
if (strstr($lang, '_local')!==false) {
|
2006-01-04 08:23:42 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2006-04-10 22:53:53 +00:00
|
|
|
|
if (substr($lang, -5) == '_utf8') { //Remove the _utf8 suffix from the lang to show
|
|
|
|
|
$shortlang = substr($lang, 0, -5);
|
|
|
|
|
} else {
|
|
|
|
|
$shortlang = $lang;
|
|
|
|
|
}
|
2006-01-04 08:23:42 +00:00
|
|
|
|
/// Search under dirroot/lang
|
|
|
|
|
if (file_exists($CFG->dirroot .'/lang/'. $lang .'/'. $filetocheck)) {
|
|
|
|
|
include($CFG->dirroot .'/lang/'. $lang .'/'. $filetocheck);
|
|
|
|
|
if (!empty($string['thislanguage'])) {
|
2006-04-10 22:53:53 +00:00
|
|
|
|
$languages[$lang] = $string['thislanguage'].' ('. $shortlang .')';
|
2006-01-04 08:23:42 +00:00
|
|
|
|
}
|
|
|
|
|
unset($string);
|
|
|
|
|
}
|
|
|
|
|
/// And moodledata/lang
|
|
|
|
|
if (file_exists($CFG->dataroot .'/lang/'. $lang .'/'. $filetocheck)) {
|
|
|
|
|
include($CFG->dataroot .'/lang/'. $lang .'/'. $filetocheck);
|
|
|
|
|
if (!empty($string['thislanguage'])) {
|
2006-04-10 22:53:53 +00:00
|
|
|
|
$languages[$lang] = $string['thislanguage'].' ('. $shortlang .')';
|
2006-01-04 08:23:42 +00:00
|
|
|
|
}
|
2003-05-03 06:50:29 +00:00
|
|
|
|
unset($string);
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-04-24 16:14:16 +00:00
|
|
|
|
|
2003-05-03 06:50:29 +00:00
|
|
|
|
} else {
|
2007-04-24 16:14:16 +00:00
|
|
|
|
/// return all languages available in system
|
2006-01-04 08:23:42 +00:00
|
|
|
|
/// Fetch langs from moodle/lang directory
|
|
|
|
|
$langdirs = get_list_of_plugins('lang');
|
|
|
|
|
/// Fetch langs from moodledata/lang directory
|
|
|
|
|
$langdirs2 = get_list_of_plugins('lang', '', $CFG->dataroot);
|
|
|
|
|
/// Merge both lists of langs
|
|
|
|
|
$langdirs = array_merge($langdirs, $langdirs2);
|
|
|
|
|
/// Sort all
|
|
|
|
|
asort($langdirs);
|
|
|
|
|
/// Get some info from each lang (first from moodledata, then from moodle)
|
2003-05-03 06:50:29 +00:00
|
|
|
|
foreach ($langdirs as $lang) {
|
2006-04-15 17:30:23 +00:00
|
|
|
|
if (strstr($lang, '_local')!==false) {
|
2005-12-21 02:06:25 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2006-04-10 22:53:53 +00:00
|
|
|
|
if (substr($lang, -5) == '_utf8') { //Remove the _utf8 suffix from the lang to show
|
|
|
|
|
$shortlang = substr($lang, 0, -5);
|
|
|
|
|
} else {
|
|
|
|
|
$shortlang = $lang;
|
|
|
|
|
}
|
2006-03-29 16:18:46 +00:00
|
|
|
|
/// Search under moodledata/lang
|
2006-01-04 08:23:42 +00:00
|
|
|
|
if (file_exists($CFG->dataroot .'/lang/'. $lang .'/'. $filetocheck)) {
|
|
|
|
|
include($CFG->dataroot .'/lang/'. $lang .'/'. $filetocheck);
|
|
|
|
|
if (!empty($string['thislanguage'])) {
|
2006-04-10 22:53:53 +00:00
|
|
|
|
$languages[$lang] = $string['thislanguage'] .' ('. $shortlang .')';
|
2006-01-04 08:23:42 +00:00
|
|
|
|
}
|
2005-12-21 02:06:25 +00:00
|
|
|
|
unset($string);
|
2006-01-13 14:43:51 +00:00
|
|
|
|
}
|
2006-03-29 16:18:46 +00:00
|
|
|
|
/// And dirroot/lang
|
2006-01-13 14:43:51 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/lang/'. $lang .'/'. $filetocheck)) {
|
2006-01-04 08:23:42 +00:00
|
|
|
|
include($CFG->dirroot .'/lang/'. $lang .'/'. $filetocheck);
|
|
|
|
|
if (!empty($string['thislanguage'])) {
|
2006-04-10 22:53:53 +00:00
|
|
|
|
$languages[$lang] = $string['thislanguage'] .' ('. $shortlang .')';
|
2006-01-04 08:23:42 +00:00
|
|
|
|
}
|
2005-07-12 11:35:30 +00:00
|
|
|
|
unset($string);
|
|
|
|
|
}
|
2003-05-03 06:50:29 +00:00
|
|
|
|
}
|
2002-09-14 03:43:24 +00:00
|
|
|
|
}
|
2006-01-04 08:23:42 +00:00
|
|
|
|
|
2007-04-24 16:14:16 +00:00
|
|
|
|
if ($refreshcache && !empty($CFG->langcache)) {
|
2007-04-24 16:33:06 +00:00
|
|
|
|
if ($returnall) {
|
2007-04-24 16:14:16 +00:00
|
|
|
|
// we have a list of all langs only, just delete old cache
|
|
|
|
|
@unlink($CFG->dataroot.'/cache/languages');
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// store the list of allowed languages
|
|
|
|
|
if ($file = fopen($CFG->dataroot .'/cache/languages', 'w')) {
|
|
|
|
|
foreach ($languages as $key => $value) {
|
|
|
|
|
fwrite($file, "$key $value\n");
|
|
|
|
|
}
|
|
|
|
|
fclose($file);
|
2005-04-11 06:41:08 +00:00
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
}
|
2005-04-11 06:41:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-09-14 03:43:24 +00:00
|
|
|
|
return $languages;
|
|
|
|
|
}
|
|
|
|
|
|
2006-01-05 16:04:26 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a list of charset codes. It's hardcoded, so they should be added manually
|
|
|
|
|
* (cheking that such charset is supported by the texlib library!)
|
|
|
|
|
*
|
|
|
|
|
* @return array And associative array with contents in the form of charset => charset
|
|
|
|
|
*/
|
|
|
|
|
function get_list_of_charsets() {
|
|
|
|
|
|
|
|
|
|
$charsets = array(
|
|
|
|
|
'EUC-JP' => 'EUC-JP',
|
|
|
|
|
'ISO-2022-JP'=> 'ISO-2022-JP',
|
|
|
|
|
'ISO-8859-1' => 'ISO-8859-1',
|
|
|
|
|
'SHIFT-JIS' => 'SHIFT-JIS',
|
2006-04-20 08:21:58 +00:00
|
|
|
|
'GB2312' => 'GB2312',
|
2007-03-08 00:10:49 +00:00
|
|
|
|
'GB18030' => 'GB18030', // gb18030 not supported by typo and mbstring
|
2006-01-05 16:04:26 +00:00
|
|
|
|
'UTF-8' => 'UTF-8');
|
|
|
|
|
|
|
|
|
|
asort($charsets);
|
|
|
|
|
|
|
|
|
|
return $charsets;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a list of country names in the current language
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $USER
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @return array
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2003-09-26 08:04:48 +00:00
|
|
|
|
function get_list_of_countries() {
|
|
|
|
|
global $CFG, $USER;
|
|
|
|
|
|
|
|
|
|
$lang = current_language();
|
|
|
|
|
|
2006-01-04 08:23:42 +00:00
|
|
|
|
if (!file_exists($CFG->dirroot .'/lang/'. $lang .'/countries.php') &&
|
|
|
|
|
!file_exists($CFG->dataroot.'/lang/'. $lang .'/countries.php')) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($parentlang = get_string('parentlanguage')) {
|
2006-01-04 08:23:42 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/lang/'. $parentlang .'/countries.php') ||
|
|
|
|
|
file_exists($CFG->dataroot.'/lang/'. $parentlang .'/countries.php')) {
|
2003-09-26 08:21:11 +00:00
|
|
|
|
$lang = $parentlang;
|
|
|
|
|
} else {
|
2006-09-03 11:38:45 +00:00
|
|
|
|
$lang = 'en_utf8'; // countries.php must exist in this pack
|
2003-09-26 08:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2006-09-03 11:38:45 +00:00
|
|
|
|
$lang = 'en_utf8'; // countries.php must exist in this pack
|
2003-09-26 08:21:11 +00:00
|
|
|
|
}
|
2003-09-26 08:04:48 +00:00
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2006-01-04 08:23:42 +00:00
|
|
|
|
if (file_exists($CFG->dataroot .'/lang/'. $lang .'/countries.php')) {
|
|
|
|
|
include($CFG->dataroot .'/lang/'. $lang .'/countries.php');
|
|
|
|
|
} else if (file_exists($CFG->dirroot .'/lang/'. $lang .'/countries.php')) {
|
|
|
|
|
include($CFG->dirroot .'/lang/'. $lang .'/countries.php');
|
|
|
|
|
}
|
2003-09-26 08:04:48 +00:00
|
|
|
|
|
2003-11-17 02:19:13 +00:00
|
|
|
|
if (!empty($string)) {
|
2008-02-06 06:18:06 +00:00
|
|
|
|
uasort($string, 'strcoll');
|
2003-11-17 02:19:13 +00:00
|
|
|
|
}
|
2003-09-26 08:04:48 +00:00
|
|
|
|
|
|
|
|
|
return $string;
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-10 10:28:27 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a list of valid and compatible themes
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
function get_list_of_themes() {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$themes = array();
|
|
|
|
|
|
|
|
|
|
if (!empty($CFG->themelist)) { // use admin's list of themes
|
|
|
|
|
$themelist = explode(',', $CFG->themelist);
|
|
|
|
|
} else {
|
|
|
|
|
$themelist = get_list_of_plugins("theme");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ($themelist as $key => $theme) {
|
2006-10-09 10:12:41 +00:00
|
|
|
|
if (!file_exists("$CFG->themedir/$theme/config.php")) { // bad folder
|
2005-02-10 10:28:27 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$THEME = new object(); // Note this is not the global one!! :-)
|
2006-10-09 10:12:41 +00:00
|
|
|
|
include("$CFG->themedir/$theme/config.php");
|
2005-02-10 10:28:27 +00:00
|
|
|
|
if (!isset($THEME->sheets)) { // Not a valid 1.5 theme
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$themes[$theme] = $theme;
|
|
|
|
|
}
|
|
|
|
|
asort($themes);
|
|
|
|
|
|
|
|
|
|
return $themes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2006-07-31 10:28:12 +00:00
|
|
|
|
* Returns a list of picture names in the current or specified language
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @return array
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2006-07-31 10:28:12 +00:00
|
|
|
|
function get_list_of_pixnames($lang = '') {
|
2003-11-07 15:11:34 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2006-07-31 10:28:12 +00:00
|
|
|
|
if (empty($lang)) {
|
|
|
|
|
$lang = current_language();
|
|
|
|
|
}
|
2003-11-07 15:11:34 +00:00
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$string = array();
|
|
|
|
|
|
2006-07-31 10:28:12 +00:00
|
|
|
|
$path = $CFG->dirroot .'/lang/en_utf8/pix.php'; // always exists
|
|
|
|
|
|
|
|
|
|
if (file_exists($CFG->dataroot .'/lang/'. $lang .'_local/pix.php')) {
|
|
|
|
|
$path = $CFG->dataroot .'/lang/'. $lang .'_local/pix.php';
|
|
|
|
|
|
|
|
|
|
} else if (file_exists($CFG->dirroot .'/lang/'. $lang .'/pix.php')) {
|
|
|
|
|
$path = $CFG->dirroot .'/lang/'. $lang .'/pix.php';
|
|
|
|
|
|
|
|
|
|
} else if (file_exists($CFG->dataroot .'/lang/'. $lang .'/pix.php')) {
|
|
|
|
|
$path = $CFG->dataroot .'/lang/'. $lang .'/pix.php';
|
|
|
|
|
|
2006-12-01 09:48:40 +00:00
|
|
|
|
} else if ($parentlang = get_string('parentlanguage') and $parentlang != '[[parentlanguage]]') {
|
2006-07-31 10:28:12 +00:00
|
|
|
|
return get_list_of_pixnames($parentlang); //return pixnames from parent language instead
|
2003-11-07 15:11:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-31 10:28:12 +00:00
|
|
|
|
include($path);
|
2003-11-07 15:11:34 +00:00
|
|
|
|
|
|
|
|
|
return $string;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-10 17:35:17 +00:00
|
|
|
|
/**
|
2006-03-01 14:03:56 +00:00
|
|
|
|
* Returns a list of timezones in the current language
|
2005-04-10 17:35:17 +00:00
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2005-07-12 03:09:25 +00:00
|
|
|
|
* @return array
|
2005-04-10 17:35:17 +00:00
|
|
|
|
*/
|
|
|
|
|
function get_list_of_timezones() {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-07-11 09:11:44 +00:00
|
|
|
|
static $timezones;
|
|
|
|
|
|
|
|
|
|
if (!empty($timezones)) { // This function has been called recently
|
|
|
|
|
return $timezones;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-10 17:51:48 +00:00
|
|
|
|
$timezones = array();
|
|
|
|
|
|
2005-05-20 00:50:45 +00:00
|
|
|
|
if ($rawtimezones = get_records_sql('SELECT MAX(id), name FROM '.$CFG->prefix.'timezone GROUP BY name')) {
|
2005-04-10 17:51:48 +00:00
|
|
|
|
foreach($rawtimezones as $timezone) {
|
|
|
|
|
if (!empty($timezone->name)) {
|
|
|
|
|
$timezones[$timezone->name] = get_string(strtolower($timezone->name), 'timezones');
|
|
|
|
|
if (substr($timezones[$timezone->name], 0, 1) == '[') { // No translation found
|
|
|
|
|
$timezones[$timezone->name] = $timezone->name;
|
|
|
|
|
}
|
2005-04-10 17:35:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-20 00:50:45 +00:00
|
|
|
|
asort($timezones);
|
2005-04-10 17:35:17 +00:00
|
|
|
|
|
|
|
|
|
for ($i = -13; $i <= 13; $i += .5) {
|
2007-11-22 06:28:58 +00:00
|
|
|
|
$tzstring = 'UTC';
|
2005-04-10 17:35:17 +00:00
|
|
|
|
if ($i < 0) {
|
2005-04-10 17:51:48 +00:00
|
|
|
|
$timezones[sprintf("%.1f", $i)] = $tzstring . $i;
|
2005-04-10 17:35:17 +00:00
|
|
|
|
} else if ($i > 0) {
|
2005-04-10 17:51:48 +00:00
|
|
|
|
$timezones[sprintf("%.1f", $i)] = $tzstring . '+' . $i;
|
2005-04-10 17:35:17 +00:00
|
|
|
|
} else {
|
2005-04-10 17:51:48 +00:00
|
|
|
|
$timezones[sprintf("%.1f", $i)] = $tzstring;
|
2005-04-10 17:35:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-10 17:51:48 +00:00
|
|
|
|
return $timezones;
|
2005-04-10 17:35:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-07-22 17:30:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a list of currencies in the current language
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $USER
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
function get_list_of_currencies() {
|
|
|
|
|
global $CFG, $USER;
|
|
|
|
|
|
|
|
|
|
$lang = current_language();
|
|
|
|
|
|
2006-02-10 01:16:54 +00:00
|
|
|
|
if (!file_exists($CFG->dataroot .'/lang/'. $lang .'/currencies.php')) {
|
2005-07-22 17:30:05 +00:00
|
|
|
|
if ($parentlang = get_string('parentlanguage')) {
|
2006-02-10 01:16:54 +00:00
|
|
|
|
if (file_exists($CFG->dataroot .'/lang/'. $parentlang .'/currencies.php')) {
|
2005-07-22 17:30:05 +00:00
|
|
|
|
$lang = $parentlang;
|
|
|
|
|
} else {
|
2006-02-10 01:16:54 +00:00
|
|
|
|
$lang = 'en_utf8'; // currencies.php must exist in this pack
|
2005-07-22 17:30:05 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2006-02-10 01:16:54 +00:00
|
|
|
|
$lang = 'en_utf8'; // currencies.php must exist in this pack
|
2005-07-22 17:30:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-02-10 01:26:16 +00:00
|
|
|
|
if (file_exists($CFG->dataroot .'/lang/'. $lang .'/currencies.php')) {
|
|
|
|
|
include_once($CFG->dataroot .'/lang/'. $lang .'/currencies.php');
|
|
|
|
|
} else { //if en_utf8 is not installed in dataroot
|
2006-02-10 01:21:52 +00:00
|
|
|
|
include_once($CFG->dirroot .'/lang/'. $lang .'/currencies.php');
|
|
|
|
|
}
|
2005-07-22 17:30:05 +00:00
|
|
|
|
|
|
|
|
|
if (!empty($string)) {
|
|
|
|
|
asort($string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-11-22 06:23:56 +00:00
|
|
|
|
/// ENCRYPTION ////////////////////////////////////////////////
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* rc4encrypt
|
|
|
|
|
*
|
|
|
|
|
* @param string $data ?
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2001-11-22 06:23:56 +00:00
|
|
|
|
function rc4encrypt($data) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$password = 'nfgjeingjk';
|
|
|
|
|
return endecrypt($password, $data, '');
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* rc4decrypt
|
|
|
|
|
*
|
|
|
|
|
* @param string $data ?
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2001-11-22 06:23:56 +00:00
|
|
|
|
function rc4decrypt($data) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$password = 'nfgjeingjk';
|
|
|
|
|
return endecrypt($password, $data, 'de');
|
2001-11-22 06:23:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Based on a class by Mukul Sabharwal [mukulsabharwal @ yahoo.com]
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $pwd ?
|
|
|
|
|
* @param string $data ?
|
|
|
|
|
* @param string $case ?
|
|
|
|
|
* @return string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function endecrypt ($pwd, $data, $case) {
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
|
|
|
|
if ($case == 'de') {
|
|
|
|
|
$data = urldecode($data);
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$key[] = '';
|
|
|
|
|
$box[] = '';
|
|
|
|
|
$temp_swap = '';
|
2001-11-22 06:23:56 +00:00
|
|
|
|
$pwd_length = 0;
|
|
|
|
|
|
|
|
|
|
$pwd_length = strlen($pwd);
|
|
|
|
|
|
|
|
|
|
for ($i = 0; $i <= 255; $i++) {
|
|
|
|
|
$key[$i] = ord(substr($pwd, ($i % $pwd_length), 1));
|
|
|
|
|
$box[$i] = $i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$x = 0;
|
|
|
|
|
|
|
|
|
|
for ($i = 0; $i <= 255; $i++) {
|
|
|
|
|
$x = ($x + $box[$i] + $key[$i]) % 256;
|
|
|
|
|
$temp_swap = $box[$i];
|
|
|
|
|
$box[$i] = $box[$x];
|
|
|
|
|
$box[$x] = $temp_swap;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$temp = '';
|
|
|
|
|
$k = '';
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$cipherby = '';
|
|
|
|
|
$cipher = '';
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
|
|
|
|
$a = 0;
|
|
|
|
|
$j = 0;
|
|
|
|
|
|
|
|
|
|
for ($i = 0; $i < strlen($data); $i++) {
|
|
|
|
|
$a = ($a + 1) % 256;
|
|
|
|
|
$j = ($j + $box[$a]) % 256;
|
|
|
|
|
$temp = $box[$a];
|
|
|
|
|
$box[$a] = $box[$j];
|
|
|
|
|
$box[$j] = $temp;
|
|
|
|
|
$k = $box[(($box[$a] + $box[$j]) % 256)];
|
|
|
|
|
$cipherby = ord(substr($data, $i, 1)) ^ $k;
|
|
|
|
|
$cipher .= chr($cipherby);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($case == 'de') {
|
|
|
|
|
$cipher = urldecode(urlencode($cipher));
|
|
|
|
|
} else {
|
|
|
|
|
$cipher = urlencode($cipher);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $cipher;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-01-17 09:47:45 +00:00
|
|
|
|
/// CALENDAR MANAGEMENT ////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Call this function to add an event to the calendar table
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* and to call any calendar plugins
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param array $event An associative array representing an event from the calendar table. The event will be identified by the id field. The object event should include the following:
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li><b>$event->name</b> - Name for the event
|
|
|
|
|
* <li><b>$event->description</b> - Description of the event (defaults to '')
|
2004-09-25 20:27:15 +00:00
|
|
|
|
* <li><b>$event->format</b> - Format for the description (using formatting types defined at the top of weblib.php)
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* <li><b>$event->courseid</b> - The id of the course this event belongs to (0 = all courses)
|
|
|
|
|
* <li><b>$event->groupid</b> - The id of the group this event belongs to (0 = no group)
|
|
|
|
|
* <li><b>$event->userid</b> - The id of the user this event belongs to (0 = no user)
|
|
|
|
|
* <li><b>$event->modulename</b> - Name of the module that creates this event
|
|
|
|
|
* <li><b>$event->instance</b> - Instance of the module that owns this event
|
|
|
|
|
* <li><b>$event->eventtype</b> - The type info together with the module info could
|
|
|
|
|
* be used by calendar plugins to decide how to display event
|
|
|
|
|
* <li><b>$event->timestart</b>- Timestamp for start of event
|
|
|
|
|
* <li><b>$event->timeduration</b> - Duration (defaults to zero)
|
2004-10-10 01:07:47 +00:00
|
|
|
|
* <li><b>$event->visible</b> - 0 if the event should be hidden (e.g. because the activity that created it is hidden)
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* </ul>
|
|
|
|
|
* @return int The id number of the resulting record
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
|
|
|
|
function add_event($event) {
|
2004-01-17 09:47:45 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$event->timemodified = time();
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (!$event->id = insert_record('event', $event)) {
|
2004-01-17 09:47:45 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2004-01-17 09:47:45 +00:00
|
|
|
|
if (!empty($CFG->calendar)) { // call the add_event function of the selected calendar
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php')) {
|
|
|
|
|
include_once($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php');
|
2004-01-17 09:47:45 +00:00
|
|
|
|
$calendar_add_event = $CFG->calendar.'_add_event';
|
|
|
|
|
if (function_exists($calendar_add_event)) {
|
|
|
|
|
$calendar_add_event($event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2004-01-17 09:47:45 +00:00
|
|
|
|
return $event->id;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Call this function to update an event in the calendar table
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* the event will be identified by the id field of the $event object.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param array $event An associative array representing an event from the calendar table. The event will be identified by the id field.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-01-17 09:47:45 +00:00
|
|
|
|
function update_event($event) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$event->timemodified = time();
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2004-01-17 09:47:45 +00:00
|
|
|
|
if (!empty($CFG->calendar)) { // call the update_event function of the selected calendar
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php')) {
|
|
|
|
|
include_once($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php');
|
2004-01-17 09:47:45 +00:00
|
|
|
|
$calendar_update_event = $CFG->calendar.'_update_event';
|
|
|
|
|
if (function_exists($calendar_update_event)) {
|
|
|
|
|
$calendar_update_event($event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return update_record('event', $event);
|
2004-01-17 09:47:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Call this function to delete the event with id $id from calendar table.
|
|
|
|
|
*
|
2006-08-15 16:53:24 +00:00
|
|
|
|
* @uses $CFG
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $id The id of an event from the 'calendar' table.
|
|
|
|
|
* @return array An associative array with the results from the SQL call.
|
|
|
|
|
* @todo Verify return type
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-01-17 09:47:45 +00:00
|
|
|
|
function delete_event($id) {
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (!empty($CFG->calendar)) { // call the delete_event function of the selected calendar
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php')) {
|
|
|
|
|
include_once($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php');
|
2004-01-17 09:47:45 +00:00
|
|
|
|
$calendar_delete_event = $CFG->calendar.'_delete_event';
|
|
|
|
|
if (function_exists($calendar_delete_event)) {
|
|
|
|
|
$calendar_delete_event($id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return delete_records('event', 'id', $id);
|
2004-01-17 09:47:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Call this function to hide an event in the calendar table
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* the event will be identified by the id field of the $event object.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param array $event An associative array representing an event from the calendar table. The event will be identified by the id field.
|
|
|
|
|
* @return array An associative array with the results from the SQL call.
|
|
|
|
|
* @todo Verify return type
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-05-05 07:07:56 +00:00
|
|
|
|
function hide_event($event) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (!empty($CFG->calendar)) { // call the update_event function of the selected calendar
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php')) {
|
|
|
|
|
include_once($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php');
|
2004-05-05 07:07:56 +00:00
|
|
|
|
$calendar_hide_event = $CFG->calendar.'_hide_event';
|
|
|
|
|
if (function_exists($calendar_hide_event)) {
|
|
|
|
|
$calendar_hide_event($event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return set_field('event', 'visible', 0, 'id', $event->id);
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Call this function to unhide an event in the calendar table
|
|
|
|
|
* the event will be identified by the id field of the $event object.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param array $event An associative array representing an event from the calendar table. The event will be identified by the id field.
|
|
|
|
|
* @return array An associative array with the results from the SQL call.
|
|
|
|
|
* @todo Verify return type
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-05-05 07:07:56 +00:00
|
|
|
|
function show_event($event) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (!empty($CFG->calendar)) { // call the update_event function of the selected calendar
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (file_exists($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php')) {
|
|
|
|
|
include_once($CFG->dirroot .'/calendar/'. $CFG->calendar .'/lib.php');
|
2004-05-05 07:07:56 +00:00
|
|
|
|
$calendar_show_event = $CFG->calendar.'_show_event';
|
|
|
|
|
if (function_exists($calendar_show_event)) {
|
|
|
|
|
$calendar_show_event($event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return set_field('event', 'visible', 1, 'id', $event->id);
|
|
|
|
|
}
|
2004-01-17 09:47:45 +00:00
|
|
|
|
|
|
|
|
|
|
2002-12-20 14:44:14 +00:00
|
|
|
|
/// ENVIRONMENT CHECKING ////////////////////////////////////////////////////////////
|
2002-08-17 13:01:06 +00:00
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Lists plugin directories within some directory
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
2006-01-04 08:23:42 +00:00
|
|
|
|
* @param string $plugin dir under we'll look for plugins (defaults to 'mod')
|
|
|
|
|
* @param string $exclude dir name to exclude from the list (defaults to none)
|
|
|
|
|
* @param string $basedir full path to the base dir where $plugin resides (defaults to $CFG->dirroot)
|
|
|
|
|
* @return array of plugins found under the requested parameters
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2006-01-04 08:23:42 +00:00
|
|
|
|
function get_list_of_plugins($plugin='mod', $exclude='', $basedir='') {
|
2002-12-23 03:07:01 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
2006-01-04 08:23:42 +00:00
|
|
|
|
|
|
|
|
|
$plugins = array();
|
|
|
|
|
|
|
|
|
|
if (empty($basedir)) {
|
2006-10-09 10:12:41 +00:00
|
|
|
|
|
|
|
|
|
# This switch allows us to use the appropiate theme directory - and potentialy alternatives for other plugins
|
|
|
|
|
switch ($plugin) {
|
|
|
|
|
case "theme":
|
|
|
|
|
$basedir = $CFG->themedir;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
$basedir = $CFG->dirroot .'/'. $plugin;
|
|
|
|
|
}
|
|
|
|
|
|
2006-01-04 08:23:42 +00:00
|
|
|
|
} else {
|
|
|
|
|
$basedir = $basedir .'/'. $plugin;
|
2005-12-21 02:06:25 +00:00
|
|
|
|
}
|
2006-10-09 10:12:41 +00:00
|
|
|
|
|
2006-01-07 10:00:49 +00:00
|
|
|
|
if (file_exists($basedir) && filetype($basedir) == 'dir') {
|
2006-01-04 08:23:42 +00:00
|
|
|
|
$dirhandle = opendir($basedir);
|
|
|
|
|
while (false !== ($dir = readdir($dirhandle))) {
|
|
|
|
|
$firstchar = substr($dir, 0, 1);
|
|
|
|
|
if ($firstchar == '.' or $dir == 'CVS' or $dir == '_vti_cnf' or $dir == $exclude) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (filetype($basedir .'/'. $dir) != 'dir') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$plugins[] = $dir;
|
2002-12-23 03:07:01 +00:00
|
|
|
|
}
|
2006-01-04 08:23:42 +00:00
|
|
|
|
closedir($dirhandle);
|
2002-12-23 03:07:01 +00:00
|
|
|
|
}
|
|
|
|
|
if ($plugins) {
|
|
|
|
|
asort($plugins);
|
|
|
|
|
}
|
|
|
|
|
return $plugins;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Returns true if the current version of PHP is greater that the specified one.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $version The version of php being tested.
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-09-22 14:39:15 +00:00
|
|
|
|
function check_php_version($version='4.1.0') {
|
2005-05-09 17:24:03 +00:00
|
|
|
|
return (version_compare(phpversion(), $version) >= 0);
|
2002-08-23 02:14:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-10-10 07:26:10 +00:00
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Checks to see if is a browser matches the specified
|
|
|
|
|
* brand and is equal or better version.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $_SERVER
|
|
|
|
|
* @param string $brand The browser identifier being tested
|
|
|
|
|
* @param int $version The version of the browser
|
2007-03-05 20:02:27 +00:00
|
|
|
|
* @return bool true if the given version is below that of the detected browser
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function check_browser_version($brand='MSIE', $version=5.5) {
|
2006-10-26 08:55:56 +00:00
|
|
|
|
if (empty($_SERVER['HTTP_USER_AGENT'])) {
|
2002-10-10 07:26:10 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2003-10-29 08:06:11 +00:00
|
|
|
|
|
2006-10-26 08:55:56 +00:00
|
|
|
|
$agent = $_SERVER['HTTP_USER_AGENT'];
|
|
|
|
|
|
2003-10-29 08:06:11 +00:00
|
|
|
|
switch ($brand) {
|
|
|
|
|
|
2006-11-15 08:07:32 +00:00
|
|
|
|
case 'Camino': /// Mozilla Firefox browsers
|
|
|
|
|
|
|
|
|
|
if (preg_match("/Camino\/([0-9\.]+)/i", $agent, $match)) {
|
|
|
|
|
if (version_compare($match[1], $version) >= 0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
2006-09-20 17:51:59 +00:00
|
|
|
|
case 'Firefox': /// Mozilla Firefox browsers
|
|
|
|
|
|
|
|
|
|
if (preg_match("/Firefox\/([0-9\.]+)/i", $agent, $match)) {
|
|
|
|
|
if (version_compare($match[1], $version) >= 0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
case 'Gecko': /// Gecko based browsers
|
2003-10-29 08:06:11 +00:00
|
|
|
|
|
2004-11-22 18:38:33 +00:00
|
|
|
|
if (substr_count($agent, 'Camino')) {
|
|
|
|
|
// MacOS X Camino support
|
|
|
|
|
$version = 20041110;
|
2003-10-29 08:06:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the proper string - Gecko/CCYYMMDD Vendor/Version
|
2005-09-23 18:38:50 +00:00
|
|
|
|
// Faster version and work-a-round No IDN problem.
|
|
|
|
|
if (preg_match("/Gecko\/([0-9]+)/i", $agent, $match)) {
|
|
|
|
|
if ($match[1] > $version) {
|
2003-10-29 08:06:11 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
case 'MSIE': /// Internet Explorer
|
2003-10-29 08:06:11 +00:00
|
|
|
|
|
2004-02-10 14:20:44 +00:00
|
|
|
|
if (strpos($agent, 'Opera')) { // Reject Opera
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$string = explode(';', $agent);
|
2003-10-29 08:06:11 +00:00
|
|
|
|
if (!isset($string[1])) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$string = explode(' ', trim($string[1]));
|
2003-10-29 08:06:11 +00:00
|
|
|
|
if (!isset($string[0]) and !isset($string[1])) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ($string[0] == $brand and (float)$string[1] >= $version ) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2007-02-28 07:54:40 +00:00
|
|
|
|
case 'Opera': /// Opera
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-02-28 07:54:40 +00:00
|
|
|
|
if (preg_match("/Opera\/([0-9\.]+)/i", $agent, $match)) {
|
|
|
|
|
if (version_compare($match[1], $version) >= 0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-02-28 07:54:40 +00:00
|
|
|
|
case 'Safari': /// Safari
|
|
|
|
|
// Look for AppleWebKit, excluding strings with OmniWeb, Shiira and SimbianOS
|
|
|
|
|
if (strpos($agent, 'OmniWeb')) { // Reject OmniWeb
|
|
|
|
|
return false;
|
|
|
|
|
} elseif (strpos($agent, 'Shiira')) { // Reject Shiira
|
|
|
|
|
return false;
|
|
|
|
|
} elseif (strpos($agent, 'SimbianOS')) { // Reject SimbianOS
|
|
|
|
|
return false;
|
2007-03-05 20:02:27 +00:00
|
|
|
|
}
|
2007-02-28 07:54:40 +00:00
|
|
|
|
|
|
|
|
|
if (preg_match("/AppleWebKit\/([0-9]+)/i", $agent, $match)) {
|
|
|
|
|
if (version_compare($match[1], $version) >= 0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2002-10-10 07:26:10 +00:00
|
|
|
|
}
|
2003-10-29 08:06:11 +00:00
|
|
|
|
|
2002-10-10 07:26:10 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function makes the return value of ini_get consistent if you are
|
|
|
|
|
* setting server directives through the .htaccess file in apache.
|
|
|
|
|
* Current behavior for value set from php.ini On = 1, Off = [blank]
|
|
|
|
|
* Current behavior for value set from .htaccess On = On, Off = Off
|
|
|
|
|
* Contributed by jdell @ unr.edu
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $ini_get_arg ?
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function ini_get_bool($ini_get_arg) {
|
2003-05-17 02:05:10 +00:00
|
|
|
|
$temp = ini_get($ini_get_arg);
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($temp == '1' or strtolower($temp) == 'on') {
|
2003-05-17 02:05:10 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-11-22 18:38:33 +00:00
|
|
|
|
* Determines if the HTML editor is enabled.
|
2004-09-25 01:29:37 +00:00
|
|
|
|
*
|
2008-03-25 09:36:01 +00:00
|
|
|
|
* This depends on site and user settings, as well as the current browser being
|
|
|
|
|
* used. The current requirements are based on Tinymce's, which are available
|
|
|
|
|
* on http://wiki.moxiecode.com/index.php/TinyMCE:Compatiblity
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2008-05-07 08:33:09 +00:00
|
|
|
|
* @return mixed false if editor cannot be used, or a string representing the compatible browser
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2008-03-25 09:36:01 +00:00
|
|
|
|
function can_use_html_editor() {
|
2002-10-10 07:26:10 +00:00
|
|
|
|
global $USER, $CFG;
|
2003-10-29 08:06:11 +00:00
|
|
|
|
|
2003-01-06 13:55:37 +00:00
|
|
|
|
if (!empty($USER->htmleditor) and !empty($CFG->htmleditor)) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (check_browser_version('MSIE', 5.5)) {
|
|
|
|
|
return 'MSIE';
|
|
|
|
|
} else if (check_browser_version('Gecko', 20030516)) {
|
|
|
|
|
return 'Gecko';
|
2008-05-07 08:33:09 +00:00
|
|
|
|
} else if (check_browser_version('Safari', 3)) {
|
|
|
|
|
return 'Safari';
|
|
|
|
|
} else if (check_browser_version('Opera', 9)) {
|
|
|
|
|
return 'Opera';
|
2003-10-29 08:06:11 +00:00
|
|
|
|
}
|
2002-10-16 04:53:44 +00:00
|
|
|
|
}
|
|
|
|
|
return false;
|
2002-10-10 07:26:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hack to find out the GD version by parsing phpinfo output
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return int GD version (1, 2, or 0)
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2002-09-19 12:01:55 +00:00
|
|
|
|
function check_gd_version() {
|
2003-05-01 23:12:05 +00:00
|
|
|
|
$gdversion = 0;
|
2002-09-19 12:01:55 +00:00
|
|
|
|
|
2003-05-01 23:12:05 +00:00
|
|
|
|
if (function_exists('gd_info')){
|
|
|
|
|
$gd_info = gd_info();
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (substr_count($gd_info['GD Version'], '2.')) {
|
2003-05-01 23:12:05 +00:00
|
|
|
|
$gdversion = 2;
|
2004-09-22 14:39:15 +00:00
|
|
|
|
} else if (substr_count($gd_info['GD Version'], '1.')) {
|
2003-05-19 03:27:13 +00:00
|
|
|
|
$gdversion = 1;
|
2003-05-01 23:12:05 +00:00
|
|
|
|
}
|
2003-05-19 03:27:13 +00:00
|
|
|
|
|
2003-05-01 23:12:05 +00:00
|
|
|
|
} else {
|
|
|
|
|
ob_start();
|
2008-03-25 09:36:01 +00:00
|
|
|
|
phpinfo(INFO_MODULES);
|
2003-05-01 23:12:05 +00:00
|
|
|
|
$phpinfo = ob_get_contents();
|
|
|
|
|
ob_end_clean();
|
2002-09-19 12:01:55 +00:00
|
|
|
|
|
2004-09-25 01:29:37 +00:00
|
|
|
|
$phpinfo = explode("\n", $phpinfo);
|
2002-09-19 12:01:55 +00:00
|
|
|
|
|
2002-12-28 14:45:54 +00:00
|
|
|
|
|
2003-05-01 23:12:05 +00:00
|
|
|
|
foreach ($phpinfo as $text) {
|
2004-09-25 01:29:37 +00:00
|
|
|
|
$parts = explode('</td>', $text);
|
2003-05-01 23:12:05 +00:00
|
|
|
|
foreach ($parts as $key => $val) {
|
|
|
|
|
$parts[$key] = trim(strip_tags($val));
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($parts[0] == 'GD Version') {
|
|
|
|
|
if (substr_count($parts[1], '2.0')) {
|
|
|
|
|
$parts[1] = '2.0';
|
2003-05-01 23:12:05 +00:00
|
|
|
|
}
|
|
|
|
|
$gdversion = intval($parts[1]);
|
2002-12-28 14:45:54 +00:00
|
|
|
|
}
|
2002-09-19 12:01:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $gdversion; // 1, 2 or 0
|
|
|
|
|
}
|
2001-11-22 06:23:56 +00:00
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Determine if moodle installation requires update
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Checks version numbers of main code and all modules to see
|
|
|
|
|
* if there are any mismatches
|
|
|
|
|
*
|
|
|
|
|
* @uses $CFG
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function moodle_needs_upgrading() {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$version = null;
|
2004-09-22 14:39:15 +00:00
|
|
|
|
include_once($CFG->dirroot .'/version.php'); # defines $version and upgrades
|
2004-04-01 10:11:20 +00:00
|
|
|
|
if ($CFG->version) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
if ($version > $CFG->version) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($mods = get_list_of_plugins('mod')) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
foreach ($mods as $mod) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$fullmod = $CFG->dirroot .'/mod/'. $mod;
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$module = new object();
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (!is_readable($fullmod .'/version.php')) {
|
|
|
|
|
notify('Module "'. $mod .'" is not readable - check permissions');
|
2003-01-08 09:07:07 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2004-09-22 14:39:15 +00:00
|
|
|
|
include_once($fullmod .'/version.php'); # defines $module with version etc
|
|
|
|
|
if ($currmodule = get_record('modules', 'name', $mod)) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
if ($module->version > $currmodule->version) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// MISCELLANEOUS ////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Notify admin users or admin user of any failed logins (since last notification).
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2007-10-09 00:11:07 +00:00
|
|
|
|
* Note that this function must be only executed from the cron script
|
|
|
|
|
* It uses the cache_flags system to store temporary records, deleting them
|
|
|
|
|
* by name before finishing
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @uses $db
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* @uses HOURSECS
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-07-25 13:48:55 +00:00
|
|
|
|
function notify_login_failures() {
|
2004-07-29 14:54:25 +00:00
|
|
|
|
global $CFG, $db;
|
2004-07-25 13:48:55 +00:00
|
|
|
|
|
|
|
|
|
switch ($CFG->notifyloginfailures) {
|
|
|
|
|
case 'mainadmin' :
|
|
|
|
|
$recip = array(get_admin());
|
|
|
|
|
break;
|
|
|
|
|
case 'alladmins':
|
|
|
|
|
$recip = get_admins();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-09-21 11:41:58 +00:00
|
|
|
|
|
2004-07-25 13:48:55 +00:00
|
|
|
|
if (empty($CFG->lastnotifyfailure)) {
|
|
|
|
|
$CFG->lastnotifyfailure=0;
|
|
|
|
|
}
|
2004-09-21 11:41:58 +00:00
|
|
|
|
|
|
|
|
|
// we need to deal with the threshold stuff first.
|
2004-07-25 14:39:19 +00:00
|
|
|
|
if (empty($CFG->notifyloginthreshold)) {
|
|
|
|
|
$CFG->notifyloginthreshold = 10; // default to something sensible.
|
2004-07-25 13:48:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-09 00:11:07 +00:00
|
|
|
|
/// Get all the IPs with more than notifyloginthreshold failures since lastnotifyfailure
|
|
|
|
|
/// and insert them into the cache_flags temp table
|
|
|
|
|
$iprs = get_recordset_sql("SELECT ip, count(*)
|
|
|
|
|
FROM {$CFG->prefix}log
|
|
|
|
|
WHERE module = 'login'
|
|
|
|
|
AND action = 'error'
|
|
|
|
|
AND time > $CFG->lastnotifyfailure
|
|
|
|
|
GROUP BY ip
|
|
|
|
|
HAVING count(*) >= $CFG->notifyloginthreshold");
|
|
|
|
|
while ($iprec = rs_fetch_next_record($iprs)) {
|
|
|
|
|
if (!empty($iprec->ip)) {
|
|
|
|
|
set_cache_flag('login_failure_by_ip', $iprec->ip, '1', 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rs_close($iprs);
|
|
|
|
|
|
|
|
|
|
/// Get all the INFOs with more than notifyloginthreshold failures since lastnotifyfailure
|
|
|
|
|
/// and insert them into the cache_flags temp table
|
|
|
|
|
$infors = get_recordset_sql("SELECT info, count(*)
|
|
|
|
|
FROM {$CFG->prefix}log
|
|
|
|
|
WHERE module = 'login'
|
|
|
|
|
AND action = 'error'
|
|
|
|
|
AND time > $CFG->lastnotifyfailure
|
|
|
|
|
GROUP BY info
|
|
|
|
|
HAVING count(*) >= $CFG->notifyloginthreshold");
|
|
|
|
|
while ($inforec = rs_fetch_next_record($infors)) {
|
|
|
|
|
if (!empty($inforec->info)) {
|
|
|
|
|
set_cache_flag('login_failure_by_info', $inforec->info, '1', 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rs_close($infors);
|
|
|
|
|
|
|
|
|
|
/// Now, select all the login error logged records belonging to the ips and infos
|
|
|
|
|
/// since lastnotifyfailure, that we have stored in the cache_flags table
|
|
|
|
|
$logsrs = get_recordset_sql("SELECT l.*, u.firstname, u.lastname
|
|
|
|
|
FROM {$CFG->prefix}log l
|
|
|
|
|
JOIN {$CFG->prefix}cache_flags cf ON (l.ip = cf.name)
|
|
|
|
|
LEFT JOIN {$CFG->prefix}user u ON (l.userid = u.id)
|
|
|
|
|
WHERE l.module = 'login'
|
|
|
|
|
AND l.action = 'error'
|
|
|
|
|
AND l.time > $CFG->lastnotifyfailure
|
|
|
|
|
AND cf.flagtype = 'login_failure_by_ip'
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT l.*, u.firstname, u.lastname
|
|
|
|
|
FROM {$CFG->prefix}log l
|
|
|
|
|
JOIN {$CFG->prefix}cache_flags cf ON (l.info = cf.name)
|
|
|
|
|
LEFT JOIN {$CFG->prefix}user u ON (l.userid = u.id)
|
|
|
|
|
WHERE l.module = 'login'
|
|
|
|
|
AND l.action = 'error'
|
|
|
|
|
AND l.time > $CFG->lastnotifyfailure
|
|
|
|
|
AND cf.flagtype = 'login_failure_by_info'
|
|
|
|
|
ORDER BY time DESC");
|
|
|
|
|
|
|
|
|
|
/// Init some variables
|
|
|
|
|
$count = 0;
|
|
|
|
|
$messages = '';
|
|
|
|
|
/// Iterate over the logs recordset
|
|
|
|
|
while ($log = rs_fetch_next_record($logsrs)) {
|
|
|
|
|
$log->time = userdate($log->time);
|
|
|
|
|
$messages .= get_string('notifyloginfailuresmessage','',$log)."\n";
|
|
|
|
|
$count++;
|
|
|
|
|
}
|
|
|
|
|
rs_close($logsrs);
|
|
|
|
|
|
|
|
|
|
/// If we haven't run in the last hour and
|
|
|
|
|
/// we have something useful to report and we
|
|
|
|
|
/// are actually supposed to be reporting to somebody
|
|
|
|
|
if ((time() - HOURSECS) > $CFG->lastnotifyfailure && $count > 0 && is_array($recip) && count($recip) > 0) {
|
|
|
|
|
$site = get_site();
|
|
|
|
|
$subject = get_string('notifyloginfailuressubject', '', format_string($site->fullname));
|
|
|
|
|
/// Calculate the complete body of notification (start + messages + end)
|
|
|
|
|
$body = get_string('notifyloginfailuresmessagestart', '', $CFG->wwwroot) .
|
|
|
|
|
(($CFG->lastnotifyfailure != 0) ? '('.userdate($CFG->lastnotifyfailure).')' : '')."\n\n" .
|
|
|
|
|
$messages .
|
|
|
|
|
"\n\n".get_string('notifyloginfailuresmessageend','',$CFG->wwwroot)."\n\n";
|
|
|
|
|
|
|
|
|
|
/// For each destination, send mail
|
|
|
|
|
foreach ($recip as $admin) {
|
|
|
|
|
mtrace('Emailing '. $admin->username .' about '. $count .' failed login attempts');
|
|
|
|
|
email_to_user($admin,get_admin(), $subject, $body);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Update lastnotifyfailure with current time
|
|
|
|
|
set_config('lastnotifyfailure', time());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Finally, delete all the temp records we have created in cache_flags
|
|
|
|
|
delete_records_select('cache_flags', "flagtype IN ('login_failure_by_ip', 'login_failure_by_info')");
|
2004-07-25 13:48:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* moodle_setlocale
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param string $locale ?
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-06-21 13:07:44 +00:00
|
|
|
|
function moodle_setlocale($locale='') {
|
|
|
|
|
|
2007-03-16 21:00:06 +00:00
|
|
|
|
global $CFG;
|
2004-06-21 13:07:44 +00:00
|
|
|
|
|
2007-03-16 21:00:06 +00:00
|
|
|
|
static $currentlocale = ''; // last locale caching
|
2006-07-30 10:39:21 +00:00
|
|
|
|
|
|
|
|
|
$oldlocale = $currentlocale;
|
|
|
|
|
|
2006-03-25 12:26:33 +00:00
|
|
|
|
/// Fetch the correct locale based on ostype
|
2006-11-11 16:07:53 +00:00
|
|
|
|
if($CFG->ostype == 'WINDOWS') {
|
2006-03-25 12:26:33 +00:00
|
|
|
|
$stringtofetch = 'localewin';
|
|
|
|
|
} else {
|
|
|
|
|
$stringtofetch = 'locale';
|
|
|
|
|
}
|
|
|
|
|
|
2006-07-30 10:39:21 +00:00
|
|
|
|
/// the priority is the same as in get_string() - parameter, config, course, session, user, global language
|
|
|
|
|
if (!empty($locale)) {
|
|
|
|
|
$currentlocale = $locale;
|
|
|
|
|
} else if (!empty($CFG->locale)) { // override locale for all language packs
|
|
|
|
|
$currentlocale = $CFG->locale;
|
|
|
|
|
} else {
|
|
|
|
|
$currentlocale = get_string($stringtofetch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// do nothing if locale already set up
|
|
|
|
|
if ($oldlocale == $currentlocale) {
|
|
|
|
|
return;
|
2004-06-21 13:07:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-25 12:26:33 +00:00
|
|
|
|
/// Due to some strange BUG we cannot set the LC_TIME directly, so we fetch current values,
|
|
|
|
|
/// set LC_ALL and then set values again. Just wondering why we cannot set LC_ALL only??? - stronk7
|
|
|
|
|
/// Some day, numeric, monetary and other categories should be set too, I think. :-/
|
|
|
|
|
|
|
|
|
|
/// Get current values
|
|
|
|
|
$monetary= setlocale (LC_MONETARY, 0);
|
|
|
|
|
$numeric = setlocale (LC_NUMERIC, 0);
|
|
|
|
|
$ctype = setlocale (LC_CTYPE, 0);
|
|
|
|
|
if ($CFG->ostype != 'WINDOWS') {
|
|
|
|
|
$messages= setlocale (LC_MESSAGES, 0);
|
|
|
|
|
}
|
|
|
|
|
/// Set locale to all
|
2006-07-30 10:39:21 +00:00
|
|
|
|
setlocale (LC_ALL, $currentlocale);
|
2006-03-25 12:26:33 +00:00
|
|
|
|
/// Set old values
|
|
|
|
|
setlocale (LC_MONETARY, $monetary);
|
|
|
|
|
setlocale (LC_NUMERIC, $numeric);
|
|
|
|
|
if ($CFG->ostype != 'WINDOWS') {
|
|
|
|
|
setlocale (LC_MESSAGES, $messages);
|
|
|
|
|
}
|
2006-07-30 10:39:21 +00:00
|
|
|
|
if ($currentlocale == 'tr_TR' or $currentlocale == 'tr_TR.UTF-8') { // To workaround a well-known PHP problem with Turkish letter Ii
|
2006-03-25 12:26:33 +00:00
|
|
|
|
setlocale (LC_CTYPE, $ctype);
|
2004-06-21 13:07:44 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Converts string to lowercase using most compatible function available.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $string The string to convert to all lowercase characters.
|
|
|
|
|
* @param string $encoding The encoding on the string.
|
|
|
|
|
* @return string
|
|
|
|
|
* @todo Add examples of calling this function with/without encoding types
|
2006-11-11 17:23:20 +00:00
|
|
|
|
* @deprecated Use textlib->strtolower($text) instead.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2003-04-21 16:39:43 +00:00
|
|
|
|
function moodle_strtolower ($string, $encoding='') {
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2006-11-11 16:07:53 +00:00
|
|
|
|
//If not specified use utf8
|
2006-06-10 10:40:16 +00:00
|
|
|
|
if (empty($encoding)) {
|
2006-11-11 16:07:53 +00:00
|
|
|
|
$encoding = 'UTF-8';
|
2004-04-01 10:11:20 +00:00
|
|
|
|
}
|
2006-06-10 10:40:16 +00:00
|
|
|
|
//Use text services
|
|
|
|
|
$textlib = textlib_get_instance();
|
|
|
|
|
|
|
|
|
|
return $textlib->strtolower($string, $encoding);
|
2003-04-21 16:39:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Count words in a string.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Words are defined as things between whitespace.
|
|
|
|
|
*
|
|
|
|
|
* @param string $string The text to be searched for words.
|
|
|
|
|
* @return int The count of words in the specified string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function count_words($string) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
$string = strip_tags($string);
|
|
|
|
|
return count(preg_split("/\w\b/", $string)) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2006-01-04 08:23:42 +00:00
|
|
|
|
/** Count letters in a string.
|
|
|
|
|
*
|
|
|
|
|
* Letters are defined as chars not in tags and different from whitespace.
|
|
|
|
|
*
|
|
|
|
|
* @param string $string The text to be searched for letters.
|
|
|
|
|
* @return int The count of letters in the specified text.
|
|
|
|
|
*/
|
|
|
|
|
function count_letters($string) {
|
|
|
|
|
/// Loading the textlib singleton instance. We are going to need it.
|
|
|
|
|
$textlib = textlib_get_instance();
|
|
|
|
|
|
|
|
|
|
$string = strip_tags($string); // Tags are out now
|
|
|
|
|
$string = ereg_replace('[[:space:]]*','',$string); //Whitespace are out now
|
|
|
|
|
|
2006-11-11 16:07:53 +00:00
|
|
|
|
return $textlib->strlen($string);
|
2006-01-04 08:23:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Generate and return a random string of the specified length.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $length The length of the string to be created.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2002-12-23 03:07:01 +00:00
|
|
|
|
function random_string ($length=15) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
|
|
|
$pool .= 'abcdefghijklmnopqrstuvwxyz';
|
|
|
|
|
$pool .= '0123456789';
|
2002-12-23 03:07:01 +00:00
|
|
|
|
$poollen = strlen($pool);
|
|
|
|
|
mt_srand ((double) microtime() * 1000000);
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$string = '';
|
2002-12-23 03:07:01 +00:00
|
|
|
|
for ($i = 0; $i < $length; $i++) {
|
|
|
|
|
$string .= substr($pool, (mt_rand()%($poollen)), 1);
|
|
|
|
|
}
|
|
|
|
|
return $string;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-14 17:03:11 +00:00
|
|
|
|
/*
|
2006-03-04 16:53:02 +00:00
|
|
|
|
* Given some text (which may contain HTML) and an ideal length,
|
2005-04-14 17:03:11 +00:00
|
|
|
|
* this function truncates the text neatly on a word boundary if possible
|
2007-12-04 05:10:12 +00:00
|
|
|
|
* @param string $text - text to be shortened
|
|
|
|
|
* @param int $ideal - ideal string length
|
|
|
|
|
* @param boolean $exact if false, $text will not be cut mid-word
|
|
|
|
|
* @return string $truncate - shortened string
|
2005-04-14 17:03:11 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2007-12-04 05:10:12 +00:00
|
|
|
|
function shorten_text($text, $ideal=30, $exact = false) {
|
2005-04-14 17:03:11 +00:00
|
|
|
|
|
2007-12-04 05:10:12 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
$ending = '...';
|
|
|
|
|
|
|
|
|
|
// if the plain text is shorter than the maximum length, return the whole text
|
|
|
|
|
if (strlen(preg_replace('/<.*?>/', '', $text)) <= $ideal) {
|
|
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// splits all html-tags to scanable lines
|
|
|
|
|
preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
|
|
|
|
|
|
|
|
|
|
$total_length = strlen($ending);
|
|
|
|
|
$open_tags = array();
|
|
|
|
|
$truncate = '';
|
|
|
|
|
|
|
|
|
|
foreach ($lines as $line_matchings) {
|
|
|
|
|
// if there is any html-tag in this line, handle it and add it (uncounted) to the output
|
|
|
|
|
if (!empty($line_matchings[1])) {
|
|
|
|
|
// if it's an "empty element" with or without xhtml-conform closing slash (f.e. <br/>)
|
|
|
|
|
if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
|
|
|
|
|
// do nothing
|
|
|
|
|
// if tag is a closing tag (f.e. </b>)
|
|
|
|
|
} else if (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
|
|
|
|
|
// delete tag from $open_tags list
|
|
|
|
|
$pos = array_search($tag_matchings[1], array_reverse($open_tags, true)); // can have multiple exact same open tags, close the last one
|
|
|
|
|
if ($pos !== false) {
|
|
|
|
|
unset($open_tags[$pos]);
|
|
|
|
|
}
|
|
|
|
|
// if tag is an opening tag (f.e. <b>)
|
|
|
|
|
} else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
|
|
|
|
|
// add tag to the beginning of $open_tags list
|
|
|
|
|
array_unshift($open_tags, strtolower($tag_matchings[1]));
|
|
|
|
|
}
|
|
|
|
|
// add html-tag to $truncate'd text
|
|
|
|
|
$truncate .= $line_matchings[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// calculate the length of the plain text part of the line; handle entities as one character
|
|
|
|
|
$content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
|
|
|
|
|
if ($total_length+$content_length > $ideal) {
|
|
|
|
|
// the number of characters which are left
|
|
|
|
|
$left = $ideal - $total_length;
|
|
|
|
|
$entities_length = 0;
|
|
|
|
|
// search for html entities
|
|
|
|
|
if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
|
|
|
|
|
// calculate the real length of all entities in the legal range
|
|
|
|
|
foreach ($entities[0] as $entity) {
|
|
|
|
|
if ($entity[1]+1-$entities_length <= $left) {
|
|
|
|
|
$left--;
|
|
|
|
|
$entities_length += strlen($entity[0]);
|
|
|
|
|
} else {
|
|
|
|
|
// no more characters left
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$truncate .= substr($line_matchings[2], 0, $left+$entities_length);
|
|
|
|
|
// maximum lenght is reached, so get off the loop
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
$truncate .= $line_matchings[2];
|
|
|
|
|
$total_length += $content_length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if the maximum length is reached, get off the loop
|
|
|
|
|
if($total_length >= $ideal) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-14 17:03:11 +00:00
|
|
|
|
|
2007-12-04 05:10:12 +00:00
|
|
|
|
// if the words shouldn't be cut in the middle...
|
|
|
|
|
if (!$exact) {
|
|
|
|
|
// ...search the last occurance of a space...
|
|
|
|
|
for ($k=strlen($truncate);$k>0;$k--) {
|
|
|
|
|
if (!empty($truncate[$k]) && ($char = $truncate[$k])) {
|
|
|
|
|
if ($char == '.' or $char == ' ') {
|
|
|
|
|
$breakpos = $k+1;
|
|
|
|
|
break;
|
|
|
|
|
} else if (ord($char) >= 0xE0) { // Chinese/Japanese/Korean text
|
|
|
|
|
$breakpos = $k; // can be truncated at any UTF-8
|
|
|
|
|
break; // character boundary.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isset($breakpos)) {
|
|
|
|
|
// ...and cut the text in this position
|
|
|
|
|
$truncate = substr($truncate, 0, $breakpos);
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-14 17:03:11 +00:00
|
|
|
|
|
2007-12-04 05:10:12 +00:00
|
|
|
|
// add the defined ending to the text
|
|
|
|
|
$truncate .= $ending;
|
2005-04-14 17:03:11 +00:00
|
|
|
|
|
2007-12-04 05:10:12 +00:00
|
|
|
|
// close all unclosed html-tags
|
|
|
|
|
foreach ($open_tags as $tag) {
|
|
|
|
|
$truncate .= '</' . $tag . '>';
|
|
|
|
|
}
|
2005-04-14 17:03:11 +00:00
|
|
|
|
|
2007-12-04 05:10:12 +00:00
|
|
|
|
return $truncate;
|
2005-04-14 17:03:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given dates in seconds, how many weeks is the date from startdate
|
|
|
|
|
* The first week is 1, the second 2 etc ...
|
|
|
|
|
*
|
2004-09-29 18:56:50 +00:00
|
|
|
|
* @uses WEEKSECS
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param ? $startdate ?
|
|
|
|
|
* @param ? $thedate ?
|
|
|
|
|
* @return string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function getweek ($startdate, $thedate) {
|
2002-12-20 14:44:14 +00:00
|
|
|
|
if ($thedate < $startdate) { // error
|
2004-04-01 10:11:20 +00:00
|
|
|
|
return 0;
|
2002-12-20 14:44:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-28 05:53:08 +00:00
|
|
|
|
return floor(($thedate - $startdate) / WEEKSECS) + 1;
|
2002-12-20 14:44:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* returns a randomly generated password of length $maxlen. inspired by
|
2008-04-18 08:04:21 +00:00
|
|
|
|
* {@link http://www.phpbuilder.com/columns/jesus19990502.php3} and
|
|
|
|
|
* {@link http://es2.php.net/manual/en/function.str-shuffle.php#73254}
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2008-04-18 08:04:21 +00:00
|
|
|
|
* @param int $maxlen The maximum size of the password being generated.
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2002-12-20 14:44:14 +00:00
|
|
|
|
function generate_password($maxlen=10) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2008-04-18 08:04:21 +00:00
|
|
|
|
if (empty($CFG->passwordpolicy)) {
|
|
|
|
|
$fillers = PASSWORD_DIGITS;
|
|
|
|
|
$wordlist = file($CFG->wordlist);
|
|
|
|
|
$word1 = trim($wordlist[rand(0, count($wordlist) - 1)]);
|
|
|
|
|
$word2 = trim($wordlist[rand(0, count($wordlist) - 1)]);
|
|
|
|
|
$filler1 = $fillers[rand(0, strlen($fillers) - 1)];
|
|
|
|
|
$password = $word1 . $filler1 . $word2;
|
|
|
|
|
} else {
|
|
|
|
|
$maxlen = !empty($CFG->minpasswordlength) ? $CFG->minpasswordlength : 0;
|
|
|
|
|
$digits = $CFG->minpassworddigits;
|
|
|
|
|
$lower = $CFG->minpasswordlower;
|
|
|
|
|
$upper = $CFG->minpasswordupper;
|
|
|
|
|
$nonalphanum = $CFG->minpasswordnonalphanum;
|
|
|
|
|
$additional = $maxlen - ($lower + $upper + $digits + $nonalphanum);
|
|
|
|
|
|
|
|
|
|
// Make sure we have enough characters to fulfill
|
|
|
|
|
// complexity requirements
|
|
|
|
|
$passworddigits = PASSWORD_DIGITS;
|
|
|
|
|
while ($digits > strlen($passworddigits)) {
|
|
|
|
|
$passworddigits .= PASSWORD_DIGITS;
|
|
|
|
|
}
|
|
|
|
|
$passwordlower = PASSWORD_LOWER;
|
|
|
|
|
while ($lower > strlen($passwordlower)) {
|
|
|
|
|
$passwordlower .= PASSWORD_LOWER;
|
|
|
|
|
}
|
|
|
|
|
$passwordupper = PASSWORD_UPPER;
|
|
|
|
|
while ($upper > strlen($passwordupper)) {
|
|
|
|
|
$passwordupper .= PASSWORD_UPPER;
|
|
|
|
|
}
|
|
|
|
|
$passwordnonalphanum = PASSWORD_NONALPHANUM;
|
|
|
|
|
while ($nonalphanum > strlen($passwordnonalphanum)) {
|
|
|
|
|
$passwordnonalphanum .= PASSWORD_NONALPHANUM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Now mix and shuffle it all
|
|
|
|
|
$password = str_shuffle (substr(str_shuffle ($passwordlower), 0, $lower) .
|
|
|
|
|
substr(str_shuffle ($passwordupper), 0, $upper) .
|
|
|
|
|
substr(str_shuffle ($passworddigits), 0, $digits) .
|
|
|
|
|
substr(str_shuffle ($passwordnonalphanum), 0 , $nonalphanum) .
|
|
|
|
|
substr(str_shuffle ($passwordlower .
|
|
|
|
|
$passwordupper .
|
|
|
|
|
$passworddigits .
|
|
|
|
|
$passwordnonalphanum), 0 , $additional));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return substr ($password, 0, $maxlen);
|
2002-12-20 14:44:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
2007-08-10 15:00:35 +00:00
|
|
|
|
* Given a float, prints it nicely.
|
2007-09-27 09:58:40 +00:00
|
|
|
|
* Localized floats must not be used in calculations!
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
2007-08-10 15:00:35 +00:00
|
|
|
|
* @param float $flaot The float to print
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $places The number of decimal places to print.
|
2007-09-27 09:58:40 +00:00
|
|
|
|
* @param bool $localized use localized decimal separator
|
2007-08-10 15:00:35 +00:00
|
|
|
|
* @return string locale float
|
|
|
|
|
*/
|
2007-09-27 09:58:40 +00:00
|
|
|
|
function format_float($float, $decimalpoints=1, $localized=true) {
|
2007-08-10 15:00:35 +00:00
|
|
|
|
if (is_null($float)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2007-09-27 09:58:40 +00:00
|
|
|
|
if ($localized) {
|
|
|
|
|
return number_format($float, $decimalpoints, get_string('decsep'), '');
|
|
|
|
|
} else {
|
|
|
|
|
return number_format($float, $decimalpoints, '.', '');
|
|
|
|
|
}
|
2007-08-10 15:00:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2007-08-20 07:29:05 +00:00
|
|
|
|
* Converts locale specific floating point/comma number back to standard PHP float value
|
2007-08-10 15:00:35 +00:00
|
|
|
|
* Do NOT try to do any math operations before this conversion on any user submitted floats!
|
|
|
|
|
*
|
2007-08-20 07:29:05 +00:00
|
|
|
|
* @param string $locale_float locale aware float representation
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2007-08-10 15:00:35 +00:00
|
|
|
|
function unformat_float($locale_float) {
|
|
|
|
|
$locale_float = trim($locale_float);
|
|
|
|
|
|
|
|
|
|
if ($locale_float == '') {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$locale_float = str_replace(' ', '', $locale_float); // no spaces - those might be used as thousand separators
|
|
|
|
|
|
|
|
|
|
return (float)str_replace(get_string('decsep'), '.', $locale_float);
|
2002-12-20 14:44:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given a simple array, this shuffles it up just like shuffle()
|
2007-08-20 07:29:05 +00:00
|
|
|
|
* Unlike PHP's shuffle() this function works on any machine.
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*
|
|
|
|
|
* @param array $array The array to be rearranged
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function swapshuffle($array) {
|
2003-02-24 09:34:10 +00:00
|
|
|
|
|
|
|
|
|
srand ((double) microtime() * 10000000);
|
|
|
|
|
$last = count($array) - 1;
|
|
|
|
|
for ($i=0;$i<=$last;$i++) {
|
|
|
|
|
$from = rand(0,$last);
|
|
|
|
|
$curr = $array[$i];
|
|
|
|
|
$array[$i] = $array[$from];
|
|
|
|
|
$array[$from] = $curr;
|
2004-04-01 10:11:20 +00:00
|
|
|
|
}
|
2003-02-24 09:34:10 +00:00
|
|
|
|
return $array;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Like {@link swapshuffle()}, but works on associative arrays
|
|
|
|
|
*
|
|
|
|
|
* @param array $array The associative array to be rearranged
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2003-04-10 13:45:07 +00:00
|
|
|
|
function swapshuffle_assoc($array) {
|
|
|
|
|
|
2007-12-28 22:56:42 +00:00
|
|
|
|
$newarray = array();
|
2003-04-10 13:45:07 +00:00
|
|
|
|
$newkeys = swapshuffle(array_keys($array));
|
2007-12-28 22:56:42 +00:00
|
|
|
|
|
2003-04-10 13:45:07 +00:00
|
|
|
|
foreach ($newkeys as $newkey) {
|
|
|
|
|
$newarray[$newkey] = $array[$newkey];
|
|
|
|
|
}
|
|
|
|
|
return $newarray;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given an arbitrary array, and a number of draws,
|
|
|
|
|
* this function returns an array with that amount
|
|
|
|
|
* of items. The indexes are retained.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param array $array ?
|
|
|
|
|
* @param ? $draws ?
|
|
|
|
|
* @return ?
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2003-02-24 09:34:10 +00:00
|
|
|
|
function draw_rand_array($array, $draws) {
|
|
|
|
|
srand ((double) microtime() * 10000000);
|
|
|
|
|
|
|
|
|
|
$return = array();
|
|
|
|
|
|
|
|
|
|
$last = count($array);
|
|
|
|
|
|
|
|
|
|
if ($draws > $last) {
|
|
|
|
|
$draws = $last;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while ($draws > 0) {
|
|
|
|
|
$last--;
|
|
|
|
|
|
|
|
|
|
$keys = array_keys($array);
|
|
|
|
|
$rand = rand(0, $last);
|
|
|
|
|
|
|
|
|
|
$return[$keys[$rand]] = $array[$keys[$rand]];
|
|
|
|
|
unset($array[$keys[$rand]]);
|
2004-04-01 10:11:20 +00:00
|
|
|
|
|
2003-02-24 09:34:10 +00:00
|
|
|
|
$draws--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $return;
|
2004-04-01 10:11:20 +00:00
|
|
|
|
}
|
2002-12-20 14:44:14 +00:00
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* microtime_diff
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $a ?
|
|
|
|
|
* @param string $b ?
|
|
|
|
|
* @return string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2003-04-27 08:13:45 +00:00
|
|
|
|
function microtime_diff($a, $b) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
list($a_dec, $a_sec) = explode(' ', $a);
|
|
|
|
|
list($b_dec, $b_sec) = explode(' ', $b);
|
2003-04-27 08:13:45 +00:00
|
|
|
|
return $b_sec - $a_sec + $b_dec - $a_dec;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Given a list (eg a,b,c,d,e) this function returns
|
|
|
|
|
* an array of 1->a, 2->b, 3->c etc
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param array $list ?
|
|
|
|
|
* @param string $separator ?
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-11-22 18:38:33 +00:00
|
|
|
|
function make_menu_from_list($list, $separator=',') {
|
2003-08-15 13:59:24 +00:00
|
|
|
|
|
|
|
|
|
$array = array_reverse(explode($separator, $list), true);
|
|
|
|
|
foreach ($array as $key => $item) {
|
|
|
|
|
$outarray[$key+1] = trim($item);
|
|
|
|
|
}
|
|
|
|
|
return $outarray;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Creates an array that represents all the current grades that
|
|
|
|
|
* can be chosen using the given grading type. Negative numbers
|
|
|
|
|
* are scales, zero is no grade, and positive numbers are maximum
|
|
|
|
|
* grades.
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $gradingtype ?
|
|
|
|
|
* return int
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2003-08-18 05:10:35 +00:00
|
|
|
|
function make_grades_menu($gradingtype) {
|
|
|
|
|
$grades = array();
|
|
|
|
|
if ($gradingtype < 0) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if ($scale = get_record('scale', 'id', - $gradingtype)) {
|
2003-08-18 05:10:35 +00:00
|
|
|
|
return make_menu_from_list($scale->scale);
|
|
|
|
|
}
|
|
|
|
|
} else if ($gradingtype > 0) {
|
|
|
|
|
for ($i=$gradingtype; $i>=0; $i--) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$grades[$i] = $i .' / '. $gradingtype;
|
2003-08-18 05:10:35 +00:00
|
|
|
|
}
|
|
|
|
|
return $grades;
|
|
|
|
|
}
|
|
|
|
|
return $grades;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function returns the nummber of activities
|
|
|
|
|
* using scaleid in a courseid
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $courseid ?
|
|
|
|
|
* @param int $scaleid ?
|
|
|
|
|
* @return int
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-09-25 01:29:37 +00:00
|
|
|
|
function course_scale_used($courseid, $scaleid) {
|
2004-05-16 00:36:00 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
2004-06-25 07:38:44 +00:00
|
|
|
|
|
2004-05-16 00:36:00 +00:00
|
|
|
|
$return = 0;
|
|
|
|
|
|
|
|
|
|
if (!empty($scaleid)) {
|
|
|
|
|
if ($cms = get_course_mods($courseid)) {
|
|
|
|
|
foreach ($cms as $cm) {
|
|
|
|
|
//Check cm->name/lib.php exists
|
|
|
|
|
if (file_exists($CFG->dirroot.'/mod/'.$cm->modname.'/lib.php')) {
|
|
|
|
|
include_once($CFG->dirroot.'/mod/'.$cm->modname.'/lib.php');
|
|
|
|
|
$function_name = $cm->modname.'_scale_used';
|
|
|
|
|
if (function_exists($function_name)) {
|
|
|
|
|
if ($function_name($cm->instance,$scaleid)) {
|
|
|
|
|
$return++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-08-09 16:41:39 +00:00
|
|
|
|
|
2007-08-01 06:24:15 +00:00
|
|
|
|
// check if any course grade item makes use of the scale
|
2007-08-09 16:41:39 +00:00
|
|
|
|
$return += count_records('grade_items', 'courseid', $courseid, 'scaleid', $scaleid);
|
2008-02-03 16:40:34 +00:00
|
|
|
|
|
|
|
|
|
// check if any outcome in the course makes use of the scale
|
|
|
|
|
$return += count_records_sql("SELECT COUNT(*)
|
|
|
|
|
FROM {$CFG->prefix}grade_outcomes_courses goc,
|
|
|
|
|
{$CFG->prefix}grade_outcomes go
|
|
|
|
|
WHERE go.id = goc.outcomeid
|
|
|
|
|
AND go.scaleid = $scaleid
|
|
|
|
|
AND goc.courseid = $courseid");
|
2004-05-16 00:36:00 +00:00
|
|
|
|
}
|
|
|
|
|
return $return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function returns the nummber of activities
|
|
|
|
|
* using scaleid in the entire site
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param int $scaleid ?
|
|
|
|
|
* @return int
|
|
|
|
|
* @todo Finish documenting this function. Is return type correct?
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
2004-11-22 05:22:20 +00:00
|
|
|
|
function site_scale_used($scaleid,&$courses) {
|
2004-05-16 00:36:00 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
$return = 0;
|
|
|
|
|
|
2004-11-22 05:22:20 +00:00
|
|
|
|
if (!is_array($courses) || count($courses) == 0) {
|
|
|
|
|
$courses = get_courses("all",false,"c.id,c.shortname");
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-16 00:36:00 +00:00
|
|
|
|
if (!empty($scaleid)) {
|
2004-11-22 05:22:20 +00:00
|
|
|
|
if (is_array($courses) && count($courses) > 0) {
|
2004-05-16 00:36:00 +00:00
|
|
|
|
foreach ($courses as $course) {
|
|
|
|
|
$return += course_scale_used($course->id,$scaleid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* make_unique_id_code
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @param string $extra ?
|
|
|
|
|
* @return string
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2004-09-22 14:39:15 +00:00
|
|
|
|
function make_unique_id_code($extra='') {
|
2003-08-23 12:22:27 +00:00
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$hostname = 'unknownhost';
|
|
|
|
|
if (!empty($_SERVER['HTTP_HOST'])) {
|
|
|
|
|
$hostname = $_SERVER['HTTP_HOST'];
|
|
|
|
|
} else if (!empty($_ENV['HTTP_HOST'])) {
|
|
|
|
|
$hostname = $_ENV['HTTP_HOST'];
|
|
|
|
|
} else if (!empty($_SERVER['SERVER_NAME'])) {
|
|
|
|
|
$hostname = $_SERVER['SERVER_NAME'];
|
|
|
|
|
} else if (!empty($_ENV['SERVER_NAME'])) {
|
|
|
|
|
$hostname = $_ENV['SERVER_NAME'];
|
2003-08-23 12:22:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-08-23 12:25:50 +00:00
|
|
|
|
$date = gmdate("ymdHis");
|
2003-08-23 12:22:27 +00:00
|
|
|
|
|
|
|
|
|
$random = random_string(6);
|
|
|
|
|
|
2003-08-23 14:18:44 +00:00
|
|
|
|
if ($extra) {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return $hostname .'+'. $date .'+'. $random .'+'. $extra;
|
2003-08-23 14:18:44 +00:00
|
|
|
|
} else {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
return $hostname .'+'. $date .'+'. $random;
|
2003-08-23 14:18:44 +00:00
|
|
|
|
}
|
2003-08-23 12:22:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-10-10 07:26:10 +00:00
|
|
|
|
|
2004-07-08 07:52:01 +00:00
|
|
|
|
/**
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Function to check the passed address is within the passed subnet
|
|
|
|
|
*
|
|
|
|
|
* The parameter is a comma separated string of subnet definitions.
|
2006-10-16 13:38:36 +00:00
|
|
|
|
* Subnet strings can be in one of three formats:
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* 1: xxx.xxx.xxx.xxx/xx
|
|
|
|
|
* 2: xxx.xxx
|
2006-10-16 13:38:36 +00:00
|
|
|
|
* 3: xxx.xxx.xxx.xxx-xxx //a range of IP addresses in the last group.
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* Code for type 1 modified from user posted comments by mediator at
|
|
|
|
|
* {@link http://au.php.net/manual/en/function.ip2long.php}
|
|
|
|
|
*
|
|
|
|
|
* @param string $addr The address you are checking
|
|
|
|
|
* @param string $subnetstr The string of subnet addresses
|
2005-07-12 02:06:33 +00:00
|
|
|
|
* @return bool
|
2004-09-25 01:29:37 +00:00
|
|
|
|
*/
|
2004-07-08 07:52:01 +00:00
|
|
|
|
function address_in_subnet($addr, $subnetstr) {
|
|
|
|
|
|
2004-09-22 14:39:15 +00:00
|
|
|
|
$subnets = explode(',', $subnetstr);
|
2004-07-08 07:52:01 +00:00
|
|
|
|
$found = false;
|
|
|
|
|
$addr = trim($addr);
|
|
|
|
|
|
|
|
|
|
foreach ($subnets as $subnet) {
|
|
|
|
|
$subnet = trim($subnet);
|
2004-09-22 14:39:15 +00:00
|
|
|
|
if (strpos($subnet, '/') !== false) { /// type 1
|
2004-07-08 07:52:01 +00:00
|
|
|
|
list($ip, $mask) = explode('/', $subnet);
|
|
|
|
|
$mask = 0xffffffff << (32 - $mask);
|
|
|
|
|
$found = ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
|
2006-10-16 13:38:36 +00:00
|
|
|
|
} else if (strpos($subnet, '-') !== false) {/// type 3
|
|
|
|
|
$subnetparts = explode('.', $subnet);
|
|
|
|
|
$addrparts = explode('.', $addr);
|
|
|
|
|
$subnetrange = explode('-', array_pop($subnetparts));
|
|
|
|
|
if (count($subnetrange) == 2) {
|
|
|
|
|
$lastaddrpart = array_pop($addrparts);
|
|
|
|
|
$found = ($subnetparts == $addrparts &&
|
|
|
|
|
$subnetrange[0] <= $lastaddrpart && $lastaddrpart <= $subnetrange[1]);
|
|
|
|
|
}
|
2004-07-08 07:52:01 +00:00
|
|
|
|
} else { /// type 2
|
|
|
|
|
$found = (strpos($addr, $subnet) === 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($found) {
|
2005-03-10 02:36:51 +00:00
|
|
|
|
break;
|
2004-07-08 07:52:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $found;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 19:44:42 +00:00
|
|
|
|
/**
|
2006-03-04 16:53:02 +00:00
|
|
|
|
* This function sets the $HTTPSPAGEREQUIRED global
|
2005-07-14 19:44:42 +00:00
|
|
|
|
* (used in some parts of moodle to change some links)
|
|
|
|
|
* and calculate the proper wwwroot to be used
|
|
|
|
|
*
|
|
|
|
|
* By using this function properly, we can ensure 100% https-ized pages
|
|
|
|
|
* at our entire discretion (login, forgot_password, change_password)
|
|
|
|
|
*/
|
|
|
|
|
function httpsrequired() {
|
|
|
|
|
|
|
|
|
|
global $CFG, $HTTPSPAGEREQUIRED;
|
|
|
|
|
|
|
|
|
|
if (!empty($CFG->loginhttps)) {
|
|
|
|
|
$HTTPSPAGEREQUIRED = true;
|
2005-08-09 15:16:23 +00:00
|
|
|
|
$CFG->httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot);
|
2006-10-09 10:12:41 +00:00
|
|
|
|
$CFG->httpsthemewww = str_replace('http:', 'https:', $CFG->themewww);
|
2007-01-27 19:56:08 +00:00
|
|
|
|
|
2007-01-28 21:18:08 +00:00
|
|
|
|
// change theme URLs to https
|
|
|
|
|
theme_setup();
|
|
|
|
|
|
2005-07-14 19:44:42 +00:00
|
|
|
|
} else {
|
|
|
|
|
$CFG->httpswwwroot = $CFG->wwwroot;
|
2006-10-09 10:12:41 +00:00
|
|
|
|
$CFG->httpsthemewww = $CFG->themewww;
|
2005-07-14 19:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-23 05:10:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* For outputting debugging info
|
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @uses STDOUT
|
|
|
|
|
* @param string $string ?
|
|
|
|
|
* @param string $eol ?
|
2004-09-23 05:10:21 +00:00
|
|
|
|
* @todo Finish documenting this function
|
|
|
|
|
*/
|
2005-02-19 14:48:44 +00:00
|
|
|
|
function mtrace($string, $eol="\n", $sleep=0) {
|
2004-08-07 03:59:53 +00:00
|
|
|
|
|
|
|
|
|
if (defined('STDOUT')) {
|
|
|
|
|
fwrite(STDOUT, $string.$eol);
|
|
|
|
|
} else {
|
2004-09-22 14:39:15 +00:00
|
|
|
|
echo $string . $eol;
|
2004-08-07 03:59:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-08-05 17:08:46 +00:00
|
|
|
|
flush();
|
2005-02-19 14:48:44 +00:00
|
|
|
|
|
|
|
|
|
//delay to keep message on user's screen in case of subsequent redirect
|
|
|
|
|
if ($sleep) {
|
|
|
|
|
sleep($sleep);
|
|
|
|
|
}
|
2004-08-05 17:08:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-10-16 11:39:52 +00:00
|
|
|
|
//Replace 1 or more slashes or backslashes to 1 slash
|
2004-10-08 06:11:17 +00:00
|
|
|
|
function cleardoubleslashes ($path) {
|
|
|
|
|
return preg_replace('/(\/|\\\){1,}/','/',$path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function zip_files ($originalfiles, $destination) {
|
2004-10-10 01:07:47 +00:00
|
|
|
|
//Zip an array of files/dirs to a destination zip file
|
|
|
|
|
//Both parameters must be FULL paths to the files/dirs
|
2004-10-08 06:11:17 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
//Extract everything from destination
|
|
|
|
|
$path_parts = pathinfo(cleardoubleslashes($destination));
|
2004-10-10 01:07:47 +00:00
|
|
|
|
$destpath = $path_parts["dirname"]; //The path of the zip file
|
|
|
|
|
$destfilename = $path_parts["basename"]; //The name of the zip file
|
|
|
|
|
$extension = $path_parts["extension"]; //The extension of the file
|
2004-10-08 06:11:17 +00:00
|
|
|
|
|
|
|
|
|
//If no file, error
|
2004-10-10 01:07:47 +00:00
|
|
|
|
if (empty($destfilename)) {
|
2004-10-08 06:11:17 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//If no extension, add it
|
2004-11-22 18:38:33 +00:00
|
|
|
|
if (empty($extension)) {
|
2004-10-08 06:11:17 +00:00
|
|
|
|
$extension = 'zip';
|
2004-10-10 01:07:47 +00:00
|
|
|
|
$destfilename = $destfilename.'.'.$extension;
|
2004-10-08 06:11:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-10-10 01:07:47 +00:00
|
|
|
|
//Check destination path exists
|
|
|
|
|
if (!is_dir($destpath)) {
|
2004-10-08 06:11:17 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-10-10 01:07:47 +00:00
|
|
|
|
//Check destination path is writable. TODO!!
|
2004-10-08 06:11:17 +00:00
|
|
|
|
|
2004-10-10 01:07:47 +00:00
|
|
|
|
//Clean destination filename
|
|
|
|
|
$destfilename = clean_filename($destfilename);
|
|
|
|
|
|
|
|
|
|
//Now check and prepare every file
|
|
|
|
|
$files = array();
|
|
|
|
|
$origpath = NULL;
|
|
|
|
|
|
|
|
|
|
foreach ($originalfiles as $file) { //Iterate over each file
|
|
|
|
|
//Check for every file
|
|
|
|
|
$tempfile = cleardoubleslashes($file); // no doubleslashes!
|
|
|
|
|
//Calculate the base path for all files if it isn't set
|
|
|
|
|
if ($origpath === NULL) {
|
|
|
|
|
$origpath = rtrim(cleardoubleslashes(dirname($tempfile)), "/");
|
|
|
|
|
}
|
|
|
|
|
//See if the file is readable
|
|
|
|
|
if (!is_readable($tempfile)) { //Is readable
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
//See if the file/dir is in the same directory than the rest
|
|
|
|
|
if (rtrim(cleardoubleslashes(dirname($tempfile)), "/") != $origpath) {
|
|
|
|
|
continue;
|
2004-10-08 06:11:17 +00:00
|
|
|
|
}
|
2004-10-10 01:07:47 +00:00
|
|
|
|
//Add the file to the array
|
|
|
|
|
$files[] = $tempfile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Everything is ready:
|
|
|
|
|
// -$origpath is the path where ALL the files to be compressed reside (dir).
|
|
|
|
|
// -$destpath is the destination path where the zip file will go (dir).
|
|
|
|
|
// -$files is an array of files/dirs to compress (fullpath)
|
|
|
|
|
// -$destfilename is the name of the zip file (without path)
|
|
|
|
|
|
|
|
|
|
//print_object($files); //Debug
|
|
|
|
|
|
|
|
|
|
if (empty($CFG->zip)) { // Use built-in php-based zip function
|
|
|
|
|
|
2004-10-08 06:11:17 +00:00
|
|
|
|
include_once("$CFG->libdir/pclzip/pclzip.lib.php");
|
2006-10-19 22:13:03 +00:00
|
|
|
|
//rewrite filenames because the old method with PCLZIP_OPT_REMOVE_PATH does not work under win32
|
|
|
|
|
$zipfiles = array();
|
|
|
|
|
$start = strlen($origpath)+1;
|
|
|
|
|
foreach($files as $file) {
|
|
|
|
|
$tf = array();
|
|
|
|
|
$tf[PCLZIP_ATT_FILE_NAME] = $file;
|
|
|
|
|
$tf[PCLZIP_ATT_FILE_NEW_FULL_NAME] = substr($file, $start);
|
|
|
|
|
$zipfiles[] = $tf;
|
|
|
|
|
}
|
|
|
|
|
//create the archive
|
2004-10-10 01:07:47 +00:00
|
|
|
|
$archive = new PclZip(cleardoubleslashes("$destpath/$destfilename"));
|
2006-10-19 22:13:03 +00:00
|
|
|
|
if (($list = $archive->create($zipfiles) == 0)) {
|
2004-10-10 01:07:47 +00:00
|
|
|
|
notice($archive->errorInfo(true));
|
|
|
|
|
return false;
|
2004-10-08 06:11:17 +00:00
|
|
|
|
}
|
2004-10-10 01:07:47 +00:00
|
|
|
|
|
2004-10-08 06:11:17 +00:00
|
|
|
|
} else { // Use external zip program
|
2004-10-10 01:07:47 +00:00
|
|
|
|
|
|
|
|
|
$filestozip = "";
|
|
|
|
|
foreach ($files as $filetozip) {
|
|
|
|
|
$filestozip .= escapeshellarg(basename($filetozip));
|
|
|
|
|
$filestozip .= " ";
|
2004-10-08 06:11:17 +00:00
|
|
|
|
}
|
2004-10-10 01:07:47 +00:00
|
|
|
|
//Construct the command
|
2007-01-04 02:52:44 +00:00
|
|
|
|
$separator = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? ' &' : ' ;';
|
|
|
|
|
$command = 'cd '.escapeshellarg($origpath).$separator.
|
2004-10-10 01:07:47 +00:00
|
|
|
|
escapeshellarg($CFG->zip).' -r '.
|
|
|
|
|
escapeshellarg(cleardoubleslashes("$destpath/$destfilename")).' '.$filestozip;
|
2004-10-10 23:25:57 +00:00
|
|
|
|
//All converted to backslashes in WIN
|
|
|
|
|
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
|
|
|
|
$command = str_replace('/','\\',$command);
|
|
|
|
|
}
|
2004-10-08 06:11:17 +00:00
|
|
|
|
Exec($command);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2004-10-16 16:33:40 +00:00
|
|
|
|
function unzip_file ($zipfile, $destination = '', $showstatus = true) {
|
2004-10-10 21:46:13 +00:00
|
|
|
|
//Unzip one zip file to a destination dir
|
|
|
|
|
//Both parameters must be FULL paths
|
|
|
|
|
//If destination isn't specified, it will be the
|
|
|
|
|
//SAME directory where the zip file resides.
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
2004-11-22 18:38:33 +00:00
|
|
|
|
|
2004-10-10 21:46:13 +00:00
|
|
|
|
//Extract everything from zipfile
|
|
|
|
|
$path_parts = pathinfo(cleardoubleslashes($zipfile));
|
|
|
|
|
$zippath = $path_parts["dirname"]; //The path of the zip file
|
|
|
|
|
$zipfilename = $path_parts["basename"]; //The name of the zip file
|
|
|
|
|
$extension = $path_parts["extension"]; //The extension of the file
|
|
|
|
|
|
|
|
|
|
//If no file, error
|
|
|
|
|
if (empty($zipfilename)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//If no extension, error
|
|
|
|
|
if (empty($extension)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2005-10-02 18:40:13 +00:00
|
|
|
|
|
|
|
|
|
//Clear $zipfile
|
|
|
|
|
$zipfile = cleardoubleslashes($zipfile);
|
|
|
|
|
|
|
|
|
|
//Check zipfile exists
|
|
|
|
|
if (!file_exists($zipfile)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-10-10 21:46:13 +00:00
|
|
|
|
|
|
|
|
|
//If no destination, passed let's go with the same directory
|
|
|
|
|
if (empty($destination)) {
|
|
|
|
|
$destination = $zippath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Clear $destination
|
|
|
|
|
$destpath = rtrim(cleardoubleslashes($destination), "/");
|
|
|
|
|
|
|
|
|
|
//Check destination path exists
|
|
|
|
|
if (!is_dir($destpath)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Check destination path is writable. TODO!!
|
|
|
|
|
|
|
|
|
|
//Everything is ready:
|
|
|
|
|
// -$zippath is the path where the zip file resides (dir)
|
|
|
|
|
// -$zipfilename is the name of the zip file (without path)
|
|
|
|
|
// -$destpath is the destination path where the zip file will uncompressed (dir)
|
|
|
|
|
|
2007-01-20 14:06:07 +00:00
|
|
|
|
$list = null;
|
|
|
|
|
|
2004-10-10 21:46:13 +00:00
|
|
|
|
if (empty($CFG->unzip)) { // Use built-in php-based unzip function
|
|
|
|
|
|
|
|
|
|
include_once("$CFG->libdir/pclzip/pclzip.lib.php");
|
|
|
|
|
$archive = new PclZip(cleardoubleslashes("$zippath/$zipfilename"));
|
|
|
|
|
if (!$list = $archive->extract(PCLZIP_OPT_PATH, $destpath,
|
2006-08-30 08:51:57 +00:00
|
|
|
|
PCLZIP_CB_PRE_EXTRACT, 'unzip_cleanfilename',
|
|
|
|
|
PCLZIP_OPT_EXTRACT_DIR_RESTRICTION, $destpath)) {
|
2008-02-21 05:24:18 +00:00
|
|
|
|
if (!empty($showstatus)) {
|
|
|
|
|
notice($archive->errorInfo(true));
|
|
|
|
|
}
|
2004-10-10 21:46:13 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else { // Use external unzip program
|
|
|
|
|
|
|
|
|
|
$separator = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? ' &' : ' ;';
|
|
|
|
|
$redirection = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '' : ' 2>&1';
|
|
|
|
|
|
|
|
|
|
$command = 'cd '.escapeshellarg($zippath).$separator.
|
|
|
|
|
escapeshellarg($CFG->unzip).' -o '.
|
|
|
|
|
escapeshellarg(cleardoubleslashes("$zippath/$zipfilename")).' -d '.
|
|
|
|
|
escapeshellarg($destpath).$redirection;
|
2004-10-10 23:25:57 +00:00
|
|
|
|
//All converted to backslashes in WIN
|
|
|
|
|
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
|
|
|
|
$command = str_replace('/','\\',$command);
|
|
|
|
|
}
|
2004-10-10 21:46:13 +00:00
|
|
|
|
Exec($command,$list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Display some info about the unzip execution
|
2004-10-16 16:33:40 +00:00
|
|
|
|
if ($showstatus) {
|
|
|
|
|
unzip_show_status($list,$destpath);
|
|
|
|
|
}
|
2004-11-22 18:38:33 +00:00
|
|
|
|
|
2004-10-10 21:46:13 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2004-10-17 22:28:53 +00:00
|
|
|
|
function unzip_cleanfilename ($p_event, &$p_header) {
|
2004-10-10 21:46:13 +00:00
|
|
|
|
//This function is used as callback in unzip_file() function
|
2004-10-17 22:28:53 +00:00
|
|
|
|
//to clean illegal characters for given platform and to prevent directory traversal.
|
|
|
|
|
//Produces the same result as info-zip unzip.
|
2004-10-17 23:44:16 +00:00
|
|
|
|
$p_header['filename'] = ereg_replace('[[:cntrl:]]', '', $p_header['filename']); //strip control chars first!
|
2004-10-17 22:28:53 +00:00
|
|
|
|
$p_header['filename'] = ereg_replace('\.\.+', '', $p_header['filename']); //directory traversal protection
|
|
|
|
|
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
|
|
|
|
$p_header['filename'] = ereg_replace('[:*"?<>|]', '_', $p_header['filename']); //replace illegal chars
|
|
|
|
|
$p_header['filename'] = ereg_replace('^([a-zA-Z])_', '\1:', $p_header['filename']); //repair drive letter
|
2004-10-10 21:46:13 +00:00
|
|
|
|
} else {
|
2004-10-17 22:28:53 +00:00
|
|
|
|
//Add filtering for other systems here
|
|
|
|
|
// BSD: none (tested)
|
|
|
|
|
// Linux: ??
|
|
|
|
|
// MacosX: ??
|
2004-11-22 18:38:33 +00:00
|
|
|
|
}
|
2004-10-17 22:28:53 +00:00
|
|
|
|
$p_header['filename'] = cleardoubleslashes($p_header['filename']); //normalize the slashes/backslashes
|
|
|
|
|
return 1;
|
2004-10-10 21:46:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-10-10 22:48:59 +00:00
|
|
|
|
function unzip_show_status ($list,$removepath) {
|
2004-10-10 21:46:13 +00:00
|
|
|
|
//This function shows the results of the unzip execution
|
|
|
|
|
//depending of the value of the $CFG->zip, results will be
|
|
|
|
|
//text or an array of files.
|
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (empty($CFG->unzip)) { // Use built-in php-based zip function
|
2004-10-10 22:48:59 +00:00
|
|
|
|
$strname = get_string("name");
|
|
|
|
|
$strsize = get_string("size");
|
|
|
|
|
$strmodified = get_string("modified");
|
|
|
|
|
$strstatus = get_string("status");
|
2007-01-05 12:58:22 +00:00
|
|
|
|
echo "<table width=\"640\">";
|
|
|
|
|
echo "<tr><th class=\"header\" scope=\"col\">$strname</th>";
|
2006-12-13 08:24:23 +00:00
|
|
|
|
echo "<th class=\"header\" align=\"right\" scope=\"col\">$strsize</th>";
|
|
|
|
|
echo "<th class=\"header\" align=\"right\" scope=\"col\">$strmodified</th>";
|
|
|
|
|
echo "<th class=\"header\" align=\"right\" scope=\"col\">$strstatus</th></tr>";
|
2004-10-10 21:46:13 +00:00
|
|
|
|
foreach ($list as $item) {
|
|
|
|
|
echo "<tr>";
|
2004-10-10 22:48:59 +00:00
|
|
|
|
$item['filename'] = str_replace(cleardoubleslashes($removepath).'/', "", $item['filename']);
|
2006-07-12 05:57:28 +00:00
|
|
|
|
print_cell("left", s($item['filename']));
|
2004-10-10 21:46:13 +00:00
|
|
|
|
if (! $item['folder']) {
|
|
|
|
|
print_cell("right", display_size($item['size']));
|
|
|
|
|
} else {
|
|
|
|
|
echo "<td> </td>";
|
|
|
|
|
}
|
|
|
|
|
$filedate = userdate($item['mtime'], get_string("strftimedatetime"));
|
|
|
|
|
print_cell("right", $filedate);
|
|
|
|
|
print_cell("right", $item['status']);
|
|
|
|
|
echo "</tr>";
|
|
|
|
|
}
|
|
|
|
|
echo "</table>";
|
|
|
|
|
|
|
|
|
|
} else { // Use external zip program
|
|
|
|
|
print_simple_box_start("center");
|
2005-03-13 13:50:23 +00:00
|
|
|
|
echo "<pre>";
|
2004-10-10 21:46:13 +00:00
|
|
|
|
foreach ($list as $item) {
|
2006-07-12 05:57:28 +00:00
|
|
|
|
echo s(str_replace(cleardoubleslashes($removepath.'/'), '', $item)).'<br />';
|
2004-10-10 21:46:13 +00:00
|
|
|
|
}
|
2005-03-13 13:50:23 +00:00
|
|
|
|
echo "</pre>";
|
2004-10-10 21:46:13 +00:00
|
|
|
|
print_simple_box_end();
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-09-23 05:10:21 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns most reliable client address
|
2004-11-22 18:38:33 +00:00
|
|
|
|
*
|
2004-09-25 01:29:37 +00:00
|
|
|
|
* @return string The remote IP address
|
2004-09-23 05:10:21 +00:00
|
|
|
|
*/
|
|
|
|
|
function getremoteaddr() {
|
2005-04-01 07:40:07 +00:00
|
|
|
|
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
2005-08-18 01:44:47 +00:00
|
|
|
|
return cleanremoteaddr($_SERVER['HTTP_CLIENT_IP']);
|
2005-04-01 07:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
2005-08-18 01:44:47 +00:00
|
|
|
|
return cleanremoteaddr($_SERVER['HTTP_X_FORWARDED_FOR']);
|
2005-04-01 07:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
if (!empty($_SERVER['REMOTE_ADDR'])) {
|
2005-08-18 01:44:47 +00:00
|
|
|
|
return cleanremoteaddr($_SERVER['REMOTE_ADDR']);
|
2005-04-01 07:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
return '';
|
2004-11-22 18:38:33 +00:00
|
|
|
|
}
|
2004-08-05 17:08:46 +00:00
|
|
|
|
|
2006-03-04 16:53:02 +00:00
|
|
|
|
/**
|
2005-08-18 01:44:47 +00:00
|
|
|
|
* Cleans a remote address ready to put into the log table
|
|
|
|
|
*/
|
|
|
|
|
function cleanremoteaddr($addr) {
|
2005-09-08 23:04:23 +00:00
|
|
|
|
$originaladdr = $addr;
|
|
|
|
|
$matches = array();
|
|
|
|
|
// first get all things that look like IP addresses.
|
|
|
|
|
if (!preg_match_all('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/',$addr,$matches,PREG_SET_ORDER)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
$goodmatches = array();
|
|
|
|
|
$lanmatches = array();
|
|
|
|
|
foreach ($matches as $match) {
|
|
|
|
|
// print_r($match);
|
|
|
|
|
// check to make sure it's not an internal address.
|
|
|
|
|
// the following are reserved for private lans...
|
|
|
|
|
// 10.0.0.0 - 10.255.255.255
|
|
|
|
|
// 172.16.0.0 - 172.31.255.255
|
|
|
|
|
// 192.168.0.0 - 192.168.255.255
|
2006-03-04 16:53:02 +00:00
|
|
|
|
// 169.254.0.0 -169.254.255.255
|
2005-09-08 23:04:23 +00:00
|
|
|
|
$bits = explode('.',$match[0]);
|
|
|
|
|
if (count($bits) != 4) {
|
|
|
|
|
// weird, preg match shouldn't give us it.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
if (($bits[0] == 10)
|
2005-09-08 23:04:23 +00:00
|
|
|
|
|| ($bits[0] == 172 && $bits[1] >= 16 && $bits[1] <= 31)
|
|
|
|
|
|| ($bits[0] == 192 && $bits[1] == 168)
|
|
|
|
|
|| ($bits[0] == 169 && $bits[1] == 254)) {
|
|
|
|
|
$lanmatches[] = $match[0];
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// finally, it's ok
|
|
|
|
|
$goodmatches[] = $match[0];
|
|
|
|
|
}
|
|
|
|
|
if (!count($goodmatches)) {
|
|
|
|
|
// perhaps we have a lan match, it's probably better to return that.
|
|
|
|
|
if (!count($lanmatches)) {
|
|
|
|
|
return '';
|
|
|
|
|
} else {
|
|
|
|
|
return array_pop($lanmatches);
|
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
}
|
2005-09-08 23:04:23 +00:00
|
|
|
|
if (count($goodmatches) == 1) {
|
|
|
|
|
return $goodmatches[0];
|
|
|
|
|
}
|
2008-02-20 07:02:14 +00:00
|
|
|
|
//Commented out following because there are so many, and it clogs the logs MDL-13544
|
|
|
|
|
//error_log("NOTICE: cleanremoteaddr gives us something funny: $originaladdr had ".count($goodmatches)." matches");
|
|
|
|
|
|
|
|
|
|
// We need to return something, so return the first
|
2005-09-08 23:04:23 +00:00
|
|
|
|
return array_pop($goodmatches);
|
2005-08-18 01:44:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-04-26 04:39:34 +00:00
|
|
|
|
/**
|
2007-07-18 05:17:45 +00:00
|
|
|
|
* This function will make a complete copy of anything it's given,
|
2006-04-26 04:39:34 +00:00
|
|
|
|
* regardless of whether it's an object or not.
|
|
|
|
|
* @param mixed $thing
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
function fullclone($thing) {
|
|
|
|
|
return unserialize(serialize($thing));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-05 05:04:06 +00:00
|
|
|
|
/*
|
|
|
|
|
* This function expects to called during shutdown
|
|
|
|
|
* should be set via register_shutdown_function()
|
|
|
|
|
* in lib/setup.php .
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2007-04-05 05:04:06 +00:00
|
|
|
|
* Right now we do it only if we are under apache, to
|
|
|
|
|
* make sure apache children that hog too much mem are
|
|
|
|
|
* killed.
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2007-04-05 05:04:06 +00:00
|
|
|
|
*/
|
|
|
|
|
function moodle_request_shutdown() {
|
|
|
|
|
|
2007-04-07 16:08:51 +00:00
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-07-18 05:17:45 +00:00
|
|
|
|
// initially, we are only ever called under apache
|
|
|
|
|
// but check just in case
|
|
|
|
|
if (function_exists('apache_child_terminate')
|
2007-06-07 21:22:20 +00:00
|
|
|
|
&& function_exists('memory_get_usage')
|
|
|
|
|
&& ini_get_bool('child_terminate')) {
|
2007-04-05 05:04:06 +00:00
|
|
|
|
if (empty($CFG->apachemaxmem)) {
|
2007-04-12 03:25:57 +00:00
|
|
|
|
$CFG->apachemaxmem = 25000000; // default 25MiB
|
2007-04-05 05:04:06 +00:00
|
|
|
|
}
|
|
|
|
|
if (memory_get_usage() > (int)$CFG->apachemaxmem) {
|
|
|
|
|
trigger_error('Mem usage over $CFG->apachemaxmem: marking child for reaping.');
|
2007-04-16 00:24:27 +00:00
|
|
|
|
@apache_child_terminate();
|
2007-04-05 05:04:06 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-09-12 02:57:26 +00:00
|
|
|
|
if (defined('MDL_PERF') || (!empty($CFG->perfdebug) and $CFG->perfdebug > 7)) {
|
|
|
|
|
if (defined('MDL_PERFTOLOG')) {
|
|
|
|
|
$perf = get_performance_info();
|
|
|
|
|
error_log("PERF: " . $perf['txt']);
|
|
|
|
|
}
|
2007-09-19 07:46:39 +00:00
|
|
|
|
if (defined('MDL_PERFINC')) {
|
|
|
|
|
$inc = get_included_files();
|
|
|
|
|
$ts = 0;
|
|
|
|
|
foreach($inc as $f) {
|
|
|
|
|
if (preg_match(':^/:', $f)) {
|
|
|
|
|
$fs = filesize($f);
|
|
|
|
|
$ts += $fs;
|
|
|
|
|
$hfs = display_size($fs);
|
|
|
|
|
error_log(substr($f,strlen($CFG->dirroot)) . " size: $fs ($hfs)"
|
|
|
|
|
, NULL, NULL, 0);
|
|
|
|
|
} else {
|
|
|
|
|
error_log($f , NULL, NULL, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($ts > 0 ) {
|
|
|
|
|
$hts = display_size($ts);
|
|
|
|
|
error_log("Total size of files included: $ts ($hts)");
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-09-12 02:57:26 +00:00
|
|
|
|
}
|
2007-04-05 05:04:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-30 12:54:22 +00:00
|
|
|
|
/**
|
2005-02-25 06:08:40 +00:00
|
|
|
|
* If new messages are waiting for the current user, then return
|
2004-12-30 12:54:22 +00:00
|
|
|
|
* Javascript code to create a popup window
|
|
|
|
|
*
|
|
|
|
|
* @return string Javascript code
|
|
|
|
|
*/
|
|
|
|
|
function message_popup_window() {
|
|
|
|
|
global $USER;
|
|
|
|
|
|
|
|
|
|
$popuplimit = 30; // Minimum seconds between popups
|
|
|
|
|
|
|
|
|
|
if (!defined('MESSAGE_WINDOW')) {
|
2007-09-04 06:47:02 +00:00
|
|
|
|
if (isset($USER->id) and !isguestuser()) {
|
2004-12-30 12:54:22 +00:00
|
|
|
|
if (!isset($USER->message_lastpopup)) {
|
|
|
|
|
$USER->message_lastpopup = 0;
|
|
|
|
|
}
|
|
|
|
|
if ((time() - $USER->message_lastpopup) > $popuplimit) { /// It's been long enough
|
|
|
|
|
if (get_user_preferences('message_showmessagewindow', 1) == 1) {
|
|
|
|
|
if (count_records_select('message', 'useridto = \''.$USER->id.'\' AND timecreated > \''.$USER->message_lastpopup.'\'')) {
|
|
|
|
|
$USER->message_lastpopup = time();
|
2007-01-03 14:44:17 +00:00
|
|
|
|
return '<script type="text/javascript">'."\n//<![CDATA[\n openpopup('/message/index.php', 'message',
|
|
|
|
|
'menubar=0,location=0,scrollbars,status,resizable,width=400,height=500', 0);\n//]]>\n</script>";
|
2004-12-30 12:54:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-02 02:22:56 +00:00
|
|
|
|
// Used to make sure that $min <= $value <= $max
|
|
|
|
|
function bounded_number($min, $value, $max) {
|
|
|
|
|
if($value < $min) {
|
|
|
|
|
return $min;
|
|
|
|
|
}
|
|
|
|
|
if($value > $max) {
|
|
|
|
|
return $max;
|
|
|
|
|
}
|
|
|
|
|
return $value;
|
|
|
|
|
}
|
|
|
|
|
|
2006-01-11 02:22:16 +00:00
|
|
|
|
function array_is_nested($array) {
|
|
|
|
|
foreach ($array as $value) {
|
|
|
|
|
if (is_array($value)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2005-04-01 10:00:18 +00:00
|
|
|
|
|
2005-04-06 07:34:05 +00:00
|
|
|
|
/**
|
|
|
|
|
*** get_performance_info() pairs up with init_performance_info()
|
2006-03-04 16:53:02 +00:00
|
|
|
|
*** loaded in setup.php. Returns an array with 'html' and 'txt'
|
2005-04-06 07:34:05 +00:00
|
|
|
|
*** values ready for use, and each of the individual stats provided
|
|
|
|
|
*** separately as well.
|
|
|
|
|
***
|
|
|
|
|
**/
|
|
|
|
|
function get_performance_info() {
|
2006-12-27 22:39:32 +00:00
|
|
|
|
global $CFG, $PERF, $rcache;
|
2005-04-01 10:00:18 +00:00
|
|
|
|
|
2005-04-06 07:34:05 +00:00
|
|
|
|
$info = array();
|
2005-04-16 17:02:05 +00:00
|
|
|
|
$info['html'] = ''; // holds userfriendly HTML representation
|
|
|
|
|
$info['txt'] = me() . ' '; // holds log-friendly representation
|
2005-04-01 10:00:18 +00:00
|
|
|
|
|
2005-04-06 07:34:05 +00:00
|
|
|
|
$info['realtime'] = microtime_diff($PERF->starttime, microtime());
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2005-04-06 07:34:05 +00:00
|
|
|
|
$info['html'] .= '<span class="timeused">'.$info['realtime'].' secs</span> ';
|
|
|
|
|
$info['txt'] .= 'time: '.$info['realtime'].'s ';
|
2005-04-01 10:00:18 +00:00
|
|
|
|
|
|
|
|
|
if (function_exists('memory_get_usage')) {
|
2005-04-06 07:34:05 +00:00
|
|
|
|
$info['memory_total'] = memory_get_usage();
|
|
|
|
|
$info['memory_growth'] = memory_get_usage() - $PERF->startmemory;
|
|
|
|
|
$info['html'] .= '<span class="memoryused">RAM: '.display_size($info['memory_total']).'</span> ';
|
|
|
|
|
$info['txt'] .= 'memory_total: '.$info['memory_total'].'B (' . display_size($info['memory_total']).') memory_growth: '.$info['memory_growth'].'B ('.display_size($info['memory_growth']).') ';
|
2005-04-01 10:00:18 +00:00
|
|
|
|
}
|
2005-04-06 07:34:05 +00:00
|
|
|
|
|
2008-02-15 11:32:34 +00:00
|
|
|
|
if (function_exists('memory_get_peak_usage')) {
|
|
|
|
|
$info['memory_peak'] = memory_get_peak_usage();
|
|
|
|
|
$info['html'] .= '<span class="memoryused">RAM peak: '.display_size($info['memory_peak']).'</span> ';
|
|
|
|
|
$info['txt'] .= 'memory_peak: '.$info['memory_peak'].'B (' . display_size($info['memory_peak']).') ';
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-06 07:34:05 +00:00
|
|
|
|
$inc = get_included_files();
|
|
|
|
|
//error_log(print_r($inc,1));
|
|
|
|
|
$info['includecount'] = count($inc);
|
|
|
|
|
$info['html'] .= '<span class="included">Included '.$info['includecount'].' files</span> ';
|
|
|
|
|
$info['txt'] .= 'includecount: '.$info['includecount'].' ';
|
|
|
|
|
|
|
|
|
|
if (!empty($PERF->dbqueries)) {
|
|
|
|
|
$info['dbqueries'] = $PERF->dbqueries;
|
2005-04-07 00:11:28 +00:00
|
|
|
|
$info['html'] .= '<span class="dbqueries">DB queries '.$info['dbqueries'].'</span> ';
|
2005-04-06 07:34:05 +00:00
|
|
|
|
$info['txt'] .= 'dbqueries: '.$info['dbqueries'].' ';
|
2005-04-01 10:00:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-04-06 07:34:05 +00:00
|
|
|
|
if (!empty($PERF->logwrites)) {
|
|
|
|
|
$info['logwrites'] = $PERF->logwrites;
|
|
|
|
|
$info['html'] .= '<span class="logwrites">Log writes '.$info['logwrites'].'</span> ';
|
|
|
|
|
$info['txt'] .= 'logwrites: '.$info['logwrites'].' ';
|
|
|
|
|
}
|
2007-07-18 05:17:45 +00:00
|
|
|
|
|
2007-03-20 02:59:34 +00:00
|
|
|
|
if (!empty($PERF->profiling) && $PERF->profiling) {
|
2007-03-19 18:54:58 +00:00
|
|
|
|
require_once($CFG->dirroot .'/lib/profilerlib.php');
|
2007-03-20 02:59:34 +00:00
|
|
|
|
$info['html'] .= '<span class="profilinginfo">'.Profiler::get_profiling(array('-R')).'</span>';
|
2007-03-19 18:54:58 +00:00
|
|
|
|
}
|
2005-04-06 07:34:05 +00:00
|
|
|
|
|
|
|
|
|
if (function_exists('posix_times')) {
|
|
|
|
|
$ptimes = posix_times();
|
2006-02-28 04:41:44 +00:00
|
|
|
|
if (is_array($ptimes)) {
|
2006-02-28 04:33:39 +00:00
|
|
|
|
foreach ($ptimes as $key => $val) {
|
2006-03-04 16:53:02 +00:00
|
|
|
|
$info[$key] = $ptimes[$key] - $PERF->startposixtimes[$key];
|
2006-02-28 04:33:39 +00:00
|
|
|
|
}
|
|
|
|
|
$info['html'] .= "<span class=\"posixtimes\">ticks: $info[ticks] user: $info[utime] sys: $info[stime] cuser: $info[cutime] csys: $info[cstime]</span> ";
|
|
|
|
|
$info['txt'] .= "ticks: $info[ticks] user: $info[utime] sys: $info[stime] cuser: $info[cutime] csys: $info[cstime] ";
|
2005-04-06 07:34:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Grab the load average for the last minute
|
|
|
|
|
// /proc will only work under some linux configurations
|
|
|
|
|
// while uptime is there under MacOSX/Darwin and other unices
|
|
|
|
|
if (is_readable('/proc/loadavg') && $loadavg = @file('/proc/loadavg')) {
|
|
|
|
|
list($server_load) = explode(' ', $loadavg[0]);
|
|
|
|
|
unset($loadavg);
|
2005-04-08 05:01:09 +00:00
|
|
|
|
} else if ( function_exists('is_executable') && is_executable('/usr/bin/uptime') && $loadavg = `/usr/bin/uptime` ) {
|
2006-10-07 10:33:58 +00:00
|
|
|
|
if (preg_match('/load averages?: (\d+[\.,:]\d+)/', $loadavg, $matches)) {
|
2005-04-06 07:34:05 +00:00
|
|
|
|
$server_load = $matches[1];
|
|
|
|
|
} else {
|
|
|
|
|
trigger_error('Could not parse uptime output!');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!empty($server_load)) {
|
|
|
|
|
$info['serverload'] = $server_load;
|
2005-05-15 04:22:40 +00:00
|
|
|
|
$info['html'] .= '<span class="serverload">Load average: '.$info['serverload'].'</span> ';
|
2006-12-27 22:39:32 +00:00
|
|
|
|
$info['txt'] .= "serverload: {$info['serverload']} ";
|
2005-04-01 10:00:18 +00:00
|
|
|
|
}
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
2006-12-27 22:39:32 +00:00
|
|
|
|
if (isset($rcache->hits) && isset($rcache->misses)) {
|
|
|
|
|
$info['rcachehits'] = $rcache->hits;
|
|
|
|
|
$info['rcachemisses'] = $rcache->misses;
|
2007-07-18 05:17:45 +00:00
|
|
|
|
$info['html'] .= '<span class="rcache">Record cache hit/miss ratio : '.
|
2006-12-27 22:40:16 +00:00
|
|
|
|
"{$rcache->hits}/{$rcache->misses}</span> ";
|
2007-07-18 05:17:45 +00:00
|
|
|
|
$info['txt'] .= 'rcache: '.
|
2006-12-27 22:40:16 +00:00
|
|
|
|
"{$rcache->hits}/{$rcache->misses} ";
|
2006-12-27 22:39:32 +00:00
|
|
|
|
}
|
2005-04-19 20:45:15 +00:00
|
|
|
|
$info['html'] = '<div class="performanceinfo">'.$info['html'].'</div>';
|
2005-04-01 10:00:18 +00:00
|
|
|
|
return $info;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-19 18:54:58 +00:00
|
|
|
|
function apd_get_profiling() {
|
|
|
|
|
return shell_exec('pprofp -u ' . ini_get('apd.dumpdir') . '/pprof.' . getmypid() . '.*');
|
|
|
|
|
}
|
2005-04-16 12:22:24 +00:00
|
|
|
|
|
2007-12-24 21:16:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* Delete directory or only it's content
|
|
|
|
|
* @param string $dir directory path
|
|
|
|
|
* @param bool $content_only
|
|
|
|
|
* @return bool success, true also if dir does not exist
|
|
|
|
|
*/
|
2005-04-20 07:29:28 +00:00
|
|
|
|
function remove_dir($dir, $content_only=false) {
|
2007-12-24 21:16:30 +00:00
|
|
|
|
if (!file_exists($dir)) {
|
|
|
|
|
// nothing to do
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2005-04-20 07:29:28 +00:00
|
|
|
|
$handle = opendir($dir);
|
2007-12-24 21:16:30 +00:00
|
|
|
|
$result = true;
|
2005-04-20 07:29:28 +00:00
|
|
|
|
while (false!==($item = readdir($handle))) {
|
|
|
|
|
if($item != '.' && $item != '..') {
|
|
|
|
|
if(is_dir($dir.'/'.$item)) {
|
2007-12-24 21:16:30 +00:00
|
|
|
|
$result = remove_dir($dir.'/'.$item) && $result;
|
2005-04-20 07:29:28 +00:00
|
|
|
|
}else{
|
2007-12-24 21:16:30 +00:00
|
|
|
|
$result = unlink($dir.'/'.$item) && $result;
|
2005-04-20 07:29:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
closedir($handle);
|
2006-03-04 16:53:02 +00:00
|
|
|
|
if ($content_only) {
|
2007-12-24 21:16:30 +00:00
|
|
|
|
return $result;
|
2005-04-20 07:29:28 +00:00
|
|
|
|
}
|
2007-12-24 21:16:30 +00:00
|
|
|
|
return rmdir($dir); // if anything left the result will be false, noo need for && $result
|
2005-04-20 07:29:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-08-02 19:40:58 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function to check if a directory exists and optionally create it.
|
|
|
|
|
*
|
2007-11-02 09:53:32 +00:00
|
|
|
|
* @param string absolute directory path (must be under $CFG->dataroot)
|
2006-08-02 19:40:58 +00:00
|
|
|
|
* @param boolean create directory if does not exist
|
|
|
|
|
* @param boolean create directory recursively
|
|
|
|
|
*
|
|
|
|
|
* @return boolean true if directory exists or created
|
|
|
|
|
*/
|
|
|
|
|
function check_dir_exists($dir, $create=false, $recursive=false) {
|
2006-03-04 16:53:02 +00:00
|
|
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2007-12-24 21:16:30 +00:00
|
|
|
|
if (strstr($dir, $CFG->dataroot.'/') === false) {
|
2007-11-02 09:53:32 +00:00
|
|
|
|
debugging('Warning. Wrong call to check_dir_exists(). $dir must be an absolute path under $CFG->dataroot ("' . $dir . '" is incorrect)', DEBUG_DEVELOPER);
|
|
|
|
|
}
|
|
|
|
|
|
2006-02-02 20:30:34 +00:00
|
|
|
|
$status = true;
|
2006-08-02 19:40:58 +00:00
|
|
|
|
|
2006-02-02 20:30:34 +00:00
|
|
|
|
if(!is_dir($dir)) {
|
|
|
|
|
if (!$create) {
|
|
|
|
|
$status = false;
|
|
|
|
|
} else {
|
|
|
|
|
umask(0000);
|
2006-08-02 19:40:58 +00:00
|
|
|
|
if ($recursive) {
|
2007-11-02 09:53:32 +00:00
|
|
|
|
/// PHP 5.0 has recursive mkdir parameter, but 4.x does not :-(
|
2006-08-02 19:40:58 +00:00
|
|
|
|
$dir = str_replace('\\', '/', $dir); //windows compatibility
|
2007-11-02 09:53:32 +00:00
|
|
|
|
/// We are going to make it recursive under $CFG->dataroot only
|
|
|
|
|
/// (will help sites running open_basedir security and others)
|
|
|
|
|
$dir = str_replace($CFG->dataroot . '/', '', $dir);
|
|
|
|
|
$dirs = explode('/', $dir); /// Extract path parts
|
|
|
|
|
/// Iterate over each part with start point $CFG->dataroot
|
|
|
|
|
$dir = $CFG->dataroot . '/';
|
2006-08-02 19:40:58 +00:00
|
|
|
|
foreach ($dirs as $part) {
|
|
|
|
|
if ($part == '') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$dir .= $part.'/';
|
|
|
|
|
if (!is_dir($dir)) {
|
|
|
|
|
if (!mkdir($dir, $CFG->directorypermissions)) {
|
|
|
|
|
$status = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$status = mkdir($dir, $CFG->directorypermissions);
|
|
|
|
|
}
|
2006-02-02 20:30:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $status;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-23 15:02:00 +00:00
|
|
|
|
function report_session_error() {
|
2005-09-07 04:23:37 +00:00
|
|
|
|
global $CFG, $FULLME;
|
2007-01-27 19:56:08 +00:00
|
|
|
|
|
2005-04-23 15:02:00 +00:00
|
|
|
|
if (empty($CFG->lang)) {
|
|
|
|
|
$CFG->lang = "en";
|
|
|
|
|
}
|
2007-01-28 21:18:08 +00:00
|
|
|
|
// Set up default theme and locale
|
|
|
|
|
theme_setup();
|
2005-04-23 15:02:00 +00:00
|
|
|
|
moodle_setlocale();
|
2007-01-28 21:18:08 +00:00
|
|
|
|
|
2005-04-23 15:02:00 +00:00
|
|
|
|
//clear session cookies
|
2008-05-01 21:15:29 +00:00
|
|
|
|
setcookie('MoodleSession'.$CFG->sessioncookie, '', time() - 3600, $CFG->sessioncookiepath, '', $CFG->cookiesecure, $CFG->cookiehttponly);
|
|
|
|
|
setcookie('MoodleSessionTest'.$CFG->sessioncookie, '', time() - 3600, $CFG->sessioncookiepath, '', $CFG->cookiesecure, $CFG->cookiehttponly);
|
|
|
|
|
|
2005-04-23 15:02:00 +00:00
|
|
|
|
//increment database error counters
|
|
|
|
|
if (isset($CFG->session_error_counter)) {
|
|
|
|
|
set_config('session_error_counter', 1 + $CFG->session_error_counter);
|
|
|
|
|
} else {
|
|
|
|
|
set_config('session_error_counter', 1);
|
|
|
|
|
}
|
2005-09-23 18:38:50 +00:00
|
|
|
|
redirect($FULLME, get_string('sessionerroruser2', 'error'), 5);
|
2005-04-23 15:02:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-06-13 16:23:10 +00:00
|
|
|
|
/**
|
|
|
|
|
* Detect if an object or a class contains a given property
|
|
|
|
|
* will take an actual object or the name of a class
|
|
|
|
|
* @param mix $obj Name of class or real object to test
|
|
|
|
|
* @param string $property name of property to find
|
|
|
|
|
* @return bool true if property exists
|
|
|
|
|
*/
|
|
|
|
|
function object_property_exists( $obj, $property ) {
|
2005-06-13 16:24:47 +00:00
|
|
|
|
if (is_string( $obj )) {
|
2005-06-13 16:23:10 +00:00
|
|
|
|
$properties = get_class_vars( $obj );
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$properties = get_object_vars( $obj );
|
|
|
|
|
}
|
2005-06-13 19:07:15 +00:00
|
|
|
|
return array_key_exists( $property, $properties );
|
2005-06-13 16:23:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-07-14 15:35:23 +00:00
|
|
|
|
/**
|
|
|
|
|
* Detect a custom script replacement in the data directory that will
|
|
|
|
|
* replace an existing moodle script
|
|
|
|
|
* @param string $urlpath path to the original script
|
|
|
|
|
* @return string full path name if a custom script exists
|
|
|
|
|
* @return bool false if no custom script exists
|
|
|
|
|
*/
|
|
|
|
|
function custom_script_path($urlpath='') {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
2006-03-06 01:45:11 +00:00
|
|
|
|
// set default $urlpath, if necessary
|
|
|
|
|
if (empty($urlpath)) {
|
|
|
|
|
$urlpath = qualified_me(); // e.g. http://www.this-server.com/moodle/this-script.php
|
2005-07-14 15:35:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-06 01:45:11 +00:00
|
|
|
|
// $urlpath is invalid if it is empty or does not start with the Moodle wwwroot
|
|
|
|
|
if (empty($urlpath) or (strpos($urlpath, $CFG->wwwroot) === false )) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2006-05-20 17:23:14 +00:00
|
|
|
|
// replace wwwroot with the path to the customscripts folder and clean path
|
|
|
|
|
$scriptpath = $CFG->customscripts . clean_param(substr($urlpath, strlen($CFG->wwwroot)), PARAM_PATH);
|
2006-03-06 01:45:11 +00:00
|
|
|
|
|
|
|
|
|
// remove the query string, if any
|
|
|
|
|
if (($strpos = strpos($scriptpath, '?')) !== false) {
|
|
|
|
|
$scriptpath = substr($scriptpath, 0, $strpos);
|
|
|
|
|
}
|
2005-07-14 15:35:23 +00:00
|
|
|
|
|
2006-03-06 01:45:11 +00:00
|
|
|
|
// remove trailing slashes, if any
|
|
|
|
|
$scriptpath = rtrim($scriptpath, '/\\');
|
2005-07-14 15:35:23 +00:00
|
|
|
|
|
2006-03-06 01:45:11 +00:00
|
|
|
|
// append index.php, if necessary
|
|
|
|
|
if (is_dir($scriptpath)) {
|
|
|
|
|
$scriptpath .= '/index.php';
|
2005-07-14 15:35:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-06 01:45:11 +00:00
|
|
|
|
// check the custom script exists
|
2005-07-14 15:35:23 +00:00
|
|
|
|
if (file_exists($scriptpath)) {
|
|
|
|
|
return $scriptpath;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-04 16:53:02 +00:00
|
|
|
|
/**
|
|
|
|
|
* Wrapper function to load necessary editor scripts
|
|
|
|
|
* to $CFG->editorsrc array. Params can be coursei id
|
|
|
|
|
* or associative array('courseid' => value, 'name' => 'editorname').
|
|
|
|
|
* @uses $CFG
|
|
|
|
|
* @param mixed $args Courseid or associative array.
|
|
|
|
|
*/
|
|
|
|
|
function loadeditor($args) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
include($CFG->libdir .'/editorlib.php');
|
|
|
|
|
return editorObject::loadeditor($args);
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-04 02:52:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns whether or not the user object is a remote MNET user. This function
|
|
|
|
|
* is in moodlelib because it does not rely on loading any of the MNET code.
|
|
|
|
|
*
|
|
|
|
|
* @param object $user A valid user object
|
|
|
|
|
* @return bool True if the user is from a remote Moodle.
|
|
|
|
|
*/
|
|
|
|
|
function is_mnet_remote_user($user) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
if (!isset($CFG->mnet_localhost_id)) {
|
|
|
|
|
include_once $CFG->dirroot . '/mnet/lib.php';
|
|
|
|
|
$env = new mnet_environment();
|
|
|
|
|
$env->init();
|
|
|
|
|
unset($env);
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-22 08:25:20 +00:00
|
|
|
|
return (!empty($user->mnethostid) && $user->mnethostid != $CFG->mnet_localhost_id);
|
2007-01-04 02:52:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks if a given plugin is in the list of enabled enrolment plugins.
|
2007-07-18 05:17:45 +00:00
|
|
|
|
*
|
2007-01-04 02:52:44 +00:00
|
|
|
|
* @param string $auth Enrolment plugin.
|
|
|
|
|
* @return boolean Whether the plugin is enabled.
|
|
|
|
|
*/
|
|
|
|
|
function is_enabled_enrol($enrol='') {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
// use the global default if not specified
|
|
|
|
|
if ($enrol == '') {
|
|
|
|
|
$enrol = $CFG->enrol;
|
|
|
|
|
}
|
|
|
|
|
return in_array($enrol, explode(',', $CFG->enrol_plugins_enabled));
|
|
|
|
|
}
|
2006-09-03 08:10:10 +00:00
|
|
|
|
|
2007-02-12 14:58:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function will search for browser prefereed languages, setting Moodle
|
|
|
|
|
* to use the best one available if $SESSION->lang is undefined
|
|
|
|
|
*/
|
|
|
|
|
function setup_lang_from_browser() {
|
|
|
|
|
|
2007-03-06 23:51:34 +00:00
|
|
|
|
global $CFG, $SESSION, $USER;
|
2007-02-12 14:58:44 +00:00
|
|
|
|
|
2007-12-15 13:28:01 +00:00
|
|
|
|
if (!empty($SESSION->lang) or !empty($USER->lang) or empty($CFG->autolang)) {
|
2007-03-06 23:51:34 +00:00
|
|
|
|
// Lang is defined in session or user profile, nothing to do
|
2007-02-12 14:58:44 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { // There isn't list of browser langs, nothing to do
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Extract and clean langs from headers
|
2007-03-06 23:51:34 +00:00
|
|
|
|
$rawlangs = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
|
|
|
|
$rawlangs = str_replace('-', '_', $rawlangs); // we are using underscores
|
|
|
|
|
$rawlangs = explode(',', $rawlangs); // Convert to array
|
|
|
|
|
$langs = array();
|
|
|
|
|
|
|
|
|
|
$order = 1.0;
|
|
|
|
|
foreach ($rawlangs as $lang) {
|
|
|
|
|
if (strpos($lang, ';') === false) {
|
|
|
|
|
$langs[(string)$order] = $lang;
|
|
|
|
|
$order = $order-0.01;
|
|
|
|
|
} else {
|
|
|
|
|
$parts = explode(';', $lang);
|
|
|
|
|
$pos = strpos($parts[1], '=');
|
|
|
|
|
$langs[substr($parts[1], $pos+1)] = $parts[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
krsort($langs, SORT_NUMERIC);
|
2007-02-12 14:58:44 +00:00
|
|
|
|
|
2007-04-24 14:24:03 +00:00
|
|
|
|
$langlist = get_list_of_languages();
|
|
|
|
|
|
2007-02-12 14:58:44 +00:00
|
|
|
|
/// Look for such langs under standard locations
|
|
|
|
|
foreach ($langs as $lang) {
|
2007-04-24 14:24:03 +00:00
|
|
|
|
$lang = strtolower(clean_param($lang.'_utf8', PARAM_SAFEDIR)); // clean it properly for include
|
|
|
|
|
if (!array_key_exists($lang, $langlist)) {
|
|
|
|
|
continue; // language not allowed, try next one
|
|
|
|
|
}
|
2007-02-12 14:58:44 +00:00
|
|
|
|
if (file_exists($CFG->dataroot .'/lang/'. $lang) or file_exists($CFG->dirroot .'/lang/'. $lang)) {
|
2007-07-18 05:17:45 +00:00
|
|
|
|
$SESSION->lang = $lang; /// Lang exists, set it in session
|
2007-02-12 14:58:44 +00:00
|
|
|
|
break; /// We have finished. Go out
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-06 14:59:39 +00:00
|
|
|
|
/**
|
|
|
|
|
* check if $url matches anything in proxybypass list
|
|
|
|
|
* @note any errors just result in the proxy being used (least bad)
|
|
|
|
|
* @param string $url - url to check
|
|
|
|
|
* @return boolean - true if we should bypass the proxy
|
|
|
|
|
*/
|
|
|
|
|
function is_proxybypass( $url ) {
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
|
|
// sanity check
|
|
|
|
|
if (empty($CFG->proxyhost) or empty($CFG->proxybypass)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the host part out of the url
|
|
|
|
|
if (!$host = parse_url( $url, PHP_URL_HOST )) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the possible bypass hosts into an array
|
|
|
|
|
$matches = explode( ',', $CFG->proxybypass );
|
|
|
|
|
|
|
|
|
|
// check for a match
|
|
|
|
|
// (IPs need to match the left hand side and hosts the right of the url,
|
|
|
|
|
// but we can recklessly check both as there can't be a false +ve)
|
|
|
|
|
$bypass = false;
|
|
|
|
|
foreach ($matches as $match) {
|
|
|
|
|
$match = trim($match);
|
|
|
|
|
|
|
|
|
|
// try for IP match (Left side)
|
|
|
|
|
$lhs = substr($host,0,strlen($match));
|
|
|
|
|
if (strcasecmp($match,$lhs)==0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// try for host match (Right side)
|
|
|
|
|
$rhs = substr($host,-strlen($match));
|
|
|
|
|
if (strcasecmp($match,$rhs)==0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// nothing matched.
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-16 20:44:32 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
function is_newnav($navigation) {
|
2007-08-31 03:45:59 +00:00
|
|
|
|
if (is_array($navigation) && !empty($navigation['newnav'])) {
|
|
|
|
|
return true;
|
2007-04-16 20:44:32 +00:00
|
|
|
|
} else {
|
2007-08-31 03:45:59 +00:00
|
|
|
|
return false;
|
2007-04-16 20:44:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-27 03:54:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* Checks whether the given variable name is defined as a variable within the given object.
|
|
|
|
|
* @note This will NOT work with stdClass objects, which have no class variables.
|
|
|
|
|
* @param string $var The variable name
|
|
|
|
|
* @param object $object The object to check
|
|
|
|
|
* @return boolean
|
|
|
|
|
*/
|
2007-08-16 15:01:25 +00:00
|
|
|
|
function in_object_vars($var, $object) {
|
2007-04-27 03:54:53 +00:00
|
|
|
|
$class_vars = get_class_vars(get_class($object));
|
|
|
|
|
$class_vars = array_keys($class_vars);
|
|
|
|
|
return in_array($var, $class_vars);
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-31 08:06:39 +00:00
|
|
|
|
/**
|
2007-08-09 16:41:39 +00:00
|
|
|
|
* Returns an array without repeated objects.
|
2007-07-31 08:06:39 +00:00
|
|
|
|
* This function is similar to array_unique, but for arrays that have objects as values
|
2007-08-09 16:41:39 +00:00
|
|
|
|
*
|
2007-07-31 08:06:39 +00:00
|
|
|
|
* @param unknown_type $array
|
|
|
|
|
* @param unknown_type $keep_key_assoc
|
|
|
|
|
* @return unknown
|
|
|
|
|
*/
|
|
|
|
|
function object_array_unique($array, $keep_key_assoc = true) {
|
|
|
|
|
$duplicate_keys = array();
|
2007-08-09 16:41:39 +00:00
|
|
|
|
$tmp = array();
|
2007-07-31 08:06:39 +00:00
|
|
|
|
|
|
|
|
|
foreach ($array as $key=>$val) {
|
|
|
|
|
// convert objects to arrays, in_array() does not support objects
|
|
|
|
|
if (is_object($val)) {
|
|
|
|
|
$val = (array)$val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!in_array($val, $tmp)) {
|
|
|
|
|
$tmp[] = $val;
|
|
|
|
|
} else {
|
|
|
|
|
$duplicate_keys[] = $key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ($duplicate_keys as $key) {
|
|
|
|
|
unset($array[$key]);
|
|
|
|
|
}
|
2007-08-09 16:41:39 +00:00
|
|
|
|
|
2007-07-31 08:06:39 +00:00
|
|
|
|
return $keep_key_assoc ? $array : array_values($array);
|
|
|
|
|
}
|
|
|
|
|
|
2008-01-25 13:00:45 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the language string for the given plugin.
|
|
|
|
|
*
|
|
|
|
|
* @param string $plugin the plugin code name
|
|
|
|
|
* @param string $type the type of plugin (mod, block, filter)
|
|
|
|
|
* @return string The plugin language string
|
|
|
|
|
*/
|
|
|
|
|
function get_plugin_name($plugin, $type='mod') {
|
|
|
|
|
$plugin_name = '';
|
|
|
|
|
|
|
|
|
|
switch ($type) {
|
|
|
|
|
case 'mod':
|
|
|
|
|
$plugin_name = get_string('modulename', $plugin);
|
|
|
|
|
break;
|
|
|
|
|
case 'blocks':
|
|
|
|
|
$plugin_name = get_string('blockname', "block_$plugin");
|
|
|
|
|
if (empty($plugin_name) || $plugin_name == '[[blockname]]') {
|
|
|
|
|
if (($block = block_instance($plugin)) !== false) {
|
|
|
|
|
$plugin_name = $block->get_title();
|
|
|
|
|
} else {
|
|
|
|
|
$plugin_name = "[[$plugin]]";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'filter':
|
|
|
|
|
$plugin_name = trim(get_string('filtername', $plugin));
|
|
|
|
|
if (empty($plugin_name) or ($plugin_name == '[[filtername]]')) {
|
|
|
|
|
$textlib = textlib_get_instance();
|
|
|
|
|
$plugin_name = $textlib->strtotitle($plugin);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
$plugin_name = $plugin;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $plugin_name;
|
|
|
|
|
}
|
|
|
|
|
|
2008-01-26 17:00:03 +00:00
|
|
|
|
/**
|
|
|
|
|
* Is a userid the primary administrator?
|
|
|
|
|
*
|
|
|
|
|
* @param $userid int id of user to check
|
|
|
|
|
* @return boolean
|
|
|
|
|
*/
|
|
|
|
|
function is_primary_admin($userid){
|
|
|
|
|
$primaryadmin = get_admin();
|
|
|
|
|
|
|
|
|
|
if($userid == $primaryadmin->id){
|
|
|
|
|
return true;
|
|
|
|
|
}else{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-14 07:55:22 +00:00
|
|
|
|
// vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140:
|
2007-07-18 05:17:45 +00:00
|
|
|
|
?>
|