2009-05-22 02:57:43 +00:00
< ? php
2009-09-01 08:39:55 +00:00
// This file is part of Moodle - http://moodle.org/
//
2009-05-22 02:57:43 +00:00
// Moodle 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 3 of the License, or
// (at your option) any later version.
//
// Moodle 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.
2009-09-01 08:39:55 +00:00
//
2009-05-22 02:57:43 +00:00
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
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
2009-05-22 02:57:43 +00:00
*
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas http :// dougiamas . com
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2004-09-23 02:48:41 +00:00
*/
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. //////////////
2009-09-16 13:52:16 +00:00
2004-10-01 12:09:52 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_ALPHA - contains only english ascii letters a - zA - Z .
2004-10-01 12:09:52 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_ALPHA' , 'alpha' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_ALPHAEXT the same contents as PARAM_ALPHA plus the chars in quotes : " _- " allowed
* NOTE : originally this allowed " / " too , please use PARAM_SAFEPATH if " / " needed
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_ALPHAEXT' , 'alphaext' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_ALPHANUM - expected numbers and letters only .
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_ALPHANUM' , 'alphanum' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_ALPHANUMEXT - expected numbers , letters only and _ -.
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_ALPHANUMEXT' , 'alphanumext' );
2005-07-12 02:06:33 +00:00
2006-12-22 13:29:20 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_AUTH - actually checks to make sure the string is a valid auth plugin
2008-07-31 20:10:55 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_AUTH' , 'auth' );
2008-07-31 20:10:55 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_BASE64 - Base 64 encoded format
2006-12-22 13:29:20 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_BASE64' , 'base64' );
2006-12-22 13:29:20 +00:00
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +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
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_BOOL' , 'bool' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_CAPABILITY - A capability name , like 'moodle/role:manage' . Actually
2010-05-22 18:38:18 +00:00
* checked against the list of capabilities in the database .
2008-07-31 20:10:55 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_CAPABILITY' , 'capability' );
2008-07-31 20:10:55 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_CLEANHTML - cleans submitted HTML code and removes slashes . It stays as HTML .
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_CLEANHTML' , 'cleanhtml' );
2005-07-12 02:06:33 +00:00
2010-02-11 09:04:39 +00:00
/**
* PARAM_EMAIL - an email address following the RFC
*/
define ( 'PARAM_EMAIL' , 'email' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +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
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_FILE' , 'file' );
2008-07-31 20:10:55 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_FLOAT - a real / floating point number .
2008-07-31 20:10:55 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_FLOAT' , 'float' );
2008-07-31 20:10:55 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_HOST - expected fully qualified domain name ( FQDN ) or an IPv4 dotted quad ( IP address )
*/
define ( 'PARAM_HOST' , 'host' );
/**
* PARAM_INT - integers only , use when expecting only numbers .
2008-07-31 20:10:55 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_INT' , 'int' );
/**
* PARAM_LANG - checks to see if the string is a valid installed language in the current site .
*/
define ( 'PARAM_LANG' , 'lang' );
/**
* 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 ! )
*/
define ( 'PARAM_LOCALURL' , 'localurl' );
2005-07-12 02:06:33 +00:00
/**
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
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_NOTAGS' , 'notags' );
2005-07-12 02:06:33 +00:00
2008-07-31 20:10:55 +00:00
/**
2009-09-16 13:52:16 +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
2006-09-18 17:40:22 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_PATH' , 'path' );
2006-09-18 17:40:22 +00:00
2008-07-31 20:10:55 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_PEM - Privacy Enhanced Mail format
2006-10-16 07:46:35 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_PEM' , 'pem' );
2006-10-16 07:46:35 +00:00
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_PERMISSION - A permission , one of CAP_INHERIT , CAP_ALLOW , CAP_PREVENT or CAP_PROHIBIT .
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_PERMISSION' , 'permission' );
2005-07-12 02:06:33 +00:00
2008-07-31 23:03:50 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_RAW specifies a parameter that is not cleaned / processed in any way
2008-07-31 23:03:50 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_RAW' , 'raw' );
2008-07-31 23:03:50 +00:00
2007-09-16 14:20:32 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_SAFEDIR - safe directory name , suitable for include () and require ()
2007-09-16 14:20:32 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_SAFEDIR' , 'safedir' );
2007-09-16 14:20:32 +00:00
2008-02-25 08:11:07 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_SAFEPATH - several PARAM_SAFEDIR joined by " / " , suitable for include () and require (), plugin paths , etc .
2008-06-30 09:04:07 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_SAFEPATH' , 'safepath' );
2008-02-25 08:11:07 +00:00
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_SEQUENCE - expects a sequence of numbers like 8 to 1 , 5 , 6 , 4 , 6 , 8 , 9. Numbers and comma only .
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_SEQUENCE' , 'sequence' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_TAG - one tag ( interests , blogs , etc . ) - mostly international characters and space , <> not supported
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_TAG' , 'tag' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_TAGLIST - list of tags separated by commas ( interests , blogs , etc . )
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_TAGLIST' , 'taglist' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_TEXT - general plain text compatible with multilang filter , no other html tags .
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_TEXT' , 'text' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_THEME - Checks to see if the string is a valid theme name in the current site
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_THEME' , 'theme' );
2005-07-12 02:06:33 +00:00
/**
2010-05-22 18:38:18 +00:00
* PARAM_URL - expected properly formatted URL . Please note that domain part is required , http :// localhost / is not accepted but http :// localhost . localdomain / is ok .
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_URL' , 'url' );
2010-01-13 06:23:54 +00:00
/**
2010-06-06 14:06:30 +00:00
* PARAM_USERNAME - Clean username to only contains allowed characters . This is to be used ONLY when manually creating user accounts , do NOT use when syncing with external systems !!
2010-01-13 06:23:54 +00:00
*/
define ( 'PARAM_USERNAME' , 'username' );
2005-07-12 02:06:33 +00:00
2010-04-28 00:06:43 +00:00
/**
* PARAM_STRINGID - used to check if the given string is valid string identifier for get_string ()
*/
define ( 'PARAM_STRINGID' , 'stringid' );
2009-09-16 13:52:16 +00:00
///// DEPRECATED PARAM TYPES OR ALIASES - DO NOT USE FOR NEW CODE /////
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_CLEAN - obsoleted , please use a 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
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_CLEAN' , 'clean' );
2005-07-12 02:06:33 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_INTEGER - deprecated alias for PARAM_INT
2005-07-12 02:06:33 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_INTEGER' , 'int' );
2005-07-12 02:06:33 +00:00
2006-08-29 02:26:37 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_NUMBER - deprecated alias of PARAM_FLOAT
2006-08-29 02:26:37 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_NUMBER' , 'float' );
2006-08-29 02:26:37 +00:00
2007-01-04 02:52:44 +00:00
/**
2010-05-22 18:38:18 +00:00
* PARAM_ACTION - deprecated alias for PARAM_ALPHANUMEXT , use for various actions in forms and urls
2009-09-16 13:52:16 +00:00
* NOTE : originally alias for PARAM_APLHA
2007-01-04 02:52:44 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_ACTION' , 'alphanumext' );
2007-01-04 02:52:44 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_FORMAT - deprecated alias for PARAM_ALPHANUMEXT , use for names of plugins , formats , etc .
* NOTE : originally alias for PARAM_APLHA
2007-01-04 02:52:44 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_FORMAT' , 'alphanumext' );
2007-01-04 02:52:44 +00:00
2008-09-08 07:00:49 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_MULTILANG - deprecated alias of PARAM_TEXT .
2008-09-08 07:00:49 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_MULTILANG' , 'text' );
2007-01-04 02:52:44 +00:00
2008-11-05 08:17:30 +00:00
/**
2009-09-16 13:52:16 +00:00
* PARAM_CLEANFILE - deprecated alias of PARAM_FILE ; originally was removing regional chars too
2008-11-05 08:17:30 +00:00
*/
2009-09-16 13:52:16 +00:00
define ( 'PARAM_CLEANFILE' , 'file' );
2010-02-05 02:58:24 +00:00
/// Web Services ///
2009-09-16 13:52:16 +00:00
2010-02-05 02:58:24 +00:00
/**
* VALUE_REQUIRED - if the parameter is not supplied , there is an error
*/
define ( 'VALUE_REQUIRED' , 1 );
/**
* VALUE_OPTIONAL - if the parameter is not supplied , then the param has no value
*/
define ( 'VALUE_OPTIONAL' , 2 );
/**
* VALUE_DEFAULT - if the parameter is not supplied , then the default value is used
*/
define ( 'VALUE_DEFAULT' , 0 );
2009-09-16 13:52:16 +00:00
2010-02-08 03:49:52 +00:00
/**
* NULL_NOT_ALLOWED - the parameter can not be set to null in the database
*/
define ( 'NULL_NOT_ALLOWED' , false );
/**
* NULL_ALLOWED - the parameter can be set to null in the database
*/
define ( 'NULL_ALLOWED' , true );
2008-11-05 08:17:30 +00:00
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' );
2009-01-02 23:49:29 +00:00
/** Get remote addr constant */
define ( 'GETREMOTEADDR_SKIP_HTTP_CLIENT_IP' , '1' );
/** Get remote addr constant */
define ( 'GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR' , '2' );
2008-07-31 20:10:55 +00:00
/// Blog access level constant declaration ///
2006-12-28 21:21:44 +00:00
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 );
2008-07-31 20:10:55 +00:00
///Tag constants///
2007-09-16 18:41:57 +00:00
/**
2008-09-03 06:02:38 +00:00
* To prevent problems with multibytes strings , Flag updating in nav not working on the review page . this should not exceed the
2008-07-31 20:10:55 +00:00
* length of " varchar(255) / 3 (bytes / utf-8 character) = 85 " .
* TODO : this is not correct , varchar ( 255 ) are 255 unicode chars ; - )
2009-05-22 02:57:43 +00:00
*
* @ todo define ( TAG_MAX_LENGTH ) this is not correct , varchar ( 255 ) are 255 unicode chars ; - )
2007-09-16 18:41:57 +00:00
*/
2008-05-30 19:59:50 +00:00
define ( 'TAG_MAX_LENGTH' , 50 );
2007-09-16 18:41:57 +00:00
2008-07-31 20:10:55 +00:00
/// Password policy constants ///
2008-04-18 08:04:21 +00:00
define ( 'PASSWORD_LOWER' , 'abcdefghijklmnopqrstuvwxyz' );
define ( 'PASSWORD_UPPER' , 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' );
define ( 'PASSWORD_DIGITS' , '0123456789' );
define ( 'PASSWORD_NONALPHANUM' , '.,;:!?_-+/*@#&$' );
2008-07-31 20:10:55 +00:00
/// Feature constants ///
// Used for plugin_supports() to report features that are, or are not, supported by a module.
2008-07-28 15:58:50 +00:00
/** True if module can provide a grade */
2008-08-27 20:22:33 +00:00
define ( 'FEATURE_GRADE_HAS_GRADE' , 'grade_has_grade' );
2009-04-21 08:57:20 +00:00
/** True if module supports outcomes */
define ( 'FEATURE_GRADE_OUTCOMES' , 'outcomes' );
2008-07-28 15:58:50 +00:00
/** True if module has code to track whether somebody viewed it */
2008-08-27 20:22:33 +00:00
define ( 'FEATURE_COMPLETION_TRACKS_VIEWS' , 'completion_tracks_views' );
2008-07-28 15:58:50 +00:00
/** True if module has custom completion rules */
2008-08-27 20:22:33 +00:00
define ( 'FEATURE_COMPLETION_HAS_RULES' , 'completion_has_rules' );
2008-07-28 15:58:50 +00:00
2009-04-21 08:57:20 +00:00
/** True if module supports outcomes */
define ( 'FEATURE_IDNUMBER' , 'idnumber' );
/** True if module supports groups */
define ( 'FEATURE_GROUPS' , 'groups' );
/** True if module supports groupings */
define ( 'FEATURE_GROUPINGS' , 'groupings' );
/** True if module supports groupmembersonly */
define ( 'FEATURE_GROUPMEMBERSONLY' , 'groupmembersonly' );
2009-08-13 20:45:50 +00:00
/** Type of module */
define ( 'FEATURE_MOD_ARCHETYPE' , 'mod_archetype' );
2009-04-21 08:57:20 +00:00
/** True if module supports intro editor */
2009-04-21 21:17:21 +00:00
define ( 'FEATURE_MOD_INTRO' , 'mod_intro' );
2009-04-21 08:57:20 +00:00
/** True if module has default completion */
define ( 'FEATURE_MODEDIT_DEFAULT_COMPLETION' , 'modedit_default_completion' );
2008-07-28 15:58:50 +00:00
2009-07-24 02:44:44 +00:00
define ( 'FEATURE_COMMENT' , 'comment' );
2010-03-16 09:37:31 +00:00
define ( 'FEATURE_RATE' , 'rate' );
2010-04-21 14:17:11 +00:00
/** True if module supports backup/restore of moodle2 format */
define ( 'FEATURE_BACKUP_MOODLE2' , 'backup_moodle2' );
2010-03-16 05:57:51 +00:00
2009-08-13 20:45:50 +00:00
/** Unspecified module archetype */
define ( 'MOD_ARCHETYPE_OTHER' , 0 );
/** Resource-like type module */
define ( 'MOD_ARCHETYPE_RESOURCE' , 1 );
2010-05-22 18:38:18 +00:00
/** Assignment module archetype */
2009-08-13 20:45:50 +00:00
define ( 'MOD_ARCHETYPE_ASSIGNMENT' , 2 );
2010-01-13 10:05:49 +00:00
/**
* Security token used for allowing access
* from external application such as web services .
* Scripts do not use any session , performance is relatively
* low because we need to load access info in each request .
2010-05-22 18:38:18 +00:00
* Scripts are executed in parallel .
2010-01-13 10:05:49 +00:00
*/
define ( 'EXTERNAL_TOKEN_PERMANENT' , 0 );
/**
* Security token used for allowing access
* of embedded applications , the code is executed in the
* active user session . Token is invalidated after user logs out .
* Scripts are executed serially - normal session locking is used .
*/
define ( 'EXTERNAL_TOKEN_EMBEDDED' , 1 );
2008-07-28 15:58:50 +00:00
2010-05-13 09:57:43 +00:00
/**
* The home page should be the site home
*/
define ( 'HOMEPAGE_SITE' , 0 );
/**
* The home page should be the users my page
*/
define ( 'HOMEPAGE_MY' , 1 );
/**
* The home page can be chosen by the user
*/
define ( 'HOMEPAGE_USER' , 2 );
2010-05-02 11:43:57 +00:00
2010-06-11 03:24:09 +00:00
/**
* Hub directory url ( should be moodle . org )
*/
define ( 'HUB_HUBDIRECTORYURL' , " http://hubdirectory.moodle.org " );
/**
* Moodle . org url ( should be moodle . org )
*/
define ( 'HUB_MOODLEORGHUBURL' , " http://hub.moodle.org " );
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 :
2009-08-27 18:37:53 +00:00
* $id = required_param ( 'id' , PARAM_INT );
2004-10-01 12:09:52 +00:00
*
2009-09-01 08:39:55 +00:00
* @ param string $parname the name of the page parameter we want ,
2009-05-22 02:57:43 +00:00
* default PARAM_CLEAN
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 required_param ( $parname , $type = PARAM_CLEAN ) {
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-05-20 02:53:46 +00:00
print_error ( 'missingparam' , '' , '' , $parname );
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 :
2009-08-27 18:37:53 +00:00
* $name = optional_param ( 'name' , 'Fred' , PARAM_TEXT );
2004-10-01 12:09:52 +00:00
*
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
2009-05-22 02:57:43 +00:00
* @ param int $type expected type of parameter , default PARAM_CLEAN
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 ) {
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 ;
}
2010-04-09 09:43:21 +00:00
2006-03-04 18:05:41 +00:00
return clean_param ( $param , $type );
2004-10-01 12:09:52 +00:00
}
2009-09-15 20:08:47 +00:00
/**
* Strict validation of parameter values , the values are only converted
* to requested PHP type . Internally it is using clean_param , the values
* before and after cleaning must be equal - otherwise
* an invalid_parameter_exception is thrown .
2010-05-22 18:38:18 +00:00
* Objects and classes are not accepted .
2009-09-15 20:08:47 +00:00
*
* @ param mixed $param
* @ param int $type PARAM_ constant
* @ param bool $allownull are nulls valid value ?
* @ param string $debuginfo optional debug information
* @ return mixed the $param value converted to PHP type or invalid_parameter_exception
*/
2010-02-08 03:49:52 +00:00
function validate_param ( $param , $type , $allownull = NULL_NOT_ALLOWED , $debuginfo = '' ) {
2009-09-15 20:08:47 +00:00
if ( is_null ( $param )) {
2010-02-08 03:49:52 +00:00
if ( $allownull == NULL_ALLOWED ) {
2009-09-15 20:08:47 +00:00
return null ;
} else {
throw new invalid_parameter_exception ( $debuginfo );
}
}
if ( is_array ( $param ) or is_object ( $param )) {
throw new invalid_parameter_exception ( $debuginfo );
}
$cleaned = clean_param ( $param , $type );
if (( string ) $param !== ( string ) $cleaned ) {
// conversion to string is usually lossless
throw new invalid_parameter_exception ( $debuginfo );
}
return $cleaned ;
}
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
*
* @ 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 ;
2010-04-09 09:43:21 +00:00
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 ;
}
2008-06-09 16:53:30 +00:00
return clean_text ( $param ); // Sweep for scripts, etc
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 = 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
2008-07-31 20:10:55 +00:00
case PARAM_FLOAT :
2006-12-22 13:29:20 +00:00
case PARAM_NUMBER :
2008-07-31 20:10:55 +00:00
return ( float ) $param ; // Convert to float
2006-12-22 13:29:20 +00:00
2006-03-04 18:05:41 +00:00
case PARAM_ALPHA : // Remove everything not a-z
2009-06-22 01:22:37 +00:00
return preg_replace ( '/[^a-zA-Z]/i' , '' , $param );
2004-10-01 12:09:52 +00:00
2008-07-31 20:10:55 +00:00
case PARAM_ALPHAEXT : // Remove everything not a-zA-Z_- (originally allowed "/" too)
2009-06-22 01:22:37 +00:00
return preg_replace ( '/[^a-zA-Z_-]/i' , '' , $param );
2008-07-31 20:10:55 +00:00
2006-03-04 18:05:41 +00:00
case PARAM_ALPHANUM : // Remove everything not a-zA-Z0-9
2009-06-22 01:22:37 +00:00
return preg_replace ( '/[^A-Za-z0-9]/i' , '' , $param );
2005-02-03 18:14:45 +00:00
2008-07-31 20:10:55 +00:00
case PARAM_ALPHANUMEXT : // Remove everything not a-zA-Z0-9_-
2009-06-22 01:22:37 +00:00
return preg_replace ( '/[^A-Za-z0-9_-]/i' , '' , $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,
2009-06-22 01:22:37 +00:00
return preg_replace ( '/[^0-9,]/i' , '' , $param );
2006-08-29 02:26:37 +00:00
2006-03-04 18:05:41 +00:00
case PARAM_BOOL : // Convert to 1 or 0
$tempstr = strtolower ( $param );
2008-07-31 20:10:55 +00:00
if ( $tempstr === 'on' or $tempstr === 'yes' or $tempstr === 'true' ) {
2006-03-04 18:05:41 +00:00
$param = 1 ;
2008-07-31 20:10:55 +00:00
} else if ( $tempstr === 'off' or $tempstr === 'no' or $tempstr === 'false' ) {
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_-
2009-06-22 01:22:37 +00:00
return preg_replace ( '/[^a-zA-Z0-9_-]/i' , '' , $param );
2005-07-04 20:23:53 +00:00
2008-07-31 20:10:55 +00:00
case PARAM_SAFEPATH : // Remove everything not a-zA-Z0-9/_-
2009-09-01 08:39:55 +00:00
return preg_replace ( '/[^a-zA-Z0-9\/_-]/i' , '' , $param );
2008-07-31 20:10:55 +00:00
2006-03-04 18:05:41 +00:00
case PARAM_FILE : // Strip all suspicious characters from filename
2010-05-12 12:05:59 +00:00
$param = preg_replace ( '~[[:cntrl:]]|[&<>"`\|\':\\\\/]~u' , '' , $param );
2009-06-22 01:22:37 +00:00
$param = preg_replace ( '~\.\.+~' , '' , $param );
2008-07-31 20:10:55 +00:00
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 );
2009-08-04 15:41:00 +00:00
$param = preg_replace ( '~[[:cntrl:]]|[&<>"`\|\':]~u' , '' , $param );
2009-06-22 01:22:37 +00:00
$param = preg_replace ( '~\.\.+~' , '' , $param );
$param = preg_replace ( '~//+~' , '/' , $param );
return preg_replace ( '~/(\./)+~' , '/' , $param );
2006-03-04 18:05:41 +00:00
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
2009-07-15 06:17:39 +00:00
if ( validateUrlSyntax ( '/' . $param , 's-u-P-a-p-f+q?r?' )) {
2006-03-04 18:05:41 +00:00
// 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-05-30 19:59:50 +00:00
//as long as magic_quotes_gpc is used, a backslash will be a
2008-02-25 01:58:17 +00:00
//problem, so remove *all* backslash.
2008-07-31 20:10:55 +00:00
//$param = str_replace('\\', '', $param);
//remove some nasties
2009-06-22 01:22:37 +00:00
$param = preg_replace ( '~[[:cntrl:]]|[<>`]~' , '' , $param );
2008-02-25 01:58:17 +00:00
//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
2008-05-30 19:59:50 +00:00
case PARAM_TAGLIST :
$tags = explode ( ',' , $param );
$result = array ();
foreach ( $tags as $tag ) {
$res = clean_param ( $tag , PARAM_TAG );
2008-07-31 20:10:55 +00:00
if ( $res !== '' ) {
2008-05-30 19:59:50 +00:00
$result [] = $res ;
}
}
if ( $result ) {
return implode ( ',' , $result );
} else {
return '' ;
2008-02-25 07:17:04 +00:00
}
2008-09-08 07:00:49 +00:00
case PARAM_CAPABILITY :
2010-03-31 07:41:31 +00:00
if ( get_capability_info ( $param )) {
2008-09-08 07:00:49 +00:00
return $param ;
} else {
return '' ;
}
2008-11-05 08:17:30 +00:00
case PARAM_PERMISSION :
$param = ( int ) $param ;
if ( in_array ( $param , array ( CAP_INHERIT , CAP_ALLOW , CAP_PREVENT , CAP_PROHIBIT ))) {
return $param ;
} else {
return CAP_INHERIT ;
}
2009-09-16 13:52:16 +00:00
case PARAM_AUTH :
$param = clean_param ( $param , PARAM_SAFEDIR );
if ( exists_auth_plugin ( $param )) {
return $param ;
} else {
return '' ;
}
case PARAM_LANG :
$param = clean_param ( $param , PARAM_SAFEDIR );
2010-04-14 13:16:20 +00:00
if ( get_string_manager () -> translation_exists ( $param )) {
2009-09-16 13:52:16 +00:00
return $param ;
} else {
2010-04-14 13:16:20 +00:00
return '' ; // Specified language is not installed or param malformed
2009-09-16 13:52:16 +00:00
}
case PARAM_THEME :
$param = clean_param ( $param , PARAM_SAFEDIR );
2009-12-23 18:52:42 +00:00
if ( file_exists ( " $CFG->dirroot /theme/ $param /config.php " )) {
return $param ;
} else if ( ! empty ( $CFG -> themedir ) and file_exists ( " $CFG->themedir / $param /config.php " )) {
2009-09-16 13:52:16 +00:00
return $param ;
} else {
return '' ; // Specified theme is not installed
}
2010-01-13 06:23:54 +00:00
case PARAM_USERNAME :
$param = str_replace ( " " , " " , $param );
2010-01-14 07:18:06 +00:00
$param = moodle_strtolower ( $param ); // Convert uppercase to lowercase MDL-16919
if ( empty ( $CFG -> extendedusernamechars )) {
2010-01-13 06:23:54 +00:00
// regular expression, eliminate all chars EXCEPT:
// alphanum, dash (-), underscore (_), at sign (@) and period (.) characters.
$param = preg_replace ( '/[^-\.@_a-z0-9]/' , '' , $param );
2010-03-31 07:41:31 +00:00
}
2010-01-13 06:23:54 +00:00
return $param ;
2010-02-11 09:04:39 +00:00
case PARAM_EMAIL :
if ( validate_email ( $param )) {
return $param ;
} else {
return '' ;
}
2010-04-28 00:06:43 +00:00
case PARAM_STRINGID :
if ( preg_match ( '|^[a-zA-Z][a-zA-Z0-9\.:/_-]*$|' , $param )) {
return $param ;
} else {
return '' ;
}
2006-03-04 18:05:41 +00:00
default : // throw error, switched parameters in optional_param or another serious problem
2009-09-16 13:52:16 +00:00
print_error ( " unknownparamtype " , '' , '' , $type );
2005-02-25 13:10:24 +00:00
}
2004-10-01 12:09:52 +00:00
}
2008-07-31 20:10:55 +00:00
/**
* Return true if given value is integer or string with integer value
2009-05-22 02:57:43 +00:00
*
* @ param mixed $value String or Int
* @ return bool true if number , false if not
2008-07-31 20:10:55 +00:00
*/
function is_number ( $value ) {
if ( is_int ( $value )) {
return true ;
} else if ( is_string ( $value )) {
return (( string )( int ) $value ) === $value ;
} else {
return false ;
}
}
2005-06-10 09:51:25 +00:00
2009-05-25 20:55:27 +00:00
/**
* Returns host part from url
* @ param string $url full url
* @ return string host , null if not found
*/
function get_host_from_url ( $url ) {
preg_match ( '|^[a-z]+://([a-zA-Z0-9-.]+)|i' , $url , $matches );
if ( $matches ) {
return $matches [ 1 ];
}
return null ;
}
2008-08-28 01:48:43 +00:00
/**
2009-05-22 02:57:43 +00:00
* Tests whether anything was returned by text editor
*
2008-08-28 01:48:43 +00:00
* This function is useful for testing whether something you got back from
* the HTML editor actually contains anything . Sometimes the HTML editor
* appear to be empty , but actually you get back a < br > tag or something .
*
* @ param string $string a string containing HTML .
* @ return boolean does the string contain any actual content - that is text ,
2010-05-22 18:38:18 +00:00
* images , objects , etc .
2008-08-28 01:48:43 +00:00
*/
function html_is_blank ( $string ) {
return trim ( strip_tags ( $string , '<img><object><applet><input><select><textarea><hr>' )) == '' ;
}
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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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 )
2009-05-22 02:57:43 +00:00
* @ param string $plugin ( optional ) the plugin scope , default NULL
2009-02-17 16:50:36 +00:00
* @ return bool true or exception
2004-09-23 02:48:41 +00:00
*/
2005-06-02 05:39:41 +00:00
function set_config ( $name , $value , $plugin = NULL ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2003-08-18 17:41:06 +00:00
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
2008-05-30 19:59:50 +00:00
if ( $DB -> get_field ( 'config' , 'name' , array ( 'name' => $name ))) {
2009-02-17 16:50:36 +00:00
if ( $value === null ) {
$DB -> delete_records ( 'config' , array ( 'name' => $name ));
2007-11-14 22:10:21 +00:00
} else {
2009-02-17 16:50:36 +00:00
$DB -> set_field ( 'config' , 'value' , $value , array ( 'name' => $name ));
2007-11-14 22:10:21 +00:00
}
2005-06-02 05:39:41 +00:00
} else {
2009-02-17 16:50:36 +00:00
if ( $value !== null ) {
$config = new object ();
$config -> name = $name ;
$config -> value = $value ;
$DB -> insert_record ( 'config' , $config , false );
2007-11-14 22:10:21 +00:00
}
2005-06-02 05:39:41 +00:00
}
2008-05-30 19:59:50 +00:00
2005-06-02 05:39:41 +00:00
} else { // plugin scope
2008-05-30 19:59:50 +00:00
if ( $id = $DB -> get_field ( 'config_plugins' , 'id' , array ( 'name' => $name , 'plugin' => $plugin ))) {
2007-11-14 22:10:21 +00:00
if ( $value === null ) {
2009-02-17 16:50:36 +00:00
$DB -> delete_records ( 'config_plugins' , array ( 'name' => $name , 'plugin' => $plugin ));
2007-11-14 22:10:21 +00:00
} else {
2009-02-17 16:50:36 +00:00
$DB -> set_field ( 'config_plugins' , 'value' , $value , array ( 'id' => $id ));
2007-11-14 22:10:21 +00:00
}
2005-06-02 05:39:41 +00:00
} else {
2009-02-17 16:50:36 +00:00
if ( $value !== null ) {
$config = new object ();
$config -> plugin = $plugin ;
$config -> name = $name ;
$config -> value = $value ;
$DB -> insert_record ( 'config_plugins' , $config , false );
2007-11-14 22:10:21 +00:00
}
2005-06-02 05:39:41 +00:00
}
}
2009-02-17 16:50:36 +00:00
return true ;
2005-06-02 05:39:41 +00:00
}
/**
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 .
*
2008-08-22 07:12:27 +00:00
* If called with one parameter , it will load all the config
2010-05-19 13:30:13 +00:00
* variables for one plugin , and return them as an object .
2008-08-22 07:12:27 +00:00
*
2010-05-19 13:30:13 +00:00
* If called with 2 parameters it will return a string single
* value or false if the value is not found .
2007-01-16 23:25:19 +00:00
*
2010-05-19 13:30:13 +00:00
* @ param string $plugin full component name
2009-05-22 02:57:43 +00:00
* @ param string $name default NULL
2010-05-01 05:05:55 +00:00
* @ return mixed hash - like object or single value , return false no config found
2005-06-02 05:39:41 +00:00
*/
2010-05-19 13:30:13 +00:00
function get_config ( $plugin , $name = NULL ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2002-11-10 08:43:44 +00:00
2010-05-19 13:30:13 +00:00
// normalise component name
if ( $plugin === 'moodle' or $plugin === 'core' ) {
$plugin = NULL ;
}
2005-06-02 05:39:41 +00:00
if ( ! empty ( $name )) { // the user is asking for a specific value
if ( ! empty ( $plugin )) {
2010-05-19 13:30:13 +00:00
if ( isset ( $CFG -> forced_plugin_settings [ $plugin ]) and array_key_exists ( $name , $CFG -> forced_plugin_settings [ $plugin ])) {
// setting forced in config file
return $CFG -> forced_plugin_settings [ $plugin ][ $name ];
} else {
return $DB -> get_field ( 'config_plugins' , 'value' , array ( 'plugin' => $plugin , 'name' => $name ));
}
2005-06-02 05:39:41 +00:00
} else {
2010-05-19 13:30:13 +00:00
if ( array_key_exists ( $name , $CFG -> config_php_settings )) {
// setting force in config file
return $CFG -> config_php_settings [ $name ];
} else {
return $DB -> get_field ( 'config' , 'value' , array ( 'name' => $name ));
}
2005-06-02 05:39:41 +00:00
}
}
// the user is after a recordset
2010-05-19 13:30:13 +00:00
if ( $plugin ) {
2008-08-22 07:12:27 +00:00
$localcfg = $DB -> get_records_menu ( 'config_plugins' , array ( 'plugin' => $plugin ), '' , 'name,value' );
2010-05-19 13:30:13 +00:00
if ( isset ( $CFG -> forced_plugin_settings [ $plugin ])) {
foreach ( $CFG -> forced_plugin_settings [ $plugin ] as $n => $v ) {
if ( is_null ( $v ) or is_array ( $v ) or is_object ( $v )) {
// we do not want any extra mess here, just real settings that could be saved in db
unset ( $localcfg [ $n ]);
} else {
//convert to string as if it went through the DB
$localcfg [ $n ] = ( string ) $v ;
2005-06-02 05:39:41 +00:00
}
}
}
2010-05-19 13:30:13 +00:00
return ( object ) $localcfg ;
2006-03-04 16:53:02 +00:00
2010-05-19 13:30:13 +00:00
} else {
// this part is not really used any more, but anyway...
$localcfg = $DB -> get_records_menu ( 'config' , array (), '' , 'name,value' );
foreach ( $CFG -> config_php_settings as $n => $v ) {
if ( is_null ( $v ) or is_array ( $v ) or is_object ( $v )) {
// we do not want any extra mess here, just real settings that could be saved in db
unset ( $localcfg [ $n ]);
} else {
//convert to string as if it went through the DB
$localcfg [ $n ] = ( string ) $v ;
}
}
return ( object ) $localcfg ;
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
2009-05-22 02:57:43 +00:00
* @ global object
2008-09-11 11:01:20 +00:00
* @ return boolean whether the operation succeeded .
2006-09-20 02:17:27 +00:00
*/
function unset_config ( $name , $plugin = NULL ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2006-09-20 02:17:27 +00:00
if ( empty ( $plugin )) {
2008-09-11 11:01:20 +00:00
unset ( $CFG -> $name );
2009-02-17 17:23:56 +00:00
$DB -> delete_records ( 'config' , array ( 'name' => $name ));
2007-07-18 05:17:45 +00:00
} else {
2009-02-17 17:23:56 +00:00
$DB -> delete_records ( 'config_plugins' , array ( 'name' => $name , 'plugin' => $plugin ));
2006-09-20 02:17:27 +00:00
}
2009-02-17 17:23:56 +00:00
return true ;
2006-09-20 02:17:27 +00:00
}
2008-09-11 11:01:20 +00:00
/**
* Remove all the config variables for a given plugin .
*
* @ param string $plugin a plugin , for example 'quiz' or 'qtype_multichoice' ;
* @ return boolean whether the operation succeeded .
*/
function unset_all_config_for_plugin ( $plugin ) {
global $DB ;
2009-02-17 17:23:56 +00:00
$DB -> delete_records ( 'config_plugins' , array ( 'plugin' => $plugin ));
$DB -> delete_records_select ( 'config' , 'name LIKE ?' , array ( $plugin . '_%' ));
return true ;
2008-09-11 11:01:20 +00:00
}
2009-01-08 07:07:00 +00:00
/**
2010-05-22 18:38:18 +00:00
* Use this function to get a list of users from a config setting of type admin_setting_users_with_capability .
2010-05-18 16:59:08 +00:00
*
* All users are verified if they still have the necessary capability .
*
2009-02-01 13:36:07 +00:00
* @ param string $value the value of the config setting .
2009-01-08 07:07:00 +00:00
* @ param string $capability the capability - must match the one passed to the admin_setting_users_with_capability constructor .
2010-05-22 18:38:18 +00:00
* @ param bool $include admins , include administrators
2009-01-08 07:07:00 +00:00
* @ return array of user objects .
*/
2010-05-18 16:59:08 +00:00
function get_users_from_config ( $value , $capability , $includeadmins = true ) {
global $CFG , $DB ;
if ( empty ( $value ) or $value === '$@NONE@$' ) {
return array ();
2009-01-08 07:07:00 +00:00
}
2010-05-18 16:59:08 +00:00
// we have to make sure that users still have the necessary capability,
// it should be faster to fetch them all first and then test if they are present
2010-06-06 14:06:30 +00:00
// instead of validating them one-by-one
2010-05-18 16:59:08 +00:00
$users = get_users_by_capability ( get_context_instance ( CONTEXT_SYSTEM ), $capability );
if ( $includeadmins ) {
$admins = get_admins ();
foreach ( $admins as $admin ) {
$users [ $admin -> id ] = $admin ;
}
}
if ( $value === '$@ALL@$' ) {
return $users ;
}
$result = array (); // result in correct order
$allowed = explode ( ',' , $value );
foreach ( $allowed as $uid ) {
if ( isset ( $users [ $uid ])) {
$user = $users [ $uid ];
$result [ $user -> id ] = $user ;
}
}
return $result ;
2009-01-08 07:07:00 +00:00
}
2010-07-13 15:09:44 +00:00
/**
* Invalidates browser caches and cached data in temp
* @ return void
*/
function purge_all_caches () {
global $CFG ;
reset_text_filters_cache ();
js_reset_all_caches ();
theme_reset_all_caches ();
get_string_manager () -> reset_caches ();
2010-07-20 08:28:00 +00:00
// purge all other caches: rss, simplepie, etc.
2010-07-13 15:09:44 +00:00
remove_dir ( $CFG -> dataroot . '/cache' , true );
// some more diagnostics in case site is misconfigured
if ( ! check_dir_exists ( $CFG -> dataroot . '/cache' , true , true )) {
debugging ( 'Can not create cache directory, please check permissions in dataroot.' );
} else if ( ! is_writeable ( $CFG -> dataroot . '/cache' )) {
debugging ( 'Cache directory is not writeable, please verify permissions in dataroot.' );
}
clearstatcache ();
}
2007-10-02 08:39:44 +00:00
/**
* Get volatile flags
*
* @ param string $type
2009-05-22 02:57:43 +00:00
* @ param int $changedsince default null
2007-10-02 08:39:44 +00:00
* @ return records array
*/
function get_cache_flags ( $type , $changedsince = NULL ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2007-10-02 08:39:44 +00:00
2008-05-30 19:59:50 +00:00
$params = array ( 'type' => $type , 'expiry' => time ());
$sqlwhere = " flagtype = :type AND expiry >= :expiry " ;
2007-10-02 08:39:44 +00:00
if ( $changedsince !== NULL ) {
2008-05-30 19:59:50 +00:00
$params [ 'changedsince' ] = $changedsince ;
$sqlwhere .= " AND timemodified > :changedsince " ;
2007-10-02 08:39:44 +00:00
}
$cf = array ();
2008-05-30 19:59:50 +00:00
if ( $flags = $DB -> get_records_select ( 'cache_flags' , $sqlwhere , $params , '' , 'name,value' )) {
2007-10-02 08:39:44 +00:00
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
2009-05-22 02:57:43 +00:00
* @ param int $changedsince default null
2008-02-27 02:57:33 +00:00
* @ return records array
*/
function get_cache_flag ( $type , $name , $changedsince = NULL ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2008-02-27 02:57:33 +00:00
2008-05-30 19:59:50 +00:00
$params = array ( 'type' => $type , 'name' => $name , 'expiry' => time ());
2008-02-27 02:57:33 +00:00
2008-05-30 19:59:50 +00:00
$sqlwhere = " flagtype = :type AND name = :name AND expiry >= :expiry " ;
2008-02-27 02:57:33 +00:00
if ( $changedsince !== NULL ) {
2008-05-30 19:59:50 +00:00
$params [ 'changedsince' ] = $changedsince ;
$sqlwhere .= " AND timemodified > :changedsince " ;
2008-02-27 02:57:33 +00:00
}
2008-05-30 19:59:50 +00:00
return $DB -> get_field_select ( 'cache_flags' , 'value' , $sqlwhere , $params );
2008-02-27 02:57:33 +00:00
}
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 () + 24 hs
2009-05-22 02:57:43 +00:00
* @ return bool Always returns true
2007-10-02 08:39:44 +00:00
*/
function set_cache_flag ( $type , $name , $value , $expiry = NULL ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2007-10-02 08:39:44 +00:00
$timemodified = time ();
if ( $expiry === NULL || $expiry < $timemodified ) {
$expiry = $timemodified + 24 * 60 * 60 ;
} else {
$expiry = ( int ) $expiry ;
}
if ( $value === NULL ) {
2009-02-17 17:23:56 +00:00
unset_cache_flag ( $type , $name );
return true ;
2007-10-02 08:39:44 +00:00
}
2009-07-04 09:35:03 +00:00
if ( $f = $DB -> get_record ( 'cache_flags' , array ( 'name' => $name , 'flagtype' => $type ), '*' , IGNORE_MULTIPLE )) { // this is a potentail problem in DEBUG_DEVELOPER
2007-10-09 12:49:54 +00:00
if ( $f -> value == $value and $f -> expiry == $expiry and $f -> timemodified == $timemodified ) {
return true ; //no need to update; helps rcache too
}
2008-05-30 19:59:50 +00:00
$f -> value = $value ;
2007-10-02 08:39:44 +00:00
$f -> expiry = $expiry ;
$f -> timemodified = $timemodified ;
2009-02-17 17:23:56 +00:00
$DB -> update_record ( 'cache_flags' , $f );
2007-10-02 08:39:44 +00:00
} 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 ;
2008-05-30 19:59:50 +00:00
$f -> value = $value ;
2007-10-02 08:39:44 +00:00
$f -> expiry = $expiry ;
$f -> timemodified = $timemodified ;
2009-02-17 17:23:56 +00:00
$DB -> insert_record ( 'cache_flags' , $f );
2007-10-02 08:39:44 +00:00
}
2009-02-17 17:23:56 +00:00
return true ;
2007-10-02 08:39:44 +00:00
}
/**
* Removes a single volatile flag
*
2009-05-22 02:57:43 +00:00
* @ global object
2007-10-02 08:39:44 +00:00
* @ param string $type the " type " namespace for the key
* @ param string $name the key to set
* @ return bool
*/
function unset_cache_flag ( $type , $name ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2009-02-17 17:23:56 +00:00
$DB -> delete_records ( 'cache_flags' , array ( 'name' => $name , 'flagtype' => $type ));
return true ;
2007-10-02 08:39:44 +00:00
}
/**
* Garbage - collect volatile flags
*
2009-05-22 02:57:43 +00:00
* @ return bool Always returns true
2007-10-02 08:39:44 +00:00
*/
function gc_cache_flags () {
2008-05-30 19:59:50 +00:00
global $DB ;
2009-02-17 17:23:56 +00:00
$DB -> delete_records_select ( 'cache_flags' , 'expiry < ?' , array ( time ()));
return true ;
2007-10-02 08:39:44 +00:00
}
2005-06-02 05:39:41 +00:00
2008-11-04 10:49:31 +00:00
/// FUNCTIONS FOR HANDLING USER PREFERENCES ////////////////////////////////////
2004-09-23 02:48:41 +00:00
/**
* Refresh current $USER session global variable with all their current preferences .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ param mixed $time default null
* @ return void
2004-09-23 02:48:41 +00:00
*/
2008-11-04 10:49:31 +00:00
function check_user_preferences_loaded ( $time = null ) {
2008-05-30 19:59:50 +00:00
global $USER , $DB ;
2008-11-04 10:49:31 +00:00
static $timenow = null ; // Static cache, so we only check up-to-dateness once per request.
2008-11-12 01:26:49 +00:00
if ( ! empty ( $USER -> preference ) && isset ( $USER -> preference [ '_lastloaded' ])) {
2008-11-04 10:49:31 +00:00
// Already loaded. Are we up to date?
if ( is_null ( $timenow ) || ( ! is_null ( $time ) && $time != $timenow )) {
$timenow = time ();
if ( ! get_cache_flag ( 'userpreferenceschanged' , $USER -> id , $USER -> preference [ '_lastloaded' ])) {
// We are up-to-date.
return ;
}
} else {
// Already checked for up-to-date-ness.
return ;
}
}
2004-01-28 14:14:19 +00:00
2008-11-04 10:49:31 +00:00
// OK, so we have to reload. Reset preference
2007-03-05 20:02:27 +00:00
$USER -> preference = array ();
2004-12-01 21:47:02 +00:00
2007-03-05 20:02:27 +00:00
if ( ! isloggedin () or isguestuser ()) {
2008-11-04 10:49:31 +00:00
// No permanent storage for not-logged-in user and guest
2004-01-28 14:14:19 +00:00
2008-05-30 19:59:50 +00:00
} else if ( $preferences = $DB -> get_records ( 'user_preferences' , array ( '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
2008-11-04 10:49:31 +00:00
$USER -> preference [ '_lastloaded' ] = $timenow ;
}
/**
* Called from set / delete_user_preferences , so that the prefs can be correctly reloaded .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
2008-11-04 10:49:31 +00:00
* @ param integer $userid the user whose prefs were changed .
*/
function mark_user_preferences_changed ( $userid ) {
global $CFG , $USER ;
if ( $userid == $USER -> id ) {
check_user_preferences_loaded ( time ());
}
set_cache_flag ( 'userpreferenceschanged' , $userid , 1 , time () + $CFG -> sessiontimeout );
2004-01-28 14:14:19 +00:00
}
2004-09-23 02:48:41 +00:00
/**
* Sets a preference for the current user
2009-05-22 02:57:43 +00:00
*
2004-09-23 02:48:41 +00:00
* Optionally , can set a preference for a different user object
2009-05-22 02:57:43 +00:00
*
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 .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
2004-09-23 02:48:41 +00:00
* @ param string $name The key to set as preference for the specified user
2010-05-22 18:38:18 +00:00
* @ param string $value The value to set for the $name key in the specified user ' s record
2009-05-22 02:57:43 +00:00
* @ param int $otheruserid A moodle user ID , default null
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 ) {
2008-05-30 19:59:50 +00:00
global $USER , $DB ;
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 ;
}
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
2008-05-30 19:59:50 +00:00
} else if ( $preference = $DB -> get_record ( 'user_preferences' , array ( 'userid' => $userid , 'name' => $name ))) {
2007-09-19 07:01:41 +00:00
if ( $preference -> value === $value ) {
return true ;
}
2009-02-17 17:23:56 +00:00
$DB -> set_field ( 'user_preferences' , 'value' , ( string ) $value , array ( 'id' => $preference -> id ));
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 ;
2008-05-30 19:59:50 +00:00
$preference -> name = $name ;
$preference -> value = ( string ) $value ;
2009-02-17 17:23:56 +00:00
$DB -> insert_record ( 'user_preferences' , $preference );
2008-11-04 10:49:31 +00:00
}
2009-02-17 17:23:56 +00:00
mark_user_preferences_changed ( $userid );
// update value in USER session if needed
if ( $userid == $USER -> id ) {
$USER -> preference [ $name ] = ( string ) $value ;
$USER -> preference [ '_lastloaded' ] = time ();
2004-01-28 14:14:19 +00:00
}
2007-03-05 20:02:27 +00:00
2009-02-17 17:23:56 +00:00
return true ;
2008-11-04 10:49:31 +00:00
}
/**
* Sets a whole array of preferences for the current user
2009-05-22 02:57:43 +00:00
*
2008-11-04 10:49:31 +00:00
* @ param array $prefarray An array of key / value pairs to be set
* @ param int $otheruserid A moodle user ID
* @ return bool
*/
function set_user_preferences ( $prefarray , $otheruserid = NULL ) {
if ( ! is_array ( $prefarray ) or empty ( $prefarray )) {
return false ;
2007-03-05 20:02:27 +00:00
}
2008-11-04 10:49:31 +00:00
foreach ( $prefarray as $name => $value ) {
2009-02-17 17:23:56 +00:00
set_user_preference ( $name , $value , $otheruserid );
2008-11-04 10:49:31 +00:00
}
2009-02-17 17:23:56 +00:00
return true ;
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
2009-05-22 02:57:43 +00:00
*
2004-09-23 04:15:19 +00:00
* Optionally , can set a preference for a different user id
2009-05-22 02:57:43 +00:00
*
* @ global object
2004-09-23 04:15:19 +00:00
* @ 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 ) {
2008-05-30 19:59:50 +00:00
global $USER , $DB ;
2004-09-23 04:15:19 +00:00
2007-03-05 20:02:27 +00:00
if ( empty ( $otheruserid )){
$userid = $USER -> id ;
2008-11-04 10:49:31 +00:00
check_user_preferences_loaded ();
2007-03-05 20:02:27 +00:00
} else {
$userid = $otheruserid ;
}
2005-07-21 18:48:26 +00:00
//Then from DB
2009-02-17 17:23:56 +00:00
$DB -> delete_records ( 'user_preferences' , array ( 'userid' => $userid , 'name' => $name ));
mark_user_preferences_changed ( $userid );
//Delete the preference from $USER if needed
if ( $userid == $USER -> id ) {
unset ( $USER -> preference [ $name ]);
$USER -> preference [ '_lastloaded' ] = time ();
2004-01-28 14:14:19 +00:00
}
2009-02-17 17:23:56 +00:00
return true ;
2004-01-28 14:14:19 +00:00
}
2004-09-23 02:48:41 +00:00
/**
2009-05-22 02:57:43 +00:00
* Used to fetch user preference ( s )
*
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 .
2009-05-22 02:57:43 +00:00
*
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 .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
2004-09-23 02:48:41 +00:00
* @ 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
* @ return string
*/
2007-03-05 20:02:27 +00:00
function get_user_preferences ( $name = NULL , $default = NULL , $otheruserid = NULL ) {
2008-05-30 19:59:50 +00:00
global $USER , $DB ;
2004-01-28 14:14:19 +00:00
2010-03-31 07:41:31 +00:00
if ( empty ( $otheruserid ) || ( isloggedin () && ( $USER -> id == $otheruserid ))){
2008-11-04 10:49:31 +00:00
check_user_preferences_loaded ();
2007-03-05 20:02:27 +00:00
2008-11-04 10:49:31 +00:00
if ( empty ( $name )) {
return $USER -> preference ; // All values
} else if ( array_key_exists ( $name , $USER -> preference )) {
return $USER -> preference [ $name ]; // The single value
} else {
return $default ; // Default value (or NULL)
2004-09-23 03:56:53 +00:00
}
2007-03-05 20:02:27 +00:00
} else {
2008-11-04 10:49:31 +00:00
if ( empty ( $name )) {
return $DB -> get_records_menu ( 'user_preferences' , array ( 'userid' => $otheruserid ), '' , 'name,value' ); // All values
2008-11-25 02:30:27 +00:00
} else if ( $value = $DB -> get_field ( 'user_preferences' , 'value' , array ( 'userid' => $otheruserid , 'name' => $name ))) {
2008-11-04 10:49:31 +00:00
return $value ; // 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
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function
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
2009-05-22 02:57:43 +00:00
* @ param float $timezone Timezone modifier
* @ param bool $applydst Toggle Daylight Saving Time , default true
2005-02-21 08:55:40 +00:00
* @ return int timestamp
2004-09-23 02:48:41 +00:00
*/
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
/**
2009-05-22 02:57:43 +00:00
* Format a date / time ( seconds ) as weeks , days , hours etc as needed
*
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
2009-05-22 02:57:43 +00:00
* @ param int $totalsecs Time in seconds
* @ param object $str Should be a time object
* @ return string A nicely formatted date / time 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
/**
2009-05-22 02:57:43 +00:00
* Returns a formatted string that represents a date in user time
*
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
2010-05-22 18:38:18 +00:00
* zero from % d , else maintain it .
2004-09-23 02:48:41 +00:00
*
2009-02-11 08:08:58 +00:00
* @ param int $date the timestamp in UTC , as obtained from the database .
* @ param string $format strftime format . You should probably get this using
* get_string ( 'strftime...' , 'langconfig' );
* @ param float $timezone by default , uses the user ' s time zone .
* @ param bool $fixday If true ( default ) then the leading zero from % d is removed .
2010-05-22 18:38:18 +00:00
* If false then the leading zero is maintained .
2009-02-11 08:08:58 +00:00
* @ return string the formatted date / time .
2004-09-23 02:48:41 +00:00
*/
2009-02-11 08:08:58 +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 )) {
2009-02-11 08:08:58 +00:00
$format = get_string ( 'strftimedaydatetime' , 'langconfig' );
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 );
2010-05-06 06:29:02 +00:00
$daystring = ltrim ( str_replace ( array ( ' 0' , ' ' ), '' , strftime ( ' %d' , $date )));
2005-02-19 02:49:31 +00:00
$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 );
2010-05-06 06:29:02 +00:00
$daystring = ltrim ( str_replace ( array ( ' 0' , ' ' ), '' , gmstrftime ( ' %d' , $date )));
2005-02-19 02:49:31 +00:00
$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' ) {
MDL-22050 removing moodle/langconfig duplicates
AMOS BEGIN
MOV [locale,core],[locale,core_langconfig]
MOV [localewin,core],[localewin,core_langconfig]
MOV [localewincharset,core],[localewincharset,core_langconfig]
MOV [oldcharset,core],[oldcharset,core_langconfig]
AMOS END
2010-04-10 17:54:39 +00:00
if ( $localewincharset = get_string ( 'localewincharset' , 'langconfig' )) {
2006-03-25 12:26:33 +00:00
$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
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function
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
*/
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
2010-01-08 06:56:29 +00:00
$datestring = gmstrftime ( '%B_%A_%j_%Y_%m_%w_%d_%H_%M_%S' , $time );
2005-02-16 22:55:13 +00:00
2010-01-08 06:56:29 +00:00
//be careful to ensure the returned array matches that produced by getdate() above
2005-01-12 11:17:18 +00:00
list (
2010-01-08 06:56:29 +00:00
$getdate [ 'month' ],
$getdate [ 'weekday' ],
$getdate [ 'yday' ],
2005-01-12 11:17:18 +00:00
$getdate [ 'year' ],
2010-01-08 06:56:29 +00:00
$getdate [ 'mon' ],
2005-01-12 11:17:18 +00:00
$getdate [ 'wday' ],
2010-01-08 06:56:29 +00:00
$getdate [ 'mday' ],
$getdate [ 'hours' ],
$getdate [ 'minutes' ],
$getdate [ 'seconds' ]
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 3 pm in India is 3 pm 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
2009-05-22 02:57:43 +00:00
* @ param float $timezone Defaults to user ' s timezone
* @ return int Returns a GMT timestamp
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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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
2009-05-22 02:57:43 +00:00
* @ return float
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
2009-05-22 02:57:43 +00:00
*
* @ global object
2008-02-16 18:33:50 +00:00
* @ 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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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
/**
2008-05-15 21:40:00 +00:00
* Returns cached timezone record for given $timezonename
2005-07-12 02:06:33 +00:00
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
2008-05-15 21:40:00 +00:00
* @ param string $timezonename
* @ return mixed timezonerecord object or false
2005-07-12 02:06:33 +00:00
*/
2005-04-08 05:28:39 +00:00
function get_timezone_record ( $timezonename ) {
2008-05-15 21:40:00 +00:00
global $CFG , $DB ;
2005-04-08 05:28:39 +00:00
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
}
2008-05-15 21:40:00 +00:00
return $cache [ $timezonename ] = $DB -> get_record_sql ( ' SELECT * FROM { timezone }
2008-05-30 19:59:50 +00:00
WHERE name = ? ORDER BY year DESC ' , array ( $timezonename ), 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
/**
2009-05-22 02:57:43 +00:00
* Build and store the users Daylight Saving Time ( DST ) table
2005-07-12 02:06:33 +00:00
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
* @ global object
* @ param mixed $from_year Start year for the table , defaults to 1971
* @ param mixed $to_year End year for the table , defaults to 2035
* @ param mixed $strtimezone
2005-07-12 02:06:33 +00:00
* @ return bool
*/
2008-03-20 03:01:58 +00:00
function calculate_user_dst_table ( $from_year = NULL , $to_year = NULL , $strtimezone = NULL ) {
2008-05-30 19:59:50 +00:00
global $CFG , $SESSION , $DB ;
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 ])) {
2008-05-30 19:59:50 +00:00
$presets_cache [ $usertz ] = $DB -> get_records ( 'timezone' , array ( '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' );
2008-02-03 16:01:33 +00:00
}
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
2009-05-22 02:57:43 +00:00
/**
* Calculates the required DST change and returns a Timestamp Array
*
* @ uses HOURSECS
* @ uses MINSECS
* @ param mixed $year Int or String Year to focus on
* @ param object $timezone Instatiated Timezone object
* @ return mixed Null , or Array dst => xx , 0 => xx , std => yy , 1 => yy
*/
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
}
2009-05-22 02:57:43 +00:00
/**
2010-05-22 18:38:18 +00:00
* Calculates the Daylight Saving Offset for a given date / time ( timestamp )
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ param int $time must NOT be compensated at all , it has to be a pure timestamp
* @ return int
*/
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
2009-05-22 02:57:43 +00:00
/**
* ?
*
* @ todo Document what this function does
* @ param int $startday
* @ param int $weekday
* @ param int $month
* @ param int $year
* @ return int
*/
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
2009-01-02 22:56:48 +00:00
/**
* Returns full login url .
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ param bool $loginguest add login guest param , return false
2009-01-02 22:56:48 +00:00
* @ return string login url
*/
function get_login_url ( $loginguest = false ) {
global $CFG ;
if ( empty ( $CFG -> loginhttps ) or $loginguest ) { //do not require https for guest logins
$loginguest = $loginguest ? '?loginguest=true' : '' ;
$url = " $CFG->wwwroot /login/index.php $loginguest " ;
} else {
$wwwroot = str_replace ( 'http:' , 'https:' , $CFG -> wwwroot );
$url = " $wwwroot /login/index.php " ;
}
return $url ;
}
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 .
2010-05-22 18:38:18 +00:00
* If $cm is given and the course module is hidden and the user is not a teacher
2005-02-16 10:40:48 +00:00
* in the course then the user is redirected to the course home page .
2004-09-23 02:48:41 +00:00
*
2009-12-27 12:02:04 +00:00
* When $cm parameter specified , this function sets page layout to 'module' .
2010-03-31 07:41:31 +00:00
* You need to change it manually later if some other layout needed .
2009-12-27 12:02:04 +00:00
*
2007-01-19 09:44:26 +00:00
* @ param mixed $courseorid id of the course or course object
2009-05-22 02:57:43 +00:00
* @ param bool $autologinguest default true
2005-07-12 02:06:33 +00:00
* @ 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
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
* @ param bool $preventredirect set to true in scripts that can not redirect ( CLI , rss feeds , etc . ), throws exceptions
2009-05-22 02:57:43 +00:00
* @ return mixed Void , exit , and die depending on path
2004-09-23 02:48:41 +00:00
*/
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
function require_login ( $courseorid = NULL , $autologinguest = true , $cm = NULL , $setwantsurltome = true , $preventredirect = false ) {
global $CFG , $SESSION , $USER , $FULLME , $PAGE , $SITE , $DB , $OUTPUT ;
2004-04-01 10:11:20 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// setup global $COURSE, themes, language and locale
2009-05-06 08:29:22 +00:00
if ( ! empty ( $courseorid )) {
if ( is_object ( $courseorid )) {
$course = $courseorid ;
} else if ( $courseorid == SITEID ) {
$course = clone ( $SITE );
} else {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
$course = $DB -> get_record ( 'course' , array ( 'id' => $courseorid ), '*' , MUST_EXIST );
2009-05-06 08:29:22 +00:00
}
2009-07-21 07:02:06 +00:00
if ( $cm ) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $cm -> course != $course -> id ) {
throw new coding_exception ( 'course and cm parameters in require_login() call do not match!!' );
}
2010-03-02 11:51:36 +00:00
$PAGE -> set_cm ( $cm , $course ); // set's up global $COURSE
2009-12-27 12:02:04 +00:00
$PAGE -> set_pagelayout ( 'incourse' );
2009-07-21 07:02:06 +00:00
} else {
2010-03-02 11:51:36 +00:00
$PAGE -> set_course ( $course ); // set's up global $COURSE
2009-07-21 07:02:06 +00:00
}
2009-05-06 08:41:02 +00:00
} else {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// do not touch global $COURSE via $PAGE->set_course(),
// the reasons is we need to be able to call require_login() at any time!!
$course = $SITE ;
if ( $cm ) {
throw new coding_exception ( 'cm parameter in require_login() requires valid course parameter!' );
}
2009-05-06 08:29:22 +00:00
}
2006-07-30 10:39:21 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +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
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $preventredirect ) {
throw new require_login_exception ( 'You are not logged in' );
}
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
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $autologinguest and ! empty ( $CFG -> guestloginbutton ) and ! empty ( $CFG -> autologinguests )) {
if ( $course -> id == SITEID ) {
$loginguest = true ;
} else {
$loginguest = false ;
}
2004-06-19 16:13:28 +00:00
} else {
2009-01-02 22:56:48 +00:00
$loginguest = false ;
2004-06-19 16:13:28 +00:00
}
2009-01-02 22:56:48 +00:00
redirect ( get_login_url ( $loginguest ));
exit ; // never reached
2001-11-22 06:23:56 +00:00
}
2002-12-30 15:30:05 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// loginas as redirection if needed
if ( $course -> id != SITEID and session_is_loggedinas ()) {
2007-03-19 18:54:58 +00:00
if ( $USER -> loginascontext -> contextlevel == CONTEXT_COURSE ) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
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
}
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// check whether the user should be changing password (but only if it is REALLY them)
2009-01-02 20:32:05 +00:00
if ( get_user_preferences ( 'auth_forcepasswordchange' ) && ! session_is_loggedinas ()) {
2007-09-19 07:25:49 +00:00
$userauth = get_auth_plugin ( $USER -> auth );
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $userauth -> can_change_password () and ! $preventredirect ) {
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
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +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 )) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $preventredirect ) {
throw new require_login_exception ( 'User not fully set-up' );
}
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
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// Make sure the USER has a sesskey set up. Used for CSRF protection.
2005-01-23 22:07:13 +00:00
sesskey ();
2004-09-27 14:35:37 +00:00
2010-07-06 01:52:32 +00:00
// Do not bother admins with any formalities
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( is_siteadmin ()) {
2010-07-06 01:52:32 +00:00
//set accesstime or the user will appear offline which messes up messaging
user_accesstime_log ( $course -> id );
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
return ;
}
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 )) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $preventredirect ) {
throw new require_login_exception ( 'Policy not agreed' );
}
2004-11-29 05:30:36 +00:00
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
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// Fetch the system context, the course context, and prefetch its child contexts
2007-09-19 07:25:49 +00:00
$sysctx = get_context_instance ( CONTEXT_SYSTEM );
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id , MUST_EXIST );
if ( $cm ) {
$cmcontext = get_context_instance ( CONTEXT_MODULE , $cm -> id , MUST_EXIST );
} else {
$cmcontext = null ;
}
2007-09-19 07:25:49 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// If the site is currently under maintenance, then print a message
2009-05-31 14:42:29 +00:00
if ( ! empty ( $CFG -> maintenance_enabled ) and ! has_capability ( 'moodle/site:config' , $sysctx )) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $preventredirect ) {
throw new require_login_exception ( 'Maintenance in progress' );
}
2009-05-31 14:42:29 +00:00
print_maintenance_message ();
2004-11-29 05:30:36 +00:00
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// make sure the course itself is not hidden
if ( $course -> id == SITEID ) {
// frontpage can not be hidden
} else {
if ( ! empty ( $USER -> access [ 'rsw' ][ $coursecontext -> path ])) {
// when switching roles ignore the hidden flag - user had to be in course to do the switch
} else {
if ( ! $course -> visible and ! has_capability ( 'moodle/course:viewhiddencourses' , $coursecontext )) {
// originally there was also test of parent category visibility,
// BUT is was very slow in complex queries involving "my courses"
// now it is also possible to simply hide all courses user is not enrolled in :-)
if ( $preventredirect ) {
throw new require_login_exception ( 'Course is hidden' );
}
notice ( get_string ( 'coursehidden' ), $CFG -> wwwroot . '/' );
}
}
}
// is the user enrolled?
if ( $course -> id == SITEID ) {
// everybody is enrolled on the frontpage
} else {
if ( session_is_loggedinas ()) {
// Make sure the REAL person can access this course first
$realuser = session_get_realuser ();
if ( ! is_enrolled ( $coursecontext , $realuser -> id , '' , true ) and ! is_viewing ( $coursecontext , $realuser -> id ) and ! is_siteadmin ( $realuser -> id )) {
if ( $preventredirect ) {
throw new require_login_exception ( 'Invalid course login-as access' );
}
echo $OUTPUT -> header ();
notice ( get_string ( 'studentnotallowed' , '' , fullname ( $USER , true )), $CFG -> wwwroot . '/' );
}
}
// very simple enrolment caching - changes in course setting are not reflected immediately
if ( ! isset ( $USER -> enrol )) {
$USER -> enrol = array ();
$USER -> enrol [ 'enrolled' ] = array ();
$USER -> enrol [ 'tempguest' ] = array ();
}
$access = false ;
if ( is_viewing ( $coursecontext , $USER )) {
// ok, no need to mess with enrol
$access = true ;
} else {
if ( isset ( $USER -> enrol [ 'enrolled' ][ $course -> id ])) {
if ( $USER -> enrol [ 'enrolled' ][ $course -> id ] == 0 ) {
$access = true ;
} else if ( $USER -> enrol [ 'enrolled' ][ $course -> id ] > time ()) {
$access = true ;
} else {
//expired
unset ( $USER -> enrol [ 'enrolled' ][ $course -> id ]);
}
}
if ( isset ( $USER -> enrol [ 'tempguest' ][ $course -> id ])) {
if ( $USER -> enrol [ 'tempguest' ][ $course -> id ] == 0 ) {
$access = true ;
} else if ( $USER -> enrol [ 'tempguest' ][ $course -> id ] > time ()) {
$access = true ;
} else {
//expired
unset ( $USER -> enrol [ 'tempguest' ][ $course -> id ]);
$USER -> access = remove_temp_roles ( $coursecontext , $USER -> access );
}
}
if ( $access ) {
// cache ok
} else if ( is_enrolled ( $coursecontext , $USER , '' , true )) {
// active participants may always access
// TODO: refactor this into some new function
$now = time ();
$sql = " SELECT MAX(ue.timeend)
FROM { user_enrolments } ue
JOIN { enrol } e ON ( e . id = ue . enrolid AND e . courseid = : courseid )
JOIN { user } u ON u . id = ue . userid
WHERE ue . userid = : userid AND ue . status = : active AND e . status = : enabled AND u . deleted = 0
AND ue . timestart < : now1 AND ( ue . timeend = 0 OR ue . timeend > : now2 ) " ;
$params = array ( 'enabled' => ENROL_INSTANCE_ENABLED , 'active' => ENROL_USER_ACTIVE ,
'userid' => $USER -> id , 'courseid' => $coursecontext -> instanceid , 'now1' => $now , 'now2' => $now );
$until = $DB -> get_field_sql ( $sql , $params );
if ( ! $until or $until > time () + ENROL_REQUIRE_LOGIN_CACHE_PERIOD ) {
$until = time () + ENROL_REQUIRE_LOGIN_CACHE_PERIOD ;
}
$USER -> enrol [ 'enrolled' ][ $course -> id ] = $until ;
$access = true ;
// remove traces of previous temp guest access
$USER -> access = remove_temp_roles ( $coursecontext , $USER -> access );
} else {
$instances = $DB -> get_records ( 'enrol' , array ( 'courseid' => $course -> id , 'status' => ENROL_INSTANCE_ENABLED ), 'sortorder, id ASC' );
$enrols = enrol_get_plugins ( true );
// first ask all enabled enrol instances in course if they want to auto enrol user
foreach ( $instances as $instance ) {
if ( ! isset ( $enrols [ $instance -> enrol ])) {
continue ;
}
$until = $enrols [ $instance -> enrol ] -> try_autoenrol ( $instance );
if ( $until !== false ) {
$USER -> enrol [ 'enrolled' ][ $course -> id ] = $until ;
$USER -> access = remove_temp_roles ( $coursecontext , $USER -> access );
$access = true ;
break ;
}
}
// if not enrolled yet try to gain temporary guest access
if ( ! $access ) {
foreach ( $instances as $instance ) {
if ( ! isset ( $enrols [ $instance -> enrol ])) {
continue ;
}
$until = $enrols [ $instance -> enrol ] -> try_guestaccess ( $instance );
if ( $until !== false ) {
$USER -> enrol [ 'tempguest' ][ $course -> id ] = $until ;
$access = true ;
break ;
}
}
}
}
}
if ( ! $access ) {
if ( $preventredirect ) {
throw new require_login_exception ( 'Not enrolled' );
}
$SESSION -> wantsurl = $FULLME ;
redirect ( $CFG -> wwwroot . '/enrol/index.php?id=' . $course -> id );
}
}
// test visibility
if ( $cm && ! $cm -> visible && ! has_capability ( 'moodle/course:viewhiddenactivities' , $cmcontext )) {
if ( $preventredirect ) {
throw new require_login_exception ( 'Activity is hidden' );
}
redirect ( $CFG -> wwwroot , get_string ( 'activityiscurrentlyhidden' ));
}
// groupmembersonly access control
2010-04-07 07:37:12 +00:00
if ( ! empty ( $CFG -> enablegroupmembersonly ) and $cm and $cm -> groupmembersonly and ! has_capability ( 'moodle/site:accessallgroups' , get_context_instance ( CONTEXT_MODULE , $cm -> id ))) {
2007-08-17 12:15:32 +00:00
if ( isguestuser () or ! groups_has_membership ( $cm )) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $preventredirect ) {
throw new require_login_exception ( 'Not member of a group' );
}
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
2008-12-17 16:37:35 +00:00
// Conditional activity access control
2010-03-31 07:41:31 +00:00
if ( ! empty ( $CFG -> enableavailability ) and $cm ) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// TODO: this is going to work with login-as-user, sorry!
2008-12-17 16:37:35 +00:00
// We cache conditional access in session
2010-03-31 07:41:31 +00:00
if ( ! isset ( $SESSION -> conditionaccessok )) {
2009-02-17 17:23:56 +00:00
$SESSION -> conditionaccessok = array ();
2008-12-17 16:37:35 +00:00
}
// If you have been allowed into the module once then you are allowed
// in for rest of session, no need to do conditional checks
2009-02-17 17:23:56 +00:00
if ( ! array_key_exists ( $cm -> id , $SESSION -> conditionaccessok )) {
2008-12-17 16:37:35 +00:00
// Get condition info (does a query for the availability table)
2009-02-01 13:36:07 +00:00
require_once ( $CFG -> libdir . '/conditionlib.php' );
2009-02-17 17:23:56 +00:00
$ci = new condition_info ( $cm , CONDITION_MISSING_EXTRATABLE );
2008-12-17 16:37:35 +00:00
// Check condition for user (this will do a query if the availability
// information depends on grade or completion information)
2010-03-31 07:41:31 +00:00
if ( $ci -> is_available ( $junk ) || has_capability ( 'moodle/course:viewhiddenactivities' , $cmcontext )) {
2009-02-17 17:23:56 +00:00
$SESSION -> conditionaccessok [ $cm -> id ] = true ;
2008-12-17 16:37:35 +00:00
} else {
print_error ( 'activityiscurrentlyhidden' );
}
}
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// Finally access granted, update lastaccess times
user_accesstime_log ( $course -> id );
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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
2006-09-03 08:10:10 +00:00
*/
function require_logout () {
2009-01-18 11:19:40 +00:00
global $USER ;
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
}
2009-01-17 15:25:08 +00:00
session_get_instance () -> terminate_current ();
2006-09-03 08:10:10 +00:00
}
2004-09-23 02:48:41 +00:00
/**
2009-05-22 02:57:43 +00:00
* Weaker version of require_login ()
*
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 .
2009-05-22 02:57:43 +00:00
* @ see require_login ()
2004-09-23 02:48:41 +00:00
*
2009-05-22 02:57:43 +00:00
* @ global object
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
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
* @ param bool $preventredirect set to true in scripts that can not redirect ( CLI , rss feeds , etc . ), throws exceptions
* @ return void
2004-09-23 02:48:41 +00:00
*/
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
function require_course_login ( $courseorid , $autologinguest = true , $cm = NULL , $setwantsurltome = true , $preventredirect = false ) {
2009-12-10 01:57:01 +00:00
global $CFG , $PAGE , $SITE ;
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
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
require_login ( $courseorid , $autologinguest , $cm , $setwantsurltome , $preventredirect );
2007-05-10 09:02:41 +00:00
} else if ( ! empty ( $cm ) and ! $cm -> visible ) {
// always login for hidden activities
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
require_login ( $courseorid , $autologinguest , $cm , $setwantsurltome , $preventredirect );
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 )) {
2009-10-01 09:58:08 +00:00
//login for SITE not required
if ( $cm and empty ( $cm -> visible )) {
// hidden activities are not accessible without login
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
require_login ( $courseorid , $autologinguest , $cm , $setwantsurltome , $preventredirect );
2010-04-07 07:37:12 +00:00
} else if ( $cm and ! empty ( $CFG -> enablegroupmembersonly ) and $cm -> groupmembersonly ) {
2009-10-01 09:58:08 +00:00
// not-logged-in users do not have any group membership
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
require_login ( $courseorid , $autologinguest , $cm , $setwantsurltome , $preventredirect );
2009-10-01 09:58:08 +00:00
} else {
2009-12-10 01:57:01 +00:00
// We still need to instatiate PAGE vars properly so that things
// that rely on it like navigation function correctly.
if ( ! empty ( $courseorid )) {
if ( is_object ( $courseorid )) {
$course = $courseorid ;
} else {
$course = clone ( $SITE );
}
if ( $cm ) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( $cm -> course != $course -> id ) {
throw new coding_exception ( 'course and cm parameters in require_course_login() call do not match!!' );
}
2009-12-10 01:57:01 +00:00
$PAGE -> set_cm ( $cm , $course );
2009-12-27 12:02:04 +00:00
$PAGE -> set_pagelayout ( 'incourse' );
2009-12-10 01:57:01 +00:00
} else {
$PAGE -> set_course ( $course );
}
} else {
// If $PAGE->course, and hence $PAGE->context, have not already been set
// up properly, set them up now.
$PAGE -> set_course ( $PAGE -> course );
}
2009-10-01 09:58:08 +00:00
//TODO: verify conditional activities here
user_accesstime_log ( SITEID );
return ;
}
2007-05-10 09:02:41 +00:00
2007-01-19 09:44:26 +00:00
} else {
// course login always required
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
require_login ( $courseorid , $autologinguest , $cm , $setwantsurltome , $preventredirect );
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 .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
* @ global object
* @ global object
* @ uses NO_MOODLE_COOKIES
* @ uses PARAM_ALPHANUM
2007-08-28 08:29:40 +00:00
* @ param string $script unique script identifier
* @ param int $instance optional instance id
2009-05-22 02:57:43 +00:00
* @ return int Instance ID
2007-08-28 08:29:40 +00:00
*/
function require_user_key_login ( $script , $instance = null ) {
2008-06-23 21:18:08 +00:00
global $USER , $SESSION , $CFG , $DB ;
2007-08-28 08:29:40 +00:00
2008-06-23 21:18:08 +00:00
if ( ! NO_MOODLE_COOKIES ) {
2008-05-20 02:53:46 +00:00
print_error ( 'sessioncookiesdisable' );
2007-08-28 08:29:40 +00:00
}
/// extra safety
@ session_write_close ();
$keyvalue = required_param ( 'key' , PARAM_ALPHANUM );
2008-05-30 19:59:50 +00:00
if ( ! $key = $DB -> get_record ( 'user_private_key' , array ( 'script' => $script , 'value' => $keyvalue , 'instance' => $instance ))) {
2008-05-20 02:53:46 +00:00
print_error ( 'invalidkey' );
2007-08-28 08:29:40 +00:00
}
if ( ! empty ( $key -> validuntil ) and $key -> validuntil < time ()) {
2008-05-20 02:53:46 +00:00
print_error ( 'expiredkey' );
2007-08-28 08:29:40 +00:00
}
2007-08-29 18:06:18 +00:00
if ( $key -> iprestriction ) {
2010-05-20 02:36:20 +00:00
$remoteaddr = getremoteaddr ( null );
if ( empty ( $remoteaddr ) or ! address_in_subnet ( $remoteaddr , $key -> iprestriction )) {
2008-05-20 02:53:46 +00:00
print_error ( 'ipmismatch' );
2007-08-29 18:06:18 +00:00
}
2007-08-28 08:29:40 +00:00
}
2008-05-30 19:59:50 +00:00
if ( ! $user = $DB -> get_record ( 'user' , array ( 'id' => $key -> userid ))) {
2008-05-20 02:53:46 +00:00
print_error ( 'invaliduserid' );
2007-08-28 08:29:40 +00:00
}
/// emulate normal session
2009-01-02 21:27:18 +00:00
session_set_user ( $user );
2007-08-28 08:29:40 +00:00
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 );
}
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 .
2009-05-22 02:57:43 +00:00
*
* @ global object
2007-08-28 08:29:40 +00:00
* @ param string $script unique target identifier
* @ param int $userid
2009-05-22 02:57:43 +00:00
* @ param int $instance optional instance id
2007-08-28 08:29:40 +00:00
* @ 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 ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2007-08-28 08:29:40 +00:00
$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
2008-05-30 19:59:50 +00:00
while ( $DB -> record_exists ( 'user_private_key' , array ( 'value' => $key -> value ))) {
2007-08-28 08:29:40 +00:00
// must be unique
$key -> value = md5 ( $userid . '_' . time () . random_string ( 40 ));
}
2009-06-03 20:16:20 +00:00
$DB -> insert_record ( 'user_private_key' , $key );
2007-08-28 08:29:40 +00:00
return $key -> value ;
}
2010-05-12 06:48:59 +00:00
/**
* Delete the user ' s new private user access keys for a particular script .
*
* @ global object
* @ param string $script unique target identifier
* @ param int $userid
* @ return void
*/
function delete_user_key ( $script , $userid ) {
global $DB ;
$DB -> delete_records ( 'user_private_key' , array ( 'script' => $script , 'userid' => $userid ));
}
2010-04-29 05:29:51 +00:00
/**
* Gets a private user access key ( and creates one if one doesn ' t exist ) .
*
* @ global object
* @ param string $script unique target identifier
* @ param int $userid
* @ param int $instance 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 get_user_key ( $script , $userid , $instance = null , $iprestriction = null , $validuntil = null ) {
global $DB ;
2010-06-06 14:06:30 +00:00
if ( $key = $DB -> get_record ( 'user_private_key' , array ( 'script' => $script , 'userid' => $userid ,
'instance' => $instance , 'iprestriction' => $iprestriction ,
2010-04-29 05:29:51 +00:00
'validuntil' => $validuntil ))) {
return $key -> value ;
} else {
return create_user_key ( $script , $userid , $instance , $iprestriction , $validuntil );
}
}
2004-09-23 02:48:41 +00:00
/**
* Modify the user table by setting the currently logged in user ' s
* last login to now .
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
* @ return bool Always returns true
2004-09-23 02:48:41 +00:00
*/
2002-12-23 03:07:01 +00:00
function update_user_login_times () {
2008-05-30 19:59:50 +00:00
global $USER , $DB ;
2002-12-23 03:07:01 +00:00
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 ;
2009-02-17 17:23:56 +00:00
$DB -> update_record ( 'user' , $user );
return true ;
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 .
*
2010-05-22 18:38:18 +00:00
* @ param user $user A { @ link $USER } object to test for the existence 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 )));
}
2009-05-22 02:57:43 +00:00
/**
* Check whether the user has exceeded the bounce threshold
*
* @ global object
* @ global object
* @ param user $user A { @ link $USER } object
* @ return bool true => User has exceeded bounce threshold
*/
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 over_bounce_threshold ( $user ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
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 ;
}
2009-03-04 15:03:00 +00:00
if ( empty ( $user -> id )) { /// No real (DB) user, nothing to do here.
return 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
// set sensible defaults
if ( empty ( $CFG -> minbounces )) {
$CFG -> minbounces = 10 ;
}
if ( empty ( $CFG -> bounceratio )) {
$CFG -> bounceratio = . 20 ;
}
$bouncecount = 0 ;
$sendcount = 0 ;
2008-05-30 19:59:50 +00:00
if ( $bounce = $DB -> get_record ( 'user_preferences' , array ( '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
$bouncecount = $bounce -> value ;
}
2008-05-30 19:59:50 +00:00
if ( $send = $DB -> get_record ( 'user_preferences' , array ( '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
$sendcount = $send -> value ;
}
return ( $bouncecount >= $CFG -> minbounces && $bouncecount / $sendcount >= $CFG -> bounceratio );
}
2005-02-25 06:08:40 +00:00
/**
2009-09-01 08:39:55 +00:00
* Used to increment or reset email sent count
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ param user $user object containing an id
* @ param bool $reset will reset the count to 0
* @ return void
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 set_send_count ( $user , $reset = false ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2009-03-04 15:03:00 +00:00
if ( empty ( $user -> id )) { /// No real (DB) user, nothing to do here.
return ;
}
2008-05-30 19:59:50 +00:00
if ( $pref = $DB -> get_record ( 'user_preferences' , array ( '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 ;
2008-05-30 19:59:50 +00:00
$DB -> update_record ( 'user_preferences' , $pref );
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
}
else if ( ! empty ( $reset )) { // if it's not there and we're resetting, don't bother.
// make a new one
2008-05-30 19:59:50 +00:00
$pref = new object ();
$pref -> name = 'email_send_count' ;
$pref -> value = 1 ;
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 -> userid = $user -> id ;
2008-05-30 19:59:50 +00:00
$DB -> 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
/**
2009-09-01 08:39:55 +00:00
* Increment or reset user ' s email bounce count
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ param user $user object containing an id
* @ param bool $reset will reset the count to 0
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 set_bounce_count ( $user , $reset = false ) {
2008-05-30 19:59:50 +00:00
global $DB ;
if ( $pref = $DB -> get_record ( 'user_preferences' , array ( '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 ;
2008-05-30 19:59:50 +00:00
$DB -> update_record ( 'user_preferences' , $pref );
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
}
else if ( ! empty ( $reset )) { // if it's not there and we're resetting, don't bother.
// make a new one
2008-05-30 19:59:50 +00:00
$pref = new object ();
$pref -> name = 'email_bounce_count' ;
$pref -> value = 1 ;
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 -> userid = $user -> id ;
2008-05-30 19:59:50 +00:00
$DB -> 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
*
2009-05-22 02:57:43 +00:00
* @ global object
2004-09-23 02:48:41 +00:00
*/
2001-11-22 06:23:56 +00:00
function update_login_count () {
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
*
2009-05-22 02:57:43 +00:00
* @ global object
2004-09-23 02:48:41 +00:00
*/
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
}
2009-05-17 18:45:00 +00:00
/**
* Returns reference to full info about modules in course ( including visibility ) .
* Cached and as fast as possible ( 0 or 1 db query ) .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
* @ global object
* @ uses CONTEXT_MODULE
* @ uses MAX_MODINFO_CACHE_SIZE
* @ param mixed $course object or 'reset' string to reset caches , modinfo may be updated in db
* @ param int $userid Defaults to current user id
2009-05-17 18:45:00 +00:00
* @ return mixed courseinfo object or nothing if resetting
*/
function & get_fast_modinfo ( & $course , $userid = 0 ) {
global $CFG , $USER , $DB ;
require_once ( $CFG -> dirroot . '/course/lib.php' );
if ( ! empty ( $CFG -> enableavailability )) {
require_once ( $CFG -> libdir . '/conditionlib.php' );
}
static $cache = array ();
if ( $course === 'reset' ) {
$cache = array ();
$nothing = null ;
return $nothing ; // we must return some reference
}
if ( empty ( $userid )) {
$userid = $USER -> id ;
}
if ( array_key_exists ( $course -> id , $cache ) and $cache [ $course -> id ] -> userid == $userid ) {
return $cache [ $course -> id ];
}
if ( empty ( $course -> modinfo )) {
// no modinfo yet - load it
rebuild_course_cache ( $course -> id );
$course -> modinfo = $DB -> get_field ( 'course' , 'modinfo' , array ( 'id' => $course -> id ));
}
$modinfo = new object ();
$modinfo -> courseid = $course -> id ;
$modinfo -> userid = $userid ;
$modinfo -> sections = array ();
$modinfo -> cms = array ();
$modinfo -> instances = array ();
$modinfo -> groups = null ; // loaded only when really needed - the only one db query
$info = unserialize ( $course -> modinfo );
if ( ! is_array ( $info )) {
// hmm, something is wrong - lets try to fix it
rebuild_course_cache ( $course -> id );
$course -> modinfo = $DB -> get_field ( 'course' , 'modinfo' , array ( 'id' => $course -> id ));
$info = unserialize ( $course -> modinfo );
if ( ! is_array ( $info )) {
return $modinfo ;
}
}
if ( $info ) {
// detect if upgrade required
$first = reset ( $info );
if ( ! isset ( $first -> id )) {
rebuild_course_cache ( $course -> id );
$course -> modinfo = $DB -> get_field ( 'course' , 'modinfo' , array ( 'id' => $course -> id ));
$info = unserialize ( $course -> modinfo );
if ( ! is_array ( $info )) {
return $modinfo ;
}
}
}
$modlurals = array ();
// If we haven't already preloaded contexts for the course, do it now
preload_course_contexts ( $course -> id );
foreach ( $info as $mod ) {
if ( empty ( $mod -> name )) {
// something is wrong here
continue ;
}
// reconstruct minimalistic $cm
$cm = new object ();
$cm -> id = $mod -> cm ;
$cm -> instance = $mod -> id ;
$cm -> course = $course -> id ;
$cm -> modname = $mod -> mod ;
2010-05-28 01:53:09 +00:00
$cm -> idnumber = $mod -> idnumber ;
2010-02-14 20:18:10 +00:00
$cm -> name = $mod -> name ;
2009-05-17 18:45:00 +00:00
$cm -> visible = $mod -> visible ;
$cm -> sectionnum = $mod -> section ;
$cm -> groupmode = $mod -> groupmode ;
$cm -> groupingid = $mod -> groupingid ;
$cm -> groupmembersonly = $mod -> groupmembersonly ;
$cm -> indent = $mod -> indent ;
$cm -> completion = $mod -> completion ;
2010-02-14 20:18:10 +00:00
$cm -> extra = isset ( $mod -> extra ) ? $mod -> extra : '' ;
2009-05-17 18:45:00 +00:00
$cm -> icon = isset ( $mod -> icon ) ? $mod -> icon : '' ;
2010-02-14 20:18:10 +00:00
$cm -> iconcomponent = isset ( $mod -> iconcomponent ) ? $mod -> iconcomponent : '' ;
2009-05-17 18:45:00 +00:00
$cm -> uservisible = true ;
if ( ! empty ( $CFG -> enableavailability )) {
// We must have completion information from modinfo. If it's not
// there, cache needs rebuilding
if ( ! isset ( $mod -> availablefrom )) {
debugging ( 'enableavailability option was changed; rebuilding ' .
'cache for course ' . $course -> id );
rebuild_course_cache ( $course -> id , true );
// Re-enter this routine to do it all properly
return get_fast_modinfo ( $course , $userid );
}
$cm -> availablefrom = $mod -> availablefrom ;
$cm -> availableuntil = $mod -> availableuntil ;
$cm -> showavailability = $mod -> showavailability ;
$cm -> conditionscompletion = $mod -> conditionscompletion ;
$cm -> conditionsgrade = $mod -> conditionsgrade ;
}
// preload long names plurals and also check module is installed properly
if ( ! isset ( $modlurals [ $cm -> modname ])) {
if ( ! file_exists ( " $CFG->dirroot /mod/ $cm->modname /lib.php " )) {
continue ;
}
$modlurals [ $cm -> modname ] = get_string ( 'modulenameplural' , $cm -> modname );
}
$cm -> modplural = $modlurals [ $cm -> modname ];
$modcontext = get_context_instance ( CONTEXT_MODULE , $cm -> id );
2009-09-01 08:39:55 +00:00
2009-05-17 18:45:00 +00:00
if ( ! empty ( $CFG -> enableavailability )) {
2009-09-01 08:39:55 +00:00
// Unfortunately the next call really wants to call
// get_fast_modinfo, but that would be recursive, so we fake up a
2009-05-17 18:45:00 +00:00
// modinfo for it already
if ( empty ( $minimalmodinfo )) {
$minimalmodinfo = new stdClass ();
$minimalmodinfo -> cms = array ();
foreach ( $info as $mod ) {
2010-04-11 08:59:27 +00:00
if ( empty ( $mod -> name )) {
// something is wrong here
continue ;
}
2010-02-14 20:18:10 +00:00
$minimalcm = new stdClass ();
$minimalcm -> id = $mod -> cm ;
$minimalcm -> name = $mod -> name ;
2009-05-17 18:45:00 +00:00
$minimalmodinfo -> cms [ $minimalcm -> id ] = $minimalcm ;
}
}
// Get availability information
$ci = new condition_info ( $cm );
2010-02-14 20:18:10 +00:00
$cm -> available = $ci -> is_available ( $cm -> availableinfo , true , $userid , $minimalmodinfo );
2009-05-17 18:45:00 +00:00
} else {
$cm -> available = true ;
}
if (( ! $cm -> visible or ! $cm -> available ) and ! has_capability ( 'moodle/course:viewhiddenactivities' , $modcontext , $userid )) {
$cm -> uservisible = false ;
2010-04-07 07:37:12 +00:00
} else if ( ! empty ( $CFG -> enablegroupmembersonly ) and ! empty ( $cm -> groupmembersonly )
2009-05-17 18:45:00 +00:00
and ! has_capability ( 'moodle/site:accessallgroups' , $modcontext , $userid )) {
if ( is_null ( $modinfo -> groups )) {
$modinfo -> groups = groups_get_user_groups ( $course -> id , $userid );
}
if ( empty ( $modinfo -> groups [ $cm -> groupingid ])) {
$cm -> uservisible = false ;
}
}
if ( ! isset ( $modinfo -> instances [ $cm -> modname ])) {
$modinfo -> instances [ $cm -> modname ] = array ();
}
$modinfo -> instances [ $cm -> modname ][ $cm -> instance ] =& $cm ;
$modinfo -> cms [ $cm -> id ] =& $cm ;
// reconstruct sections
if ( ! isset ( $modinfo -> sections [ $cm -> sectionnum ])) {
$modinfo -> sections [ $cm -> sectionnum ] = array ();
}
$modinfo -> sections [ $cm -> sectionnum ][] = $cm -> id ;
unset ( $cm );
}
unset ( $cache [ $course -> id ]); // prevent potential reference problems when switching users
$cache [ $course -> id ] = $modinfo ;
// Ensure cache does not use too much RAM
if ( count ( $cache ) > MAX_MODINFO_CACHE_SIZE ) {
2009-05-24 07:24:16 +00:00
reset ( $cache );
$key = key ( $cache );
unset ( $cache [ $key ]);
2009-05-17 18:45:00 +00:00
}
return $cache [ $course -> id ];
}
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
*
2009-05-22 02:57:43 +00:00
* @ deprecated since Moodle 2.0 - use $PAGE -> user_is_editing () instead .
* @ todo Deprecated function remove when ready
*
* @ global object
* @ uses DEBUG_DEVELOPER
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 () {
2009-05-06 08:59:29 +00:00
global $PAGE ;
debugging ( 'call to deprecated function isediting(). Please use $PAGE->user_is_editing() instead' , DEBUG_DEVELOPER );
return $PAGE -> user_is_editing ();
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
*
2009-05-22 02:57:43 +00:00
* @ global object
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
/**
2009-05-22 02:57:43 +00:00
* Returns a persons full name
*
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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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 .
2009-05-22 02:57:43 +00:00
* @ return string
2004-09-23 02:48:41 +00:00
*/
2003-11-19 15:59:45 +00:00
function fullname ( $user , $override = false ) {
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
2008-08-16 12:16:01 +00:00
if ( ! isset ( $CFG -> fullnamedisplay ) or $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
/**
2007-01-04 02:52:44 +00:00
* Returns whether a given authentication plugin exists .
2004-09-23 02:48:41 +00:00
*
2009-05-22 02:57:43 +00:00
* @ global object
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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
2007-02-21 21:48:48 +00:00
* @ param string $auth name of authentication plugin
2010-04-11 21:13:45 +00:00
* @ return auth_plugin_base An instance of the required authentication plugin .
2007-01-04 02:52:44 +00:00
*/
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-05-20 02:53:46 +00:00
print_error ( 'authpluginnotfound' , 'debug' , '' , $auth );
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
*
* @ 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
}
2009-11-18 01:05:58 +00:00
/**
* Returns true if the user is a 'restored' one
*
* Used in the login process to inform the user
* and allow him / her to reset the password
*
* @ uses $CFG
* @ uses $DB
* @ param string $username username to be checked
* @ return bool
*/
function is_restored_user ( $username ) {
global $CFG , $DB ;
return $DB -> record_exists ( 'user' , array ( 'username' => $username , 'mnethostid' => $CFG -> mnet_localhost_id , 'password' => 'restored' ));
}
2004-09-23 05:10:21 +00:00
/**
* Returns an array of user fields
*
2004-09-25 01:29:37 +00:00
* @ 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 () {
2008-05-15 21:40:00 +00:00
global $DB ;
2004-09-23 03:56:53 +00:00
2008-05-15 21:40:00 +00:00
$fieldarray = $DB -> get_columns ( 'user' );
unset ( $fieldarray [ 'id' ]);
$fieldarray = array_keys ( $fieldarray );
2004-09-23 03:56:53 +00:00
return $fieldarray ;
2003-09-22 13:58:20 +00:00
}
2001-11-22 06:23:56 +00:00
2004-09-23 02:48:41 +00:00
/**
* Creates a bare - bones user record
*
2009-05-22 02:57:43 +00:00
* @ todo Outline auth types and provide code example
*
* @ global object
* @ global object
2004-09-23 02:48:41 +00:00
* @ 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
*/
2007-04-04 09:19:31 +00:00
function create_user_record ( $username , $password , $auth = 'manual' ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
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 );
2008-05-30 19:59:50 +00:00
$newuser = new object ();
2007-03-22 12:27:52 +00:00
if ( $newinfo = $authplugin -> get_userinfo ( $username )) {
$newinfo = truncate_userinfo ( $newinfo );
foreach ( $newinfo as $key => $value ){
2008-05-30 19:59:50 +00:00
$newuser -> $key = $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 );
}
}
2008-12-29 21:46:59 +00:00
if ( ! isset ( $newuser -> city )) {
$newuser -> city = '' ;
}
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
2010-04-14 13:16:20 +00:00
if ( empty ( $newuser -> lang ) || ! get_string_manager () -> translation_exists ( $newuser -> lang )) {
2009-02-17 17:32:36 +00:00
$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
2009-02-17 17:32:36 +00:00
$DB -> insert_record ( 'user' , $newuser );
$user = get_complete_user_data ( 'username' , $newuser -> username );
if ( ! empty ( $CFG -> { 'auth_' . $newuser -> auth . '_forcechangepassword' })){
set_user_preference ( 'auth_forcepasswordchange' , 1 , $user -> id );
2002-09-26 07:03:22 +00:00
}
2009-02-17 17:32:36 +00:00
update_internal_user_password ( $user , $password );
return $user ;
2002-09-26 07:03:22 +00:00
}
2004-09-23 02:48:41 +00:00
/**
* Will update a local user record from an external source
*
2009-05-22 02:57:43 +00:00
* @ global object
2004-09-23 02:48:41 +00:00
* @ param string $username New user ' s username to add to record
2009-05-22 02:57:43 +00:00
* @ param string $authplugin Unused
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 ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2007-03-22 12:27:52 +00:00
$username = trim ( moodle_strtolower ( $username )); /// just in case check text case
2008-05-30 19:59:50 +00:00
$oldinfo = $DB -> get_record ( 'user' , array ( 'username' => $username ), 'username, auth' );
2007-03-22 12:27:52 +00:00
$userauth = get_auth_plugin ( $oldinfo -> auth );
if ( $newinfo = $userauth -> get_userinfo ( $username )) {
$newinfo = truncate_userinfo ( $newinfo );
foreach ( $newinfo as $key => $value ){
2008-08-25 22:44:45 +00:00
if ( $key === 'username' ) {
// 'username' is not a mapped updateable/lockable field, so skip it.
continue ;
}
2008-05-31 13:30:22 +00:00
$confval = $userauth -> config -> { 'field_updatelocal_' . $key };
$lockval = $userauth -> config -> { 'field_lock_' . $key };
if ( empty ( $confval ) || empty ( $lockval )) {
continue ;
}
if ( $confval === 'onlogin' ) {
// MDL-4207 Don't overwrite modified user profile values with
// empty LDAP values when 'unlocked if empty' is set. The purpose
// of the setting 'unlocked if empty' is to allow the user to fill
// in a value for the selected field _if LDAP is giving
// nothing_ for this field. Thus it makes sense to let this value
// stand in until LDAP is giving a value for this field.
if ( ! ( empty ( $value ) && $lockval === 'unlockedifempty' )) {
2009-02-19 16:21:46 +00:00
$DB -> set_field ( 'user' , $key , $value , array ( 'username' => $username ));
2008-05-31 13:30:22 +00:00
}
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
2008-05-30 20:54:19 +00:00
/**
2009-05-22 02:57:43 +00:00
* Will truncate userinfo as it comes from auth_get_userinfo ( from external auth )
2008-05-30 20:54:19 +00:00
* which may have large fields
2009-05-22 02:57:43 +00:00
*
* @ todo Add vartype handling to ensure $info is an array
*
* @ param array $info Array of user properties to truncate if needed
* @ return array The now truncated information that was passed in
2008-05-30 20:54:19 +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 ) {
// 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 ,
2010-07-08 11:15:49 +00:00
'city' => 120 ,
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
'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 .
2009-05-22 02:57:43 +00:00
*
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
* Any plugin that needs to purge user data should register the 'user_deleted' event .
2009-05-22 02:57:43 +00:00
*
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
* @ param object $user User object before delete
* @ return boolean always true
2007-08-21 20:52:36 +00:00
*/
function delete_user ( $user ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2007-08-21 20:52:36 +00:00
require_once ( $CFG -> libdir . '/grouplib.php' );
2007-10-03 12:22:25 +00:00
require_once ( $CFG -> libdir . '/gradelib.php' );
2009-04-26 22:56:56 +00:00
require_once ( $CFG -> dirroot . '/message/lib.php' );
2010-06-06 14:06:30 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// delete all grades - backup is kept in grade_grades_history table
grade_user_delete ( $user -> id );
2007-08-21 20:52:36 +00:00
2009-11-07 08:52:56 +00:00
//move unread messages from this user to read
message_move_userfrom_unread2read ( $user -> id );
2007-08-21 20:52:36 +00:00
2010-04-23 09:18:12 +00:00
// remove from all cohorts
$DB -> delete_records ( 'cohort_members' , array ( 'userid' => $user -> id ));
2009-11-07 08:52:56 +00:00
// remove from all groups
$DB -> delete_records ( 'groups_members' , array ( 'userid' => $user -> id ));
2007-08-21 20:52:36 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// brute force unenrol from all courses
$DB -> delete_records ( 'user_enrolments' , array ( 'userid' => $user -> id ));
// purge user preferences
$DB -> delete_records ( 'user_preferences' , array ( 'userid' => $user -> id ));
// purge user extra profile info
$DB -> delete_records ( 'user_info_data' , array ( 'userid' => $user -> id ));
// last course access not necessary either
$DB -> delete_records ( 'user_lastaccess' , array ( 'userid' => $user -> id ));
2007-08-21 20:52:36 +00:00
2010-07-11 11:43:15 +00:00
// final accesslib cleanup - removes all role assignments in user context and context itself, files, etc.
2009-11-07 08:52:56 +00:00
delete_context ( CONTEXT_USER , $user -> id );
2008-04-28 08:35:21 +00:00
2009-11-07 08:52:56 +00:00
require_once ( $CFG -> dirroot . '/tag/lib.php' );
tag_set ( 'user' , $user -> id , array ());
2009-02-17 17:32:36 +00:00
2009-11-07 08:52:56 +00:00
// workaround for bulk deletes of users with the same email address
$delname = " $user->email . " . time ();
while ( $DB -> record_exists ( 'user' , array ( 'username' => $delname ))) { // no need to use mnethostid here
$delname ++ ;
}
2007-08-21 20:52:36 +00:00
2009-11-07 08:52:56 +00:00
// mark internal user record as "deleted"
$updateuser = new object ();
$updateuser -> id = $user -> id ;
$updateuser -> deleted = 1 ;
2009-11-23 18:50:47 +00:00
$updateuser -> username = $delname ; // Remember it just in case
$updateuser -> email = md5 ( $user -> username ); // Store hash of username, useful importing/restoring users
$updateuser -> idnumber = '' ; // Clear this field to free it up
2009-11-07 08:52:56 +00:00
$updateuser -> timemodified = time ();
2009-02-17 17:32:36 +00:00
2009-11-07 08:52:56 +00:00
$DB -> update_record ( 'user' , $updateuser );
2008-07-06 17:57:06 +00:00
2009-11-07 08:52:56 +00:00
// notify auth plugin - do not block the delete even when plugin fails
$authplugin = get_auth_plugin ( $user -> auth );
$authplugin -> user_delete ( $user );
2007-08-21 20:52:36 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// any plugin that needs to cleanup should register this event
2009-11-07 08:52:56 +00:00
events_trigger ( 'user_deleted' , $user );
2009-02-17 17:32:36 +00:00
return true ;
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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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 () {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2004-01-25 09:35:45 +00:00
2008-05-30 19:59:50 +00:00
if ( $newuser = $DB -> get_record ( 'user' , array ( '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
/**
2009-05-22 02:57:43 +00:00
* Authenticates a user against the chosen authentication mechanism
*
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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
2008-05-30 20:54:19 +00:00
* @ param string $username User ' s username
* @ param string $password User ' s password
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 ) {
2009-08-18 05:20:12 +00:00
global $CFG , $DB , $OUTPUT ;
2002-09-26 07:03:22 +00:00
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
2010-07-07 07:14:03 +00:00
if ( ! empty ( $user -> suspended )) {
2010-07-05 21:51:58 +00:00
add_to_log ( 0 , 'login' , 'error' , 'index.php' , $username );
error_log ( '[client ' . getremoteaddr () . " ] $CFG->wwwroot Suspended Login: $username " . $_SERVER [ 'HTTP_USER_AGENT' ]);
return false ;
}
2007-02-20 17:15:13 +00:00
if ( $auth == 'nologin' or ! is_enabled_auth ( $auth )) {
add_to_log ( 0 , 'login' , 'error' , 'index.php' , $username );
2009-01-03 14:28:02 +00:00
error_log ( '[client ' . getremoteaddr () . " ] $CFG->wwwroot Disabled Login: $username " . $_SERVER [ 'HTTP_USER_AGENT' ]);
2007-02-20 17:15:13 +00:00
return false ;
2004-08-29 05:48:15 +00:00
}
2007-02-20 17:15:13 +00:00
$auths = array ( $auth );
2004-08-31 12:33:20 +00:00
} else {
2009-09-26 20:17:57 +00:00
// check if there's a deleted record (cheaply)
if ( $DB -> get_field ( 'user' , 'id' , array ( 'username' => $username , 'deleted' => 1 ))) {
error_log ( '[client ' . $_SERVER [ 'REMOTE_ADDR' ] . " ] $CFG->wwwroot Deleted Login: $username " . $_SERVER [ 'HTTP_USER_AGENT' ]);
return false ;
}
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
2008-05-30 19:59:50 +00:00
$DB -> set_field ( 'user' , 'auth' , $auth , array ( 'username' => $username ));
2007-02-20 17:15:13 +00:00
$user -> auth = $auth ;
2004-08-31 12:33:20 +00:00
}
2009-03-11 11:22:55 +00:00
if ( empty ( $user -> firstaccess )) { //prevent firstaccess from remaining 0 for manual account that never required confirmation
$DB -> set_field ( 'user' , 'firstaccess' , $user -> timemodified , array ( 'id' => $user -> id ));
$user -> firstaccess = $user -> timemodified ;
}
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 );
}
2010-07-05 21:51:58 +00:00
if ( empty ( $user -> id )) {
return false ;
}
2010-07-07 07:14:03 +00:00
if ( ! empty ( $user -> suspended )) {
2010-07-05 21:51:58 +00:00
// just in case some auth plugin suspended account
add_to_log ( 0 , 'login' , 'error' , 'index.php' , $username );
error_log ( '[client ' . getremoteaddr () . " ] $CFG->wwwroot Suspended Login: $username " . $_SERVER [ 'HTTP_USER_AGENT' ]);
2008-02-27 02:56:48 +00:00
return false ;
}
2010-07-05 21:51:58 +00:00
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 )) {
2009-01-03 14:28:02 +00:00
error_log ( '[client ' . getremoteaddr () . " ] $CFG->wwwroot Failed Login: $username " . $_SERVER [ 'HTTP_USER_AGENT' ]);
2008-02-25 07:17:04 +00:00
}
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 .
2008-05-30 19:59:50 +00:00
*
2007-11-14 22:03:46 +00:00
* NOTE :
* - It will NOT log anything -- up to the caller to decide what to log .
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
* @ global object
* @ param object $user
* @ param bool $setcookie
2009-01-02 20:32:05 +00:00
* @ return object A { @ link $USER } object - BC only , do not use
2007-11-14 22:03:46 +00:00
*/
2009-01-12 15:13:44 +00:00
function complete_user_login ( $user , $setcookie = true ) {
2008-06-23 21:18:08 +00:00
global $CFG , $USER , $SESSION ;
2008-05-30 19:59:50 +00:00
2009-08-06 13:25:21 +00:00
// regenerate session id and delete old session,
// this helps prevent session fixation attacks from the same domain
session_regenerate_id ( true );
2009-09-01 08:39:55 +00:00
2009-01-02 20:32:05 +00:00
// check enrolments, load caps and setup $USER object
session_set_user ( $user );
2007-11-14 22:03:46 +00:00
update_user_login_times ();
set_login_session_preferences ();
2009-01-12 15:13:44 +00:00
if ( $setcookie ) {
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' );
}
}
2007-11-14 22:03:46 +00:00
/// 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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ param object $user
* @ param string $password plain text password
2006-03-11 11:26:36 +00:00
* @ 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 ;
2010-06-26 15:38:16 +00:00
if ( $user -> password == md5 ( $password . $CFG -> passwordsaltmain ) or $user -> password == md5 ( $password )) {
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 )) {
2010-07-04 12:33:46 +00:00
if ( $user -> password == md5 ( $password . $CFG -> $alt )) {
2006-04-30 21:02:28 +00:00
$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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ param string $password
2006-03-11 11:26:36 +00:00
* @ 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
}
/**
2010-05-22 18:38:18 +00:00
* Update password hash in user object .
2007-07-18 05:17:45 +00:00
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
* @ param object $user
* @ param string $password plain text password
* @ return bool true if hash changed
2006-03-11 11:26:36 +00:00
*/
2007-02-20 17:15:13 +00:00
function update_internal_user_password ( & $user , $password ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2006-03-11 11:26:36 +00:00
2007-01-04 02:52:44 +00:00
$authplugin = get_auth_plugin ( $user -> auth );
2009-11-23 21:50:40 +00:00
if ( $authplugin -> prevent_local_passwords ()) {
2006-03-11 11:26:36 +00:00
$hashedpassword = 'not cached' ;
} else {
$hashedpassword = hash_internal_user_password ( $password );
}
2009-02-17 17:32:36 +00:00
$DB -> set_field ( 'user' , 'password' , $hashedpassword , array ( 'id' => $user -> id ));
return true ;
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
2009-05-22 02:57:43 +00:00
* in the user record .
*
2005-04-17 12:08:46 +00:00
* Intended for setting as $USER session variable
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
2005-04-17 12:08:46 +00:00
* @ 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 .
2009-05-22 02:57:43 +00:00
* @ param int $mnethostid
* @ return mixed False , or A { @ link $USER } object .
2005-04-17 12:08:46 +00:00
*/
2007-01-10 00:50:59 +00:00
function get_complete_user_data ( $field , $value , $mnethostid = null ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2005-04-17 12:08:46 +00:00
if ( ! $field || ! $value ) {
return false ;
}
2007-01-10 00:50:59 +00:00
/// Build the WHERE clause for an SQL query
2008-05-30 19:59:50 +00:00
$params = array ( 'fieldval' => $value );
$constraints = " $field = :fieldval AND deleted <> 1 " ;
2007-01-10 00:50:59 +00:00
2008-08-14 23:36:37 +00:00
// If we are loading user data based on anything other than id,
// we must also restrict our search based on mnet host.
if ( $field != 'id' ) {
if ( empty ( $mnethostid )) {
// if empty, we restrict to local users
$mnethostid = $CFG -> mnet_localhost_id ;
}
}
if ( ! empty ( $mnethostid )) {
$params [ 'mnethostid' ] = $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
2008-05-30 19:59:50 +00:00
if ( ! $user = $DB -> get_record_select ( 'user' , $constraints , $params )) {
2005-04-17 12:08:46 +00:00
return false ;
}
/// Get various settings and preferences
2008-05-30 19:59:50 +00:00
if ( $displays = $DB -> get_records ( 'course_display' , array ( 'userid' => $user -> id ))) {
2005-04-17 12:08:46 +00:00
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 );
2008-11-04 10:49:31 +00:00
$user -> preference [ '_lastloaded' ] = time ();
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
2008-05-30 19:59:50 +00:00
if ( $lastaccesses = $DB -> get_records ( 'user_lastaccess' , array ( 'userid' => $user -> id ))) {
2006-10-22 07:42:04 +00:00
foreach ( $lastaccesses as $lastaccess ) {
$user -> lastcourseaccess [ $lastaccess -> courseid ] = $lastaccess -> timeaccess ;
}
}
2007-08-16 11:06:48 +00:00
$sql = " SELECT g.id, g.courseid
2008-05-30 19:59:50 +00:00
FROM { groups } g , { groups_members } gm
WHERE gm . groupid = g . id AND gm . userid = ? " ;
2007-08-16 11:06:48 +00:00
// this is a special hack to speedup calendar display
$user -> groupmember = array ();
2008-05-30 19:59:50 +00:00
if ( $groups = $DB -> get_records_sql ( $sql , array ( $user -> id ))) {
2007-08-16 11:06:48 +00:00
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
2008-05-30 19:59:50 +00:00
require_once ( $CFG -> dirroot . '/user/profile/lib.php' );
2007-10-08 07:23:18 +00:00
$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 = ' ' ;
}
return $user ;
}
2007-04-25 19:36:47 +00:00
/**
2010-05-22 18:38:18 +00:00
* Validate a password against the configured password policy
2009-05-22 02:57:43 +00:00
*
* @ global object
2010-05-22 18:38:18 +00:00
* @ param string $password the password to be checked against the password policy
2007-04-25 19:36:47 +00:00
* @ 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 ) {
2008-09-26 08:09:47 +00:00
$errmsg .= '<div>' . get_string ( 'errorminpasswordlength' , 'auth' , $CFG -> minpasswordlength ) . '</div>' ;
2007-04-25 19:36:47 +00:00
2008-09-26 08:09:47 +00:00
}
if ( preg_match_all ( '/[[:digit:]]/u' , $password , $matches ) < $CFG -> minpassworddigits ) {
$errmsg .= '<div>' . get_string ( 'errorminpassworddigits' , 'auth' , $CFG -> minpassworddigits ) . '</div>' ;
2007-04-25 19:36:47 +00:00
2008-09-26 08:09:47 +00:00
}
if ( preg_match_all ( '/[[:lower:]]/u' , $password , $matches ) < $CFG -> minpasswordlower ) {
$errmsg .= '<div>' . get_string ( 'errorminpasswordlower' , 'auth' , $CFG -> minpasswordlower ) . '</div>' ;
2005-04-17 12:08:46 +00:00
2008-09-26 08:09:47 +00:00
}
if ( preg_match_all ( '/[[:upper:]]/u' , $password , $matches ) < $CFG -> minpasswordupper ) {
$errmsg .= '<div>' . get_string ( 'errorminpasswordupper' , 'auth' , $CFG -> minpasswordupper ) . '</div>' ;
2006-09-16 13:59:38 +00:00
2008-09-26 08:09:47 +00:00
}
if ( preg_match_all ( '/[^[:upper:][:lower:][:digit:]]/u' , $password , $matches ) < $CFG -> minpasswordnonalphanum ) {
$errmsg .= '<div>' . get_string ( 'errorminpasswordnonalphanum' , 'auth' , $CFG -> minpasswordnonalphanum ) . '</div>' ;
2007-04-25 19:36:47 +00:00
}
2009-04-03 02:22:52 +00:00
if ( ! check_consecutive_identical_characters ( $password , $CFG -> maxconsecutiveidentchars )) {
$errmsg .= '<div>' . get_string ( 'errormaxconsecutiveidentchars' , 'auth' , $CFG -> maxconsecutiveidentchars ) . '</div>' ;
}
2007-04-25 19:36:47 +00:00
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
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
2005-04-17 12:08:46 +00:00
*/
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' );
2008-10-09 13:00:48 +00:00
calendar_set_filters_status ( get_user_preferences ( 'calendar_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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
2008-07-06 17:57:06 +00:00
* @ param mixed $courseorid The id of the course or course object to delete .
2006-03-02 11:58:43 +00:00
* @ 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 .
*/
2008-07-06 17:57:06 +00:00
function delete_course ( $courseorid , $showfeedback = true ) {
2009-08-18 05:20:12 +00:00
global $CFG , $DB , $OUTPUT ;
2006-03-04 16:53:02 +00:00
2008-07-06 17:57:06 +00:00
if ( is_object ( $courseorid )) {
$courseid = $courseorid -> id ;
$course = $courseorid ;
} else {
$courseid = $courseorid ;
if ( ! $course = $DB -> get_record ( 'course' , array ( 'id' => $courseid ))) {
return false ;
2008-09-18 10:24:52 +00:00
}
2008-07-06 17:57:06 +00:00
}
2007-10-09 16:07:15 +00:00
// frontpage course can not be deleted!!
if ( $courseid == SITEID ) {
return false ;
}
2010-05-20 07:59:13 +00:00
remove_course_contents ( $courseid , $showfeedback );
2006-03-02 11:58:43 +00:00
2009-02-17 17:32:36 +00:00
$DB -> delete_records ( " course " , array ( " id " => $courseid ));
2006-03-02 11:58:43 +00:00
2010-05-20 07:59:13 +00:00
// Delete all roles and overiddes in the course context
delete_context ( CONTEXT_COURSE , $courseid );
2006-03-04 16:53:02 +00:00
2010-05-20 07:59:13 +00:00
//trigger events
events_trigger ( 'course_deleted' , $course );
2008-07-06 17:57:06 +00:00
2010-05-20 07:59:13 +00:00
return true ;
2006-03-02 11:58:43 +00:00
}
2004-09-23 02:48:41 +00:00
/**
* Clear a course out completely , deleting all content
* but don ' t delete the course itself
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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 ) {
2009-08-18 05:20:12 +00:00
global $CFG , $DB , $OUTPUT ;
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
2010-05-20 07:59:13 +00:00
$course = $DB -> get_record ( 'course' , array ( 'id' => $courseid ), '*' , MUST_EXIST );
$context = get_context_instance ( CONTEXT_COURSE , $courseid , MUST_EXIST );
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
2009-01-12 06:24:00 +00:00
/// Clean up course formats (iterate through all formats in the even the course format was ever changed)
2009-06-19 14:25:56 +00:00
$formats = get_plugin_list ( 'format' );
foreach ( $formats as $format => $formatdir ) {
2010-07-15 15:27:18 +00:00
$formatdelete = 'format_' . $format . '_delete_course' ;
2009-06-19 14:25:56 +00:00
$formatlib = " $formatdir /lib.php " ;
2009-01-12 06:24:00 +00:00
if ( file_exists ( $formatlib )) {
include_once ( $formatlib );
if ( function_exists ( $formatdelete )) {
if ( $showfeedback ) {
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> notification ( $strdeleted . ' ' . $format );
2009-01-12 06:24:00 +00:00
}
$formatdelete ( $course -> id );
}
}
}
/// Delete every instance of every module
2004-04-01 10:11:20 +00:00
2008-05-30 19:59:50 +00:00
if ( $allmods = $DB -> 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 )) {
2008-05-30 19:59:50 +00:00
if ( $instances = $DB -> get_records ( $modname , array ( '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 {
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> notification ( 'Could not delete ' . $modname . ' instance ' . $instance -> id . ' (' . format_string ( $instance -> name ) . ')' );
2003-08-02 11:32:59 +00:00
}
2007-10-09 16:07:15 +00:00
if ( $cm ) {
// delete cm and its context in correct order
2008-05-30 19:59:50 +00:00
$DB -> delete_records ( 'course_modules' , array ( 'id' => $cm -> id ));
2007-10-09 16:07:15 +00:00
delete_context ( CONTEXT_MODULE , $cm -> id );
}
2003-08-02 11:32:59 +00:00
}
}
} else {
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> notification ( 'Function ' . $moddelete . '() doesn\'t exist!' );
2003-08-02 11:32:59 +00:00
}
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 ) {
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> notification ( $strdeleted . ' ' . $count . ' x ' . $modname );
2003-08-02 11:32:59 +00:00
}
}
}
2006-09-23 06:10:48 +00:00
/// Delete course blocks
2009-05-07 08:55:10 +00:00
blocks_delete_all_for_context ( $context -> id );
2006-09-23 06:10:48 +00:00
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 ) {
2010-05-20 07:59:13 +00:00
$DB -> delete_records ( $table , array ( $col => $course -> id ));
2003-08-02 11:32:59 +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
remove_course_grades ( $courseid , $showfeedback );
remove_grade_letters ( $context , $showfeedback );
2008-06-30 09:04:07 +00:00
/// Delete course tags
require_once ( $CFG -> dirroot . '/tag/coursetagslib.php' );
coursetag_delete_course_tags ( $course -> id , $showfeedback );
2010-05-20 07:59:13 +00:00
// Delete legacy files
fulldelete ( $CFG -> dataroot . '/' . $courseid );
//trigger events
events_trigger ( 'course_content_removed' , $course );
2010-06-06 14:06:30 +00:00
2010-05-20 07:59:13 +00:00
return true ;
2003-08-02 11:32:59 +00:00
}
2004-09-23 02:48:41 +00:00
/**
2007-11-29 14:43:04 +00:00
* Change dates in module - used from course reset .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
2010-05-22 18:38:18 +00:00
* @ param string $modname forum , assignment , etc
2007-11-29 14:43:04 +00:00
* @ param array $fields array of date fields from mod table
* @ param int $timeshift time difference
2009-05-22 02:57:43 +00:00
* @ param int $courseid
* @ return bool 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 ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2007-11-29 14:43:04 +00:00
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 ) {
2008-05-30 19:59:50 +00:00
$updatesql = " UPDATE { " . $modname . " }
SET $field = $field + ?
WHERE course = ? AND $field <> 0 AND $field <> 0 " ;
$return = $DB -> execute ( $updatesql , array ( $timeshift , $courseid )) && $return ;
2007-11-29 14:43:04 +00:00
}
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 .
2009-05-22 02:57:43 +00:00
*
2007-11-29 14:43:04 +00:00
* @ 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 ) {
2008-05-30 19:59:50 +00:00
global $CFG , $USER , $DB ;
2007-11-29 14:43:04 +00:00
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
2008-05-30 19:59:50 +00:00
$DB -> set_field ( 'course' , 'startdate' , $data -> reset_start_date , array ( 'id' => $data -> courseid ));
2007-11-29 14:43:04 +00:00
// update all course and group events - do not move activity events
2008-06-05 20:35:28 +00:00
$updatesql = " UPDATE { event}
2008-05-30 19:59:50 +00:00
SET timestart = timestart + ?
WHERE courseid = ? AND instance = 0 " ;
$DB -> execute ( $updatesql , array ( $data -> timeshift , $data -> courseid ));
2007-11-29 14:43:04 +00:00
$status [] = array ( 'component' => $componentstr , 'item' => get_string ( 'datechanged' ), 'error' => false );
}
if ( ! empty ( $data -> reset_logs )) {
2008-06-02 21:52:27 +00:00
$DB -> delete_records ( 'log' , array ( 'course' => $data -> courseid ));
2007-11-29 14:43:04 +00:00
$status [] = array ( 'component' => $componentstr , 'item' => get_string ( 'deletelogs' ), 'error' => false );
}
if ( ! empty ( $data -> reset_events )) {
2008-06-02 21:52:27 +00:00
$DB -> delete_records ( 'event' , array ( 'courseid' => $data -> courseid ));
2007-11-29 14:43:04 +00:00
$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 );
}
2009-11-01 11:31:16 +00:00
2009-10-30 07:25:50 +00:00
if ( ! empty ( $data -> delete_blog_associations )) {
require_once ( $CFG -> dirroot . '/blog/lib.php' );
blog_remove_associations_for_course ( $data -> courseid );
$status [] = array ( 'component' => $componentstr , 'item' => get_string ( 'deleteblogassociations' , 'blog' ), 'error' => false );
}
2007-11-29 14:43:04 +00:00
$componentstr = get_string ( 'roles' );
if ( ! empty ( $data -> reset_roles_overrides )) {
$children = get_child_contexts ( $context );
foreach ( $children as $child ) {
2008-05-30 19:59:50 +00:00
$DB -> delete_records ( 'role_capabilities' , array ( 'contextid' => $child -> id ));
2004-08-01 07:34:39 +00:00
}
2008-05-30 19:59:50 +00:00
$DB -> delete_records ( 'role_capabilities' , array ( 'contextid' => $context -> id ));
2007-11-29 14:43:04 +00:00
//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 ) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
role_unassign_all ( array ( 'contextid' => $child -> id ));
2007-11-29 14:43:04 +00:00
}
//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 ();
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
if ( ! empty ( $data -> unenrol_users )) {
$plugins = enrol_get_plugins ( true );
$instances = enrol_get_instances ( $data -> courseid , true );
foreach ( $instances as $key => $instance ) {
if ( ! isset ( $plugins [ $instance -> enrol ])) {
unset ( $instances [ $key ]);
continue ;
}
if ( ! $plugins [ $instance -> enrol ] -> allow_unenrol ( $instance )) {
unset ( $instances [ $key ]);
}
}
$sqlempty = $DB -> sql_empty ();
foreach ( $data -> unenrol_users as $withroleid ) {
$sql = " SELECT DISTINCT ue.userid, ue.enrolid
FROM { user_enrolments } ue
JOIN { enrol } e ON ( e . id = ue . enrolid AND e . courseid = : courseid )
JOIN { context } c ON ( c . contextlevel = : courselevel AND c . instanceid = e . courseid )
JOIN { role_assignments } ra ON ( ra . contextid = c . id AND ra . roleid = : roleid AND ra . userid = ue . userid ) " ;
$params = array ( 'courseid' => $data -> courseid , 'roleid' => $withroleid , 'courselevel' => CONTEXT_COURSE );
$rs = $DB -> get_recordset_sql ( $sql , $params );
foreach ( $rs as $ue ) {
if ( ! isset ( $instances [ $ue -> enrolid ])) {
continue ;
2007-11-29 14:43:04 +00:00
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
$plugins [ $instances [ $ue -> enrolid ] -> enrol ] -> unenrol_user ( $instances [ $ue -> enrolid ], $ue -> userid );
$data -> unenrolled [ $ue -> userid ] = $ue -> userid ;
2004-08-01 07:34:39 +00:00
}
}
}
2007-11-29 14:43:04 +00:00
if ( ! empty ( $data -> unenrolled )) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
$status [] = array ( 'component' => $componentstr , 'item' => get_string ( 'unenrol' , 'enrol' ) . ' (' . count ( $data -> unenrolled ) . ')' , 'error' => false );
2007-11-29 14:43:04 +00:00
}
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 )) {
2008-07-06 22:54:46 +00:00
groups_delete_group_members ( $data -> courseid );
2007-11-29 14:43:04 +00:00
$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 ();
2008-05-30 19:59:50 +00:00
if ( $allmods = $DB -> get_records ( 'modules' ) ) {
2007-11-29 14:43:04 +00:00
foreach ( $allmods as $mod ) {
$modname = $mod -> name ;
2008-05-30 19:59:50 +00:00
if ( ! $DB -> count_records ( $modname , array ( 'course' => $data -> courseid ))) {
2007-11-29 14:43:04 +00:00
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
}
2009-05-22 02:57:43 +00:00
/**
* Generate an email processing address
2009-09-01 08:39:55 +00:00
*
2009-05-22 02:57:43 +00:00
* @ param int $modid
* @ param string $modargs
* @ return string Returns email processing address
*/
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
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 ;
2009-01-20 03:16:30 +00:00
return $header . substr ( md5 ( $header . get_site_identifier ()), 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
}
2009-05-22 02:57:43 +00:00
/**
* ?
*
* @ todo Finish documenting this function
*
* @ global object
* @ param string $modargs
* @ param string $body Currently unused
*/
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 ) {
2008-05-30 19:59:50 +00:00
global $DB ;
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
// 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 )));
2008-05-30 19:59:50 +00:00
if ( $user = $DB -> get_record ( " user " , array ( 'id' => $userid ), " id,email " )) {
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
// 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 .
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ param string $action 'get' , 'buffer' , 'close' or 'flush'
* @ return object | null reference to mailer instance if 'get' used or nothing
2008-02-01 07:05:58 +00:00
*/
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' );
}
2009-11-03 21:02:36 +00:00
include_once ( $CFG -> libdir . '/phpmailer/moodle_phpmailer.php' );
$mailer = new moodle_phpmailer ();
2008-02-01 07:05:58 +00:00
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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global string
* @ global string IdentityProvider ( IDP ) URL user hits to jump to mnet peer .
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
2009-05-22 02:57:43 +00:00
* @ param string $replyto Email address to reply to
* @ param string $replytoname Name of reply to recipient
* @ param int $wordwrapwidth custom word wrap width , default 79
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
2008-08-20 05:57:06 +00:00
global $CFG , $FULLME , $MNETIDPJUMPURL ;
2008-08-03 23:24:12 +00:00
static $mnetjumps = array ();
2004-02-09 08:49:54 +00:00
2009-03-19 10:35:08 +00:00
if ( empty ( $user ) || empty ( $user -> email )) {
2010-07-06 08:59:39 +00:00
mtrace ( 'Error: lib/moodlelib.php email_to_user(): User is null or has no email' );
2004-02-20 10:27:24 +00:00
return false ;
}
2008-09-11 19:54:39 +00:00
if ( ! empty ( $user -> deleted )) {
// do not mail delted users
2010-07-06 08:59:39 +00:00
mtrace ( 'Error: lib/moodlelib.php email_to_user(): User is deleted' );
2008-09-11 19:54:39 +00:00
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
2010-07-06 08:59:39 +00:00
mtrace ( 'Error: lib/moodlelib.php email_to_user(): Not sending email due to noemailever config setting' );
2008-02-15 10:47:02 +00:00
return true ;
}
2010-03-25 01:29:02 +00:00
if ( ! empty ( $CFG -> divertallemailsto )) {
$subject = " [DIVERTED { $user -> email } ] $subject " ;
$user = clone ( $user );
$user -> email = $CFG -> divertallemailsto ;
}
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 )) {
2010-07-06 08:59:39 +00:00
$bouncemsg = " User $user->id ( " . fullname ( $user ) . " ) is over bounce threshold! Not sending. " ;
error_log ( $bouncemsg );
mtrace ( 'Error: lib/moodlelib.php email_to_user(): ' . $bouncemsg );
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 false ;
}
2004-04-01 10:11:20 +00:00
2008-08-03 23:24:12 +00:00
// If the user is a remote mnet user, parse the email text for URL to the
// wwwroot and modify the url to direct the user's browser to login at their
// home site (identity provider - idp) before hitting the link itself
2009-02-02 17:47:12 +00:00
if ( is_mnet_remote_user ( $user )) {
2008-08-03 23:24:12 +00:00
require_once ( $CFG -> dirroot . '/mnet/lib.php' );
2010-02-02 03:13:40 +00:00
$jumpurl = mnet_get_idp_jump_url ( $user );
$callback = partial ( 'mnet_sso_apply_redirection' , $jumpurl );
2008-08-03 23:24:12 +00:00
$messagetext = preg_replace_callback ( " %( $CFG->wwwroot [^[:space:]]*)% " ,
2010-02-02 03:13:40 +00:00
$callback ,
2008-08-03 23:24:12 +00:00
$messagetext );
$messagehtml = preg_replace_callback ( " %href=[ \" '`]( $CFG->wwwroot [ \ w_: \ ?=#&@/;.~-]*)[ \" '`]% " ,
2010-02-02 03:13:40 +00:00
$callback ,
2008-08-03 23:24:12 +00:00
$messagehtml );
}
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 ) {
2008-09-23 20:51:47 +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 );
}
2008-05-30 20:33:19 +00:00
$mail -> Subject = substr ( $subject , 0 , 900 );
2001-11-22 06:23:56 +00:00
2008-09-23 20:51:47 +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 ;
}
2010-07-06 08:59:39 +00:00
if ( $messagehtml && ! empty ( $user -> mailformat ) && $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 ) {
2009-06-22 01:22:37 +00:00
if ( preg_match ( " ~ \\ . \\ .~ " , $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
2009-03-25 09:18:19 +00:00
$mail -> ReplyTo [ $key ][ 1 ] = $textlib -> convert ( $rt [ 1 ], 'utf-8' , $mail -> CharSet );
2006-03-18 17:48:52 +00:00
}
$mail -> Subject = $textlib -> convert ( $mail -> Subject , 'utf-8' , $mail -> CharSet ); //Subject
foreach ( $mail -> to as $key => $to ) {
2009-03-25 09:18:19 +00:00
$mail -> to [ $key ][ 1 ] = $textlib -> convert ( $to [ 1 ], 'utf-8' , $mail -> CharSet ); //To Names
2006-03-18 17:48:52 +00:00
}
$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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ return string
2007-08-01 09:00:21 +00:00
*/
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
2009-05-22 02:57:43 +00:00
* @ global object
2008-05-30 19:59:50 +00:00
* @ return object user info
2007-08-01 09:00:21 +00:00
*/
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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
2006-01-16 02:51:02 +00:00
* @ 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 ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2006-01-16 02:51:02 +00:00
$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 ();
2010-06-04 18:19:34 +00:00
$DB -> set_field ( 'user' , 'password' , hash_internal_user_password ( $newpassword ), array ( 'id' => $user -> id ));
2006-01-16 02:51:02 +00:00
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 );
2008-05-30 19:59:50 +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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
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 ();
2008-05-30 19:59:50 +00:00
if ( ! $userauth -> user_update_password ( $user , $newpassword )) {
2008-05-20 02:53:46 +00:00
print_error ( " cannotsetpassword " );
2002-12-23 03:07:01 +00:00
}
2007-01-20 14:06:07 +00:00
$a = new object ();
2009-01-31 21:38:12 +00:00
$a -> firstname = $user -> firstname ;
$a -> lastname = $user -> lastname ;
$a -> sitename = format_string ( $site -> fullname );
$a -> username = $user -> username ;
2002-12-23 03:07:01 +00:00
$a -> newpassword = $newpassword ;
2009-01-31 21:38:12 +00:00
$a -> link = $CFG -> httpswwwroot . '/login/change_password.php' ;
$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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
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 );
2008-05-30 19:59:50 +00:00
$data -> sitename = format_string ( $site -> fullname );
$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
2008-05-30 19:59:50 +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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
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 ;
2009-01-07 19:03:38 +00:00
$data -> lastname = $user -> lastname ;
2008-05-30 19:59:50 +00:00
$data -> sitename = format_string ( $site -> fullname );
$data -> link = $CFG -> httpswwwroot . '/login/forgot_password.php?p=' . $user -> secret . '&s=' . urlencode ( $user -> username );
$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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
2007-02-21 21:48:48 +00:00
* @ 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 ;
2009-01-31 21:38:12 +00:00
$data -> lastname = $user -> lastname ;
2008-05-30 19:59:50 +00:00
$data -> sitename = format_string ( $site -> fullname );
$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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
2005-07-12 03:09:25 +00:00
* @ 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
2001-11-22 06:23:56 +00:00
/// FILE HANDLING /////////////////////////////////////////////
2008-07-31 22:15:30 +00:00
/**
* Returns local file storage instance
2009-05-22 02:57:43 +00:00
*
2010-01-05 17:54:15 +00:00
* @ return file_storage
2008-07-31 22:15:30 +00:00
*/
function get_file_storage () {
global $CFG ;
static $fs = null ;
if ( $fs ) {
return $fs ;
}
require_once ( " $CFG->libdir /filelib.php " );
2008-08-04 13:21:38 +00:00
if ( isset ( $CFG -> filedir )) {
$filedir = $CFG -> filedir ;
} else {
$filedir = $CFG -> dataroot . '/filedir' ;
}
2009-06-03 08:10:21 +00:00
if ( isset ( $CFG -> trashdir )) {
$trashdirdir = $CFG -> trashdir ;
} else {
$trashdirdir = $CFG -> dataroot . '/trashdir' ;
}
2010-05-20 17:13:07 +00:00
$fs = new file_storage ( $filedir , $trashdirdir , " $CFG->dataroot /temp/filestorage " , $CFG -> directorypermissions , $CFG -> filepermissions );
2008-07-31 22:15:30 +00:00
return $fs ;
}
/**
* Returns local file storage instance
2009-05-22 02:57:43 +00:00
*
2010-01-05 17:54:15 +00:00
* @ return file_browser
2008-07-31 22:15:30 +00:00
*/
function get_file_browser () {
global $CFG ;
static $fb = null ;
if ( $fb ) {
return $fb ;
}
require_once ( " $CFG->libdir /filelib.php " );
$fb = new file_browser ();
return $fb ;
}
2004-02-20 14:12:49 +00:00
2008-08-02 12:45:02 +00:00
/**
2008-08-06 11:28:17 +00:00
* Returns file packer
2009-05-22 02:57:43 +00:00
*
* @ param string $mimetype default application / zip
2010-01-05 17:54:15 +00:00
* @ return file_packer
2008-08-02 12:45:02 +00:00
*/
2008-08-08 10:22:59 +00:00
function get_file_packer ( $mimetype = 'application/zip' ) {
2008-08-02 12:45:02 +00:00
global $CFG ;
2008-08-08 10:22:59 +00:00
static $fp = array ();;
2008-08-02 12:45:02 +00:00
2008-08-08 10:22:59 +00:00
if ( isset ( $fp [ $mimetype ])) {
return $fp [ $mimetype ];
2008-08-02 12:45:02 +00:00
}
2008-08-08 10:22:59 +00:00
switch ( $mimetype ) {
case 'application/zip' :
$classname = 'zip_packer' ;
break ;
case 'application/x-tar' :
// $classname = 'tar_packer';
// break;
default :
return false ;
}
2008-08-02 12:45:02 +00:00
2010-07-03 13:37:13 +00:00
require_once ( " $CFG->libdir /filestorage/ $classname .php " );
2008-08-08 10:22:59 +00:00
$fp [ $mimetype ] = new $classname ();
2008-08-02 12:45:02 +00:00
2008-08-08 10:22:59 +00:00
return $fp [ $mimetype ];
2008-08-02 12:45:02 +00:00
}
2007-10-11 09:01:29 +00:00
/**
* Makes a directory for a particular user .
*
2009-05-22 02:57:43 +00:00
* @ global object
2007-10-11 09:01:29 +00:00
* @ 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 ) {
2009-08-18 05:20:12 +00:00
global $CFG , $OUTPUT ;
2007-10-11 09:01:29 +00:00
2009-06-22 01:22:37 +00:00
if ( is_bool ( $userid ) || $userid < 0 || ! preg_match ( '/^[0-9]{1,10}$/' , $userid ) || $userid > 2147483647 ) {
2007-10-11 09:01:29 +00:00
if ( ! $test ) {
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> notification ( " Given userid was not a valid integer! ( " . gettype ( $userid ) . " $userid ) " );
2007-10-11 09:01:29 +00:00
}
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 ;
2008-05-30 19:59:50 +00:00
2007-10-11 09:01:29 +00:00
$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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
2007-10-12 19:13:18 +00:00
* @ 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 )
2008-05-30 19:59:50 +00:00
* @ return array An associative array : userid => array ( basedir => $basedir , userfolder => $userfolder )
2007-10-12 19:13:18 +00:00
*/
function get_user_directories ( $only_non_empty = true , $legacy = false ) {
2009-08-18 05:20:12 +00:00
global $CFG , $OUTPUT ;
2007-10-12 19:13:18 +00:00
$rootdir = $CFG -> dataroot . " /user " ;
2008-05-30 19:59:50 +00:00
2007-10-12 19:13:18 +00:00
if ( $legacy ) {
2008-05-30 19:59:50 +00:00
$rootdir = $CFG -> dataroot . " /users " ;
2007-10-12 19:13:18 +00:00
}
$dirlist = array ();
2008-05-30 19:59:50 +00:00
//Check if directory exists
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 {
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> notification ( " no directories found under $rootdir " );
2008-05-30 19:59:50 +00:00
}
2007-10-12 19:13:18 +00:00
} 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 );
}
}
}
2008-05-30 19:59:50 +00:00
}
2007-10-12 19:13:18 +00:00
}
} else {
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> notification ( " $rootdir does not exist! " );
2007-10-12 19:13:18 +00:00
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 .
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function
*
* @ param int $sizebytes Set maximum size
2004-09-25 01:29:37 +00:00
* @ 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
*/
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
/**
2009-05-22 02:57:43 +00:00
* Returns an array of possible sizes in local language
*
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 .
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function
*
* @ global object
2004-09-25 01:29:37 +00:00
* @ uses SORT_NUMERIC
2009-05-22 02:57:43 +00:00
* @ param int $sizebytes Set maximum size
2004-09-25 01:29:37 +00:00
* @ 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
*/
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
/**
2009-05-22 02:57:43 +00:00
* Returns an array with all the filenames in all subdirectories , relative to the given rootdir .
*
2010-05-22 18:38:18 +00:00
* If excludefiles is defined , then that file / directory is ignored
2004-09-23 02:48:41 +00:00
* 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 ! )
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function . Add examples of $excludefile usage .
*
* @ param string $rootdir A given root directory to start from
* @ param string | array $excludefile If defined then the specified file / directory is ignored
* @ param bool $descend If true then subdirectories are recursed as well
* @ param bool $getdirs If true then ( sub ) directories are included in the output
2005-07-12 02:06:33 +00:00
* @ 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
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 .
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ param string $rootdir The directory to start from
* @ param string $excludefile A file to exclude when summing directory size
* @ return int The summed size of all files and subfiles within the root directory
2004-09-23 02:48:41 +00:00
*/
2004-09-22 14:39:15 +00:00
function get_directory_size ( $rootdir , $excludefile = '' ) {
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 ))) {
2008-07-18 06:42:08 +00:00
$command = trim ( $CFG -> pathtodu ) . ' -sk ' . 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
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function . Verify return type .
*
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
2009-05-22 02:57:43 +00:00
* @ param int $size The size to convert to human readable form
* @ return string
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
2009-05-22 02:57:43 +00:00
* @ see clean_param ()
2006-03-04 11:35:08 +00:00
*
2009-05-22 02:57:43 +00:00
* @ uses PARAM_FILE
2006-03-04 11:35:08 +00:00
* @ 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 ) {
2008-07-31 23:03:50 +00:00
return clean_param ( $string , PARAM_FILE );
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
*
* @ 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
2008-05-19 18:02:33 +00:00
} else if ( isset ( $CFG -> lang )) {
2006-09-25 06:04:02 +00:00
$return = $CFG -> lang ;
2008-05-19 18:02:33 +00:00
} else {
2010-04-10 07:24:56 +00:00
$return = 'en' ;
2006-09-25 06:04:02 +00:00
}
2010-07-01 04:31:40 +00:00
$return = str_replace ( '_utf8' , '' , $return ); // Just in case this slipped in from somewhere by accident
2006-09-25 06:04:02 +00:00
return $return ;
2002-10-02 10:33:05 +00:00
}
2002-07-04 07:49:38 +00:00
2009-02-07 18:55:21 +00:00
/**
* Returns parent language of current active language if defined
2009-05-22 02:57:43 +00:00
*
* @ uses COURSE
* @ uses SESSION
2009-02-08 22:33:54 +00:00
* @ param string $lang null means current language
2009-02-07 18:55:21 +00:00
* @ return string
*/
2009-02-08 22:33:54 +00:00
function get_parent_language ( $lang = null ) {
global $COURSE , $SESSION ;
//let's hack around the current language
if ( ! empty ( $lang )) {
$old_course_lang = empty ( $COURSE -> lang ) ? '' : $COURSE -> lang ;
$old_session_lang = empty ( $SESSION -> lang ) ? '' : $SESSION -> lang ;
$COURSE -> lang = '' ;
$SESSION -> lang = $lang ;
}
2010-04-10 18:01:49 +00:00
$parentlang = get_string ( 'parentlanguage' , 'langconfig' );
2010-04-11 20:30:58 +00:00
if ( $parentlang === 'en' ) {
2009-02-08 22:33:54 +00:00
$parentlang = '' ;
2009-02-07 18:55:21 +00:00
}
2009-02-08 22:33:54 +00:00
//let's hack around the current language
if ( ! empty ( $lang )) {
$COURSE -> lang = $old_course_lang ;
$SESSION -> lang = $old_session_lang ;
}
2009-02-07 18:55:21 +00:00
return $parentlang ;
}
2005-06-21 12:30:34 +00:00
/**
2010-04-01 18:50:28 +00:00
* Returns current string_manager instance .
2010-05-10 14:46:59 +00:00
*
* The param $forcereload is needed for CLI installer only where the string_manager instance
* must be replaced during the install . php script life time .
*
* @ param bool $forcereload shall the singleton be released and new instance created instead ?
2010-04-01 18:50:28 +00:00
* @ return string_manager
*/
2010-05-10 14:46:59 +00:00
function get_string_manager ( $forcereload = false ) {
2010-04-01 18:50:28 +00:00
global $CFG ;
static $singleton = null ;
2010-05-10 14:46:59 +00:00
if ( $forcereload ) {
$singleton = null ;
}
2010-04-01 18:50:28 +00:00
if ( $singleton === null ) {
2010-04-10 07:24:56 +00:00
if ( empty ( $CFG -> early_install_lang )) {
2010-05-22 22:31:19 +00:00
if ( empty ( $CFG -> langlist )) {
$translist = array ();
} else {
$translist = explode ( ',' , $CFG -> langlist );
}
$singleton = new core_string_manager ( $CFG -> langotherroot , $CFG -> langlocalroot , " $CFG->dataroot /cache/lang " , ! empty ( $CFG -> langstringcache ), $translist );
2010-04-04 21:18:57 +00:00
} else {
2010-04-10 20:35:52 +00:00
$singleton = new install_string_manager ();
2010-04-04 21:18:57 +00:00
}
2010-04-01 18:50:28 +00:00
}
return $singleton ;
}
2010-04-10 19:28:34 +00:00
/**
* Interface describing class which is responsible for getting
* of localised strings from language packs .
*
* @ package moodlecore
* @ copyright 2010 Petr Skoda ( http :// skodak . org )
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
interface string_manager {
/**
2010-04-14 12:51:53 +00:00
* Get String returns a requested string
2010-04-10 19:28:34 +00:00
*
* @ param string $identifier The identifier of the string to search for
* @ param string $component The module the string is associated with
2010-04-14 12:51:53 +00:00
* @ param string | object | array $a An object , string or number that can be used
2010-04-10 19:28:34 +00:00
* within translation strings
2010-04-14 12:51:53 +00:00
* @ param string $lang moodle translation language , NULL means use current
2010-04-10 19:28:34 +00:00
* @ return string The String !
*/
2010-04-14 12:51:53 +00:00
public function get_string ( $identifier , $component = '' , $a = NULL , $lang = NULL );
2010-04-10 19:28:34 +00:00
2010-04-13 20:14:31 +00:00
/**
* Does the string actually exist ?
*
* get_string () is throwing debug warnings , sometimes we do not want them
* or we want to display better explanation of the problem .
*
* Use with care !
*
* @ param string $identifier The identifier of the string to search for
* @ param string $component The module the string is associated with
* @ return boot true if exists
*/
public function string_exists ( $identifier , $component );
2010-04-14 12:14:18 +00:00
2010-04-10 19:28:34 +00:00
/**
2010-04-14 12:42:48 +00:00
* Returns a localised list of all country names , sorted by country keys .
* @ param bool $returnall return all or just enabled
* @ param string $lang moodle translation language , NULL means use current
2010-04-10 19:28:34 +00:00
* @ return array two - letter country code => translated name .
*/
2010-04-14 12:42:48 +00:00
public function get_list_of_countries ( $returnall = false , $lang = NULL );
2010-04-10 21:22:15 +00:00
2010-04-14 10:02:05 +00:00
/**
2010-04-14 12:14:18 +00:00
* Returns a localised list of languages , sorted by code keys .
*
* @ param string $lang moodle translation language , NULL means use current
* @ param string $standard language list standard
* iso6392 : three - letter language code ( ISO 639 - 2 / T ) => translated name .
* @ return array language code => translated name
2010-04-14 10:02:05 +00:00
*/
2010-04-14 12:14:18 +00:00
public function get_list_of_languages ( $lang = NULL , $standard = 'iso6392' );
2010-04-14 10:02:05 +00:00
2010-04-14 13:16:20 +00:00
/**
* Does the translation exist ?
*
* @ param string $lang moodle translation language code
* @ param bool include also disabled translations ?
* @ return boot true if exists
*/
public function translation_exists ( $lang , $includeall = true );
2010-04-10 21:22:15 +00:00
/**
2010-04-14 09:45:49 +00:00
* Returns localised list of installed translations
2010-04-10 21:22:15 +00:00
* @ param bool $returnall return all or just enabled
2010-04-14 13:37:59 +00:00
* @ return array moodle translation code => localised translation name
2010-04-10 21:22:15 +00:00
*/
2010-04-14 09:45:49 +00:00
public function get_list_of_translations ( $returnall = false );
2010-04-11 20:37:13 +00:00
2010-04-14 14:04:21 +00:00
/**
* Returns localised list of currencies .
*
* @ param string $lang moodle translation language , NULL means use current
* @ return array currency code => localised currency name
*/
public function get_list_of_currencies ( $lang = NULL );
2010-04-11 20:37:13 +00:00
/**
* Load all strings for one component
* @ param string $component The module the string is associated with
* @ param string $lang
2010-06-28 16:04:22 +00:00
* @ param bool $disablecache Do not use caches , force fetching the strings from sources
2010-04-11 20:37:13 +00:00
* @ return array of all string for given component and lang
*/
2010-06-28 16:04:22 +00:00
public function load_component_strings ( $component , $lang , $disablecache = false );
2010-05-16 19:37:19 +00:00
/**
* Invalidates all caches , should the implementation use any
*/
public function reset_caches ();
2010-04-10 19:28:34 +00:00
}
/**
2010-04-12 12:55:42 +00:00
* Standard string_manager implementation
2010-04-10 19:28:34 +00:00
*
* @ package moodlecore
* @ copyright 2010 Petr Skoda ( http :// skodak . org )
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2010-04-12 12:55:42 +00:00
class core_string_manager implements string_manager {
2010-04-10 20:35:52 +00:00
/** @var string location of all packs except 'en' */
protected $otherroot ;
/** @var string location of all lang pack local modifications */
protected $localroot ;
2010-05-16 11:45:33 +00:00
/** @var string location of on-disk cache of merged strings */
protected $cacheroot ;
2010-04-10 20:35:52 +00:00
/** @var array lang string cache - it will be optimised more later */
protected $cache = array ();
2010-05-16 11:45:33 +00:00
/** @var int get_string() counter */
protected $countgetstring = 0 ;
/** @var int in-memory cache hits counter */
protected $countmemcache = 0 ;
/** @var int on-disk cache hits counter */
protected $countdiskcache = 0 ;
2010-05-22 22:37:47 +00:00
/** @var bool use disk cache */
protected $usediskcache ;
2010-05-22 22:31:19 +00:00
/* @var array limit list of translations */
protected $translist ;
2010-05-16 19:37:19 +00:00
2010-04-04 21:18:57 +00:00
/**
2010-05-16 11:45:33 +00:00
* Crate new instance of string manager
2010-04-04 21:18:57 +00:00
*
* @ param string $otherroot location of downlaoded lang packs - usually $CFG -> dataroot / lang
* @ param string $localroot usually the same as $otherroot
2010-05-22 22:31:19 +00:00
* @ param string $cacheroot usually lang dir in cache folder
2010-05-22 22:37:47 +00:00
* @ param bool $usediskcache use disk cache
2010-05-22 22:31:19 +00:00
* @ param array $translist limit list of visible translations
2010-04-04 21:18:57 +00:00
*/
2010-05-22 22:37:47 +00:00
public function __construct ( $otherroot , $localroot , $cacheroot , $usediskcache , $translist ) {
$this -> otherroot = $otherroot ;
$this -> localroot = $localroot ;
$this -> cacheroot = $cacheroot ;
$this -> usediskcache = $usediskcache ;
$this -> translist = $translist ;
2010-04-04 21:18:57 +00:00
}
/**
2010-04-11 07:42:51 +00:00
* Returns dependencies of current language , en is not included .
2010-04-04 21:18:57 +00:00
* @ param string $lang
* @ return array all parents , the lang itself is last
*/
public function get_language_dependencies ( $lang ) {
if ( $lang === 'en' ) {
return array ();
}
if ( ! file_exists ( " $this->otherroot / $lang /langconfig.php " )) {
return array ();
}
$string = array ();
include ( " $this->otherroot / $lang /langconfig.php " );
if ( empty ( $string [ 'parentlanguage' ])) {
return array ( $lang );
} else {
$parentlang = $string [ 'parentlanguage' ];
unset ( $string );
2010-04-11 07:42:51 +00:00
return array_merge ( $this -> get_language_dependencies ( $parentlang ), array ( $lang ));
2010-04-04 21:18:57 +00:00
}
}
/**
* Load all strings for one component
* @ param string $component The module the string is associated with
* @ param string $lang
2010-06-25 09:40:34 +00:00
* @ param bool $disablecache Do not use caches , force fetching the strings from sources
2010-04-04 21:18:57 +00:00
* @ return array of all string for given component and lang
*/
2010-06-25 09:40:34 +00:00
public function load_component_strings ( $component , $lang , $disablecache = false ) {
2010-04-10 20:35:52 +00:00
global $CFG ;
2010-04-04 21:18:57 +00:00
list ( $plugintype , $pluginname ) = normalize_component ( $component );
2010-05-16 11:45:33 +00:00
if ( $plugintype == 'core' and is_null ( $pluginname )) {
$component = 'core' ;
} else {
$component = $plugintype . '_' . $pluginname ;
}
2010-04-04 21:18:57 +00:00
2010-06-25 09:40:34 +00:00
if ( ! $disablecache ) {
// try in-memory cache first
if ( isset ( $this -> cache [ $lang ][ $component ])) {
$this -> countmemcache ++ ;
return $this -> cache [ $lang ][ $component ];
}
2010-04-10 07:24:56 +00:00
2010-06-25 09:40:34 +00:00
// try on-disk cache then
if ( $this -> usediskcache and file_exists ( $this -> cacheroot . " / $lang / $component .php " )) {
$this -> countdiskcache ++ ;
include ( $this -> cacheroot . " / $lang / $component .php " );
return $this -> cache [ $lang ][ $component ];
}
2010-04-10 07:24:56 +00:00
}
2010-05-16 11:45:33 +00:00
// no cache found - let us merge all possible sources of the strings
2010-04-04 21:18:57 +00:00
if ( $plugintype === 'core' ) {
$file = $pluginname ;
if ( $file === null ) {
$file = 'moodle' ;
}
$string = array ();
// first load english pack
2010-04-10 20:35:52 +00:00
if ( ! file_exists ( " $CFG->dirroot /lang/en/ $file .php " )) {
2010-04-04 21:18:57 +00:00
return array ();
}
2010-04-10 20:35:52 +00:00
include ( " $CFG->dirroot /lang/en/ $file .php " );
2010-04-04 21:18:57 +00:00
$originalkeys = array_keys ( $string );
$originalkeys = array_flip ( $originalkeys );
// and then corresponding local if present
if ( file_exists ( " $this->localroot /en_local/ $file .php " )) {
include ( " $this->localroot /en_local/ $file .php " );
}
// now loop through all langs in correct order
$deps = $this -> get_language_dependencies ( $lang );
foreach ( $deps as $dep ) {
// the main lang string location
if ( file_exists ( " $this->otherroot / $dep / $file .php " )) {
include ( " $this->otherroot / $dep / $file .php " );
}
if ( file_exists ( " $this->localroot / { $dep } _local/ $file .php " )) {
include ( " $this->localroot / { $dep } _local/ $file .php " );
}
}
} else {
if ( ! $location = get_plugin_directory ( $plugintype , $pluginname ) or ! is_dir ( $location )) {
return array ();
}
if ( $plugintype === 'mod' ) {
// bloody mod hack
$file = $pluginname ;
} else {
$file = $plugintype . '_' . $pluginname ;
}
$string = array ();
2010-05-22 22:31:19 +00:00
// first load English pack
2010-04-04 21:18:57 +00:00
if ( ! file_exists ( " $location /lang/en/ $file .php " )) {
2010-05-22 22:31:19 +00:00
//English pack does not exist, so do not try to load anything else
2010-04-04 21:18:57 +00:00
return array ();
}
include ( " $location /lang/en/ $file .php " );
$originalkeys = array_keys ( $string );
$originalkeys = array_flip ( $originalkeys );
// now loop through all langs in correct order
$deps = $this -> get_language_dependencies ( $lang );
foreach ( $deps as $dep ) {
// legacy location - used by contrib only
if ( file_exists ( " $location /lang/ $dep / $file .php " )) {
include ( " $location /lang/ $dep / $file .php " );
}
// the main lang string location
if ( file_exists ( " $this->otherroot / $dep / $file .php " )) {
include ( " $this->otherroot / $dep / $file .php " );
}
// local customisations
if ( file_exists ( " $this->localroot / { $dep } _local/ $file .php " )) {
include ( " $this->localroot / { $dep } _local/ $file .php " );
}
}
}
// we do not want any extra strings from other languages - everything must be in en lang pack
$string = array_intersect_key ( $string , $originalkeys );
2010-05-16 11:45:33 +00:00
// now we have a list of strings from all possible sources. put it into both in-memory and on-disk
2010-05-22 22:31:19 +00:00
// caches so we do not need to do all this merging and dependencies resolving again
2010-05-16 11:45:33 +00:00
$this -> cache [ $lang ][ $component ] = $string ;
2010-05-22 22:37:47 +00:00
if ( $this -> usediskcache ) {
2010-05-22 22:31:19 +00:00
check_dir_exists ( " $this->cacheroot / $lang " , true , true );
2010-05-24 14:53:34 +00:00
file_put_contents ( " $this->cacheroot / $lang / $component .php " , " <?php \$ this->cache[' $lang '][' $component '] = " . var_export ( $string , true ) . " ; " );
2010-05-16 19:58:47 +00:00
}
2010-04-04 21:18:57 +00:00
return $string ;
}
2010-04-13 20:14:31 +00:00
/**
* Does the string actually exist ?
*
* get_string () is throwing debug warnings , sometimes we do not want them
* or we want to display better explanation of the problem .
*
* Use with care !
*
* @ param string $identifier The identifier of the string to search for
* @ param string $component The module the string is associated with
* @ return boot true if exists
*/
public function string_exists ( $identifier , $component ) {
2010-04-30 10:53:39 +00:00
$identifier = clean_param ( $identifier , PARAM_STRINGID );
if ( empty ( $identifier )) {
return false ;
}
2010-04-13 20:14:31 +00:00
$lang = current_language ();
2010-06-25 13:43:50 +00:00
$string = $this -> load_component_strings ( $component , $lang );
2010-04-13 20:14:31 +00:00
return isset ( $string [ $identifier ]);
}
2010-04-04 21:18:57 +00:00
/**
* Get String returns a requested string
*
* @ param string $identifier The identifier of the string to search for
* @ param string $component The module the string is associated with
2010-04-14 12:51:53 +00:00
* @ param string | object | array $a An object , string or number that can be used
2010-04-04 21:18:57 +00:00
* within translation strings
2010-04-14 12:51:53 +00:00
* @ param string $lang moodle translation language , NULL means use current
2010-04-04 21:18:57 +00:00
* @ return string The String !
*/
2010-04-14 12:51:53 +00:00
public function get_string ( $identifier , $component = '' , $a = NULL , $lang = NULL ) {
2010-05-16 11:45:33 +00:00
$this -> countgetstring ++ ;
2010-04-10 19:02:11 +00:00
// there are very many uses of these time formating strings without the 'langconfig' component,
// it would not be reasonable to expect that all of them would be converted during 2.0 migration
static $langconfigstrs = array (
MDL-22050 removing moodle/langconfig duplicates
AMOS BEGIN
MOV [strftimedate,core],[strftimedate,core_langconfig]
MOV [strftimedatefullshort,core],[strftimedatefullshort,core_langconfig]
MOV [strftimedateshort,core],[strftimedateshort,core_langconfig]
MOV [strftimedatetime,core],[strftimedatetime,core_langconfig]
MOV [strftimedatetimeshort,core],[strftimedatetimeshort,core_langconfig]
MOV [strftimedaydate,core],[strftimedaydate,core_langconfig]
MOV [strftimedaydatetime,core],[strftimedaydatetime,core_langconfig]
MOV [strftimedayshort,core],[strftimedayshort,core_langconfig]
MOV [strftimedaytime,core],[strftimedaytime,core_langconfig]
MOV [strftimemonthyear,core],[strftimemonthyear,core_langconfig]
MOV [strftimerecent,core],[strftimerecent,core_langconfig]
MOV [strftimerecentfull,core],[strftimerecentfull,core_langconfig]
MOV [strftimetime,core],[strftimetime,core_langconfig]
AMOS END
2010-04-10 18:15:30 +00:00
'strftimedate' => 1 ,
'strftimedatefullshort' => 1 ,
'strftimedateshort' => 1 ,
'strftimedatetime' => 1 ,
'strftimedatetimeshort' => 1 ,
'strftimedaydate' => 1 ,
'strftimedaydatetime' => 1 ,
'strftimedayshort' => 1 ,
'strftimedaytime' => 1 ,
'strftimemonthyear' => 1 ,
'strftimerecent' => 1 ,
'strftimerecentfull' => 1 ,
2010-04-10 19:02:11 +00:00
'strftimetime' => 1 );
2010-04-10 07:24:56 +00:00
2010-04-10 17:30:00 +00:00
if ( empty ( $component )) {
2010-04-10 19:02:11 +00:00
if ( isset ( $langconfigstrs [ $identifier ])) {
$component = 'langconfig' ;
} else {
$component = 'moodle' ;
}
2010-04-10 17:30:00 +00:00
}
2010-04-14 12:51:53 +00:00
if ( $lang === NULL ) {
$lang = current_language ();
}
2010-04-04 21:18:57 +00:00
$string = $this -> load_component_strings ( $component , $lang );
if ( ! isset ( $string [ $identifier ])) {
2010-04-11 20:22:07 +00:00
if ( $component === 'pix' or $component === 'core_pix' ) {
// this component contains only alt tags for emoticons,
// not all of them are supposed to be defined
return '' ;
}
2010-04-11 20:30:58 +00:00
if ( $identifier === 'parentlanguage' and ( $component === 'langconfig' or $component === 'core_langconfig' )) {
2010-05-22 22:31:19 +00:00
// parentlanguage is a special string, undefined means use English if not defined
2010-04-11 20:30:58 +00:00
return 'en' ;
2010-04-10 07:24:56 +00:00
}
2010-06-25 09:40:34 +00:00
if ( $this -> usediskcache ) {
// maybe the on-disk cache is dirty - let the last attempt be to find the string in original sources
$string = $this -> load_component_strings ( $component , $lang , true );
}
if ( ! isset ( $string [ $identifier ])) {
// the string is still missing - should be fixed by developer
debugging ( " Invalid get_string() identifier: ' $identifier ' or component ' $component ' " , DEBUG_DEVELOPER );
return " [[ $identifier ]] " ;
}
2010-04-04 21:18:57 +00:00
}
$string = $string [ $identifier ];
if ( $a !== NULL ) {
if ( is_object ( $a ) or is_array ( $a )) {
$a = ( array ) $a ;
$search = array ();
$replace = array ();
foreach ( $a as $key => $value ) {
if ( is_int ( $key )) {
// we do not support numeric keys - sorry!
continue ;
}
2010-04-13 06:22:57 +00:00
if ( is_object ( $value ) or is_array ( $value )) {
// we support just string as value
continue ;
}
2010-04-10 14:01:45 +00:00
$search [] = '{$a->' . $key . '}' ;
2010-04-04 21:18:57 +00:00
$replace [] = ( string ) $value ;
}
if ( $search ) {
$string = str_replace ( $search , $replace , $string );
}
} else {
2010-04-10 14:01:45 +00:00
$string = str_replace ( '{$a}' , ( string ) $a , $string );
2010-04-04 21:18:57 +00:00
}
}
return $string ;
}
2010-05-16 11:45:33 +00:00
/**
* Returns information about the string_manager performance
* @ return array
*/
public function get_performance_summary () {
return array ( array (
'langcountgetstring' => $this -> countgetstring ,
'langcountmemcache' => $this -> countmemcache ,
'langcountdiskcache' => $this -> countdiskcache ,
), array (
'langcountgetstring' => 'get_string calls' ,
'langcountmemcache' => 'strings mem cache hits' ,
'langcountdiskcache' => 'strings disk cache hits' ,
));
}
2010-04-04 21:18:57 +00:00
/**
2010-04-29 07:43:19 +00:00
* Returns a localised list of all country names , sorted by localised name .
2010-04-14 12:42:48 +00:00
*
* @ param bool $returnall return all or just enabled
* @ param string $lang moodle translation language , NULL means use current
2010-04-04 21:18:57 +00:00
* @ return array two - letter country code => translated name .
*/
2010-04-14 12:42:48 +00:00
public function get_list_of_countries ( $returnall = false , $lang = NULL ) {
global $CFG ;
if ( $lang === NULL ) {
$lang = current_language ();
}
$countries = $this -> load_component_strings ( 'core_countries' , $lang );
2010-04-29 07:43:19 +00:00
asort ( $countries );
2010-04-14 12:42:48 +00:00
if ( ! $returnall and ! empty ( $CFG -> allcountrycodes )) {
$enabled = explode ( ',' , $CFG -> allcountrycodes );
$return = array ();
foreach ( $enabled as $c ) {
if ( isset ( $countries [ $c ])) {
$return [ $c ] = $countries [ $c ];
}
}
return $return ;
}
return $countries ;
2010-04-04 21:18:57 +00:00
}
2010-04-10 21:22:15 +00:00
2010-04-14 10:02:05 +00:00
/**
2010-04-14 12:14:18 +00:00
* Returns a localised list of languages , sorted by code keys .
*
* @ param string $lang moodle translation language , NULL means use current
* @ param string $standard language list standard
* - iso6392 : three - letter language code ( ISO 639 - 2 / T ) => translated name
2010-04-20 08:36:22 +00:00
* - iso6391 : two - letter langauge code ( ISO 639 - 1 ) => translated name
2010-04-14 12:14:18 +00:00
* @ return array language code => translated name
2010-04-14 10:02:05 +00:00
*/
2010-04-20 08:36:22 +00:00
public function get_list_of_languages ( $lang = NULL , $standard = 'iso6391' ) {
2010-04-14 12:14:18 +00:00
if ( $lang === NULL ) {
$lang = current_language ();
}
2010-04-20 08:36:22 +00:00
2010-04-14 12:14:18 +00:00
if ( $standard === 'iso6392' ) {
$langs = $this -> load_component_strings ( 'core_iso6392' , $lang );
2010-04-14 12:42:48 +00:00
ksort ( $langs );
2010-04-14 12:14:18 +00:00
return $langs ;
2010-04-20 08:36:22 +00:00
} else if ( $standard === 'iso6391' ) {
$langs2 = $this -> load_component_strings ( 'core_iso6392' , $lang );
static $mapping = array ( 'aar' => 'aa' , 'abk' => 'ab' , 'afr' => 'af' , 'aka' => 'ak' , 'sqi' => 'sq' , 'amh' => 'am' , 'ara' => 'ar' , 'arg' => 'an' , 'hye' => 'hy' ,
'asm' => 'as' , 'ava' => 'av' , 'ave' => 'ae' , 'aym' => 'ay' , 'aze' => 'az' , 'bak' => 'ba' , 'bam' => 'bm' , 'eus' => 'eu' , 'bel' => 'be' , 'ben' => 'bn' , 'bih' => 'bh' ,
'bis' => 'bi' , 'bos' => 'bs' , 'bre' => 'br' , 'bul' => 'bg' , 'mya' => 'my' , 'cat' => 'ca' , 'cha' => 'ch' , 'che' => 'ce' , 'zho' => 'zh' , 'chu' => 'cu' , 'chv' => 'cv' ,
'cor' => 'kw' , 'cos' => 'co' , 'cre' => 'cr' , 'ces' => 'cs' , 'dan' => 'da' , 'div' => 'dv' , 'nld' => 'nl' , 'dzo' => 'dz' , 'eng' => 'en' , 'epo' => 'eo' , 'est' => 'et' ,
'ewe' => 'ee' , 'fao' => 'fo' , 'fij' => 'fj' , 'fin' => 'fi' , 'fra' => 'fr' , 'fry' => 'fy' , 'ful' => 'ff' , 'kat' => 'ka' , 'deu' => 'de' , 'gla' => 'gd' , 'gle' => 'ga' ,
'glg' => 'gl' , 'glv' => 'gv' , 'ell' => 'el' , 'grn' => 'gn' , 'guj' => 'gu' , 'hat' => 'ht' , 'hau' => 'ha' , 'heb' => 'he' , 'her' => 'hz' , 'hin' => 'hi' , 'hmo' => 'ho' ,
'hrv' => 'hr' , 'hun' => 'hu' , 'ibo' => 'ig' , 'isl' => 'is' , 'ido' => 'io' , 'iii' => 'ii' , 'iku' => 'iu' , 'ile' => 'ie' , 'ina' => 'ia' , 'ind' => 'id' , 'ipk' => 'ik' ,
'ita' => 'it' , 'jav' => 'jv' , 'jpn' => 'ja' , 'kal' => 'kl' , 'kan' => 'kn' , 'kas' => 'ks' , 'kau' => 'kr' , 'kaz' => 'kk' , 'khm' => 'km' , 'kik' => 'ki' , 'kin' => 'rw' ,
'kir' => 'ky' , 'kom' => 'kv' , 'kon' => 'kg' , 'kor' => 'ko' , 'kua' => 'kj' , 'kur' => 'ku' , 'lao' => 'lo' , 'lat' => 'la' , 'lav' => 'lv' , 'lim' => 'li' , 'lin' => 'ln' ,
'lit' => 'lt' , 'ltz' => 'lb' , 'lub' => 'lu' , 'lug' => 'lg' , 'mkd' => 'mk' , 'mah' => 'mh' , 'mal' => 'ml' , 'mri' => 'mi' , 'mar' => 'mr' , 'msa' => 'ms' , 'mlg' => 'mg' ,
'mlt' => 'mt' , 'mon' => 'mn' , 'nau' => 'na' , 'nav' => 'nv' , 'nbl' => 'nr' , 'nde' => 'nd' , 'ndo' => 'ng' , 'nep' => 'ne' , 'nno' => 'nn' , 'nob' => 'nb' , 'nor' => 'no' ,
'nya' => 'ny' , 'oci' => 'oc' , 'oji' => 'oj' , 'ori' => 'or' , 'orm' => 'om' , 'oss' => 'os' , 'pan' => 'pa' , 'fas' => 'fa' , 'pli' => 'pi' , 'pol' => 'pl' , 'por' => 'pt' ,
'pus' => 'ps' , 'que' => 'qu' , 'roh' => 'rm' , 'ron' => 'ro' , 'run' => 'rn' , 'rus' => 'ru' , 'sag' => 'sg' , 'san' => 'sa' , 'sin' => 'si' , 'slk' => 'sk' , 'slv' => 'sl' ,
'sme' => 'se' , 'smo' => 'sm' , 'sna' => 'sn' , 'snd' => 'sd' , 'som' => 'so' , 'sot' => 'st' , 'spa' => 'es' , 'srd' => 'sc' , 'srp' => 'sr' , 'ssw' => 'ss' , 'sun' => 'su' ,
'swa' => 'sw' , 'swe' => 'sv' , 'tah' => 'ty' , 'tam' => 'ta' , 'tat' => 'tt' , 'tel' => 'te' , 'tgk' => 'tg' , 'tgl' => 'tl' , 'tha' => 'th' , 'bod' => 'bo' , 'tir' => 'ti' ,
'ton' => 'to' , 'tsn' => 'tn' , 'tso' => 'ts' , 'tuk' => 'tk' , 'tur' => 'tr' , 'twi' => 'tw' , 'uig' => 'ug' , 'ukr' => 'uk' , 'urd' => 'ur' , 'uzb' => 'uz' , 'ven' => 've' ,
'vie' => 'vi' , 'vol' => 'vo' , 'cym' => 'cy' , 'wln' => 'wa' , 'wol' => 'wo' , 'xho' => 'xh' , 'yid' => 'yi' , 'yor' => 'yo' , 'zha' => 'za' , 'zul' => 'zu' );
$langs1 = array ();
foreach ( $mapping as $c2 => $c1 ) {
$langs1 [ $c1 ] = $langs2 [ $c2 ];
}
ksort ( $langs1 );
return $langs1 ;
2010-04-14 12:14:18 +00:00
} else {
debugging ( 'Unsupported $standard parameter in get_list_of_languages() method: ' . $standard );
}
2010-04-20 08:36:22 +00:00
2010-04-14 10:02:05 +00:00
return array ();
}
2010-04-14 13:16:20 +00:00
/**
* Does the translation exist ?
*
* @ param string $lang moodle translation language code
* @ param bool include also disabled translations ?
* @ return boot true if exists
*/
public function translation_exists ( $lang , $includeall = true ) {
global $CFG ;
if ( strpos ( $lang , '_local' ) !== false ) {
// _local packs are not real translations
return false ;
}
if ( ! $includeall and ! empty ( $CFG -> langlist )) {
$enabled = explode ( ',' , $CFG -> langlist );
if ( ! in_array ( $lang , $enabled )) {
return false ;
}
}
if ( $lang === 'en' ) {
// part of distribution
return true ;
}
2010-04-14 14:37:56 +00:00
return file_exists ( " $this->otherroot / $lang /langconfig.php " );
2010-04-14 13:16:20 +00:00
}
2010-04-10 21:22:15 +00:00
/**
2010-04-14 09:45:49 +00:00
* Returns localised list of installed translations
2010-04-10 21:22:15 +00:00
* @ param bool $returnall return all or just enabled
2010-04-14 13:37:59 +00:00
* @ return array moodle translation code => localised translation name
2010-04-10 21:22:15 +00:00
*/
2010-04-14 09:45:49 +00:00
public function get_list_of_translations ( $returnall = false ) {
2010-04-10 21:22:15 +00:00
global $CFG ;
$languages = array ();
2010-05-22 22:31:19 +00:00
//TODO: add some translist cache stored in normal cache dir
if ( ! $returnall and ! empty ( $this -> translist )) {
// return only some translations
foreach ( $this -> translist as $lang ) {
2010-04-10 21:22:15 +00:00
$lang = trim ( $lang ); //Just trim spaces to be a bit more permissive
if ( strstr ( $lang , '_local' ) !== false ) {
continue ;
}
2010-04-11 14:37:12 +00:00
if ( strstr ( $lang , '_utf8' ) !== false ) {
continue ;
}
2010-04-10 21:22:15 +00:00
if ( $lang !== 'en' and ! file_exists ( " $this->otherroot / $lang /langconfig.php " )) {
2010-05-22 22:31:19 +00:00
// some broken or missing lang - can not switch to it anyway
2010-04-10 21:22:15 +00:00
continue ;
}
$string = $this -> load_component_strings ( 'langconfig' , $lang );
if ( ! empty ( $string [ 'thislanguage' ])) {
$languages [ $lang ] = $string [ 'thislanguage' ] . ' (' . $lang . ')' ;
}
unset ( $string );
}
} else {
// return all languages available in system
$langdirs = get_list_of_plugins ( '' , '' , $this -> otherroot );
$langdirs = array_merge ( $langdirs , array ( " $CFG->dirroot /lang/en " => 'en' ));
// Sort all
asort ( $langdirs );
// Loop through all langs and get info
foreach ( $langdirs as $lang ) {
if ( strstr ( $lang , '_local' ) !== false ) {
continue ;
}
2010-04-11 14:37:12 +00:00
if ( strstr ( $lang , '_utf8' ) !== false ) {
continue ;
}
2010-04-10 21:22:15 +00:00
$string = $this -> load_component_strings ( 'langconfig' , $lang );
if ( ! empty ( $string [ 'thislanguage' ])) {
$languages [ $lang ] = $string [ 'thislanguage' ] . ' (' . $lang . ')' ;
}
unset ( $string );
}
}
return $languages ;
}
2010-04-14 14:04:21 +00:00
/**
* Returns localised list of currencies .
*
* @ param string $lang moodle translation language , NULL means use current
* @ return array currency code => localised currency name
*/
public function get_list_of_currencies ( $lang = NULL ) {
if ( $lang === NULL ) {
$lang = current_language ();
}
$currencies = $this -> load_component_strings ( 'core_currencies' , $lang );
asort ( $currencies );
return $currencies ;
}
2010-05-16 19:37:19 +00:00
/**
* Clears both in - memory and on - disk caches
*/
public function reset_caches () {
global $CFG ;
require_once ( " $CFG->libdir /filelib.php " );
fulldelete ( $this -> cacheroot );
$this -> cache = array ();
}
2010-04-10 07:24:56 +00:00
}
2010-04-10 19:28:34 +00:00
/**
* Minimalistic string fetching implementation
2010-05-22 18:38:18 +00:00
* that is used in installer before we fetch the wanted
2010-04-10 19:28:34 +00:00
* language pack from moodle . org lang download site .
*
* @ package moodlecore
* @ copyright 2010 Petr Skoda ( http :// skodak . org )
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2010-04-10 07:24:56 +00:00
class install_string_manager implements string_manager {
2010-04-10 20:35:52 +00:00
/** @var string location of pre-install packs for all langs */
protected $installroot ;
2010-04-04 21:18:57 +00:00
/**
2010-04-10 07:24:56 +00:00
* Crate new instance of install string manager
2010-04-04 21:18:57 +00:00
*/
2010-04-10 20:35:52 +00:00
public function __construct () {
global $CFG ;
$this -> installroot = " $CFG->dirroot /install/lang " ;
2010-04-10 07:24:56 +00:00
}
2010-04-11 20:37:13 +00:00
/**
* Load all strings for one component
* @ param string $component The module the string is associated with
* @ param string $lang
2010-06-28 16:04:22 +00:00
* @ param bool $disablecache Do not use caches , force fetching the strings from sources
2010-04-11 20:37:13 +00:00
* @ return array of all string for given component and lang
*/
2010-06-28 16:04:22 +00:00
public function load_component_strings ( $component , $lang , $disablecache = false ) {
2010-04-13 20:14:31 +00:00
// not needed in installer
2010-04-11 20:37:13 +00:00
return array ();
}
2010-04-13 20:14:31 +00:00
/**
* Does the string actually exist ?
*
* get_string () is throwing debug warnings , sometimes we do not want them
* or we want to display better explanation of the problem .
*
* Use with care !
*
* @ param string $identifier The identifier of the string to search for
* @ param string $component The module the string is associated with
* @ return boot true if exists
*/
public function string_exists ( $identifier , $component ) {
2010-04-30 10:53:39 +00:00
$identifier = clean_param ( $identifier , PARAM_STRINGID );
if ( empty ( $identifier )) {
return false ;
}
2010-04-13 20:14:31 +00:00
// simple old style hack ;)
$str = get_string ( $identifier , $component );
return ( strpos ( $str , '[[' ) === false );
}
2010-04-10 07:24:56 +00:00
/**
* Get String returns a requested string
*
* @ param string $identifier The identifier of the string to search for
* @ param string $component The module the string is associated with
2010-04-14 12:51:53 +00:00
* @ param string | object | array $a An object , string or number that can be used
2010-04-10 07:24:56 +00:00
* within translation strings
2010-04-14 12:51:53 +00:00
* @ param string $lang moodle translation language , NULL means use current
2010-04-10 07:24:56 +00:00
* @ return string The String !
*/
2010-04-14 12:51:53 +00:00
public function get_string ( $identifier , $component = '' , $a = NULL , $lang = NULL ) {
2010-04-11 18:26:19 +00:00
if ( ! $component ) {
$component = 'moodle' ;
}
2010-04-10 07:24:56 +00:00
2010-04-14 12:51:53 +00:00
if ( $lang === NULL ) {
$lang = current_language ();
}
2010-04-14 14:04:21 +00:00
2010-04-11 18:26:19 +00:00
//get parent lang
$parent = '' ;
if ( $lang !== 'en' and $identifier !== 'parentlanguage' and $component !== 'langconfig' ) {
if ( file_exists ( " $this->installroot / $lang /langconfig.php " )) {
$string = array ();
include ( " $this->installroot / $lang /langconfig.php " );
if ( isset ( $string [ 'parentlanguage' ])) {
$parent = $string [ 'parentlanguage' ];
}
unset ( $string );
}
}
// include en string first
if ( ! file_exists ( " $this->installroot /en/ $component .php " )) {
return " [[ $identifier ]] " ;
}
2010-04-10 07:24:56 +00:00
$string = array ();
2010-04-11 18:26:19 +00:00
include ( " $this->installroot /en/ $component .php " );
// now override en with parent if defined
if ( $parent and $parent !== 'en' and file_exists ( " $this->installroot / $parent / $component .php " )) {
include ( " $this->installroot / $parent / $component .php " );
}
2010-04-10 07:24:56 +00:00
2010-04-11 18:26:19 +00:00
// finally override with requested language
if ( $lang !== 'en' and file_exists ( " $this->installroot / $lang / $component .php " )) {
include ( " $this->installroot / $lang / $component .php " );
2010-04-10 07:24:56 +00:00
}
if ( ! isset ( $string [ $identifier ])) {
return " [[ $identifier ]] " ;
}
$string = $string [ $identifier ];
if ( $a !== NULL ) {
if ( is_object ( $a ) or is_array ( $a )) {
$a = ( array ) $a ;
$search = array ();
$replace = array ();
foreach ( $a as $key => $value ) {
if ( is_int ( $key )) {
// we do not support numeric keys - sorry!
continue ;
}
2010-04-11 18:26:19 +00:00
$search [] = '{$a->' . $key . '}' ;
2010-04-10 07:24:56 +00:00
$replace [] = ( string ) $value ;
}
if ( $search ) {
$string = str_replace ( $search , $replace , $string );
}
} else {
2010-04-11 18:26:19 +00:00
$string = str_replace ( '{$a}' , ( string ) $a , $string );
2010-04-10 07:24:56 +00:00
}
}
return $string ;
}
/**
2010-04-14 12:42:48 +00:00
* Returns a localised list of all country names , sorted by country keys .
*
* @ param bool $returnall return all or just enabled
* @ param string $lang moodle translation language , NULL means use current
2010-04-10 07:24:56 +00:00
* @ return array two - letter country code => translated name .
*/
2010-04-14 12:42:48 +00:00
public function get_list_of_countries ( $returnall = false , $lang = NULL ) {
2010-04-14 10:02:05 +00:00
//not used in installer
return array ();
}
/**
2010-04-14 12:14:18 +00:00
* Returns a localised list of languages , sorted by code keys .
*
* @ param string $lang moodle translation language , NULL means use current
* @ param string $standard language list standard
* iso6392 : three - letter language code ( ISO 639 - 2 / T ) => translated name .
* @ return array language code => translated name
2010-04-14 10:02:05 +00:00
*/
2010-04-14 12:14:18 +00:00
public function get_list_of_languages ( $lang = NULL , $standard = 'iso6392' ) {
2010-04-14 10:02:05 +00:00
//not used in installer
2010-04-10 07:24:56 +00:00
return array ();
2010-04-04 21:18:57 +00:00
}
2010-04-10 21:22:15 +00:00
2010-04-14 13:16:20 +00:00
/**
* Does the translation exist ?
*
* @ param string $lang moodle translation language code
* @ param bool include also disabled translations ?
* @ return boot true if exists
*/
public function translation_exists ( $lang , $includeall = true ) {
2010-04-14 14:04:21 +00:00
return file_exists ( $this -> installroot . '/' . $lang . '/langconfig.php' );
2010-04-14 13:16:20 +00:00
}
2010-04-10 21:22:15 +00:00
/**
2010-04-14 09:45:49 +00:00
* Returns localised list of installed translations
2010-04-10 21:22:15 +00:00
* @ param bool $returnall return all or just enabled
2010-04-14 13:37:59 +00:00
* @ return array moodle translation code => localised translation name
2010-04-10 21:22:15 +00:00
*/
2010-04-14 09:45:49 +00:00
public function get_list_of_translations ( $returnall = false ) {
2010-04-10 21:22:15 +00:00
// return all is ignored here - we need to know all langs in installer
$languages = array ();
// Get raw list of lang directories
$langdirs = get_list_of_plugins ( 'install/lang' );
asort ( $langdirs );
// Get some info from each lang
foreach ( $langdirs as $lang ) {
2010-04-11 18:26:19 +00:00
if ( file_exists ( $this -> installroot . '/' . $lang . '/langconfig.php' )) {
2010-04-10 21:22:15 +00:00
$string = array ();
2010-04-11 18:26:19 +00:00
include ( $this -> installroot . '/' . $lang . '/langconfig.php' );
2010-04-10 21:22:15 +00:00
if ( ! empty ( $string [ 'thislanguage' ])) {
$languages [ $lang ] = $string [ 'thislanguage' ] . ' (' . $lang . ')' ;
}
}
}
// Return array
return $languages ;
}
2010-04-14 14:04:21 +00:00
/**
* Returns localised list of currencies .
*
* @ param string $lang moodle translation language , NULL means use current
* @ return array currency code => localised currency name
*/
public function get_list_of_currencies ( $lang = NULL ) {
// not used in installer
return array ();
}
2010-05-16 19:37:19 +00:00
/**
* This implementation does not use any caches
*/
public function reset_caches () {}
2010-04-04 21:18:57 +00:00
}
2002-06-27 08:47:27 +00:00
2004-09-23 05:10:21 +00:00
/**
2009-03-30 02:21:27 +00:00
* Returns a localized string .
*
* Returns the translated string specified by $identifier as
* for $module . Uses the same format files as STphp .
* $a is an object , string or number that can be used
* within translation strings
*
2010-04-10 19:28:34 +00:00
* eg 'hello {$a->firstname} {$a->lastname}'
* or 'hello {$a}'
2009-03-30 02:21:27 +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
2010-05-22 18:38:18 +00:00
* to retrieve it .< br />
2010-04-10 19:28:34 +00:00
* If you open moodle / lang / en / moodle . php and look near line 278
* you will find a string to prompt a user for their word for 'course'
2009-03-30 02:21:27 +00:00
* < code >
2010-04-10 19:28:34 +00:00
* $string [ 'course' ] = 'Course' ;
2009-03-30 02:21:27 +00:00
* </ code >
2010-04-10 19:28:34 +00:00
* So if you want to display the string 'Course'
2009-03-30 02:21:27 +00:00
* in any language that supports it on your site
2010-04-10 19:28:34 +00:00
* you just need to use the identifier 'course'
2009-03-30 02:21:27 +00:00
* < code >
2010-04-10 19:28:34 +00:00
* $mystring = '<strong>' . get_string ( 'course' ) . '</strong>' ;
2009-05-22 02:57:43 +00:00
* or
2009-03-30 02:21:27 +00:00
* </ code >
* 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
* around line 75 :
* < code >
* $string [ 'typecourse' ] = 'Course event' ;
* </ code >
* If you want to display the string " Course event " in any language
* supported you would use the identifier 'typecourse' and the module 'calendar'
* ( 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
*
2009-03-30 02:21:27 +00:00
* @ param string $identifier The key identifier for the localized string
2010-04-10 19:28:34 +00:00
* @ param string $component The module where the key identifier is stored ,
2009-03-30 02:21:27 +00:00
* usually expressed as the filename in the language pack without the
* . php on the end but can also be written as mod / forum or grade / export / xls .
* If none is specified then moodle . php is used .
2010-04-14 12:51:53 +00:00
* @ param string | object | array $a An object , string or number that can be used
2009-03-30 02:21:27 +00:00
* within translation strings
* @ return string The localized string .
2004-09-23 05:10:21 +00:00
*/
2010-04-10 19:28:34 +00:00
function get_string ( $identifier , $component = '' , $a = NULL ) {
2010-04-28 00:06:43 +00:00
$identifier = clean_param ( $identifier , PARAM_STRINGID );
if ( empty ( $identifier )) {
throw new coding_exception ( 'Invalid string identifier. Most probably some illegal character is part of the string identifier. Please fix your get_string() call and string definition' );
}
2010-04-10 19:28:34 +00:00
if ( func_num_args () > 3 ) {
2010-04-01 18:50:28 +00:00
debugging ( 'extralocations parameter in get_string() is not supported any more, please use standard lang locations only.' );
}
2010-04-10 19:28:34 +00:00
if ( strpos ( $component , '/' ) !== false ) {
2010-04-02 08:23:08 +00:00
debugging ( 'The module name you passed to get_string is the deprecated format ' .
'like mod/mymod or block/myblock. The correct form looks like mymod, or block_myblock.' , DEBUG_DEVELOPER );
2010-07-20 01:38:54 +00:00
$componentpath = explode ( '/' , $component );
2010-04-02 08:23:08 +00:00
2010-04-10 19:28:34 +00:00
switch ( $componentpath [ 0 ]) {
2010-04-02 08:23:08 +00:00
case 'mod' :
2010-04-10 19:28:34 +00:00
$component = $componentpath [ 1 ];
2010-04-02 08:23:08 +00:00
break ;
case 'blocks' :
case 'block' :
2010-04-10 19:28:34 +00:00
$component = 'block_' . $componentpath [ 1 ];
2010-04-02 08:23:08 +00:00
break ;
case 'enrol' :
2010-04-10 19:28:34 +00:00
$component = 'enrol_' . $componentpath [ 1 ];
2010-04-02 08:23:08 +00:00
break ;
case 'format' :
2010-04-10 19:28:34 +00:00
$component = 'format_' . $componentpath [ 1 ];
2010-04-02 08:23:08 +00:00
break ;
case 'grade' :
2010-04-10 19:28:34 +00:00
$component = 'grade' . $componentpath [ 1 ] . '_' . $componentpath [ 2 ];
2010-04-02 08:23:08 +00:00
break ;
}
}
2010-04-04 19:58:03 +00:00
2010-04-10 19:28:34 +00:00
return get_string_manager () -> get_string ( $identifier , $component , $a );
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 .
2009-03-30 02:21:27 +00:00
* @ return array and array of translated strings .
2004-09-23 05:10:21 +00:00
*/
2010-04-10 19:28:34 +00:00
function get_strings ( $array , $component = '' ) {
2009-03-30 02:21:27 +00:00
$string = new stdClass ;
2004-07-25 13:48:55 +00:00
foreach ( $array as $item ) {
2010-04-10 19:28:34 +00:00
$string -> $item = get_string ( $item , $component );
2004-07-25 13:48:55 +00:00
}
return $string ;
}
2001-11-22 06:23:56 +00:00
2010-04-10 19:28:34 +00:00
/**
* Prints out a translated string .
*
* Prints out a translated string using the return value from the { @ link get_string ()} function .
*
* Example usage of this function when the string is in the moodle . php file :< br />
* < code >
* echo '<strong>' ;
* print_string ( 'course' );
* echo '</strong>' ;
* </ code >
*
* Example usage of this function when the string is not in the moodle . php file :< br />
* < code >
* echo '<h1>' ;
* print_string ( 'typecourse' , 'calendar' );
* echo '</h1>' ;
* </ code >
*
* @ param string $identifier The key identifier for the localized string
* @ param string $component 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
*/
function print_string ( $identifier , $component = '' , $a = NULL ) {
echo get_string ( $identifier , $component , $a );
}
2006-01-05 16:04:26 +00:00
/**
2009-05-22 02:57:43 +00:00
* Returns a list of charset codes
*
2006-01-05 16:04:26 +00:00
* Returns a list of charset codes . It ' s hardcoded , so they should be added manually
2010-05-22 18:38:18 +00:00
* ( checking that such charset is supported by the texlib library ! )
2006-01-05 16:04:26 +00:00
*
* @ 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 ;
}
2005-02-10 10:28:27 +00:00
/**
* Returns a list of valid and compatible themes
*
2009-05-22 02:57:43 +00:00
* @ global object
2005-02-10 10:28:27 +00:00
* @ 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 {
2009-06-19 14:25:56 +00:00
$themelist = array_keys ( get_plugin_list ( " theme " ));
2005-02-10 10:28:27 +00:00
}
2009-12-16 18:00:58 +00:00
foreach ( $themelist as $key => $themename ) {
$theme = theme_config :: load ( $themename );
$themes [ $themename ] = $theme ;
2005-02-10 10:28:27 +00:00
}
asort ( $themes );
return $themes ;
}
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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
2005-07-12 03:09:25 +00:00
* @ return array
2005-04-10 17:35:17 +00:00
*/
function get_list_of_timezones () {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
2005-04-10 17:35:17 +00:00
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 ();
2008-05-30 19:59:50 +00:00
if ( $rawtimezones = $DB -> get_records_sql ( " SELECT MAX(id), name FROM { timezone} GROUP BY name " )) {
2005-04-10 17:51:48 +00:00
foreach ( $rawtimezones as $timezone ) {
if ( ! empty ( $timezone -> name )) {
2010-04-23 00:11:54 +00:00
if ( get_string_manager () -> string_exists ( strtolower ( $timezone -> name ), 'timezones' )) {
$timezones [ $timezone -> name ] = get_string ( strtolower ( $timezone -> name ), 'timezones' );
} else {
$timezones [ $timezone -> name ] = $timezone -> name ;
}
2005-04-10 17:51:48 +00:00
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
}
2001-11-22 06:23:56 +00:00
/// ENCRYPTION ////////////////////////////////////////////////
2004-09-23 05:10:21 +00:00
/**
* rc4encrypt
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ param string $data Data to encrypt
* @ return string The now encrypted data
2004-09-23 05:10:21 +00:00
*/
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
*
2008-07-06 17:57:06 +00:00
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ param string $data Data to decrypt
* @ return string The now decrypted data
2004-09-23 05:10:21 +00:00
*/
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 ]
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ param string $pwd The password to use when encrypting or decrypting
* @ param string $data The data to be decrypted / encrypted
* @ param string $case Either 'de' for decrypt or '' for encrypt
* @ return string
2004-09-23 05:10:21 +00:00
*/
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 ;
}
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
/**
2010-04-10 23:21:18 +00:00
* Returns the exact absolute path to plugin directory .
*
2009-06-19 14:25:56 +00:00
* @ param string $plugintype type of plugin
* @ param string $name name of the plugin
2010-04-10 23:21:18 +00:00
* @ return string full path to plugin directory ; NULL if not found
2009-06-19 14:25:56 +00:00
*/
2010-04-10 23:21:18 +00:00
function get_plugin_directory ( $plugintype , $name ) {
2009-06-19 14:25:56 +00:00
if ( $plugintype === '' ) {
$plugintype = 'mod' ;
}
2010-04-10 23:21:18 +00:00
$types = get_plugin_types ( true );
2009-06-19 14:25:56 +00:00
if ( ! array_key_exists ( $plugintype , $types )) {
2010-04-10 23:21:18 +00:00
return NULL ;
2009-06-19 14:25:56 +00:00
}
$name = clean_param ( $name , PARAM_SAFEDIR ); // just in case ;-)
return $types [ $plugintype ] . '/' . $name ;
}
/**
2010-04-10 23:21:18 +00:00
* Return exact absolute path to a plugin directory ,
2009-06-19 14:25:56 +00:00
* this method support " simpletest_ " prefix designed for unit testing .
2010-04-10 23:21:18 +00:00
*
2009-06-19 14:25:56 +00:00
* @ param string $component name such as 'moodle' , 'mod_forum' or special simpletest value
2010-04-10 23:21:18 +00:00
* @ return string full path to component directory ; NULL if not found
2009-06-19 14:25:56 +00:00
*/
2010-04-10 23:21:18 +00:00
function get_component_directory ( $component ) {
2009-06-19 14:25:56 +00:00
global $CFG ;
2010-04-10 23:21:18 +00:00
/*
2009-06-19 14:25:56 +00:00
$simpletest = false ;
if ( strpos ( $component , 'simpletest_' ) === 0 ) {
$subdir = substr ( $component , strlen ( 'simpletest_' ));
2010-04-10 23:21:18 +00:00
//TODO: this looks borked, where is it used actually?
2009-06-19 14:25:56 +00:00
return $subdir ;
}
2010-04-10 23:21:18 +00:00
*/
2010-04-01 20:54:27 +00:00
list ( $type , $plugin ) = normalize_component ( $component );
if ( $type === 'core' ) {
if ( $plugin === NULL ) {
2010-04-10 23:21:18 +00:00
$path = $CFG -> libdir ;
2009-12-16 18:00:58 +00:00
} else {
2010-04-01 20:54:27 +00:00
$subsystems = get_core_subsystems ();
if ( isset ( $subsystems [ $plugin ])) {
2010-04-10 23:21:18 +00:00
$path = $CFG -> dirroot . '/' . $subsystems [ $plugin ];
2010-04-01 20:54:27 +00:00
} else {
$path = NULL ;
}
2009-12-16 18:00:58 +00:00
}
2010-04-01 20:54:27 +00:00
} else {
2010-04-10 23:21:18 +00:00
$path = get_plugin_directory ( $type , $plugin );
2009-09-01 08:39:55 +00:00
}
2009-06-19 14:25:56 +00:00
return $path ;
}
2010-04-01 20:54:27 +00:00
/**
* Normalize the component name using the " frankenstyle " names .
* @ param string $component
* @ return array $type + $plugin elements
*/
function normalize_component ( $component ) {
if ( $component === 'moodle' or $component === 'core' ) {
$type = 'core' ;
$plugin = NULL ;
} else if ( strpos ( $component , '_' ) === false ) {
$subsystems = get_core_subsystems ();
if ( array_key_exists ( $component , $subsystems )) {
$type = 'core' ;
$plugin = $component ;
} else {
// everything else is a module
$type = 'mod' ;
$plugin = $component ;
}
} else {
list ( $type , $plugin ) = explode ( '_' , $component , 2 );
}
return array ( $type , $plugin );
}
/**
2010-04-22 19:40:22 +00:00
* List all core subsystems and their location
2010-04-22 08:45:36 +00:00
*
2010-04-22 19:40:22 +00:00
* This is a whitelist of components that are part of the core and their
* language strings are defined in / lang / en /<< subsystem >>. php . If a given
* plugin is not listed here and it does not have proper plugintype prefix ,
* then it is considered as course activity module .
2010-04-22 08:45:36 +00:00
*
2010-04-22 19:40:22 +00:00
* The location is dirroot relative path . NULL means there is no special
* directory for this subsystem . If the location is set , the subsystem ' s
* renderer . php is expected to be there .
2010-04-01 20:54:27 +00:00
*
2010-04-22 19:40:22 +00:00
* @ return array of ( string ) name => ( string | null ) location
2010-04-01 20:54:27 +00:00
*/
function get_core_subsystems () {
global $CFG ;
2010-04-22 08:45:36 +00:00
static $info = null ;
2010-04-01 20:54:27 +00:00
if ( ! $info ) {
$info = array (
'access' => NULL ,
2010-04-01 20:56:08 +00:00
'admin' => $CFG -> admin ,
2010-04-01 20:54:27 +00:00
'auth' => 'auth' ,
2010-05-01 09:51:39 +00:00
'backup' => 'backup/util/ui' ,
2010-04-01 20:54:27 +00:00
'block' => 'blocks' ,
'blog' => 'blog' ,
'bulkusers' => NULL ,
'calendar' => 'calendar' ,
2010-04-23 09:09:34 +00:00
'cohort' => 'cohort' ,
2010-04-01 20:54:27 +00:00
'condition' => NULL ,
'completion' => NULL ,
'countries' => NULL ,
2010-05-27 01:40:11 +00:00
'course' => 'course' ,
2010-04-01 20:54:27 +00:00
'currencies' => NULL ,
'dbtransfer' => NULL ,
'debug' => NULL ,
'dock' => NULL ,
'editor' => 'lib/editor' ,
2010-05-01 05:05:55 +00:00
'edufields' => NULL ,
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
'enrol' => 'enrol' ,
2010-04-01 20:54:27 +00:00
'error' => NULL ,
'filepicker' => NULL ,
2010-07-03 13:37:13 +00:00
'files' => 'files' ,
2010-04-01 20:54:27 +00:00
'filters' => NULL ,
'flashdetect' => NULL ,
'fonts' => NULL ,
'form' => 'lib/form' ,
'grades' => 'grade' ,
'group' => 'group' ,
'help' => NULL ,
2010-05-01 05:05:55 +00:00
'hub' => NULL ,
2010-04-01 20:54:27 +00:00
'imscc' => NULL ,
'install' => NULL ,
2010-04-14 12:14:18 +00:00
'iso6392' => NULL ,
2010-04-01 20:54:27 +00:00
'langconfig' => NULL ,
'license' => NULL ,
'message' => 'message' ,
'mimetypes' => NULL ,
'mnet' => 'mnet' ,
'moodle.org' => NULL , // the dot is nasty, watch out! should be renamed to moodleorg
'my' => 'my' ,
'notes' => 'notes' ,
'pagetype' => NULL ,
'pix' => NULL ,
'portfolio' => 'portfolio' ,
2010-05-01 05:05:55 +00:00
'publish' => 'course/publish' ,
2010-04-01 20:54:27 +00:00
'question' => 'question' ,
'rating' => 'rating' ,
2010-05-01 05:05:55 +00:00
'register' => 'admin/registration' ,
2010-04-01 20:54:27 +00:00
'repository' => 'repository' ,
2010-05-13 02:07:57 +00:00
'rss' => 'rss' ,
2010-04-01 20:54:27 +00:00
'role' => $CFG -> admin . '/role' ,
'simpletest' => NULL ,
'search' => 'search' ,
'table' => NULL ,
'tag' => 'tag' ,
'timezones' => NULL ,
2010-07-19 10:10:51 +00:00
'user' => 'user' ,
2010-04-01 20:54:27 +00:00
'userkey' => NULL ,
'webservice' => 'webservice' ,
'xmldb' => NULL ,
);
}
return $info ;
}
2009-06-19 14:25:56 +00:00
/**
* Lists all plugin types
* @ param bool $fullpaths false means relative paths from dirroot
* @ return array Array of strings - name => location
*/
function get_plugin_types ( $fullpaths = true ) {
global $CFG ;
static $info = null ;
static $fullinfo = null ;
if ( ! $info ) {
$info = array ( 'mod' => 'mod' ,
'auth' => 'auth' ,
'enrol' => 'enrol' ,
'message' => 'message/output' ,
'block' => 'blocks' ,
'filter' => 'filter' ,
'editor' => 'lib/editor' ,
'format' => 'course/format' ,
'import' => 'course/import' ,
'profilefield' => 'user/profile/field' ,
'report' => $CFG -> admin . '/report' ,
'coursereport' => 'course/report' , // must be after system reports
'gradeexport' => 'grade/export' ,
'gradeimport' => 'grade/import' ,
'gradereport' => 'grade/report' ,
2010-07-17 22:18:07 +00:00
'mnetservice' => 'mnet/service' ,
2009-10-08 22:02:50 +00:00
'webservice' => 'webservice' ,
2009-06-19 14:25:56 +00:00
'repository' => 'repository' ,
2009-11-18 13:27:38 +00:00
'portfolio' => 'portfolio' ,
2009-06-19 14:25:56 +00:00
'qtype' => 'question/type' ,
2009-12-16 18:00:58 +00:00
'qformat' => 'question/format' ,
'theme' => 'theme' ); // this is a bit hacky, themes may be in dataroot too
2009-07-02 15:02:51 +00:00
2009-06-19 14:25:56 +00:00
$mods = get_plugin_list ( 'mod' );
foreach ( $mods as $mod => $moddir ) {
2010-04-04 19:58:03 +00:00
if ( file_exists ( " $moddir /db/subplugins.php " )) {
$subplugins = array ();
include ( " $moddir /db/subplugins.php " );
foreach ( $subplugins as $subtype => $dir ) {
$info [ $subtype ] = $dir ;
}
2009-06-19 14:25:56 +00:00
}
}
2009-07-02 15:02:51 +00:00
2009-12-16 18:00:58 +00:00
// local is always last!
2009-06-19 14:25:56 +00:00
$info [ 'local' ] = 'local' ;
$fullinfo = array ();
foreach ( $info as $type => $dir ) {
$fullinfo [ $type ] = $CFG -> dirroot . '/' . $dir ;
}
}
return ( $fullpaths ? $fullinfo : $info );
}
/**
* Simplified version of get_list_of_plugins ()
* @ param string $plugintype type of plugin
* @ return array name => fulllocation pairs of plugins of given type
*/
2009-12-16 18:00:58 +00:00
function get_plugin_list ( $plugintype ) {
2009-06-19 14:25:56 +00:00
global $CFG ;
2010-07-01 02:26:21 +00:00
$ignored = array ( 'CVS' , '_vti_cnf' , 'simpletest' , 'db' , 'yui' );
2009-07-24 04:05:39 +00:00
if ( $plugintype == 'auth' ) {
// Historically we have had an auth plugin called 'db', so allow a special case.
$key = array_search ( 'db' , $ignored );
if ( $key !== false ) {
unset ( $ignored [ $key ]);
}
}
2009-06-19 14:25:56 +00:00
if ( $plugintype === '' ) {
$plugintype = 'mod' ;
}
2009-12-16 18:00:58 +00:00
$fulldirs = array ();
2009-06-19 14:25:56 +00:00
if ( $plugintype === 'mod' ) {
2009-07-02 15:02:51 +00:00
// mod is an exception because we have to call this function from get_plugin_types()
2009-12-16 18:00:58 +00:00
$fulldirs [] = $CFG -> dirroot . '/mod' ;
} else if ( $plugintype === 'theme' ) {
$fulldirs [] = $CFG -> dirroot . '/theme' ;
2009-12-23 18:52:42 +00:00
// themes are special because they may be stored also in separate directory
if ( ! empty ( $CFG -> themedir ) and file_exists ( $CFG -> themedir ) and is_dir ( $CFG -> themedir ) ) {
$fulldirs [] = $CFG -> themedir ;
}
2009-06-19 14:25:56 +00:00
} else {
2009-12-16 18:00:58 +00:00
$types = get_plugin_types ( true );
2009-06-19 14:25:56 +00:00
if ( ! array_key_exists ( $plugintype , $types )) {
return array ();
}
2009-12-16 18:00:58 +00:00
$fulldir = $types [ $plugintype ];
2009-06-19 14:25:56 +00:00
if ( ! file_exists ( $fulldir )) {
return array ();
}
2009-12-16 18:00:58 +00:00
$fulldirs [] = $fulldir ;
2009-06-19 14:25:56 +00:00
}
$result = array ();
2009-12-16 18:00:58 +00:00
foreach ( $fulldirs as $fulldir ) {
if ( ! is_dir ( $fulldir )) {
2009-06-19 14:25:56 +00:00
continue ;
}
2009-12-16 18:00:58 +00:00
$items = new DirectoryIterator ( $fulldir );
foreach ( $items as $item ) {
if ( $item -> isDot () or ! $item -> isDir ()) {
continue ;
}
$pluginname = $item -> getFilename ();
if ( in_array ( $pluginname , $ignored )) {
continue ;
}
if ( $pluginname !== clean_param ( $pluginname , PARAM_SAFEDIR )) {
// better ignore plugins with problematic names here
continue ;
}
$result [ $pluginname ] = $fulldir . '/' . $pluginname ;
unset ( $item );
2009-06-19 14:25:56 +00:00
}
2009-12-16 18:00:58 +00:00
unset ( $items );
2009-06-19 14:25:56 +00:00
}
2010-07-13 13:56:55 +00:00
//TODO: implement better sorting once we migrated all plugin names to 'pluginname', ksort does not work for unicode, that is why we have to sort by the dir name, not the strings!
2009-06-19 14:25:56 +00:00
ksort ( $result );
return $result ;
}
/**
* Lists plugin - like directories within specified directory
2004-09-23 05:10:21 +00:00
*
2010-05-22 18:38:18 +00:00
* This function was originally used for standard Moodle plugins , please use
2009-06-19 14:25:56 +00:00
* new get_plugin_list () now .
*
2010-05-22 18:38:18 +00:00
* This function is used for general directory listing and backwards compatility .
2009-06-19 14:25:56 +00:00
*
2010-05-22 18:38:18 +00:00
* @ param string $directory relative directory from root
2006-01-04 08:23:42 +00:00
* @ 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 )
2009-06-19 14:25:56 +00:00
* @ return array Sorted array of directory names found under the requested parameters
2004-09-23 05:10:21 +00:00
*/
2009-06-19 14:25:56 +00:00
function get_list_of_plugins ( $directory = '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 )) {
2009-12-16 18:00:58 +00:00
$basedir = $CFG -> dirroot . '/' . $directory ;
2006-10-09 10:12:41 +00:00
2006-01-04 08:23:42 +00:00
} else {
2009-06-19 14:25:56 +00:00
$basedir = $basedir . '/' . $directory ;
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 );
2010-07-01 02:26:21 +00:00
if ( $firstchar == '.' or $dir == 'CVS' or $dir == '_vti_cnf' or $dir == 'simpletest' or $dir == 'yui' or $dir == $exclude ) {
2006-01-04 08:23:42 +00:00
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 ;
}
2009-07-24 02:44:44 +00:00
/**
* invoke plugin ' s callback functions
*
* @ param string $type Plugin type e . g . 'mod'
* @ param string $name Plugin name
* @ param string $feature Feature code ( FEATURE_xx constant )
* @ param string $action Feature ' s action
* @ param string $options parameters of callback function , should be an array
* @ param mixed $default default value if callback function hasn ' t been defined
* @ return mixed
*/
function plugin_callback ( $type , $name , $feature , $action , $options = null , $default = null ) {
global $CFG ;
$name = clean_param ( $name , PARAM_SAFEDIR );
$function = $name . '_' . $feature . '_' . $action ;
switch ( $type ) {
case 'mod' :
$file = $CFG -> dirroot . '/mod/' . $name . '/lib.php' ;
break ;
case 'block' :
// load block_base class
require_once ( $CFG -> dirroot . '/blocks/moodleblock.class.php' );
// block uses class based callback functions
// see blocks/moodleblock.class.php
$file = $CFG -> dirroot . '/blocks/' . $name . '/block_' . $name . '.php' ;
$function = array ( 'block_' . $name , 'comment_' . $action );
break ;
case 'moodle' :
// for special plugins, such as blog and tag
$file = $CFG -> dirroot . '/' . $name . '/lib.php' ;
break ;
default :
throw new Exception ( 'Unsupported callback type (' . $type . ')' );
}
// Load library and look for function
if ( file_exists ( $file )) {
require_once ( $file );
}
if ( is_array ( $function ) || function_exists ( $function )) {
// Function exists, so just return function result
2009-10-08 06:52:30 +00:00
$ret = call_user_func_array ( $function , ( array ) $options );
2009-07-24 02:44:44 +00:00
if ( is_null ( $ret )) {
return $default ;
} else {
return $ret ;
}
} else {
switch ( $feature ) {
// If some features can also be checked in other ways
// for legacy support, this could be added here
default : return $default ;
}
}
}
2008-07-28 12:31:29 +00:00
/**
* Checks whether a plugin supports a specified feature .
*
* @ param string $type Plugin type e . g . 'mod'
2010-07-03 19:05:08 +00:00
* @ param string $name Plugin name e . g . 'forum'
2008-07-28 12:31:29 +00:00
* @ param string $feature Feature code ( FEATURE_xx constant )
2008-08-27 20:22:33 +00:00
* @ param mixed $default default value if feature support unknown
* @ return mixed Feature result ( false if not supported , null if feature is unknown ,
2009-09-01 08:39:01 +00:00
* otherwise usually true but may have other feature - specific value such as array )
2008-07-28 12:31:29 +00:00
*/
2010-07-03 19:05:08 +00:00
function plugin_supports ( $type , $name , $feature , $default = NULL ) {
2008-07-28 12:31:29 +00:00
global $CFG ;
2008-08-27 20:22:33 +00:00
2009-09-01 08:39:01 +00:00
$name = clean_param ( $name , PARAM_SAFEDIR ); //bit of extra security
2008-08-27 20:22:33 +00:00
2010-07-03 19:05:08 +00:00
$function = null ;
2009-09-01 08:39:01 +00:00
if ( $type === 'mod' ) {
2009-12-16 18:00:58 +00:00
// we need this special case because we support subplugins in modules,
// otherwise it would end up in infinite loop
if ( $name === 'NEWMODULE' ) {
2010-07-03 19:06:50 +00:00
//somebody forgot to rename the module template
2009-12-16 18:00:58 +00:00
return false ;
}
2010-07-03 19:05:08 +00:00
if ( file_exists ( " $CFG->dirroot /mod/ $name /lib.php " )) {
include_once ( " $CFG->dirroot /mod/ $name /lib.php " );
$function = $type . '_' . $name . '_supports' ;
if ( ! function_exists ( $function )) {
// legacy non-frankenstyle function name
$function = $name . '_supports' ;
}
}
2008-07-28 12:31:29 +00:00
2010-07-03 19:05:08 +00:00
} else {
if ( ! $path = get_plugin_directory ( $type , $name )) {
// non existent plugin type
return false ;
}
if ( file_exists ( " $path /lib.php " )) {
include_once ( " $path /lib.php " );
$function = $type . '_' . $name . '_supports' ;
}
2008-08-27 20:22:33 +00:00
}
2009-09-01 08:39:01 +00:00
2010-07-03 19:05:08 +00:00
if ( $function and function_exists ( $function )) {
2008-08-27 20:22:33 +00:00
$supports = $function ( $feature );
if ( is_null ( $supports )) {
2009-12-16 18:00:58 +00:00
// plugin does not know - use default
2008-08-27 20:22:33 +00:00
return $default ;
} else {
return $supports ;
}
2008-07-28 12:31:29 +00:00
}
2009-09-01 08:39:01 +00:00
//plugin does not care, so use default
return $default ;
2008-07-28 12:31:29 +00:00
}
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
*
2009-05-22 02:57:43 +00:00
* @ todo Check PHP version being required here is it too low ?
*
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
*/
2008-08-01 09:44:37 +00:00
function check_php_version ( $version = '5.2.4' ) {
2005-05-09 17:24:03 +00:00
return ( version_compare ( phpversion (), $version ) >= 0 );
2002-08-23 02:14:19 +00:00
}
2008-06-18 05:58:06 +00:00
/**
2008-09-18 10:24:52 +00:00
* Checks to see if is the browser operating system matches the specified
2008-06-18 05:58:06 +00:00
* brand .
2008-09-18 10:24:52 +00:00
*
2008-06-18 05:58:06 +00:00
* Known brand : 'Windows' , 'Linux' , 'Macintosh' , 'SGI' , 'SunOS' , 'HP-UX'
*
* @ uses $_SERVER
2008-09-18 10:24:52 +00:00
* @ param string $brand The operating system identifier being tested
2008-06-18 05:58:06 +00:00
* @ return bool true if the given brand below to the detected operating system
*/
function check_browser_operating_system ( $brand ) {
if ( empty ( $_SERVER [ 'HTTP_USER_AGENT' ])) {
return false ;
}
if ( preg_match ( " / $brand /i " , $_SERVER [ 'HTTP_USER_AGENT' ])) {
return true ;
}
2008-09-18 10:24:52 +00:00
return false ;
2008-06-18 05:58:06 +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
2010-06-23 09:17:55 +00:00
if ( preg_match ( " /Camino \ /([0-9 \ .]+)/i " , $agent , $match )) {
if ( version_compare ( $match [ 1 ], $version ) >= 0 ) {
return true ;
2006-11-15 08:07:32 +00:00
}
2010-06-23 09:17:55 +00:00
}
break ;
2006-11-15 08:07:32 +00:00
2006-09-20 17:51:59 +00:00
case 'Firefox' : /// Mozilla Firefox browsers
2008-08-12 17:23:38 +00:00
if ( preg_match ( " /(Iceweasel|Firefox) \ /([0-9 \ .]+)/i " , $agent , $match )) {
if ( version_compare ( $match [ 2 ], $version ) >= 0 ) {
2006-09-20 17:51:59 +00:00
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
2010-06-23 09:17:55 +00:00
case 'Safari iOS' : /// Safari on iPhone and iPad
if ( strpos ( $agent , 'iPhone' )) {
return true ;
}
if ( strpos ( $agent , 'iPad' )) {
return true ;
}
break ;
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 ;
}
2009-02-10 15:33:25 +00:00
/**
* Returns one or several CSS class names that match the user ' s browser . These can be put
* in the body tag of the page to apply browser - specific rules without relying on CSS hacks
2009-05-22 02:57:43 +00:00
*
* @ return array An array of browser version classes
2009-02-10 15:33:25 +00:00
*/
function get_browser_version_classes () {
2009-05-06 08:44:58 +00:00
$classes = array ();
2009-02-10 15:33:25 +00:00
if ( check_browser_version ( " MSIE " , " 0 " )) {
2009-05-06 08:44:58 +00:00
$classes [] = 'ie' ;
2009-02-10 15:33:25 +00:00
if ( check_browser_version ( " MSIE " , 8 )) {
2009-05-06 08:44:58 +00:00
$classes [] = 'ie8' ;
2009-02-10 15:33:25 +00:00
} elseif ( check_browser_version ( " MSIE " , 7 )) {
2009-05-06 08:44:58 +00:00
$classes [] = 'ie7' ;
2009-02-10 15:33:25 +00:00
} elseif ( check_browser_version ( " MSIE " , 6 )) {
2009-05-06 08:44:58 +00:00
$classes [] = 'ie6' ;
2009-02-10 15:33:25 +00:00
}
2009-05-06 08:44:58 +00:00
} elseif ( check_browser_version ( " Firefox " , 0 ) || check_browser_version ( " Gecko " , 0 ) || check_browser_version ( " Camino " , 0 )) {
$classes [] = 'gecko' ;
2009-02-10 15:33:25 +00:00
if ( preg_match ( '/rv\:([1-2])\.([0-9])/' , $_SERVER [ 'HTTP_USER_AGENT' ], $matches )) {
2009-05-06 08:44:58 +00:00
$classes [] = " gecko { $matches [ 1 ] } { $matches [ 2 ] } " ;
2009-02-10 15:33:25 +00:00
}
} elseif ( check_browser_version ( " Safari " , 0 )) {
2009-05-06 08:44:58 +00:00
$classes [] = 'safari' ;
2009-02-10 15:33:25 +00:00
} elseif ( check_browser_version ( " Opera " , 0 )) {
2009-05-06 08:44:58 +00:00
$classes [] = 'opera' ;
2009-02-10 15:33:25 +00:00
}
return $classes ;
}
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 .
2009-05-22 02:57:43 +00:00
*
2004-09-23 05:10:21 +00:00
* 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
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ param string $ini_get_arg The argument to get
* @ return bool True for on false for not
2004-09-23 05:10:21 +00:00
*/
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 ;
}
2008-11-18 10:17:27 +00:00
/**
* Can handle rotated text . Whether it is safe to use the trickery in textrotate . js .
2009-05-22 02:57:43 +00:00
*
* @ return bool True for yes , false for no
2008-11-18 10:17:27 +00:00
*/
function can_use_rotated_text () {
global $USER ;
return ajaxenabled ( array ( 'Firefox' => 2.0 )) && ! $USER -> screenreader ;;
}
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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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 () {
2009-08-18 05:20:12 +00:00
global $CFG , $DB , $OUTPUT ;
2002-12-20 14:44:14 +00:00
2010-04-04 20:32:21 +00:00
if ( empty ( $CFG -> version )) {
return true ;
}
// main versio nfirst
2007-01-20 14:06:07 +00:00
$version = null ;
2010-04-04 20:32:21 +00:00
include ( $CFG -> dirroot . '/version.php' ); // defines $version and upgrades
if ( $version > $CFG -> version ) {
return true ;
}
// modules
$mods = get_plugin_list ( 'mod' );
$installed = $DB -> get_records ( 'modules' , array (), '' , 'name, version' );
foreach ( $mods as $mod => $fullmod ) {
if ( $mod === 'NEWMODULE' ) { // Someone has unzipped the template, ignore it
continue ;
}
$module = new object ();
if ( ! is_readable ( $fullmod . '/version.php' )) {
continue ;
}
include ( $fullmod . '/version.php' ); // defines $module with version etc
if ( empty ( $installed [ $mod ])) {
return true ;
} else if ( $module -> version > $installed [ $mod ] -> version ) {
2002-12-20 14:44:14 +00:00
return true ;
}
2010-04-04 20:32:21 +00:00
}
unset ( $installed );
// blocks
$blocks = get_plugin_list ( 'block' );
$installed = $DB -> get_records ( 'block' , array (), '' , 'name, version' );
require_once ( $CFG -> dirroot . '/blocks/moodleblock.class.php' );
foreach ( $blocks as $blockname => $fullblock ) {
if ( $blockname === 'NEWBLOCK' ) { // Someone has unzipped the template, ignore it
continue ;
}
2010-07-04 12:18:22 +00:00
if ( ! is_readable ( $fullblock . '/version.php' )) {
2010-04-04 20:32:21 +00:00
continue ;
}
2010-07-04 12:18:22 +00:00
$plugin = new object ();
$plugin -> version = NULL ;
include ( $fullblock . '/version.php' );
2010-04-04 20:32:21 +00:00
if ( empty ( $installed [ $blockname ])) {
return true ;
2010-07-04 12:18:22 +00:00
} else if ( $plugin -> version > $installed [ $blockname ] -> version ) {
2010-04-04 20:32:21 +00:00
return true ;
}
}
unset ( $installed );
// now the rest of plugins
$plugintypes = get_plugin_types ();
unset ( $plugintypes [ 'mod' ]);
unset ( $plugintypes [ 'block' ]);
foreach ( $plugintypes as $type => $unused ) {
$plugs = get_plugin_list ( $type );
foreach ( $plugs as $plug => $fullplug ) {
$component = $type . '_' . $plug ;
if ( ! is_readable ( $fullplug . '/version.php' )) {
2009-06-19 14:25:56 +00:00
continue ;
}
2010-04-04 20:32:21 +00:00
$plugin = new object ();
include ( $fullplug . '/version.php' ); // defines $plugin with version etc
$installedversion = get_config ( $component , 'version' );
if ( empty ( $installedversion )) { // new installation
return true ;
} else if ( $installedversion < $plugin -> version ) { // upgrade
return true ;
2002-12-20 14:44:14 +00:00
}
}
}
2010-04-04 20:32:21 +00:00
2002-12-20 14:44:14 +00:00
return false ;
}
2008-08-16 12:16:01 +00:00
/**
* Sets maximum expected time needed for upgrade task .
* Please always make sure that upgrade will not run longer !
*
2008-09-18 10:24:52 +00:00
* The script may be automatically aborted if upgrade times out .
2008-08-16 12:16:01 +00:00
*
2009-05-22 02:57:43 +00:00
* @ global object
2008-08-16 12:16:01 +00:00
* @ param int $max_execution_time in seconds ( can not be less than 60 s )
*/
function upgrade_set_timeout ( $max_execution_time = 300 ) {
global $CFG ;
if ( ! isset ( $CFG -> upgraderunning ) or $CFG -> upgraderunning < time ()) {
$upgraderunning = get_config ( null , 'upgraderunning' );
} else {
$upgraderunning = $CFG -> upgraderunning ;
2008-09-18 10:24:52 +00:00
}
2008-08-16 12:16:01 +00:00
if ( ! $upgraderunning ) {
// upgrade not running or aborted
print_error ( 'upgradetimedout' , 'admin' , " $CFG->wwroot / $CFG->admin / " );
die ;
}
if ( $max_execution_time < 60 ) {
// protection against 0 here
$max_execution_time = 60 ;
}
$expected_end = time () + $max_execution_time ;
if ( $expected_end < $upgraderunning + 10 and $expected_end > $upgraderunning - 10 ) {
// no need to store new end, it is nearly the same ;-)
return ;
}
set_time_limit ( $max_execution_time );
set_config ( 'upgraderunning' , $expected_end ); // keep upgrade locked until this time
}
2002-12-20 14:44:14 +00:00
/// 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
*
2009-05-22 02:57:43 +00:00
* @ global object
* @ global object
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 () {
2009-08-18 05:20:12 +00:00
global $CFG , $DB , $OUTPUT ;
2004-07-25 13:48:55 +00:00
2009-01-08 07:07:00 +00:00
$recip = get_users_from_config ( $CFG -> notifyloginfailures , 'moodle/site:config' );
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
2008-05-30 19:59:50 +00:00
$sql = " SELECT ip, COUNT(*)
FROM { log }
WHERE module = 'login' AND action = 'error'
AND time > ?
GROUP BY ip
HAVING COUNT ( * ) >= ? " ;
$params = array ( $CFG -> lastnotifyfailure , $CFG -> notifyloginthreshold );
if ( $rs = $DB -> get_recordset_sql ( $sql , $params )) {
foreach ( $rs as $iprec ) {
if ( ! empty ( $iprec -> ip )) {
set_cache_flag ( 'login_failure_by_ip' , $iprec -> ip , '1' , 0 );
}
2007-10-09 00:11:07 +00:00
}
2008-05-30 19:59:50 +00:00
$rs -> close ();
2007-10-09 00:11:07 +00:00
}
/// Get all the INFOs with more than notifyloginthreshold failures since lastnotifyfailure
/// and insert them into the cache_flags temp table
2008-05-30 19:59:50 +00:00
$sql = " SELECT info, count(*)
2008-06-05 20:35:28 +00:00
FROM { log }
2008-05-30 19:59:50 +00:00
WHERE module = 'login' AND action = 'error'
AND time > ?
GROUP BY info
HAVING count ( * ) >= ? " ;
$params = array ( $CFG -> lastnotifyfailure , $CFG -> notifyloginthreshold );
if ( $rs = $DB -> get_recordset_sql ( $sql , $params )) {
foreach ( $rs as $inforec ) {
if ( ! empty ( $inforec -> info )) {
set_cache_flag ( 'login_failure_by_info' , $inforec -> info , '1' , 0 );
}
2007-10-09 00:11:07 +00:00
}
2008-05-30 19:59:50 +00:00
$rs -> close ();
2007-10-09 00:11:07 +00:00
}
/// 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
2008-05-30 19:59:50 +00:00
$sql = " SELECT l.*, u.firstname, u.lastname
FROM { log } l
JOIN { cache_flags } cf ON l . ip = cf . name
LEFT JOIN { user } u ON l . userid = u . id
WHERE l . module = 'login' AND l . action = 'error'
AND l . time > ?
AND cf . flagtype = 'login_failure_by_ip'
UNION ALL
SELECT l .* , u . firstname , u . lastname
FROM { log } l
JOIN { cache_flags } cf ON l . info = cf . name
LEFT JOIN { user } u ON l . userid = u . id
WHERE l . module = 'login' AND l . action = 'error'
AND l . time > ?
AND cf . flagtype = 'login_failure_by_info'
ORDER BY time DESC " ;
$params = array ( $CFG -> lastnotifyfailure , $CFG -> lastnotifyfailure );
2007-10-09 00:11:07 +00:00
/// Init some variables
$count = 0 ;
$messages = '' ;
/// Iterate over the logs recordset
2008-05-30 19:59:50 +00:00
if ( $rs = $DB -> get_recordset_sql ( $sql , $params )) {
foreach ( $rs as $log ) {
$log -> time = userdate ( $log -> time );
$messages .= get_string ( 'notifyloginfailuresmessage' , '' , $log ) . " \n " ;
$count ++ ;
}
$rs -> close ();
2007-10-09 00:11:07 +00:00
}
/// 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
2010-03-18 22:00:09 +00:00
mtrace ( 'Emailing admins about ' . $count . ' failed login attempts' );
2007-10-09 00:11:07 +00:00
foreach ( $recip as $admin ) {
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
2008-05-30 19:59:50 +00:00
$DB -> 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
/**
2009-05-22 02:57:43 +00:00
* Sets the system locale
2004-09-23 05:10:21 +00:00
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ param string $locale Can be used to force a locale
2004-09-23 05:10:21 +00:00
*/
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
MDL-22050 removing moodle/langconfig duplicates
AMOS BEGIN
MOV [locale,core],[locale,core_langconfig]
MOV [localewin,core],[localewin,core_langconfig]
MOV [localewincharset,core],[localewincharset,core_langconfig]
MOV [oldcharset,core],[oldcharset,core_langconfig]
AMOS END
2010-04-10 17:54:39 +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 {
MDL-22050 removing moodle/langconfig duplicates
AMOS BEGIN
MOV [locale,core],[locale,core_langconfig]
MOV [localewin,core],[localewin,core_langconfig]
MOV [localewincharset,core],[localewincharset,core_langconfig]
MOV [oldcharset,core],[oldcharset,core_langconfig]
AMOS END
2010-04-10 17:54:39 +00:00
$currentlocale = get_string ( $stringtofetch , 'langconfig' );
2006-07-30 10:39:21 +00:00
}
/// 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 .
*
2009-05-22 02:57:43 +00:00
* @ todo Remove this function when no longer in use
* @ deprecated Use textlib -> strtolower ( $text ) instead .
*
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
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
2009-06-22 01:22:37 +00:00
$string = preg_replace ( '/[[:space:]]*/' , '' , $string ); //Whitespace are out now
2006-01-04 08:23:42 +00:00
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 ;
}
2009-11-17 16:11:25 +00:00
/**
2010-05-22 18:38:18 +00:00
* Generate a complex random string ( useful for md5 salts )
2009-11-17 16:11:25 +00:00
*
* This function is based on the above { @ link random_string ()} however it uses a
* larger pool of characters and generates a string between 24 and 32 characters
*
* @ param int $length Optional if set generates a string to exactly this length
* @ return string
*/
function complex_random_string ( $length = null ) {
$pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' ;
$pool .= '`~!@#%^&*()_+-=[];,./<>?:{} ' ;
$poollen = strlen ( $pool );
mt_srand (( double ) microtime () * 1000000 );
if ( $length === null ) {
$length = floor ( rand ( 24 , 32 ));
}
$string = '' ;
for ( $i = 0 ; $i < $length ; $i ++ ) {
$string .= $pool [( mt_rand () % $poollen )];
}
return $string ;
}
2008-05-30 19:59:50 +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
2009-05-22 02:57:43 +00:00
*
* @ global object
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
2009-05-22 02:57:43 +00:00
* @ param string $ending The string to append if the passed string is truncated
2008-05-30 19:59:50 +00:00
* @ return string $truncate - shortened string
2005-04-14 17:03:11 +00:00
*/
2009-01-19 06:19:26 +00:00
function shorten_text ( $text , $ideal = 30 , $exact = false , $ending = '...' ) {
2005-04-14 17:03:11 +00:00
2007-12-04 05:10:12 +00:00
global $CFG ;
// if the plain text is shorter than the maximum length, return the whole text
if ( strlen ( preg_replace ( '/<.*?>/' , '' , $text )) <= $ideal ) {
return $text ;
}
2008-05-30 19:59:50 +00:00
2009-10-19 17:13:50 +00:00
// Splits on HTML tags. Each open/close/empty tag will be the first thing
// and only tag in its 'line'
2007-12-04 05:10:12 +00:00
preg_match_all ( '/(<.+?>)?([^<>]*)/s' , $text , $lines , PREG_SET_ORDER );
$total_length = strlen ( $ending );
$truncate = '' ;
2009-10-19 17:13:50 +00:00
// This array stores information about open and close tags and their position
// in the truncated string. Each item in the array is an object with fields
2009-11-01 11:31:16 +00:00
// ->open (true if open), ->tag (tag name in lower case), and ->pos
2009-10-19 17:13:50 +00:00
// (byte position in truncated text)
$tagdetails = array ();
2007-12-04 05:10:12 +00:00
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 )) {
2009-10-19 17:13:50 +00:00
// record closing tag
2009-11-01 11:31:16 +00:00
$tagdetails [] = ( object ) array ( 'open' => false ,
2009-10-19 17:13:50 +00:00
'tag' => strtolower ( $tag_matchings [ 1 ]), 'pos' => strlen ( $truncate ));
2007-12-04 05:10:12 +00:00
// if tag is an opening tag (f.e. <b>)
} else if ( preg_match ( '/^<\s*([^\s>!]+).*?>$/s' , $line_matchings [ 1 ], $tag_matchings )) {
2009-10-19 17:13:50 +00:00
// record opening tag
2009-11-01 11:31:16 +00:00
$tagdetails [] = ( object ) array ( 'open' => true ,
2009-10-19 17:13:50 +00:00
'tag' => strtolower ( $tag_matchings [ 1 ]), 'pos' => strlen ( $truncate ));
2007-12-04 05:10:12 +00:00
}
// 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 );
2010-05-22 18:38:18 +00:00
// maximum length is reached, so get off the loop
2007-12-04 05:10:12 +00:00
break ;
} else {
$truncate .= $line_matchings [ 2 ];
$total_length += $content_length ;
}
2008-05-30 19:59:50 +00:00
2007-12-04 05:10:12 +00:00
// 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 ) {
2010-05-22 18:38:18 +00:00
// ...search the last occurence of a space...
2009-07-30 15:16:53 +00:00
for ( $k = strlen ( $truncate ); $k > 0 ; $k -- ) {
2007-12-04 05:10:12 +00:00
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.
}
}
2009-07-30 15:16:53 +00:00
}
2008-05-30 19:59:50 +00:00
2009-07-30 15:16:53 +00:00
if ( isset ( $breakpos )) {
2007-12-04 05:10:12 +00:00
// ...and cut the text in this position
$truncate = substr ( $truncate , 0 , $breakpos );
2009-07-30 15:16:53 +00:00
}
}
2005-04-14 17:03:11 +00:00
2007-12-04 05:10:12 +00:00
// add the defined ending to the text
2009-07-30 15:16:53 +00:00
$truncate .= $ending ;
2005-04-14 17:03:11 +00:00
2009-10-19 17:13:50 +00:00
// Now calculate the list of open html tags based on the truncate position
$open_tags = array ();
foreach ( $tagdetails as $taginfo ) {
if ( isset ( $breakpos ) && $taginfo -> pos >= $breakpos ) {
// Don't include tags after we made the break!
break ;
}
if ( $taginfo -> open ) {
// add tag to the beginning of $open_tags list
array_unshift ( $open_tags , $taginfo -> tag );
} else {
$pos = array_search ( $taginfo -> tag , array_reverse ( $open_tags , true )); // can have multiple exact same open tags, close the last one
if ( $pos !== false ) {
unset ( $open_tags [ $pos ]);
}
}
}
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
2009-07-30 15:16:53 +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 ...
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function
*
2004-09-29 18:56:50 +00:00
* @ uses WEEKSECS
2009-05-22 02:57:43 +00:00
* @ param int $startdate Timestamp for the start date
* @ param int $thedate Timestamp for the end date
2004-09-25 01:29:37 +00:00
* @ return string
2004-09-23 05:10:21 +00:00
*/
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
2009-05-22 02:57:43 +00:00
*
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
*
2009-05-22 02:57:43 +00:00
* @ global object
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
*
2010-05-22 18:38:18 +00:00
* @ param float $float 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 ) {
2010-04-10 17:40:58 +00:00
return number_format ( $float , $decimalpoints , get_string ( 'decsep' , 'langconfig' ), '' );
2007-09-27 09:58:40 +00:00
} 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
2009-05-22 02:57:43 +00:00
* @ return float
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
2010-04-10 17:40:58 +00:00
return ( float ) str_replace ( get_string ( 'decsep' , 'langconfig' ), '.' , $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 .
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ param array $array
* @ param int $draws
* @ return array
2004-09-23 05:10:21 +00:00
*/
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
/**
2009-05-22 02:57:43 +00:00
* Calculate the difference between two microtimes
2004-09-23 05:10:21 +00:00
*
2009-05-22 02:57:43 +00:00
* @ param string $a The first Microtime
* @ param string $b The second Microtime
2004-09-25 01:29:37 +00:00
* @ return string
2004-09-23 05:10:21 +00:00
*/
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
*
2009-05-22 02:57:43 +00:00
* @ param string $list The string to explode into array bits
2010-05-22 18:38:18 +00:00
* @ param string $separator The separator used within the list string
2009-05-22 02:57:43 +00:00
* @ return array The now assembled array
2004-09-23 05:10:21 +00:00
*/
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
2009-09-01 08:39:01 +00:00
* can be chosen using the given grading type .
2009-05-22 02:57:43 +00:00
*
* Negative numbers
2004-09-23 05:10:21 +00:00
* are scales , zero is no grade , and positive numbers are maximum
* grades .
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ param int $gradingtype
* @ return int
2004-09-23 05:10:21 +00:00
*/
2003-08-18 05:10:35 +00:00
function make_grades_menu ( $gradingtype ) {
2008-05-30 19:59:50 +00:00
global $DB ;
2003-08-18 05:10:35 +00:00
$grades = array ();
if ( $gradingtype < 0 ) {
2008-05-30 19:59:50 +00:00
if ( $scale = $DB -> get_record ( 'scale' , array ( '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
/**
2010-05-22 18:38:18 +00:00
* This function returns the number of activities
2004-09-23 05:10:21 +00:00
* using scaleid in a courseid
*
2009-05-22 02:57:43 +00:00
* @ todo Finish documenting this function
*
* @ global object
* @ global object
2004-09-25 01:29:37 +00:00
* @ param int $courseid ?
* @ param int $scaleid ?
* @ return int
2004-09-23 05:10:21 +00:00
*/
2004-09-25 01:29:37 +00:00
function course_scale_used ( $courseid , $scaleid ) {
2008-05-30 19:59:50 +00:00
global $CFG , $DB ;
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
2008-05-30 19:59:50 +00:00
$return += $DB -> count_records ( 'grade_items' , array ( 'courseid' => $courseid , 'scaleid' => $scaleid ));
2008-02-03 16:40:34 +00:00
// check if any outcome in the course makes use of the scale
2008-05-30 19:59:50 +00:00
$return += $DB -> count_records_sql ( " SELECT COUNT('x')
FROM { grade_outcomes_courses } goc ,
{ grade_outcomes } go
WHERE go . id = goc . outcomeid
AND go . scaleid = ? AND goc . courseid = ? " ,
array ( $scaleid , $courseid ));
2004-05-16 00:36:00 +00:00
}
return $return ;
}
2004-09-23 05:10:21 +00:00
/**
2010-05-22 18:38:18 +00:00
* This function returns the number of activities
2004-09-23 05:10:21 +00:00
* using scaleid in the entire site
*
2009-05-22 02:57:43 +00:00
* @ param int $scaleid
* @ param array $courses
2004-09-25 01:29:37 +00:00
* @ return int
2004-09-23 05:10:21 +00:00
*/
2008-05-30 19:59:50 +00:00
function site_scale_used ( $scaleid , & $courses ) {
2004-05-16 00:36:00 +00:00
$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
*
* @ todo Finish documenting this function
2009-05-22 02:57:43 +00:00
*
* @ uses $_SERVER
* @ param string $extra Extra string to append to the end of the code
* @ return string
2004-09-23 05:10:21 +00:00
*/
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 :
2009-01-09 21:16:26 +00:00
* 1 : xxx . xxx . xxx . xxx / nn or xxxx : xxxx : xxxx : xxxx : xxxx : xxxx : xxxx / nnn ( number of bits in net mask )
* 2 : xxx . xxx . xxx . xxx - yyy or xxxx : xxxx : xxxx : xxxx : xxxx : xxxx : xxxx :: xxxx - yyyy ( a range of IP addresses in the last group )
* 3 : xxx . xxx or xxx . xxx . or xxx : xxx : xxxx or xxx : xxx : xxxx . ( incomplete address , a bit non - technical ; - )
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 ) {
2010-05-20 02:36:20 +00:00
if ( $addr == '0.0.0.0' ) {
return false ;
}
2004-09-22 14:39:15 +00:00
$subnets = explode ( ',' , $subnetstr );
2004-07-08 07:52:01 +00:00
$found = false ;
$addr = trim ( $addr );
2009-01-09 21:16:26 +00:00
$addr = cleanremoteaddr ( $addr , false ); // normalise
if ( $addr === null ) {
return false ;
}
$addrparts = explode ( ':' , $addr );
$ipv6 = strpos ( $addr , ':' );
2004-07-08 07:52:01 +00:00
foreach ( $subnets as $subnet ) {
$subnet = trim ( $subnet );
2009-01-09 21:16:26 +00:00
if ( $subnet === '' ) {
continue ;
}
if ( strpos ( $subnet , '/' ) !== false ) {
///1: xxx.xxx.xxx.xxx/nn or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/nnn
2004-07-08 07:52:01 +00:00
list ( $ip , $mask ) = explode ( '/' , $subnet );
2009-01-09 21:16:26 +00:00
$mask = trim ( $mask );
if ( ! is_number ( $mask )) {
continue ; // incorect mask number, eh?
}
$ip = cleanremoteaddr ( $ip , false ); // normalise
if ( $ip === null ) {
continue ;
2008-09-01 04:17:11 +00:00
}
2009-01-09 21:16:26 +00:00
if ( strpos ( $ip , ':' ) !== false ) {
// IPv6
if ( ! $ipv6 ) {
continue ;
}
if ( $mask > 128 or $mask < 0 ) {
continue ; // nonsense
}
if ( $mask == 0 ) {
return true ; // any address
}
if ( $mask == 128 ) {
if ( $ip === $addr ) {
return true ;
}
continue ;
}
$ipparts = explode ( ':' , $ip );
$modulo = $mask % 16 ;
$ipnet = array_slice ( $ipparts , 0 , ( $mask - $modulo ) / 16 );
$addrnet = array_slice ( $addrparts , 0 , ( $mask - $modulo ) / 16 );
if ( implode ( ':' , $ipnet ) === implode ( ':' , $addrnet )) {
if ( $modulo == 0 ) {
return true ;
}
$pos = ( $mask - $modulo ) / 16 ;
$ipnet = hexdec ( $ipparts [ $pos ]);
$addrnet = hexdec ( $addrparts [ $pos ]);
$mask = 0xffff << ( 16 - $modulo );
if (( $addrnet & $mask ) == ( $ipnet & $mask )) {
return true ;
}
}
} else {
// IPv4
if ( $ipv6 ) {
continue ;
}
if ( $mask > 32 or $mask < 0 ) {
continue ; // nonsense
}
if ( $mask == 0 ) {
return true ;
}
if ( $mask == 32 ) {
if ( $ip === $addr ) {
return true ;
}
continue ;
}
$mask = 0xffffffff << ( 32 - $mask );
if ((( ip2long ( $addr ) & $mask ) == ( ip2long ( $ip ) & $mask ))) {
return true ;
}
2006-10-16 13:38:36 +00:00
}
2009-01-09 21:16:26 +00:00
} else if ( strpos ( $subnet , '-' ) !== false ) {
/// 2: xxx.xxx.xxx.xxx-yyy or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::xxxx-yyyy ...a range of IP addresses in the last group.
$parts = explode ( '-' , $subnet );
if ( count ( $parts ) != 2 ) {
continue ;
2008-09-01 04:17:11 +00:00
}
2004-07-08 07:52:01 +00:00
2009-01-09 21:16:26 +00:00
if ( strpos ( $subnet , ':' ) !== false ) {
// IPv6
if ( ! $ipv6 ) {
continue ;
}
$ipstart = cleanremoteaddr ( trim ( $parts [ 0 ]), false ); // normalise
if ( $ipstart === null ) {
continue ;
}
$ipparts = explode ( ':' , $ipstart );
$start = hexdec ( array_pop ( $ipparts ));
$ipparts [] = trim ( $parts [ 1 ]);
$ipend = cleanremoteaddr ( implode ( ':' , $ipparts ), false ); // normalise
if ( $ipend === null ) {
continue ;
}
$ipparts [ 7 ] = '' ;
$ipnet = implode ( ':' , $ipparts );
if ( strpos ( $addr , $ipnet ) !== 0 ) {
continue ;
}
$ipparts = explode ( ':' , $ipend );
$end = hexdec ( $ipparts [ 7 ]);
$addrend = hexdec ( $addrparts [ 7 ]);
if (( $addrend >= $start ) and ( $addrend <= $end )) {
return true ;
}
} else {
// IPv4
if ( $ipv6 ) {
continue ;
}
$ipstart = cleanremoteaddr ( trim ( $parts [ 0 ]), false ); // normalise
if ( $ipstart === null ) {
continue ;
}
$ipparts = explode ( '.' , $ipstart );
$ipparts [ 3 ] = trim ( $parts [ 1 ]);
$ipend = cleanremoteaddr ( implode ( '.' , $ipparts ), false ); // normalise
if ( $ipend === null ) {
continue ;
}
if (( ip2long ( $addr ) >= ip2long ( $ipstart )) and ( ip2long ( $addr ) <= ip2long ( $ipend ))) {
return true ;
}
}
} else {
/// 3: xxx.xxx or xxx.xxx. or xxx:xxx:xxxx or xxx:xxx:xxxx.
if ( strpos ( $subnet , ':' ) !== false ) {
// IPv6
if ( ! $ipv6 ) {
continue ;
}
$parts = explode ( ':' , $subnet );
$count = count ( $parts );
if ( $parts [ $count - 1 ] === '' ) {
unset ( $parts [ $count - 1 ]); // trim trailing :
$count -- ;
$subnet = implode ( '.' , $parts );
}
$isip = cleanremoteaddr ( $subnet , false ); // normalise
if ( $isip !== null ) {
if ( $isip === $addr ) {
return true ;
}
continue ;
} else if ( $count > 8 ) {
continue ;
}
$zeros = array_fill ( 0 , 8 - $count , '0' );
$subnet = $subnet . ':' . implode ( ':' , $zeros ) . '/' . ( $count * 16 );
if ( address_in_subnet ( $addr , $subnet )) {
return true ;
}
} else {
// IPv4
if ( $ipv6 ) {
continue ;
}
$parts = explode ( '.' , $subnet );
$count = count ( $parts );
if ( $parts [ $count - 1 ] === '' ) {
unset ( $parts [ $count - 1 ]); // trim trailing .
$count -- ;
$subnet = implode ( '.' , $parts );
}
if ( $count == 4 ) {
$subnet = cleanremoteaddr ( $subnet , false ); // normalise
if ( $subnet === $addr ) {
return true ;
}
continue ;
} else if ( $count > 4 ) {
continue ;
}
$zeros = array_fill ( 0 , 4 - $count , '0' );
$subnet = $subnet . '.' . implode ( '.' , $zeros ) . '/' . ( $count * 8 );
if ( address_in_subnet ( $addr , $subnet )) {
return true ;
}
}
2004-07-08 07:52:01 +00:00
}
}
2009-01-09 21:16:26 +00:00
return false ;
2004-07-08 07:52:01 +00:00
}
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 () {
2009-07-01 05:54:26 +00:00
global $PAGE ;
$PAGE -> https_required ();
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
2009-05-22 02:57:43 +00:00
* @ param string $string The string to write
* @ param string $eol The end of line char ( s ) to use
* @ param string $sleep Period to make the application sleep
* This ensures any messages have time to display before redirect
2004-09-23 05:10:21 +00:00
*/
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
}
2009-05-22 02:57:43 +00:00
/**
* Replace 1 or more slashes or backslashes to 1 slash
*
* @ param string $path The path to strip
* @ return string the path with double slashes removed
*/
2004-10-08 06:11:17 +00:00
function cleardoubleslashes ( $path ) {
return preg_replace ( '/(\/|\\\){1,}/' , '/' , $path );
}
2008-07-25 08:27:50 +00:00
/**
* Is current ip in give list ?
2009-05-22 02:57:43 +00:00
*
2008-07-25 08:27:50 +00:00
* @ param string $list
* @ return bool
*/
function remoteip_in_list ( $list ){
$inlist = false ;
2010-05-20 02:36:20 +00:00
$client_ip = getremoteaddr ( null );
2010-03-21 15:03:26 +00:00
if ( ! $client_ip ){
// ensure access on cli
return true ;
}
2008-07-25 08:27:50 +00:00
$list = explode ( " \n " , $list );
foreach ( $list as $subnet ) {
$subnet = trim ( $subnet );
if ( address_in_subnet ( $client_ip , $subnet )) {
$inlist = true ;
break ;
2008-09-18 10:24:52 +00:00
}
2008-07-25 08:27:50 +00:00
}
return $inlist ;
}
2004-09-23 05:10:21 +00:00
/**
* Returns most reliable client address
2004-11-22 18:38:33 +00:00
*
2009-05-22 02:57:43 +00:00
* @ global object
2010-05-20 02:36:20 +00:00
* @ param string $default If an address can ' t be determined , then return this
2004-09-25 01:29:37 +00:00
* @ return string The remote IP address
2004-09-23 05:10:21 +00:00
*/
2010-05-20 02:36:20 +00:00
function getremoteaddr ( $default = '0.0.0.0' ) {
2008-09-18 08:18:58 +00:00
global $CFG ;
2008-09-23 05:18:42 +00:00
if ( empty ( $CFG -> getremoteaddrconf )) {
// This will happen, for example, before just after the upgrade, as the
// user is redirected to the admin screen.
$variablestoskip = 0 ;
} else {
$variablestoskip = $CFG -> getremoteaddrconf ;
}
if ( ! ( $variablestoskip & GETREMOTEADDR_SKIP_HTTP_CLIENT_IP )) {
if ( ! empty ( $_SERVER [ 'HTTP_CLIENT_IP' ])) {
2010-05-20 02:36:20 +00:00
$address = cleanremoteaddr ( $_SERVER [ 'HTTP_CLIENT_IP' ]);
return $address ? $address : $default ;
2008-09-23 05:18:42 +00:00
}
}
if ( ! ( $variablestoskip & GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR )) {
if ( ! empty ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ])) {
2010-05-20 02:36:20 +00:00
$address = cleanremoteaddr ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]);
return $address ? $address : $default ;
2008-09-23 05:18:42 +00:00
}
2005-04-01 07:40:07 +00:00
}
2008-12-11 05:18:17 +00:00
if ( ! empty ( $_SERVER [ 'REMOTE_ADDR' ])) {
2010-05-20 02:36:20 +00:00
$address = cleanremoteaddr ( $_SERVER [ 'REMOTE_ADDR' ]);
return $address ? $address : $default ;
2008-12-11 05:18:17 +00:00
} else {
2010-05-20 02:36:20 +00:00
return $default ;
2008-12-11 05:18:17 +00:00
}
2004-11-22 18:38:33 +00:00
}
2004-08-05 17:08:46 +00:00
2006-03-04 16:53:02 +00:00
/**
2009-01-06 22:18:01 +00:00
* Cleans an ip address . Internal addresses are now allowed .
* ( Originally local addresses were not allowed . )
*
* @ param string $addr IPv4 or IPv6 address
* @ param bool $compress use IPv6 address compression
* @ return string normalised ip address string , null if error
2005-08-18 01:44:47 +00:00
*/
2009-01-06 22:18:01 +00:00
function cleanremoteaddr ( $addr , $compress = false ) {
$addr = trim ( $addr );
//TODO: maybe add a separate function is_addr_public() or something like this
if ( strpos ( $addr , ':' ) !== false ) {
// can be only IPv6
$parts = explode ( ':' , $addr );
$count = count ( $parts );
if ( strpos ( $parts [ $count - 1 ], '.' ) !== false ) {
//legacy ipv4 notation
$last = array_pop ( $parts );
$ipv4 = cleanremoteaddr ( $last , true );
if ( $ipv4 === null ) {
return null ;
}
$bits = explode ( '.' , $ipv4 );
$parts [] = dechex ( $bits [ 0 ]) . dechex ( $bits [ 1 ]);
$parts [] = dechex ( $bits [ 2 ]) . dechex ( $bits [ 3 ]);
$count = count ( $parts );
$addr = implode ( ':' , $parts );
2005-09-08 23:04:23 +00:00
}
2009-01-06 22:18:01 +00:00
if ( $count < 3 or $count > 8 ) {
return null ; // severly malformed
2005-09-08 23:04:23 +00:00
}
2009-01-06 22:18:01 +00:00
if ( $count != 8 ) {
if ( strpos ( $addr , '::' ) === false ) {
return null ; // malformed
}
// uncompress ::
$insertat = array_search ( '' , $parts , true );
$missing = array_fill ( 0 , 1 + 8 - $count , '0' );
array_splice ( $parts , $insertat , 1 , $missing );
foreach ( $parts as $key => $part ) {
if ( $part === '' ) {
$parts [ $key ] = '0' ;
}
}
}
$adr = implode ( ':' , $parts );
if ( ! preg_match ( '/^([0-9a-f]{1,4})(:[0-9a-f]{1,4})*$/i' , $adr )) {
return null ; // incorrect format - sorry
}
// normalise 0s and case
$parts = array_map ( 'hexdec' , $parts );
$parts = array_map ( 'dechex' , $parts );
$result = implode ( ':' , $parts );
2009-01-09 10:16:07 +00:00
if ( ! $compress ) {
return $result ;
}
if ( $result === '0:0:0:0:0:0:0:0' ) {
return '::' ; // all addresses
}
$compressed = preg_replace ( '/(:0)+:0$/' , '::' , $result , 1 );
if ( $compressed !== $result ) {
return $compressed ;
}
$compressed = preg_replace ( '/^(0:){2,7}/' , '::' , $result , 1 );
if ( $compressed !== $result ) {
return $compressed ;
}
$compressed = preg_replace ( '/(:0){2,6}:/' , '::' , $result , 1 );
if ( $compressed !== $result ) {
return $compressed ;
2005-09-08 23:04:23 +00:00
}
2009-01-06 22:18:01 +00:00
return $result ;
2006-03-04 16:53:02 +00:00
}
2009-01-06 22:18:01 +00:00
// first get all things that look like IPv4 addresses
$parts = array ();
if ( ! preg_match ( '/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/' , $addr , $parts )) {
return null ;
}
unset ( $parts [ 0 ]);
2009-02-01 13:36:07 +00:00
2009-01-06 22:18:01 +00:00
foreach ( $parts as $key => $match ) {
if ( $match > 255 ) {
return null ;
}
$parts [ $key ] = ( int ) $match ; // normalise 0s
2005-09-08 23:04:23 +00:00
}
2008-02-20 07:02:14 +00:00
2009-01-06 22:18:01 +00:00
return implode ( '.' , $parts );
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 .
2009-05-22 02:57:43 +00:00
*
* @ param mixed $thing Something you want cloned
* @ return mixed What ever it is you passed it
2006-04-26 04:39:34 +00:00
*/
function fullclone ( $thing ) {
return unserialize ( serialize ( $thing ));
}
2008-05-30 19:59:50 +00:00
/**
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
*
2009-05-22 02:57:43 +00:00
* @ global object
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
}
2010-06-30 06:35:47 +00:00
/**
* If new messages are waiting for the current user , then insert
* JavaScript to pop up the messaging window into the page
*
* @ global moodle_page $PAGE
* @ return void
*/
2004-12-30 12:54:22 +00:00
function message_popup_window () {
2010-06-29 07:02:28 +00:00
global $USER , $DB , $PAGE , $CFG , $SITE ;
2004-12-30 12:54:22 +00:00
2009-06-26 09:06:16 +00:00
if ( defined ( 'MESSAGE_WINDOW' ) || empty ( $CFG -> messaging )) {
return ;
}
2010-06-29 03:08:27 +00:00
if ( ! isloggedin () || isguestuser ()) {
2009-06-26 09:06:16 +00:00
return ;
}
if ( ! isset ( $USER -> message_lastpopup )) {
$USER -> message_lastpopup = 0 ;
}
2010-06-30 03:29:02 +00:00
$message_users = null ;
2004-12-30 12:54:22 +00:00
2010-06-30 03:29:02 +00:00
$sql = " SELECT m.id, u.firstname, u.lastname FROM { message} m
2010-06-29 03:08:27 +00:00
JOIN { message_working } mw ON m . id = mw . unreadmessageid
JOIN { message_processors } p ON mw . processorid = p . id
2010-06-30 03:29:02 +00:00
JOIN { user } u ON m . useridfrom = u . id
2010-06-29 03:08:27 +00:00
WHERE m . useridto = : userid AND m . timecreated > : ts AND p . name = 'popup' " ;
2010-06-30 03:29:02 +00:00
$message_users = $DB -> get_records_sql ( $sql , array ( 'userid' => $USER -> id , 'ts' => $USER -> message_lastpopup ));
if ( empty ( $message_users )) {
//if the user was last notified over an hour ago remind them of any new messages regardless of when they were sent
$canrenotify = ( time () - $USER -> message_lastpopup ) > 3600 ;
if ( $canrenotify ) {
$sql = " SELECT m.id, u.firstname, u.lastname FROM { message} m
JOIN { message_working } mw ON m . id = mw . unreadmessageid
JOIN { message_processors } p ON mw . processorid = p . id
JOIN { user } u ON m . useridfrom = u . id
WHERE m . useridto = : userid AND p . name = 'popup' " ;
$message_users = $DB -> get_records_sql ( $sql , array ( 'userid' => $USER -> id ));
}
}
2010-06-29 07:02:28 +00:00
2010-06-30 03:29:02 +00:00
//if we have new messages to notify the user about
if ( ! empty ( $message_users )) {
$strmessages = '' ;
if ( count ( $message_users ) > 1 ) {
$strmessages = get_string ( 'unreadnewmessages' , 'message' , count ( $message_users ));
} else {
$strmessages = get_string ( 'unreadnewmessage' , 'message' , fullname ( reset ( $message_users )) );
}
2010-07-03 19:05:08 +00:00
2010-06-29 07:02:28 +00:00
$strgomessage = get_string ( 'gotomessages' , 'message' );
$strstaymessage = get_string ( 'ignore' , 'admin' );
2010-06-30 03:29:02 +00:00
$url = $CFG -> wwwroot . '/message/index.php' ;
$content = html_writer :: start_tag ( 'div' , array ( 'id' => 'newmessageoverlay' , 'class' => 'mdl-align' )) .
html_writer :: start_tag ( 'div' , array ( 'id' => 'newmessagetext' )) .
2010-06-29 07:02:28 +00:00
$strmessages .
html_writer :: end_tag ( 'div' ) .
2010-06-30 03:29:02 +00:00
html_writer :: start_tag ( 'div' , array ( 'id' => 'newmessagelinks' )) .
html_writer :: link ( $url , $strgomessage , array ( 'id' => 'notificationyes' )) . ' ' .
html_writer :: link ( '' , $strstaymessage , array ( 'id' => 'notificationno' )) .
html_writer :: end_tag ( 'div' );
2010-06-29 07:02:28 +00:00
html_writer :: end_tag ( 'div' );
$PAGE -> requires -> js_init_call ( 'M.core_message.init_notification' , array ( '' , $content , $url ));
2004-12-30 12:54:22 +00:00
2009-06-26 09:06:16 +00:00
$USER -> message_lastpopup = time ();
}
2004-12-30 12:54:22 +00:00
}
2009-05-22 02:57:43 +00:00
/**
* Used to make sure that $min <= $value <= $max
*
* Make sure that value is between min , and max
*
* @ param int $min The minimum value
* @ param int $value The value to check
* @ param int $max The maximum value
*/
2005-02-02 02:22:56 +00:00
function bounded_number ( $min , $value , $max ) {
if ( $value < $min ) {
return $min ;
}
if ( $value > $max ) {
return $max ;
}
return $value ;
}
2009-05-22 02:57:43 +00:00
/**
* Check if there is a nested array within the passed array
*
* @ param array $array
* @ return bool true if there is a nested array false otherwise
*/
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
/**
2009-05-22 02:57:43 +00:00
* get_performance_info () pairs up with init_performance_info ()
* loaded in setup . php . Returns an array with 'html' and 'txt'
* values ready for use , and each of the individual stats provided
* separately as well .
*
* @ global object
* @ global object
* @ global object
* @ return array
*/
2005-04-06 07:34:05 +00:00
function get_performance_info () {
2008-06-16 21:01:54 +00:00
global $CFG , $PERF , $DB ;
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' ] . ' ' ;
2009-04-13 06:56:32 +00:00
$filtermanager = filter_manager :: instance ();
if ( method_exists ( $filtermanager , 'get_performance_summary' )) {
list ( $filterinfo , $nicenames ) = $filtermanager -> get_performance_summary ();
$info = array_merge ( $filterinfo , $info );
foreach ( $filterinfo as $key => $value ) {
$info [ 'html' ] .= " <span class=' $key '> $nicenames[$key] : $value </span> " ;
$info [ 'txt' ] .= " $key : $value " ;
}
}
2010-05-16 11:45:33 +00:00
$stringmanager = get_string_manager ();
if ( method_exists ( $stringmanager , 'get_performance_summary' )) {
list ( $filterinfo , $nicenames ) = $stringmanager -> get_performance_summary ();
$info = array_merge ( $filterinfo , $info );
foreach ( $filterinfo as $key => $value ) {
$info [ 'html' ] .= " <span class=' $key '> $nicenames[$key] : $value </span> " ;
$info [ 'txt' ] .= " $key : $value " ;
}
}
2005-04-06 07:34:05 +00:00
if ( ! empty ( $PERF -> logwrites )) {
$info [ 'logwrites' ] = $PERF -> logwrites ;
2008-06-16 21:01:54 +00:00
$info [ 'html' ] .= '<span class="logwrites">Log DB writes ' . $info [ 'logwrites' ] . '</span> ' ;
2005-04-06 07:34:05 +00:00
$info [ 'txt' ] .= 'logwrites: ' . $info [ 'logwrites' ] . ' ' ;
}
2007-07-18 05:17:45 +00:00
2008-06-16 21:01:54 +00:00
$info [ 'dbqueries' ] = $DB -> perf_get_reads () . '/' . ( $DB -> perf_get_writes () - $PERF -> logwrites );
$info [ 'html' ] .= '<span class="dbqueries">DB reads/writes: ' . $info [ 'dbqueries' ] . '</span> ' ;
$info [ 'txt' ] .= 'db reads/writes: ' . $info [ 'dbqueries' ] . ' ' ;
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
2008-05-15 21:40:00 +00:00
/* if ( isset ( $rcache -> hits ) && isset ( $rcache -> misses )) {
2006-12-27 22:39:32 +00:00
$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 } " ;
2008-05-15 21:40:00 +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 ;
}
2009-05-22 02:57:43 +00:00
/**
* @ todo Document this function linux people
*/
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
2009-05-22 02:57:43 +00:00
*
2007-12-24 21:16:30 +00:00
* @ 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
}
2010-05-22 18:38:18 +00:00
return rmdir ( $dir ); // if anything left the result will be false, no 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 ;
2010-05-22 19:59:59 +00:00
if ( strpos ( str_replace ( '\\' , '/' , $dir ), str_replace ( '\\' , '/' , $CFG -> dataroot . '/' )) !== 0 ) {
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 );
2010-05-22 19:59:59 +00:00
return false ;
2007-11-02 09:53:32 +00:00
}
2010-05-22 20:02:17 +00:00
if ( is_dir ( $dir )) {
return true ;
}
2006-08-02 19:40:58 +00:00
2010-05-22 20:02:17 +00:00
if ( ! $create ) {
return false ;
2006-02-02 20:30:34 +00:00
}
2010-05-22 20:02:17 +00:00
return mkdir ( $dir , $CFG -> directorypermissions , $recursive );
2006-02-02 20:30:34 +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
2009-05-22 02:57:43 +00:00
*
2005-06-13 16:23:10 +00:00
* @ 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
2009-05-22 02:57:43 +00:00
*
2005-07-14 15:35:23 +00:00
* @ param string $urlpath path to the original script
2009-05-22 02:57:43 +00:00
* @ return string | bool full path name if a custom script exists , false if no custom script exists
2005-07-14 15:35:23 +00:00
*/
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 ;
}
}
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 .
*
2009-05-22 02:57:43 +00:00
* @ global object
2007-01-04 02:52:44 +00:00
* @ 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
}
/**
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
* This function will search for browser prefereed languages , setting Moodle
2007-02-12 14:58:44 +00:00
* to use the best one available if $SESSION -> lang is undefined
2009-05-22 02:57:43 +00:00
*
* @ global object
* @ global object
* @ global object
2007-02-12 14:58:44 +00:00
*/
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
/// Look for such langs under standard locations
foreach ( $langs as $lang ) {
2010-04-10 07:24:56 +00:00
$lang = strtolower ( clean_param ( $lang , PARAM_SAFEDIR )); // clean it properly for include
2010-04-14 13:16:20 +00:00
if ( get_string_manager () -> translation_exists ( $lang , false )) {
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
2009-05-22 02:57:43 +00:00
*
* any errors just result in the proxy being used ( least bad )
*
* @ global object
* @ param string $url url to check
* @ return boolean true if we should bypass the proxy
2008-05-06 14:59:39 +00:00
*/
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)
2008-05-30 19:59:50 +00:00
$rhs = substr ( $host , - strlen ( $match ));
2008-05-06 14:59:39 +00:00
if ( strcasecmp ( $match , $rhs ) == 0 ) {
return true ;
2008-05-30 19:59:50 +00:00
}
2008-05-06 14:59:39 +00:00
}
// nothing matched.
2008-05-30 19:59:50 +00:00
return false ;
2008-05-06 14:59:39 +00:00
}
2007-04-16 20:44:32 +00:00
////////////////////////////////////////////////////////////////////////////////
2009-05-22 02:57:43 +00:00
/**
* Check if the passed navigation is of the new style
2009-09-01 08:39:01 +00:00
*
2009-05-22 02:57:43 +00:00
* @ param mixed $navigation
* @ return bool true for yes false for no
*/
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 .
2009-05-22 02:57:43 +00:00
*
* This will NOT work with stdClass objects , which have no class variables .
*
2007-04-27 03:54:53 +00:00
* @ 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
*
2009-05-22 02:57:43 +00:00
* @ param array $array
* @ param bool $keep_key_assoc
* @ return array
2007-07-31 08:06:39 +00:00
*/
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 .
2008-05-30 19:59:50 +00:00
*
2008-01-25 13:00:45 +00:00
* @ 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 ) {
2008-05-30 19:59:50 +00:00
case 'mod' :
2008-01-25 13:00:45 +00:00
$plugin_name = get_string ( 'modulename' , $plugin );
break ;
case 'blocks' :
2010-04-11 10:09:59 +00:00
$plugin_name = get_string ( 'pluginname' , " block_ $plugin " );
if ( empty ( $plugin_name ) || $plugin_name == '[[pluginname]]' ) {
2008-01-25 13:00:45 +00:00
if (( $block = block_instance ( $plugin )) !== false ) {
$plugin_name = $block -> get_title ();
} else {
$plugin_name = " [[ $plugin ]] " ;
}
2008-05-30 19:59:50 +00:00
}
2008-01-25 13:00:45 +00:00
break ;
case 'filter' :
2009-04-13 07:12:41 +00:00
$plugin_name = filter_get_name ( 'filter/' . $plugin );
2008-01-25 13:00:45 +00:00
break ;
default :
$plugin_name = $plugin ;
break ;
}
return $plugin_name ;
}
2008-01-26 17:00:03 +00:00
/**
* Is a userid the primary administrator ?
*
2009-05-22 02:57:43 +00:00
* @ param int $userid int id of user to check
2008-05-30 19:59:50 +00:00
* @ return boolean
2008-01-26 17:00:03 +00:00
*/
function is_primary_admin ( $userid ){
$primaryadmin = get_admin ();
if ( $userid == $primaryadmin -> id ){
return true ;
} else {
return false ;
}
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
/**
2009-05-22 02:57:43 +00:00
* Returns the site identifier
*
* @ global object
2009-01-20 03:16:30 +00:00
* @ return string $CFG -> siteidentifier , first making sure it is properly initialised .
*/
function get_site_identifier () {
global $CFG ;
// Check to see if it is missing. If so, initialise it.
if ( empty ( $CFG -> siteidentifier )) {
set_config ( 'siteidentifier' , random_string ( 32 ) . $_SERVER [ 'HTTP_HOST' ]);
}
// Return it.
return $CFG -> siteidentifier ;
}
2009-04-03 02:22:52 +00:00
/**
* Check whether the given password has no more than the specified
* number of consecutive identical characters .
*
2010-05-22 18:38:18 +00:00
* @ param string $password password to be checked against the password policy
2009-04-03 02:22:52 +00:00
* @ param integer $maxchars maximum number of consecutive identical characters
*/
function check_consecutive_identical_characters ( $password , $maxchars ) {
if ( $maxchars < 1 ) {
return true ; // 0 is to disable this check
}
if ( strlen ( $password ) <= $maxchars ) {
return true ; // too short to fail this test
}
$previouschar = '' ;
$consecutivecount = 1 ;
foreach ( str_split ( $password ) as $char ) {
if ( $char != $previouschar ) {
$consecutivecount = 1 ;
}
else {
$consecutivecount ++ ;
if ( $consecutivecount > $maxchars ) {
return false ; // check failed already
}
}
$previouschar = $char ;
}
return true ;
}
2009-12-17 08:34:07 +00:00
/**
* helper function to do partial function binding
* so we can use it for preg_replace_callback , for example
* this works with php functions , user functions , static methods and class methods
* it returns you a callback that you can pass on like so :
*
* $callback = partial ( 'somefunction' , $arg1 , $arg2 );
* or
* $callback = partial ( array ( 'someclass' , 'somestaticmethod' ), $arg1 , $arg2 );
* or even
* $obj = new someclass ();
* $callback = partial ( array ( $obj , 'somemethod' ), $arg1 , $arg2 );
*
* and then the arguments that are passed through at calltime are appended to the argument list .
*
* @ param mixed $function a php callback
* $param mixed $arg1 .. $argv arguments to partially bind with
*
* @ return callback
*/
function partial () {
if ( ! class_exists ( 'partial' )) {
class partial {
var $values = array ();
var $func ;
function __construct ( $func , $args ) {
$this -> values = $args ;
$this -> func = $func ;
}
function method () {
$args = func_get_args ();
return call_user_func_array ( $this -> func , array_merge ( $this -> values , $args ));
}
}
}
$args = func_get_args ();
$func = array_shift ( $args );
$p = new partial ( $func , $args );
return array ( $p , 'method' );
}
2010-02-02 03:13:40 +00:00
/**
* helper function to load up and initialise the mnet environment
* this must be called before you use mnet functions .
*
* @ return mnet_environment the equivalent of old $MNET global
*/
function get_mnet_environment () {
global $CFG ;
require_once ( $CFG -> dirroot . '/mnet/lib.php' );
static $instance = null ;
if ( empty ( $instance )) {
$instance = new mnet_environment ();
$instance -> init ();
}
return $instance ;
}
/**
* during xmlrpc server code execution , any code wishing to access
* information about the remote peer must use this to get it .
*
* @ return mnet_remote_client the equivalent of old $MNET_REMOTE_CLIENT global
*/
function get_mnet_remote_client () {
if ( ! defined ( 'MNET_SERVER' )) {
debugging ( get_string ( 'notinxmlrpcserver' , 'mnet' ));
return false ;
}
global $MNET_REMOTE_CLIENT ;
if ( isset ( $MNET_REMOTE_CLIENT )) {
return $MNET_REMOTE_CLIENT ;
}
return false ;
}
/**
* during the xmlrpc server code execution , this will be called
* to setup the object returned by { @ see get_mnet_remote_client }
*
* @ param mnet_remote_client $client the client to set up
*/
function set_mnet_remote_client ( $client ) {
if ( ! defined ( 'MNET_SERVER' )) {
throw new moodle_exception ( 'notinxmlrpcserver' , 'mnet' );
}
global $MNET_REMOTE_CLIENT ;
$MNET_REMOTE_CLIENT = $client ;
}
/**
* return the jump url for a given remote user
* this is used for rewriting forum post links in emails , etc
*
* @ param stdclass $user the user to get the idp url for
*/
function mnet_get_idp_jump_url ( $user ) {
static $mnetjumps = array ();
if ( ! array_key_exists ( $user -> mnethostid , $mnetjumps )) {
$idp = mnet_get_peer_host ( $user -> mnethostid );
$idpjumppath = mnet_get_app_jumppath ( $idp -> applicationid );
$mnetjumps [ $user -> mnethostid ] = $idp -> wwwroot . $idpjumppath . '?hostwwwroot=' . $CFG -> wwwroot . '&wantsurl=' ;
}
return $mnetjumps [ $user -> mnethostid ];
}
2010-05-13 09:57:43 +00:00
/**
* Gets the homepage to use for the current user
*
* @ return int One of HOMEPAGE_ *
*/
function get_home_page () {
global $CFG ;
if ( isloggedin () && ! isguestuser () && ! empty ( $CFG -> defaulthomepage )) {
if ( $CFG -> defaulthomepage == HOMEPAGE_MY ) {
return HOMEPAGE_MY ;
} else {
return ( int ) get_user_preferences ( 'user_home_page_preference' , HOMEPAGE_MY );
}
}
return HOMEPAGE_SITE ;
2010-05-16 11:45:33 +00:00
}