Moodle3.3.2 2017.10.28
fs_moodle5.00.15
続き
@@ -0,0 +1,315 @@ | ||
1 | +// This file is part of Moodle - http://moodle.org/ | |
2 | +// | |
3 | +// Moodle is free software: you can redistribute it and/or modify | |
4 | +// it under the terms of the GNU General Public License as published by | |
5 | +// the Free Software Foundation, either version 3 of the License, or | |
6 | +// (at your option) any later version. | |
7 | +// | |
8 | +// Moodle is distributed in the hope that it will be useful, | |
9 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | +// GNU General Public License for more details. | |
12 | +// | |
13 | +// You should have received a copy of the GNU General Public License | |
14 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
15 | + | |
16 | +/** | |
17 | + * Readme file for local customisations | |
18 | + * | |
19 | + * @package local | |
20 | + * @copyright 2009 Petr Skoda (http://skodak.org) | |
21 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
22 | + */ | |
23 | + | |
24 | +Local customisations directory | |
25 | +============================== | |
26 | +This directory is the recommended place for local customisations. | |
27 | +Wherever possible, customisations should be written using one | |
28 | +of the standard plug-in points like modules, blocks, auth plugins, themes, etc. | |
29 | + | |
30 | +See also http://docs.moodle.org/dev/Local_customisation for more | |
31 | +information. | |
32 | + | |
33 | + | |
34 | +Directory structure | |
35 | +------------------- | |
36 | +This directory has standard plugin structure. All standard plugin features | |
37 | +are supported. There may be some extra files with special meaning in /local/. | |
38 | + | |
39 | +Sample /local/ directory listing: | |
40 | +/local/nicehack/ - first customisation plugin | |
41 | +/local/otherhack/ - other customisation plugin | |
42 | +/local/preupgrade.php - executed before each core upgrade, use $version and $CFG->version | |
43 | + if you need to tweak specific local hacks | |
44 | +/local/defaults.php - custom admin setting defaults | |
45 | + | |
46 | + | |
47 | + | |
48 | +Local plugins | |
49 | +============= | |
50 | +Local plugins are used in cases when no standard plugin fits, examples are: | |
51 | +* event consumers communicating with external systems | |
52 | +* custom definitions of web services and external functions | |
53 | +* applications that extend moodle at the system level (hub server, amos server, etc.) | |
54 | +* new database tables used in core hacks (discouraged) | |
55 | +* new capability definitions used in core hacks | |
56 | +* custom admin settings | |
57 | + | |
58 | +Standard plugin features: | |
59 | +* /local/pluginname/version.php - version of script (must be incremented after changes) | |
60 | +* /local/pluginname/db/install.xml - executed during install (new version.php found) | |
61 | +* /local/pluginname/db/install.php - executed right after install.xml | |
62 | +* /local/pluginname/db/uninstall.php - executed during uninstallation | |
63 | +* /local/pluginname/db/upgrade.php - executed after version.php change | |
64 | +* /local/pluginname/db/access.php - definition of capabilities | |
65 | +* /local/pluginname/db/events.php - event handlers and subscripts | |
66 | +* /local/pluginname/db/messages.php - messaging registration | |
67 | +* /local/pluginname/db/services.php - definition of web services and web service functions | |
68 | +* /local/pluginname/db/subplugins.php - list of subplugins types supported by this local plugin | |
69 | +* /local/pluginname/lang/en/local_pluginname.php - language file | |
70 | +* /local/pluginname/settings.php - admin settings | |
71 | + | |
72 | + | |
73 | +Local plugin version specification | |
74 | +---------------------------------- | |
75 | +version.php is mandatory for most of the standard plugin infrastructure. | |
76 | +The version number must be incremented most plugin changes, the changed | |
77 | +version tells Moodle to invalidate all caches, do db upgrades if necessary, | |
78 | +install new capabilities, register event handlers, etc. | |
79 | + | |
80 | +Example: | |
81 | +/local/nicehack/version.php | |
82 | +<?php | |
83 | +$plugin->version = 2010022400; // The (date) version of this plugin | |
84 | +$plugin->requires = 2010021900; // Requires this Moodle version | |
85 | + | |
86 | + | |
87 | +Local plugin capabilities | |
88 | +------------------------- | |
89 | +Each local plugin may define own capabilities. It is not recommended to define | |
90 | +capabilities belonging to other plugins here, but it should work too. | |
91 | + | |
92 | +/local/nicehack/access.php content | |
93 | +<?php | |
94 | +$local_nicehack_capabilities = array( | |
95 | + 'local/nicehack:nicecapability' => array( | |
96 | + 'captype' => 'read', | |
97 | + 'contextlevel' => CONTEXT_SYSTEM, | |
98 | + ), | |
99 | +); | |
100 | + | |
101 | + | |
102 | +Local plugin language strings | |
103 | +----------------------------- | |
104 | +If customisation needs new strings it is recommended to use normal plugin | |
105 | +strings. | |
106 | + | |
107 | +sample language file /local/nicehack/lang/en/local_nicehack.php | |
108 | +<?php | |
109 | +$string['hello'] = 'Hi {$a}'; | |
110 | +$string['nicehack:nicecapability'] = 'Some capability'; | |
111 | + | |
112 | + | |
113 | +use of the new string in code: | |
114 | +echo get_string('hello', 'local_nicehack', 'petr'); | |
115 | + | |
116 | + | |
117 | +Local plugin admin menu items | |
118 | +----------------------------- | |
119 | +It is possible to add new items and categories to the admin_tree block. | |
120 | +I you need to define new admin setting classes put them into separate | |
121 | +file and require_once() from settings.php | |
122 | + | |
123 | +For example if you want to add new external page use following | |
124 | +/local/nicehack/settings.php | |
125 | +<?php | |
126 | +$ADMIN->add('root', new admin_category('tweaks', 'Custom tweaks')); | |
127 | +$ADMIN->add('tweaks', new admin_externalpage('nicehackery', 'Tweak something', | |
128 | + $CFG->wwwroot.'/local/nicehack/setuppage.php')); | |
129 | + | |
130 | +Or if you want a new standard settings page for the plugin, inside the local | |
131 | +plugins category: | |
132 | +<?php | |
133 | +defined('MOODLE_INTERNAL') || die; | |
134 | + | |
135 | +if ($hassiteconfig) { // needs this condition or there is error on login page | |
136 | + $settings = new admin_settingpage('local_thisplugin', 'This plugin'); | |
137 | + $ADMIN->add('localplugins', $settings); | |
138 | + | |
139 | + $settings->add(new admin_setting_configtext('local_thisplugin/option', | |
140 | + 'Option', 'Information about this option', 100, PARAM_INT)); | |
141 | +} | |
142 | + | |
143 | +Local plugin event handlers | |
144 | +--------------------------- | |
145 | +Events are intended primarily for communication "core --> plugins". | |
146 | +(It should not be use in opposite direction!) | |
147 | +In theory it could be also used for "plugin --> plugin" communication too. | |
148 | +The list of core events is documented in lib/db/events.php | |
149 | + | |
150 | +sample files | |
151 | +/local/nicehack/db/events.php | |
152 | +$handlers = array ( | |
153 | + 'user_deleted' => array ( | |
154 | + 'handlerfile' => '/local/nicehack/lib.php', | |
155 | + 'handlerfunction' => 'nicehack_userdeleted_handler', | |
156 | + 'schedule' => 'instant' | |
157 | + ), | |
158 | +); | |
159 | + | |
160 | +NOTE: events are not yet fully implemented in current Moodle 2.0dev. | |
161 | + | |
162 | + | |
163 | +Local plugin database tables | |
164 | +---------------------------- | |
165 | +XMLDB editors is the recommended tool. Please note that modification | |
166 | +of core table structure is highly discouraged. | |
167 | + | |
168 | +If you really really really need to modify core tables you might want to do | |
169 | +that in install.php and later upgrade.php | |
170 | + | |
171 | +Note: it is forbidden to manually modify the DB structure, without corresponding | |
172 | + changes in install.xml files. | |
173 | + | |
174 | +List of upgrade related files: | |
175 | +/local/nicehack/db/install.xml - contains XML definition of new tables | |
176 | +/local/nicehack/db/install.php - executed after db creation, may be also used | |
177 | + for general install code | |
178 | +/local/nicehack/db/upgrade.php - executed when version changes | |
179 | + | |
180 | + | |
181 | +Local plugin web services | |
182 | +------------------------- | |
183 | +During plugin installation or upgrade, the web service definitions are read | |
184 | +from /local/nicehack/db/services.php and are automatically installed/updated in Moodle. | |
185 | + | |
186 | +sample files | |
187 | +/local/nicehack/db/services.php | |
188 | +$$functions = array ( | |
189 | + 'nicehack_hello_world' => array( | |
190 | + 'classname' => 'local_nicehack_external', | |
191 | + 'methodname' => 'hello_world', | |
192 | + 'classpath' => 'local/nicehack/externallib.php', | |
193 | + 'description' => 'Get hello world string', | |
194 | + 'type' => 'read', | |
195 | + ), | |
196 | +); | |
197 | +$services = array( | |
198 | + 'Nice hack service 1' => array( | |
199 | + 'functions' => array ('nicehack_hello_world'), | |
200 | + 'enabled'=>1, | |
201 | + ), | |
202 | +); | |
203 | + | |
204 | + | |
205 | +You will need to write the /local/nicehack/externallib.php - external functions | |
206 | +description and code. See some examples from the core files (/user/externallib.php, | |
207 | +/group/externallib.php...). | |
208 | + | |
209 | +Local plugin navigation hooks | |
210 | +----------------------------- | |
211 | +There are two functions that your plugin can define that allow it to extend the main | |
212 | +navigation and the settings navigation. | |
213 | +These two functions both need to be defined within /local/nicehack/lib.php. | |
214 | + | |
215 | +sample code | |
216 | +<?php | |
217 | +function local_nicehack_extend_navigation(global_navigation $nav) { | |
218 | + // $nav is the global navigation instance. | |
219 | + // Here you can add to and manipulate the navigation structure as you like. | |
220 | + // This callback was introduced in 2.0 as nicehack_extends_navigation(global_navigation $nav) | |
221 | + // In 2.3 support was added for local_nicehack_extends_navigation(global_navigation $nav). | |
222 | + // In 2.9 the name was corrected to local_nicehack_extend_navigation() for consistency | |
223 | +} | |
224 | +function local_nicehack_extend_settings_navigation(settings_navigation $nav, context $context) { | |
225 | + // $nav is the settings navigation instance. | |
226 | + // $context is the context the settings have been loaded for (settings is context specific) | |
227 | + // Here you can add to and manipulate the settings structure as you like. | |
228 | + // This callback was introduced in 2.3, originally as local_nicehack_extends_settings_navigation() | |
229 | + // In 2.9 the name was corrected to the imperative mood ('extend', not 'extends') | |
230 | +} | |
231 | + | |
232 | +Other local customisation files | |
233 | +=============================== | |
234 | + | |
235 | +Customised site defaults | |
236 | +------------------------ | |
237 | +Different default site settings can be stored in file /local/defaults.php. | |
238 | +These new defaults are used during installation, upgrade and later are | |
239 | +displayed as default values in admin settings. This means that the content | |
240 | +of the defaults files is usually updated BEFORE installation or upgrade. | |
241 | + | |
242 | +These customised defaults are useful especially when using CLI tools | |
243 | +for installation and upgrade. | |
244 | + | |
245 | +Sample /local/defaults.php file content: | |
246 | +<?php | |
247 | +$defaults['moodle']['forcelogin'] = 1; // new default for $CFG->forcelogin | |
248 | +$defaults['scorm']['maxgrade'] = 20; // default for get_config('scorm', 'maxgrade') | |
249 | +$defaults['moodlecourse']['numsections'] = 11; | |
250 | +$defaults['moodle']['hiddenuserfields'] = array('city', 'country'); | |
251 | + | |
252 | +First bracket contains string from column plugin of config_plugins table. | |
253 | +Second bracket is the name of setting. In the admin settings UI the plugin and | |
254 | +name of setting is separated by "|". | |
255 | + | |
256 | +The values usually correspond to the raw string in config table, with the exception | |
257 | +of comma separated lists that are usually entered as real arrays. | |
258 | + | |
259 | +Please note that not all settings are converted to admin_tree, | |
260 | +they are mostly intended to be set directly in config.php. | |
261 | + | |
262 | + | |
263 | +2.0 pre-upgrade script | |
264 | +---------------------- | |
265 | +You an use /local/upgrade_pre20.php script for any code that needs to | |
266 | +be executed before the main upgrade to 2.0. Most probably this will | |
267 | +be used for undoing of old hacks that would otherwise break normal | |
268 | +2.0 upgrade. | |
269 | + | |
270 | +This file is just included directly, there does not need to be any | |
271 | +function inside. If the execution stops the script is executed again | |
272 | +during the next upgrade. The first execution of lib/db/upgrade.php | |
273 | +increments the version number and the pre upgrade script is not | |
274 | +executed any more. | |
275 | + | |
276 | + | |
277 | + | |
278 | +1.9.x upgrade notes | |
279 | +=================== | |
280 | +1.9.x contains basic support for local hacks placed directly into | |
281 | +/local/ directory. This old local API was completely removed and can | |
282 | +not be used any more in 2.0. All old customisations need to be | |
283 | +migrated to new local plugins before running of the 2.0 upgrade script. | |
284 | + | |
285 | + | |
286 | + | |
287 | +Other site customisation outside of "/local/" directory | |
288 | +======================================================= | |
289 | + | |
290 | +Local language pack modifications | |
291 | +--------------------------------- | |
292 | +Moodle supports other type of local customisation of standard language | |
293 | +packs. If you want to create your own language pack based on another | |
294 | +language create new dataroot directory with "_local" suffix, for example | |
295 | +following file with content changes string "Login" to "Sign in": | |
296 | +moodledata/lang/en_local | |
297 | +<?php | |
298 | + $string['login'] = 'Sign in'; | |
299 | + | |
300 | +See also http://docs.moodle.org/en/Language_editing | |
301 | + | |
302 | + | |
303 | +Custom script injection | |
304 | +----------------------- | |
305 | +Very old customisation option that allows you to modify scripts by injecting | |
306 | +code right after the require 'config.php' call. | |
307 | + | |
308 | +This setting is enabled by manually setting $CFG->customscripts variable | |
309 | +in config.php script. The value is expected to be full path to directory | |
310 | +with the same structure as dirroot. Please note this hack only affects | |
311 | +files that actually include the config.php! | |
312 | + | |
313 | +Examples: | |
314 | +* disable one specific moodle page without code modification | |
315 | +* alter page parameters on the fly |
@@ -0,0 +1,13 @@ | ||
1 | +This file describes API changes for the plugins of the type 'local'. | |
2 | + | |
3 | +=== 3.1 === | |
4 | + | |
5 | +* Navigation API callbacks local_<plugin>_extends_navigation() and local_<plugin>_extends_settings_navigation() have been removed. | |
6 | + Please rename them to local_<plugin>_extend_navigation() and local_<plugin>_extend_settings_navigation() respectively. | |
7 | + | |
8 | +=== 2.9 === | |
9 | + | |
10 | +* Navigation API callbacks local_<plugin>_extends_navigation() and local_<plugin>_extends_settings_navigation() are deprecated. | |
11 | + Please rename them to local_<plugin>_extend_navigation() and local_<plugin>_extend_settings_navigation() respectively. The | |
12 | + deprecated variant will be supported in 2.9 and 3.0 and then the support will be dropped. | |
13 | +* Definitely dropped support for the original <plugin>_extends_navigation() that has been deprecated since 2.3. |
@@ -0,0 +1,166 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * Change password page. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +require('../config.php'); | |
28 | +require_once($CFG->dirroot.'/user/lib.php'); | |
29 | +require_once('change_password_form.php'); | |
30 | +require_once($CFG->libdir.'/authlib.php'); | |
31 | +require_once($CFG->dirroot.'/webservice/lib.php'); | |
32 | + | |
33 | +$id = optional_param('id', SITEID, PARAM_INT); // current course | |
34 | +$return = optional_param('return', 0, PARAM_BOOL); // redirect after password change | |
35 | + | |
36 | +$systemcontext = context_system::instance(); | |
37 | + | |
38 | +//HTTPS is required in this page when $CFG->loginhttps enabled | |
39 | +$PAGE->https_required(); | |
40 | + | |
41 | +$PAGE->set_url('/login/change_password.php', array('id'=>$id)); | |
42 | + | |
43 | +$PAGE->set_context($systemcontext); | |
44 | + | |
45 | +if ($return) { | |
46 | + // this redirect prevents security warning because https can not POST to http pages | |
47 | + if (empty($SESSION->wantsurl) | |
48 | + or stripos(str_replace('https://', 'http://', $SESSION->wantsurl), str_replace('https://', 'http://', $CFG->wwwroot.'/login/change_password.php')) === 0) { | |
49 | + $returnto = "$CFG->wwwroot/user/preferences.php?userid=$USER->id&course=$id"; | |
50 | + } else { | |
51 | + $returnto = $SESSION->wantsurl; | |
52 | + } | |
53 | + unset($SESSION->wantsurl); | |
54 | + | |
55 | + redirect($returnto); | |
56 | +} | |
57 | + | |
58 | +$strparticipants = get_string('participants'); | |
59 | + | |
60 | +if (!$course = $DB->get_record('course', array('id'=>$id))) { | |
61 | + print_error('invalidcourseid'); | |
62 | +} | |
63 | + | |
64 | +// require proper login; guest user can not change password | |
65 | +if (!isloggedin() or isguestuser()) { | |
66 | + if (empty($SESSION->wantsurl)) { | |
67 | + $SESSION->wantsurl = $CFG->httpswwwroot.'/login/change_password.php'; | |
68 | + } | |
69 | + redirect(get_login_url()); | |
70 | +} | |
71 | + | |
72 | +$PAGE->set_context(context_user::instance($USER->id)); | |
73 | +$PAGE->set_pagelayout('admin'); | |
74 | +$PAGE->set_course($course); | |
75 | + | |
76 | +// do not require change own password cap if change forced | |
77 | +if (!get_user_preferences('auth_forcepasswordchange', false)) { | |
78 | + require_capability('moodle/user:changeownpassword', $systemcontext); | |
79 | +} | |
80 | + | |
81 | +// do not allow "Logged in as" users to change any passwords | |
82 | +if (\core\session\manager::is_loggedinas()) { | |
83 | + print_error('cannotcallscript'); | |
84 | +} | |
85 | + | |
86 | +if (is_mnet_remote_user($USER)) { | |
87 | + $message = get_string('usercannotchangepassword', 'mnet'); | |
88 | + if ($idprovider = $DB->get_record('mnet_host', array('id'=>$USER->mnethostid))) { | |
89 | + $message .= get_string('userchangepasswordlink', 'mnet', $idprovider); | |
90 | + } | |
91 | + print_error('userchangepasswordlink', 'mnet', '', $message); | |
92 | +} | |
93 | + | |
94 | +// load the appropriate auth plugin | |
95 | +$userauth = get_auth_plugin($USER->auth); | |
96 | + | |
97 | +if (!$userauth->can_change_password()) { | |
98 | + print_error('nopasswordchange', 'auth'); | |
99 | +} | |
100 | + | |
101 | +if ($changeurl = $userauth->change_password_url()) { | |
102 | + // this internal scrip not used | |
103 | + redirect($changeurl); | |
104 | +} | |
105 | + | |
106 | +$mform = new login_change_password_form(); | |
107 | +$mform->set_data(array('id'=>$course->id)); | |
108 | + | |
109 | +$navlinks = array(); | |
110 | +$navlinks[] = array('name' => $strparticipants, 'link' => "$CFG->wwwroot/user/index.php?id=$course->id", 'type' => 'misc'); | |
111 | + | |
112 | +if ($mform->is_cancelled()) { | |
113 | + redirect($CFG->wwwroot.'/user/preferences.php?userid='.$USER->id.'&course='.$course->id); | |
114 | +} else if ($data = $mform->get_data()) { | |
115 | + | |
116 | + if (!$userauth->user_update_password($USER, $data->newpassword1)) { | |
117 | + print_error('errorpasswordupdate', 'auth'); | |
118 | + } | |
119 | + | |
120 | + user_add_password_history($USER->id, $data->newpassword1); | |
121 | + | |
122 | + if (!empty($CFG->passwordchangelogout)) { | |
123 | + \core\session\manager::kill_user_sessions($USER->id, session_id()); | |
124 | + } | |
125 | + | |
126 | + if (!empty($data->signoutofotherservices)) { | |
127 | + webservice::delete_user_ws_tokens($USER->id); | |
128 | + } | |
129 | + | |
130 | + // Reset login lockout - we want to prevent any accidental confusion here. | |
131 | + login_unlock_account($USER); | |
132 | + | |
133 | + // register success changing password | |
134 | + unset_user_preference('auth_forcepasswordchange', $USER); | |
135 | + unset_user_preference('create_password', $USER); | |
136 | + | |
137 | + $strpasswordchanged = get_string('passwordchanged'); | |
138 | + | |
139 | + $fullname = fullname($USER, true); | |
140 | + | |
141 | + $PAGE->set_title($strpasswordchanged); | |
142 | + $PAGE->set_heading(fullname($USER)); | |
143 | + echo $OUTPUT->header(); | |
144 | + | |
145 | + notice($strpasswordchanged, new moodle_url($PAGE->url, array('return'=>1))); | |
146 | + | |
147 | + echo $OUTPUT->footer(); | |
148 | + exit; | |
149 | +} | |
150 | + | |
151 | +// make sure we really are on the https page when https login required | |
152 | +$PAGE->verify_https_required(); | |
153 | + | |
154 | +$strchangepassword = get_string('changepassword'); | |
155 | + | |
156 | +$fullname = fullname($USER, true); | |
157 | + | |
158 | +$PAGE->set_title($strchangepassword); | |
159 | +$PAGE->set_heading($fullname); | |
160 | +echo $OUTPUT->header(); | |
161 | + | |
162 | +if (get_user_preferences('auth_forcepasswordchange')) { | |
163 | + echo $OUTPUT->notification(get_string('forcepasswordchangenotice')); | |
164 | +} | |
165 | +$mform->display(); | |
166 | +echo $OUTPUT->footer(); |
@@ -0,0 +1,121 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * Change password form definition. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 2006 Petr Skoda {@link http://skodak.org} | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +defined('MOODLE_INTERNAL') || die(); | |
28 | + | |
29 | +require_once $CFG->libdir.'/formslib.php'; | |
30 | + | |
31 | +class login_change_password_form extends moodleform { | |
32 | + | |
33 | + function definition() { | |
34 | + global $USER, $CFG; | |
35 | + | |
36 | + $mform = $this->_form; | |
37 | + $mform->setDisableShortforms(true); | |
38 | + | |
39 | + $mform->addElement('header', 'changepassword', get_string('changepassword'), ''); | |
40 | + | |
41 | + // visible elements | |
42 | + $mform->addElement('static', 'username', get_string('username'), $USER->username); | |
43 | + | |
44 | + $policies = array(); | |
45 | + if (!empty($CFG->passwordpolicy)) { | |
46 | + $policies[] = print_password_policy(); | |
47 | + } | |
48 | + if (!empty($CFG->passwordreuselimit) and $CFG->passwordreuselimit > 0) { | |
49 | + $policies[] = get_string('informminpasswordreuselimit', 'auth', $CFG->passwordreuselimit); | |
50 | + } | |
51 | + if ($policies) { | |
52 | + $mform->addElement('static', 'passwordpolicyinfo', '', implode('<br />', $policies)); | |
53 | + } | |
54 | + $mform->addElement('password', 'password', get_string('oldpassword')); | |
55 | + $mform->addRule('password', get_string('required'), 'required', null, 'client'); | |
56 | + $mform->setType('password', PARAM_RAW); | |
57 | + | |
58 | + $mform->addElement('password', 'newpassword1', get_string('newpassword')); | |
59 | + $mform->addRule('newpassword1', get_string('required'), 'required', null, 'client'); | |
60 | + $mform->setType('newpassword1', PARAM_RAW); | |
61 | + | |
62 | + $mform->addElement('password', 'newpassword2', get_string('newpassword').' ('.get_String('again').')'); | |
63 | + $mform->addRule('newpassword2', get_string('required'), 'required', null, 'client'); | |
64 | + $mform->setType('newpassword2', PARAM_RAW); | |
65 | + | |
66 | + if (empty($CFG->passwordchangetokendeletion) and !empty(webservice::get_active_tokens($USER->id))) { | |
67 | + $mform->addElement('advcheckbox', 'signoutofotherservices', get_string('signoutofotherservices')); | |
68 | + $mform->addHelpButton('signoutofotherservices', 'signoutofotherservices'); | |
69 | + $mform->setDefault('signoutofotherservices', 1); | |
70 | + } | |
71 | + | |
72 | + // hidden optional params | |
73 | + $mform->addElement('hidden', 'id', 0); | |
74 | + $mform->setType('id', PARAM_INT); | |
75 | + | |
76 | + // buttons | |
77 | + if (get_user_preferences('auth_forcepasswordchange')) { | |
78 | + $this->add_action_buttons(false); | |
79 | + } else { | |
80 | + $this->add_action_buttons(true); | |
81 | + } | |
82 | + } | |
83 | + | |
84 | +/// perform extra password change validation | |
85 | + function validation($data, $files) { | |
86 | + global $USER; | |
87 | + $errors = parent::validation($data, $files); | |
88 | + | |
89 | + // ignore submitted username | |
90 | + if (!$user = authenticate_user_login($USER->username, $data['password'], true)) { | |
91 | + $errors['password'] = get_string('invalidlogin'); | |
92 | + return $errors; | |
93 | + } | |
94 | + | |
95 | + if ($data['newpassword1'] <> $data['newpassword2']) { | |
96 | + $errors['newpassword1'] = get_string('passwordsdiffer'); | |
97 | + $errors['newpassword2'] = get_string('passwordsdiffer'); | |
98 | + return $errors; | |
99 | + } | |
100 | + | |
101 | + if ($data['password'] == $data['newpassword1']){ | |
102 | + $errors['newpassword1'] = get_string('mustchangepassword'); | |
103 | + $errors['newpassword2'] = get_string('mustchangepassword'); | |
104 | + return $errors; | |
105 | + } | |
106 | + | |
107 | + if (user_is_previously_used_password($USER->id, $data['newpassword1'])) { | |
108 | + $errors['newpassword1'] = get_string('errorpasswordreused', 'core_auth'); | |
109 | + $errors['newpassword2'] = get_string('errorpasswordreused', 'core_auth'); | |
110 | + } | |
111 | + | |
112 | + $errmsg = '';//prevents eclipse warnings | |
113 | + if (!check_password_policy($data['newpassword1'], $errmsg)) { | |
114 | + $errors['newpassword1'] = $errmsg; | |
115 | + $errors['newpassword2'] = $errmsg; | |
116 | + return $errors; | |
117 | + } | |
118 | + | |
119 | + return $errors; | |
120 | + } | |
121 | +} |
@@ -0,0 +1,102 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * Confirm self registered user. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 1999 Martin Dougiamas http://dougiamas.com | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +require(__DIR__ . '/../config.php'); | |
28 | +require(__DIR__ . '/lib.php'); | |
29 | +require_once($CFG->libdir . '/authlib.php'); | |
30 | + | |
31 | +$data = optional_param('data', '', PARAM_RAW); // Formatted as: secret/username | |
32 | + | |
33 | +$p = optional_param('p', '', PARAM_ALPHANUM); // Old parameter: secret | |
34 | +$s = optional_param('s', '', PARAM_RAW); // Old parameter: username | |
35 | +$redirect = optional_param('redirect', '', PARAM_LOCALURL); // Where to redirect the browser once the user has been confirmed. | |
36 | + | |
37 | +$PAGE->set_url('/login/confirm.php'); | |
38 | +$PAGE->set_context(context_system::instance()); | |
39 | + | |
40 | +if (!$authplugin = signup_get_user_confirmation_authplugin()) { | |
41 | + throw new moodle_exception('confirmationnotenabled'); | |
42 | +} | |
43 | + | |
44 | +if (!empty($data) || (!empty($p) && !empty($s))) { | |
45 | + | |
46 | + if (!empty($data)) { | |
47 | + $dataelements = explode('/', $data, 2); // Stop after 1st slash. Rest is username. MDL-7647 | |
48 | + $usersecret = $dataelements[0]; | |
49 | + $username = $dataelements[1]; | |
50 | + } else { | |
51 | + $usersecret = $p; | |
52 | + $username = $s; | |
53 | + } | |
54 | + | |
55 | + $confirmed = $authplugin->user_confirm($username, $usersecret); | |
56 | + | |
57 | + if ($confirmed == AUTH_CONFIRM_ALREADY) { | |
58 | + $user = get_complete_user_data('username', $username); | |
59 | + $PAGE->navbar->add(get_string("alreadyconfirmed")); | |
60 | + $PAGE->set_title(get_string("alreadyconfirmed")); | |
61 | + $PAGE->set_heading($COURSE->fullname); | |
62 | + echo $OUTPUT->header(); | |
63 | + echo $OUTPUT->box_start('generalbox centerpara boxwidthnormal boxaligncenter'); | |
64 | + echo "<p>".get_string("alreadyconfirmed")."</p>\n"; | |
65 | + echo $OUTPUT->single_button(core_login_get_return_url(), get_string('courses')); | |
66 | + echo $OUTPUT->box_end(); | |
67 | + echo $OUTPUT->footer(); | |
68 | + exit; | |
69 | + | |
70 | + } else if ($confirmed == AUTH_CONFIRM_OK) { | |
71 | + | |
72 | + // The user has confirmed successfully, let's log them in | |
73 | + | |
74 | + if (!$user = get_complete_user_data('username', $username)) { | |
75 | + print_error('cannotfinduser', '', '', s($username)); | |
76 | + } | |
77 | + | |
78 | + if (!$user->suspended) { | |
79 | + complete_user_login($user); | |
80 | + | |
81 | + \core\session\manager::apply_concurrent_login_limit($user->id, session_id()); | |
82 | + } | |
83 | + | |
84 | + $PAGE->navbar->add(get_string("confirmed")); | |
85 | + $PAGE->set_title(get_string("confirmed")); | |
86 | + $PAGE->set_heading($COURSE->fullname); | |
87 | + echo $OUTPUT->header(); | |
88 | + echo $OUTPUT->box_start('generalbox centerpara boxwidthnormal boxaligncenter'); | |
89 | + echo "<h3>".get_string("thanks").", ". fullname($USER) . "</h3>\n"; | |
90 | + echo "<p>".get_string("confirmed")."</p>\n"; | |
91 | + echo $OUTPUT->single_button(core_login_get_return_url(), get_string('continue')); | |
92 | + echo $OUTPUT->box_end(); | |
93 | + echo $OUTPUT->footer(); | |
94 | + exit; | |
95 | + } else { | |
96 | + print_error('invalidconfirmdata'); | |
97 | + } | |
98 | +} else { | |
99 | + print_error("errorwhenconfirming"); | |
100 | +} | |
101 | + | |
102 | +redirect("$CFG->wwwroot/"); |
@@ -0,0 +1,93 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * Forgot password routine. | |
19 | + * | |
20 | + * Finds the user and calls the appropriate routine for their authentication type. | |
21 | + * | |
22 | + * There are several pathways to/through this page, summarised below: | |
23 | + * 1. User clicks the 'forgotten your username or password?' link on the login page. | |
24 | + * - No token is received, render the username/email search form. | |
25 | + * 2. User clicks the link in the forgot password email | |
26 | + * - Token received as GET param, store the token in session, redirect to self | |
27 | + * 3. Redirected from (2) | |
28 | + * - Fetch token from session, and continue to run the reset routine defined in 'core_login_process_password_set()'. | |
29 | + * | |
30 | + * @package core | |
31 | + * @subpackage auth | |
32 | + * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com | |
33 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
34 | + */ | |
35 | + | |
36 | +require('../config.php'); | |
37 | +require_once($CFG->libdir.'/authlib.php'); | |
38 | +require_once(__DIR__ . '/lib.php'); | |
39 | +require_once('forgot_password_form.php'); | |
40 | +require_once('set_password_form.php'); | |
41 | + | |
42 | +$token = optional_param('token', false, PARAM_ALPHANUM); | |
43 | + | |
44 | +//HTTPS is required in this page when $CFG->loginhttps enabled | |
45 | +$PAGE->https_required(); | |
46 | + | |
47 | +$PAGE->set_url('/login/forgot_password.php'); | |
48 | +$systemcontext = context_system::instance(); | |
49 | +$PAGE->set_context($systemcontext); | |
50 | + | |
51 | +// setup text strings | |
52 | +$strforgotten = get_string('passwordforgotten'); | |
53 | +$strlogin = get_string('login'); | |
54 | + | |
55 | +$PAGE->navbar->add($strlogin, get_login_url()); | |
56 | +$PAGE->navbar->add($strforgotten); | |
57 | +$PAGE->set_title($strforgotten); | |
58 | +$PAGE->set_heading($COURSE->fullname); | |
59 | + | |
60 | +// if alternatepasswordurl is defined, then we'll just head there | |
61 | +if (!empty($CFG->forgottenpasswordurl)) { | |
62 | + redirect($CFG->forgottenpasswordurl); | |
63 | +} | |
64 | + | |
65 | +// if you are logged in then you shouldn't be here! | |
66 | +if (isloggedin() and !isguestuser()) { | |
67 | + redirect($CFG->wwwroot.'/index.php', get_string('loginalready'), 5); | |
68 | +} | |
69 | + | |
70 | +// Fetch the token from the session, if present, and unset the session var immediately. | |
71 | +$tokeninsession = false; | |
72 | +if (!empty($SESSION->password_reset_token)) { | |
73 | + $token = $SESSION->password_reset_token; | |
74 | + unset($SESSION->password_reset_token); | |
75 | + $tokeninsession = true; | |
76 | +} | |
77 | + | |
78 | +if (empty($token)) { | |
79 | + // This is a new password reset request. | |
80 | + // Process the request; identify the user & send confirmation email. | |
81 | + core_login_process_password_reset_request(); | |
82 | +} else { | |
83 | + // A token has been found, but not in the session, and not from a form post. | |
84 | + // This must be the user following the original rest link, so store the reset token in the session and redirect to self. | |
85 | + // The session var is intentionally used only during the lifespan of one request (the redirect) and is unset above. | |
86 | + if (!$tokeninsession && $_SERVER['REQUEST_METHOD'] === 'GET') { | |
87 | + $SESSION->password_reset_token = $token; | |
88 | + redirect($CFG->httpswwwroot . '/login/forgot_password.php'); | |
89 | + } else { | |
90 | + // Continue with the password reset process. | |
91 | + core_login_process_password_set($token); | |
92 | + } | |
93 | +} |
@@ -0,0 +1,110 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * Forgot password page. | |
19 | + * | |
20 | + * @package core | |
21 | + * @subpackage auth | |
22 | + * @copyright 2006 Petr Skoda {@link http://skodak.org} | |
23 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | + */ | |
25 | +defined('MOODLE_INTERNAL') || die(); | |
26 | + | |
27 | +require_once($CFG->libdir.'/formslib.php'); | |
28 | + | |
29 | +/** | |
30 | + * Reset forgotten password form definition. | |
31 | + * | |
32 | + * @package core | |
33 | + * @subpackage auth | |
34 | + * @copyright 2006 Petr Skoda {@link http://skodak.org} | |
35 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
36 | + */ | |
37 | +class login_forgot_password_form extends moodleform { | |
38 | + | |
39 | + /** | |
40 | + * Define the forgot password form. | |
41 | + */ | |
42 | + function definition() { | |
43 | + $mform = $this->_form; | |
44 | + $mform->setDisableShortforms(true); | |
45 | + | |
46 | + $mform->addElement('header', 'searchbyusername', get_string('searchbyusername'), ''); | |
47 | + | |
48 | + $mform->addElement('text', 'username', get_string('username')); | |
49 | + $mform->setType('username', PARAM_RAW); | |
50 | + | |
51 | + $submitlabel = get_string('search'); | |
52 | + $mform->addElement('submit', 'submitbuttonusername', $submitlabel); | |
53 | + | |
54 | + $mform->addElement('header', 'searchbyemail', get_string('searchbyemail'), ''); | |
55 | + | |
56 | + $mform->addElement('text', 'email', get_string('email')); | |
57 | + $mform->setType('email', PARAM_RAW_TRIMMED); | |
58 | + | |
59 | + $submitlabel = get_string('search'); | |
60 | + $mform->addElement('submit', 'submitbuttonemail', $submitlabel); | |
61 | + } | |
62 | + | |
63 | + /** | |
64 | + * Validate user input from the forgot password form. | |
65 | + * @param array $data array of submitted form fields. | |
66 | + * @param array $files submitted with the form. | |
67 | + * @return array errors occuring during validation. | |
68 | + */ | |
69 | + function validation($data, $files) { | |
70 | + global $CFG, $DB; | |
71 | + | |
72 | + $errors = parent::validation($data, $files); | |
73 | + | |
74 | + if ((!empty($data['username']) and !empty($data['email'])) or (empty($data['username']) and empty($data['email']))) { | |
75 | + $errors['username'] = get_string('usernameoremail'); | |
76 | + $errors['email'] = get_string('usernameoremail'); | |
77 | + | |
78 | + } else if (!empty($data['email'])) { | |
79 | + if (!validate_email($data['email'])) { | |
80 | + $errors['email'] = get_string('invalidemail'); | |
81 | + | |
82 | + } else if ($DB->count_records('user', array('email'=>$data['email'])) > 1) { | |
83 | + $errors['email'] = get_string('forgottenduplicate'); | |
84 | + | |
85 | + } else { | |
86 | + if ($user = get_complete_user_data('email', $data['email'])) { | |
87 | + if (empty($user->confirmed)) { | |
88 | + $errors['email'] = get_string('confirmednot'); | |
89 | + } | |
90 | + } | |
91 | + if (!$user and empty($CFG->protectusernames)) { | |
92 | + $errors['email'] = get_string('emailnotfound'); | |
93 | + } | |
94 | + } | |
95 | + | |
96 | + } else { | |
97 | + if ($user = get_complete_user_data('username', $data['username'])) { | |
98 | + if (empty($user->confirmed)) { | |
99 | + $errors['email'] = get_string('confirmednot'); | |
100 | + } | |
101 | + } | |
102 | + if (!$user and empty($CFG->protectusernames)) { | |
103 | + $errors['username'] = get_string('usernamenotfound'); | |
104 | + } | |
105 | + } | |
106 | + | |
107 | + return $errors; | |
108 | + } | |
109 | + | |
110 | +} |
@@ -0,0 +1,369 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * Main login page. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +require('../config.php'); | |
28 | +require_once('lib.php'); | |
29 | + | |
30 | +// Try to prevent searching for sites that allow sign-up. | |
31 | +if (!isset($CFG->additionalhtmlhead)) { | |
32 | + $CFG->additionalhtmlhead = ''; | |
33 | +} | |
34 | +$CFG->additionalhtmlhead .= '<meta name="robots" content="noindex" />'; | |
35 | + | |
36 | +redirect_if_major_upgrade_required(); | |
37 | + | |
38 | +$testsession = optional_param('testsession', 0, PARAM_INT); // test session works properly | |
39 | +$cancel = optional_param('cancel', 0, PARAM_BOOL); // redirect to frontpage, needed for loginhttps | |
40 | +$anchor = optional_param('anchor', '', PARAM_RAW); // Used to restore hash anchor to wantsurl. | |
41 | + | |
42 | +if ($cancel) { | |
43 | + redirect(new moodle_url('/')); | |
44 | +} | |
45 | + | |
46 | +//HTTPS is required in this page when $CFG->loginhttps enabled | |
47 | +$PAGE->https_required(); | |
48 | + | |
49 | +$context = context_system::instance(); | |
50 | +$PAGE->set_url("$CFG->httpswwwroot/login/index.php"); | |
51 | +$PAGE->set_context($context); | |
52 | +$PAGE->set_pagelayout('login'); | |
53 | + | |
54 | +/// Initialize variables | |
55 | +$errormsg = ''; | |
56 | +$errorcode = 0; | |
57 | + | |
58 | +// login page requested session test | |
59 | +if ($testsession) { | |
60 | + if ($testsession == $USER->id) { | |
61 | + if (isset($SESSION->wantsurl)) { | |
62 | + $urltogo = $SESSION->wantsurl; | |
63 | + } else { | |
64 | + $urltogo = $CFG->wwwroot.'/'; | |
65 | + } | |
66 | + unset($SESSION->wantsurl); | |
67 | + redirect($urltogo); | |
68 | + } else { | |
69 | + // TODO: try to find out what is the exact reason why sessions do not work | |
70 | + $errormsg = get_string("cookiesnotenabled"); | |
71 | + $errorcode = 1; | |
72 | + } | |
73 | +} | |
74 | + | |
75 | +/// Check for timed out sessions | |
76 | +if (!empty($SESSION->has_timed_out)) { | |
77 | + $session_has_timed_out = true; | |
78 | + unset($SESSION->has_timed_out); | |
79 | +} else { | |
80 | + $session_has_timed_out = false; | |
81 | +} | |
82 | + | |
83 | +/// auth plugins may override these - SSO anyone? | |
84 | +$frm = false; | |
85 | +$user = false; | |
86 | + | |
87 | +$authsequence = get_enabled_auth_plugins(true); // auths, in sequence | |
88 | +foreach($authsequence as $authname) { | |
89 | + $authplugin = get_auth_plugin($authname); | |
90 | + $authplugin->loginpage_hook(); | |
91 | +} | |
92 | + | |
93 | + | |
94 | +/// Define variables used in page | |
95 | +$site = get_site(); | |
96 | + | |
97 | +// Ignore any active pages in the navigation/settings. | |
98 | +// We do this because there won't be an active page there, and by ignoring the active pages the | |
99 | +// navigation and settings won't be initialised unless something else needs them. | |
100 | +$PAGE->navbar->ignore_active(); | |
101 | +$loginsite = get_string("loginsite"); | |
102 | +$PAGE->navbar->add($loginsite); | |
103 | + | |
104 | +if ($user !== false or $frm !== false or $errormsg !== '') { | |
105 | + // some auth plugin already supplied full user, fake form data or prevented user login with error message | |
106 | + | |
107 | +} else if (!empty($SESSION->wantsurl) && file_exists($CFG->dirroot.'/login/weblinkauth.php')) { | |
108 | + // Handles the case of another Moodle site linking into a page on this site | |
109 | + //TODO: move weblink into own auth plugin | |
110 | + include($CFG->dirroot.'/login/weblinkauth.php'); | |
111 | + if (function_exists('weblink_auth')) { | |
112 | + $user = weblink_auth($SESSION->wantsurl); | |
113 | + } | |
114 | + if ($user) { | |
115 | + $frm->username = $user->username; | |
116 | + } else { | |
117 | + $frm = data_submitted(); | |
118 | + } | |
119 | + | |
120 | +} else { | |
121 | + $frm = data_submitted(); | |
122 | +} | |
123 | + | |
124 | +// Restore the #anchor to the original wantsurl. Note that this | |
125 | +// will only work for internal auth plugins, SSO plugins such as | |
126 | +// SAML / CAS / OIDC will have to handle this correctly directly. | |
127 | +if ($anchor && isset($SESSION->wantsurl) && strpos($SESSION->wantsurl, '#') === false) { | |
128 | + $wantsurl = new moodle_url($SESSION->wantsurl); | |
129 | + $wantsurl->set_anchor(substr($anchor, 1)); | |
130 | + $SESSION->wantsurl = $wantsurl->out(); | |
131 | +} | |
132 | + | |
133 | +/// Check if the user has actually submitted login data to us | |
134 | + | |
135 | +if ($frm and isset($frm->username)) { // Login WITH cookies | |
136 | + | |
137 | + $frm->username = trim(core_text::strtolower($frm->username)); | |
138 | + | |
139 | + if (is_enabled_auth('none') ) { | |
140 | + if ($frm->username !== core_user::clean_field($frm->username, 'username')) { | |
141 | + $errormsg = get_string('username').': '.get_string("invalidusername"); | |
142 | + $errorcode = 2; | |
143 | + $user = null; | |
144 | + } | |
145 | + } | |
146 | + | |
147 | + if ($user) { | |
148 | + //user already supplied by aut plugin prelogin hook | |
149 | + } else if (($frm->username == 'guest') and empty($CFG->guestloginbutton)) { | |
150 | + $user = false; /// Can't log in as guest if guest button is disabled | |
151 | + $frm = false; | |
152 | + } else { | |
153 | + if (empty($errormsg)) { | |
154 | + $user = authenticate_user_login($frm->username, $frm->password, false, $errorcode); | |
155 | + } | |
156 | + } | |
157 | + | |
158 | + // Intercept 'restored' users to provide them with info & reset password | |
159 | + if (!$user and $frm and is_restored_user($frm->username)) { | |
160 | + $PAGE->set_title(get_string('restoredaccount')); | |
161 | + $PAGE->set_heading($site->fullname); | |
162 | + echo $OUTPUT->header(); | |
163 | + echo $OUTPUT->heading(get_string('restoredaccount')); | |
164 | + echo $OUTPUT->box(get_string('restoredaccountinfo'), 'generalbox boxaligncenter'); | |
165 | + require_once('restored_password_form.php'); // Use our "supplanter" login_forgot_password_form. MDL-20846 | |
166 | + $form = new login_forgot_password_form('forgot_password.php', array('username' => $frm->username)); | |
167 | + $form->display(); | |
168 | + echo $OUTPUT->footer(); | |
169 | + die; | |
170 | + } | |
171 | + | |
172 | + if ($user) { | |
173 | + | |
174 | + // language setup | |
175 | + if (isguestuser($user)) { | |
176 | + // no predefined language for guests - use existing session or default site lang | |
177 | + unset($user->lang); | |
178 | + | |
179 | + } else if (!empty($user->lang)) { | |
180 | + // unset previous session language - use user preference instead | |
181 | + unset($SESSION->lang); | |
182 | + } | |
183 | + | |
184 | + if (empty($user->confirmed)) { // This account was never confirmed | |
185 | + $PAGE->set_title(get_string("mustconfirm")); | |
186 | + $PAGE->set_heading($site->fullname); | |
187 | + echo $OUTPUT->header(); | |
188 | + echo $OUTPUT->heading(get_string("mustconfirm")); | |
189 | + echo $OUTPUT->box(get_string("emailconfirmsent", "", $user->email), "generalbox boxaligncenter"); | |
190 | + echo $OUTPUT->footer(); | |
191 | + die; | |
192 | + } | |
193 | + | |
194 | + /// Let's get them all set up. | |
195 | + complete_user_login($user); | |
196 | + | |
197 | + \core\session\manager::apply_concurrent_login_limit($user->id, session_id()); | |
198 | + | |
199 | + // sets the username cookie | |
200 | + if (!empty($CFG->nolastloggedin)) { | |
201 | + // do not store last logged in user in cookie | |
202 | + // auth plugins can temporarily override this from loginpage_hook() | |
203 | + // do not save $CFG->nolastloggedin in database! | |
204 | + | |
205 | + } else if (empty($CFG->rememberusername) or ($CFG->rememberusername == 2 and empty($frm->rememberusername))) { | |
206 | + // no permanent cookies, delete old one if exists | |
207 | + set_moodle_cookie(''); | |
208 | + | |
209 | + } else { | |
210 | + set_moodle_cookie($USER->username); | |
211 | + } | |
212 | + | |
213 | + $urltogo = core_login_get_return_url(); | |
214 | + | |
215 | + /// check if user password has expired | |
216 | + /// Currently supported only for ldap-authentication module | |
217 | + $userauth = get_auth_plugin($USER->auth); | |
218 | + if (!isguestuser() and !empty($userauth->config->expiration) and $userauth->config->expiration == 1) { | |
219 | + $externalchangepassword = false; | |
220 | + if ($userauth->can_change_password()) { | |
221 | + $passwordchangeurl = $userauth->change_password_url(); | |
222 | + if (!$passwordchangeurl) { | |
223 | + $passwordchangeurl = $CFG->httpswwwroot.'/login/change_password.php'; | |
224 | + } else { | |
225 | + $externalchangepassword = true; | |
226 | + } | |
227 | + } else { | |
228 | + $passwordchangeurl = $CFG->httpswwwroot.'/login/change_password.php'; | |
229 | + } | |
230 | + $days2expire = $userauth->password_expire($USER->username); | |
231 | + $PAGE->set_title("$site->fullname: $loginsite"); | |
232 | + $PAGE->set_heading("$site->fullname"); | |
233 | + if (intval($days2expire) > 0 && intval($days2expire) < intval($userauth->config->expiration_warning)) { | |
234 | + echo $OUTPUT->header(); | |
235 | + echo $OUTPUT->confirm(get_string('auth_passwordwillexpire', 'auth', $days2expire), $passwordchangeurl, $urltogo); | |
236 | + echo $OUTPUT->footer(); | |
237 | + exit; | |
238 | + } elseif (intval($days2expire) < 0 ) { | |
239 | + if ($externalchangepassword) { | |
240 | + // We end the session if the change password form is external. This prevents access to the site | |
241 | + // until the password is correctly changed. | |
242 | + require_logout(); | |
243 | + } else { | |
244 | + // If we use the standard change password form, this user preference will be reset when the password | |
245 | + // is changed. Until then it will prevent access to the site. | |
246 | + set_user_preference('auth_forcepasswordchange', 1, $USER); | |
247 | + } | |
248 | + echo $OUTPUT->header(); | |
249 | + echo $OUTPUT->confirm(get_string('auth_passwordisexpired', 'auth'), $passwordchangeurl, $urltogo); | |
250 | + echo $OUTPUT->footer(); | |
251 | + exit; | |
252 | + } | |
253 | + } | |
254 | + | |
255 | + // Discard any errors before the last redirect. | |
256 | + unset($SESSION->loginerrormsg); | |
257 | + | |
258 | + // test the session actually works by redirecting to self | |
259 | + $SESSION->wantsurl = $urltogo; | |
260 | + redirect(new moodle_url(get_login_url(), array('testsession'=>$USER->id))); | |
261 | + | |
262 | + } else { | |
263 | + if (empty($errormsg)) { | |
264 | + if ($errorcode == AUTH_LOGIN_UNAUTHORISED) { | |
265 | + $errormsg = get_string("unauthorisedlogin", "", $frm->username); | |
266 | + } else { | |
267 | + $errormsg = get_string("invalidlogin"); | |
268 | + $errorcode = 3; | |
269 | + } | |
270 | + } | |
271 | + } | |
272 | +} | |
273 | + | |
274 | +/// Detect problems with timedout sessions | |
275 | +if ($session_has_timed_out and !data_submitted()) { | |
276 | + $errormsg = get_string('sessionerroruser', 'error'); | |
277 | + $errorcode = 4; | |
278 | +} | |
279 | + | |
280 | +/// First, let's remember where the user was trying to get to before they got here | |
281 | + | |
282 | +if (empty($SESSION->wantsurl)) { | |
283 | + $SESSION->wantsurl = null; | |
284 | + $referer = get_local_referer(false); | |
285 | + if ($referer && | |
286 | + $referer != $CFG->wwwroot && | |
287 | + $referer != $CFG->wwwroot . '/' && | |
288 | + $referer != $CFG->httpswwwroot . '/login/' && | |
289 | + strpos($referer, $CFG->httpswwwroot . '/login/?') !== 0 && | |
290 | + strpos($referer, $CFG->httpswwwroot . '/login/index.php') !== 0) { // There might be some extra params such as ?lang=. | |
291 | + $SESSION->wantsurl = $referer; | |
292 | + } | |
293 | +} | |
294 | + | |
295 | +/// Redirect to alternative login URL if needed | |
296 | +if (!empty($CFG->alternateloginurl)) { | |
297 | + $loginurl = new moodle_url($CFG->alternateloginurl); | |
298 | + | |
299 | + $loginurlstr = $loginurl->out(false); | |
300 | + | |
301 | + if (strpos($SESSION->wantsurl, $loginurlstr) === 0) { | |
302 | + // We do not want to return to alternate url. | |
303 | + $SESSION->wantsurl = null; | |
304 | + } | |
305 | + | |
306 | + // If error code then add that to url. | |
307 | + if ($errorcode) { | |
308 | + $loginurl->param('errorcode', $errorcode); | |
309 | + } | |
310 | + | |
311 | + redirect($loginurl->out(false)); | |
312 | +} | |
313 | + | |
314 | +// make sure we really are on the https page when https login required | |
315 | +$PAGE->verify_https_required(); | |
316 | + | |
317 | +/// Generate the login page with forms | |
318 | + | |
319 | +if (!isset($frm) or !is_object($frm)) { | |
320 | + $frm = new stdClass(); | |
321 | +} | |
322 | + | |
323 | +if (empty($frm->username) && $authsequence[0] != 'shibboleth') { // See bug 5184 | |
324 | + if (!empty($_GET["username"])) { | |
325 | + // we do not want data from _POST here | |
326 | + $frm->username = clean_param($_GET["username"], PARAM_RAW); // we do not want data from _POST here | |
327 | + } else { | |
328 | + $frm->username = get_moodle_cookie(); | |
329 | + } | |
330 | + | |
331 | + $frm->password = ""; | |
332 | +} | |
333 | + | |
334 | +if (!empty($SESSION->loginerrormsg)) { | |
335 | + // We had some errors before redirect, show them now. | |
336 | + $errormsg = $SESSION->loginerrormsg; | |
337 | + unset($SESSION->loginerrormsg); | |
338 | + | |
339 | +} else if ($testsession) { | |
340 | + // No need to redirect here. | |
341 | + unset($SESSION->loginerrormsg); | |
342 | + | |
343 | +} else if ($errormsg or !empty($frm->password)) { | |
344 | + // We must redirect after every password submission. | |
345 | + if ($errormsg) { | |
346 | + $SESSION->loginerrormsg = $errormsg; | |
347 | + } | |
348 | + redirect(new moodle_url($CFG->httpswwwroot . '/login/index.php')); | |
349 | +} | |
350 | + | |
351 | +$PAGE->set_title("$site->fullname: $loginsite"); | |
352 | +$PAGE->set_heading("$site->fullname"); | |
353 | + | |
354 | +echo $OUTPUT->header(); | |
355 | + | |
356 | +if (isloggedin() and !isguestuser()) { | |
357 | + // prevent logging when already logged in, we do not want them to relogin by accident because sesskey would be changed | |
358 | + echo $OUTPUT->box_start(); | |
359 | + $logout = new single_button(new moodle_url($CFG->httpswwwroot.'/login/logout.php', array('sesskey'=>sesskey(),'loginpage'=>1)), get_string('logout'), 'post'); | |
360 | + $continue = new single_button(new moodle_url($CFG->httpswwwroot.'/login/index.php', array('cancel'=>1)), get_string('cancel'), 'get'); | |
361 | + echo $OUTPUT->confirm(get_string('alreadyloggedin', 'error', fullname($USER)), $logout, $continue); | |
362 | + echo $OUTPUT->box_end(); | |
363 | +} else { | |
364 | + $loginform = new \core_auth\output\login($authsequence, $frm->username); | |
365 | + $loginform->set_error($errormsg); | |
366 | + echo $OUTPUT->render($loginform); | |
367 | +} | |
368 | + | |
369 | +echo $OUTPUT->footer(); |
@@ -0,0 +1,313 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * | |
19 | + * Login library file of login/password related Moodle functions. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage lib | |
23 | + * @copyright Catalyst IT | |
24 | + * @copyright Peter Bulmer | |
25 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
26 | + */ | |
27 | +define('PWRESET_STATUS_NOEMAILSENT', 1); | |
28 | +define('PWRESET_STATUS_TOKENSENT', 2); | |
29 | +define('PWRESET_STATUS_OTHEREMAILSENT', 3); | |
30 | +define('PWRESET_STATUS_ALREADYSENT', 4); | |
31 | + | |
32 | +/** | |
33 | + * Processes a user's request to set a new password in the event they forgot the old one. | |
34 | + * If no user identifier has been supplied, it displays a form where they can submit their identifier. | |
35 | + * Where they have supplied identifier, the function will check their status, and send email as appropriate. | |
36 | + */ | |
37 | +function core_login_process_password_reset_request() { | |
38 | + global $DB, $OUTPUT, $CFG, $PAGE; | |
39 | + $systemcontext = context_system::instance(); | |
40 | + $mform = new login_forgot_password_form(); | |
41 | + | |
42 | + if ($mform->is_cancelled()) { | |
43 | + redirect(get_login_url()); | |
44 | + | |
45 | + } else if ($data = $mform->get_data()) { | |
46 | + // Requesting user has submitted form data. | |
47 | + // Next find the user account in the database which the requesting user claims to own. | |
48 | + if (!empty($data->username)) { | |
49 | + // Username has been specified - load the user record based on that. | |
50 | + $username = core_text::strtolower($data->username); // Mimic the login page process. | |
51 | + $userparams = array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0, 'suspended' => 0); | |
52 | + $user = $DB->get_record('user', $userparams); | |
53 | + } else { | |
54 | + // Try to load the user record based on email address. | |
55 | + // this is tricky because | |
56 | + // 1/ the email is not guaranteed to be unique - TODO: send email with all usernames to select the account for pw reset | |
57 | + // 2/ mailbox may be case sensitive, the email domain is case insensitive - let's pretend it is all case-insensitive. | |
58 | + | |
59 | + $select = $DB->sql_like('email', ':email', false, true, false, '|') . | |
60 | + " AND mnethostid = :mnethostid AND deleted=0 AND suspended=0"; | |
61 | + $params = array('email' => $DB->sql_like_escape($data->email, '|'), 'mnethostid' => $CFG->mnet_localhost_id); | |
62 | + $user = $DB->get_record_select('user', $select, $params, '*', IGNORE_MULTIPLE); | |
63 | + } | |
64 | + | |
65 | + // Target user details have now been identified, or we know that there is no such account. | |
66 | + // Send email address to account's email address if appropriate. | |
67 | + $pwresetstatus = PWRESET_STATUS_NOEMAILSENT; | |
68 | + if ($user and !empty($user->confirmed)) { | |
69 | + $userauth = get_auth_plugin($user->auth); | |
70 | + if (!$userauth->can_reset_password() or !is_enabled_auth($user->auth) | |
71 | + or !has_capability('moodle/user:changeownpassword', $systemcontext, $user->id)) { | |
72 | + if (send_password_change_info($user)) { | |
73 | + $pwresetstatus = PWRESET_STATUS_OTHEREMAILSENT; | |
74 | + } else { | |
75 | + print_error('cannotmailconfirm'); | |
76 | + } | |
77 | + } else { | |
78 | + // The account the requesting user claims to be is entitled to change their password. | |
79 | + // Next, check if they have an existing password reset in progress. | |
80 | + $resetinprogress = $DB->get_record('user_password_resets', array('userid' => $user->id)); | |
81 | + if (empty($resetinprogress)) { | |
82 | + // Completely new reset request - common case. | |
83 | + $resetrecord = core_login_generate_password_reset($user); | |
84 | + $sendemail = true; | |
85 | + } else if ($resetinprogress->timerequested < (time() - $CFG->pwresettime)) { | |
86 | + // Preexisting, but expired request - delete old record & create new one. | |
87 | + // Uncommon case - expired requests are cleaned up by cron. | |
88 | + $DB->delete_records('user_password_resets', array('id' => $resetinprogress->id)); | |
89 | + $resetrecord = core_login_generate_password_reset($user); | |
90 | + $sendemail = true; | |
91 | + } else if (empty($resetinprogress->timererequested)) { | |
92 | + // Preexisting, valid request. This is the first time user has re-requested the reset. | |
93 | + // Re-sending the same email once can actually help in certain circumstances | |
94 | + // eg by reducing the delay caused by greylisting. | |
95 | + $resetinprogress->timererequested = time(); | |
96 | + $DB->update_record('user_password_resets', $resetinprogress); | |
97 | + $resetrecord = $resetinprogress; | |
98 | + $sendemail = true; | |
99 | + } else { | |
100 | + // Preexisting, valid request. User has already re-requested email. | |
101 | + $pwresetstatus = PWRESET_STATUS_ALREADYSENT; | |
102 | + $sendemail = false; | |
103 | + } | |
104 | + | |
105 | + if ($sendemail) { | |
106 | + $sendresult = send_password_change_confirmation_email($user, $resetrecord); | |
107 | + if ($sendresult) { | |
108 | + $pwresetstatus = PWRESET_STATUS_TOKENSENT; | |
109 | + } else { | |
110 | + print_error('cannotmailconfirm'); | |
111 | + } | |
112 | + } | |
113 | + } | |
114 | + } | |
115 | + | |
116 | + // Any email has now been sent. | |
117 | + // Next display results to requesting user if settings permit. | |
118 | + echo $OUTPUT->header(); | |
119 | + | |
120 | + if (!empty($CFG->protectusernames)) { | |
121 | + // Neither confirm, nor deny existance of any username or email address in database. | |
122 | + // Print general (non-commital) message. | |
123 | + notice(get_string('emailpasswordconfirmmaybesent'), $CFG->wwwroot.'/index.php'); | |
124 | + die; // Never reached. | |
125 | + } else if (empty($user)) { | |
126 | + // Protect usernames is off, and we couldn't find the user with details specified. | |
127 | + // Print failure advice. | |
128 | + notice(get_string('emailpasswordconfirmnotsent'), $CFG->wwwroot.'/forgot_password.php'); | |
129 | + die; // Never reached. | |
130 | + } else if (empty($user->email)) { | |
131 | + // User doesn't have an email set - can't send a password change confimation email. | |
132 | + notice(get_string('emailpasswordconfirmnoemail'), $CFG->wwwroot.'/index.php'); | |
133 | + die; // Never reached. | |
134 | + } else if ($pwresetstatus == PWRESET_STATUS_ALREADYSENT) { | |
135 | + // User found, protectusernames is off, but user has already (re) requested a reset. | |
136 | + // Don't send a 3rd reset email. | |
137 | + $stremailalreadysent = get_string('emailalreadysent'); | |
138 | + notice($stremailalreadysent, $CFG->wwwroot.'/index.php'); | |
139 | + die; // Never reached. | |
140 | + } else if ($pwresetstatus == PWRESET_STATUS_NOEMAILSENT) { | |
141 | + // User found, protectusernames is off, but user is not confirmed. | |
142 | + // Pretend we sent them an email. | |
143 | + // This is a big usability problem - need to tell users why we didn't send them an email. | |
144 | + // Obfuscate email address to protect privacy. | |
145 | + $protectedemail = preg_replace('/([^@]*)@(.*)/', '******@$2', $user->email); | |
146 | + $stremailpasswordconfirmsent = get_string('emailpasswordconfirmsent', '', $protectedemail); | |
147 | + notice($stremailpasswordconfirmsent, $CFG->wwwroot.'/index.php'); | |
148 | + die; // Never reached. | |
149 | + } else { | |
150 | + // Confirm email sent. (Obfuscate email address to protect privacy). | |
151 | + $protectedemail = preg_replace('/([^@]*)@(.*)/', '******@$2', $user->email); | |
152 | + // This is a small usability problem - may be obfuscating the email address which the user has just supplied. | |
153 | + $stremailresetconfirmsent = get_string('emailresetconfirmsent', '', $protectedemail); | |
154 | + notice($stremailresetconfirmsent, $CFG->wwwroot.'/index.php'); | |
155 | + die; // Never reached. | |
156 | + } | |
157 | + die; // Never reached. | |
158 | + } | |
159 | + | |
160 | + // Make sure we really are on the https page when https login required. | |
161 | + $PAGE->verify_https_required(); | |
162 | + | |
163 | + // DISPLAY FORM. | |
164 | + | |
165 | + echo $OUTPUT->header(); | |
166 | + echo $OUTPUT->box(get_string('passwordforgotteninstructions2'), 'generalbox boxwidthnormal boxaligncenter'); | |
167 | + $mform->display(); | |
168 | + | |
169 | + echo $OUTPUT->footer(); | |
170 | +} | |
171 | + | |
172 | +/** | |
173 | + * This function processes a user's submitted token to validate the request to set a new password. | |
174 | + * If the user's token is validated, they are prompted to set a new password. | |
175 | + * @param string $token the one-use identifier which should verify the password reset request as being valid. | |
176 | + * @return void | |
177 | + */ | |
178 | +function core_login_process_password_set($token) { | |
179 | + global $DB, $CFG, $OUTPUT, $PAGE, $SESSION; | |
180 | + require_once($CFG->dirroot.'/user/lib.php'); | |
181 | + | |
182 | + $pwresettime = isset($CFG->pwresettime) ? $CFG->pwresettime : 1800; | |
183 | + $sql = "SELECT u.*, upr.token, upr.timerequested, upr.id as tokenid | |
184 | + FROM {user} u | |
185 | + JOIN {user_password_resets} upr ON upr.userid = u.id | |
186 | + WHERE upr.token = ?"; | |
187 | + $user = $DB->get_record_sql($sql, array($token)); | |
188 | + | |
189 | + $forgotpasswordurl = "{$CFG->httpswwwroot}/login/forgot_password.php"; | |
190 | + if (empty($user) or ($user->timerequested < (time() - $pwresettime - DAYSECS))) { | |
191 | + // There is no valid reset request record - not even a recently expired one. | |
192 | + // (suspicious) | |
193 | + // Direct the user to the forgot password page to request a password reset. | |
194 | + echo $OUTPUT->header(); | |
195 | + notice(get_string('noresetrecord'), $forgotpasswordurl); | |
196 | + die; // Never reached. | |
197 | + } | |
198 | + if ($user->timerequested < (time() - $pwresettime)) { | |
199 | + // There is a reset record, but it's expired. | |
200 | + // Direct the user to the forgot password page to request a password reset. | |
201 | + $pwresetmins = floor($pwresettime / MINSECS); | |
202 | + echo $OUTPUT->header(); | |
203 | + notice(get_string('resetrecordexpired', '', $pwresetmins), $forgotpasswordurl); | |
204 | + die; // Never reached. | |
205 | + } | |
206 | + | |
207 | + if ($user->auth === 'nologin' or !is_enabled_auth($user->auth)) { | |
208 | + // Bad luck - user is not able to login, do not let them set password. | |
209 | + echo $OUTPUT->header(); | |
210 | + print_error('forgotteninvalidurl'); | |
211 | + die; // Never reached. | |
212 | + } | |
213 | + | |
214 | + // Check this isn't guest user. | |
215 | + if (isguestuser($user)) { | |
216 | + print_error('cannotresetguestpwd'); | |
217 | + } | |
218 | + | |
219 | + // Token is correct, and unexpired. | |
220 | + $mform = new login_set_password_form(null, $user); | |
221 | + $data = $mform->get_data(); | |
222 | + if (empty($data)) { | |
223 | + // User hasn't submitted form, they got here directly from email link. | |
224 | + // Next, display the form. | |
225 | + $setdata = new stdClass(); | |
226 | + $setdata->username = $user->username; | |
227 | + $setdata->username2 = $user->username; | |
228 | + $setdata->token = $user->token; | |
229 | + $mform->set_data($setdata); | |
230 | + $PAGE->verify_https_required(); | |
231 | + echo $OUTPUT->header(); | |
232 | + echo $OUTPUT->box(get_string('setpasswordinstructions'), 'generalbox boxwidthnormal boxaligncenter'); | |
233 | + $mform->display(); | |
234 | + echo $OUTPUT->footer(); | |
235 | + return; | |
236 | + } else { | |
237 | + // User has submitted form. | |
238 | + // Delete this token so it can't be used again. | |
239 | + $DB->delete_records('user_password_resets', array('id' => $user->tokenid)); | |
240 | + $userauth = get_auth_plugin($user->auth); | |
241 | + if (!$userauth->user_update_password($user, $data->password)) { | |
242 | + print_error('errorpasswordupdate', 'auth'); | |
243 | + } | |
244 | + user_add_password_history($user->id, $data->password); | |
245 | + if (!empty($CFG->passwordchangelogout)) { | |
246 | + \core\session\manager::kill_user_sessions($user->id, session_id()); | |
247 | + } | |
248 | + // Reset login lockout (if present) before a new password is set. | |
249 | + login_unlock_account($user); | |
250 | + // Clear any requirement to change passwords. | |
251 | + unset_user_preference('auth_forcepasswordchange', $user); | |
252 | + unset_user_preference('create_password', $user); | |
253 | + | |
254 | + if (!empty($user->lang)) { | |
255 | + // Unset previous session language - use user preference instead. | |
256 | + unset($SESSION->lang); | |
257 | + } | |
258 | + complete_user_login($user); // Triggers the login event. | |
259 | + | |
260 | + \core\session\manager::apply_concurrent_login_limit($user->id, session_id()); | |
261 | + | |
262 | + $urltogo = core_login_get_return_url(); | |
263 | + unset($SESSION->wantsurl); | |
264 | + redirect($urltogo, get_string('passwordset'), 1); | |
265 | + } | |
266 | +} | |
267 | + | |
268 | +/** Create a new record in the database to track a new password set request for user. | |
269 | + * @param object $user the user record, the requester would like a new password set for. | |
270 | + * @return record created. | |
271 | + */ | |
272 | +function core_login_generate_password_reset ($user) { | |
273 | + global $DB; | |
274 | + $resetrecord = new stdClass(); | |
275 | + $resetrecord->timerequested = time(); | |
276 | + $resetrecord->userid = $user->id; | |
277 | + $resetrecord->token = random_string(32); | |
278 | + $resetrecord->id = $DB->insert_record('user_password_resets', $resetrecord); | |
279 | + return $resetrecord; | |
280 | +} | |
281 | + | |
282 | +/** Determine where a user should be redirected after they have been logged in. | |
283 | + * @return string url the user should be redirected to. | |
284 | + */ | |
285 | +function core_login_get_return_url() { | |
286 | + global $CFG, $SESSION, $USER; | |
287 | + // Prepare redirection. | |
288 | + if (user_not_fully_set_up($USER, true)) { | |
289 | + $urltogo = $CFG->wwwroot.'/user/edit.php'; | |
290 | + // We don't delete $SESSION->wantsurl yet, so we get there later. | |
291 | + | |
292 | + } else if (isset($SESSION->wantsurl) and (strpos($SESSION->wantsurl, $CFG->wwwroot) === 0 | |
293 | + or strpos($SESSION->wantsurl, str_replace('http://', 'https://', $CFG->wwwroot)) === 0)) { | |
294 | + $urltogo = $SESSION->wantsurl; // Because it's an address in this site. | |
295 | + unset($SESSION->wantsurl); | |
296 | + } else { | |
297 | + // No wantsurl stored or external - go to homepage. | |
298 | + $urltogo = $CFG->wwwroot.'/'; | |
299 | + unset($SESSION->wantsurl); | |
300 | + } | |
301 | + | |
302 | + // If the url to go to is the same as the site page, check for default homepage. | |
303 | + if ($urltogo == ($CFG->wwwroot . '/')) { | |
304 | + $homepage = get_home_page(); | |
305 | + // Go to my-moodle page instead of site homepage if defaulthomepage set to homepage_my. | |
306 | + if ($homepage == HOMEPAGE_MY && !is_siteadmin() && !isguestuser()) { | |
307 | + if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot.'/' or $urltogo == $CFG->wwwroot.'/index.php') { | |
308 | + $urltogo = $CFG->wwwroot.'/my/'; | |
309 | + } | |
310 | + } | |
311 | + } | |
312 | + return $urltogo; | |
313 | +} |
@@ -0,0 +1,64 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * Logs the user out and sends them to the home page | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +require_once('../config.php'); | |
28 | + | |
29 | +$PAGE->set_url('/login/logout.php'); | |
30 | +$PAGE->set_context(context_system::instance()); | |
31 | + | |
32 | +$sesskey = optional_param('sesskey', '__notpresent__', PARAM_RAW); // we want not null default to prevent required sesskey warning | |
33 | +$login = optional_param('loginpage', 0, PARAM_BOOL); | |
34 | + | |
35 | +// can be overridden by auth plugins | |
36 | +if ($login) { | |
37 | + $redirect = get_login_url(); | |
38 | +} else { | |
39 | + $redirect = $CFG->wwwroot.'/'; | |
40 | +} | |
41 | + | |
42 | +if (!isloggedin()) { | |
43 | + // no confirmation, user has already logged out | |
44 | + require_logout(); | |
45 | + redirect($redirect); | |
46 | + | |
47 | +} else if (!confirm_sesskey($sesskey)) { | |
48 | + $PAGE->set_title($SITE->fullname); | |
49 | + $PAGE->set_heading($SITE->fullname); | |
50 | + echo $OUTPUT->header(); | |
51 | + echo $OUTPUT->confirm(get_string('logoutconfirm'), new moodle_url($PAGE->url, array('sesskey'=>sesskey())), $CFG->wwwroot.'/'); | |
52 | + echo $OUTPUT->footer(); | |
53 | + die; | |
54 | +} | |
55 | + | |
56 | +$authsequence = get_enabled_auth_plugins(); // auths, in sequence | |
57 | +foreach($authsequence as $authname) { | |
58 | + $authplugin = get_auth_plugin($authname); | |
59 | + $authplugin->logoutpage_hook(); | |
60 | +} | |
61 | + | |
62 | +require_logout(); | |
63 | + | |
64 | +redirect($redirect); | |
\ No newline at end of file |
@@ -0,0 +1,55 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * Magic that deals restored users without passwords. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +// This is one "supplanter" form that generates | |
28 | +// one correct forgot_password.php request in | |
29 | +// order to get the mailout for 'restored' users | |
30 | +// working automatically without having to | |
31 | +// fill the form manually (the user already has | |
32 | +// filled the username and it has been detected | |
33 | +// as a 'restored' one. Surely, some day this will | |
34 | +// be out, with the forgot_password utility being | |
35 | +// part of each plugin, but now now. See MDL-20846 | |
36 | +// for the rationale for this implementation. | |
37 | + | |
38 | +defined('MOODLE_INTERNAL') || die(); | |
39 | + | |
40 | +require_once $CFG->libdir.'/formslib.php'; | |
41 | + | |
42 | +class login_forgot_password_form extends moodleform { | |
43 | + | |
44 | + function definition() { | |
45 | + $mform = $this->_form; | |
46 | + | |
47 | + $username = $this->_customdata['username']; | |
48 | + | |
49 | + $mform->addElement('hidden', 'username', $username); | |
50 | + $mform->setType('username', PARAM_RAW); | |
51 | + | |
52 | + $this->add_action_buttons(false, get_string('continue')); | |
53 | + } | |
54 | + | |
55 | +} |
@@ -0,0 +1,116 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * Set password form definition. | |
19 | + * | |
20 | + * @package core | |
21 | + * @subpackage auth | |
22 | + * @copyright 2006 Petr Skoda {@link http://skodak.org} | |
23 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | + */ | |
25 | + | |
26 | +defined('MOODLE_INTERNAL') || die(); | |
27 | + | |
28 | +require_once($CFG->libdir.'/formslib.php'); | |
29 | +require_once($CFG->dirroot.'/user/lib.php'); | |
30 | + | |
31 | +/** | |
32 | + * Set forgotten password form definition. | |
33 | + * | |
34 | + * @package core | |
35 | + * @subpackage auth | |
36 | + * @copyright 2006 Petr Skoda {@link http://skodak.org} | |
37 | + * @copyright 2013 Peter Bulmer | |
38 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
39 | + */ | |
40 | +class login_set_password_form extends moodleform { | |
41 | + | |
42 | + /** | |
43 | + * Define the set password form. | |
44 | + */ | |
45 | + public function definition() { | |
46 | + global $CFG; | |
47 | + | |
48 | + $mform = $this->_form; | |
49 | + $mform->setDisableShortforms(true); | |
50 | + $mform->addElement('header', 'setpassword', get_string('setpassword'), ''); | |
51 | + | |
52 | + // Include the username in the form so browsers will recognise that a password is being set. | |
53 | + $mform->addElement('text', 'username', '', 'style="display: none;"'); | |
54 | + $mform->setType('username', PARAM_RAW); | |
55 | + // Token gives authority to change password. | |
56 | + $mform->addElement('hidden', 'token', ''); | |
57 | + $mform->setType('token', PARAM_ALPHANUM); | |
58 | + | |
59 | + // Visible elements. | |
60 | + $mform->addElement('static', 'username2', get_string('username')); | |
61 | + | |
62 | + $policies = array(); | |
63 | + if (!empty($CFG->passwordpolicy)) { | |
64 | + $policies[] = print_password_policy(); | |
65 | + } | |
66 | + if (!empty($CFG->passwordreuselimit) and $CFG->passwordreuselimit > 0) { | |
67 | + $policies[] = get_string('informminpasswordreuselimit', 'auth', $CFG->passwordreuselimit); | |
68 | + } | |
69 | + if ($policies) { | |
70 | + $mform->addElement('static', 'passwordpolicyinfo', '', implode('<br />', $policies)); | |
71 | + } | |
72 | + $mform->addElement('password', 'password', get_string('newpassword')); | |
73 | + $mform->addRule('password', get_string('required'), 'required', null, 'client'); | |
74 | + $mform->setType('password', PARAM_RAW); | |
75 | + | |
76 | + $strpasswordagain = get_string('newpassword') . ' (' . get_string('again') . ')'; | |
77 | + $mform->addElement('password', 'password2', $strpasswordagain); | |
78 | + $mform->addRule('password2', get_string('required'), 'required', null, 'client'); | |
79 | + $mform->setType('password2', PARAM_RAW); | |
80 | + | |
81 | + $this->add_action_buttons(true); | |
82 | + } | |
83 | + | |
84 | + /** | |
85 | + * Perform extra password change validation. | |
86 | + * @param array $data submitted form fields. | |
87 | + * @param array $files submitted with the form. | |
88 | + * @return array errors occuring during validation. | |
89 | + */ | |
90 | + public function validation($data, $files) { | |
91 | + $user = $this->_customdata; | |
92 | + | |
93 | + $errors = parent::validation($data, $files); | |
94 | + | |
95 | + // Ignore submitted username. | |
96 | + if ($data['password'] !== $data['password2']) { | |
97 | + $errors['password'] = get_string('passwordsdiffer'); | |
98 | + $errors['password2'] = get_string('passwordsdiffer'); | |
99 | + return $errors; | |
100 | + } | |
101 | + | |
102 | + $errmsg = ''; // Prevents eclipse warnings. | |
103 | + if (!check_password_policy($data['password'], $errmsg)) { | |
104 | + $errors['password'] = $errmsg; | |
105 | + $errors['password2'] = $errmsg; | |
106 | + return $errors; | |
107 | + } | |
108 | + | |
109 | + if (user_is_previously_used_password($user->id, $data['password'])) { | |
110 | + $errors['password'] = get_string('errorpasswordreused', 'core_auth'); | |
111 | + $errors['password2'] = get_string('errorpasswordreused', 'core_auth'); | |
112 | + } | |
113 | + | |
114 | + return $errors; | |
115 | + } | |
116 | +} |
@@ -0,0 +1,113 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * user signup page. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +require('../config.php'); | |
28 | +require_once($CFG->dirroot . '/user/editlib.php'); | |
29 | +require_once($CFG->libdir . '/authlib.php'); | |
30 | + | |
31 | +// Try to prevent searching for sites that allow sign-up. | |
32 | +if (!isset($CFG->additionalhtmlhead)) { | |
33 | + $CFG->additionalhtmlhead = ''; | |
34 | +} | |
35 | +$CFG->additionalhtmlhead .= '<meta name="robots" content="noindex" />'; | |
36 | + | |
37 | +if (!$authplugin = signup_is_enabled()) { | |
38 | + print_error('notlocalisederrormessage', 'error', '', 'Sorry, you may not use this page.'); | |
39 | +} | |
40 | + | |
41 | +//HTTPS is required in this page when $CFG->loginhttps enabled | |
42 | +$PAGE->https_required(); | |
43 | + | |
44 | +$PAGE->set_url('/login/signup.php'); | |
45 | +$PAGE->set_context(context_system::instance()); | |
46 | + | |
47 | +// If wantsurl is empty or /login/signup.php, override wanted URL. | |
48 | +// We do not want to end up here again if user clicks "Login". | |
49 | +if (empty($SESSION->wantsurl)) { | |
50 | + $SESSION->wantsurl = $CFG->wwwroot . '/'; | |
51 | +} else { | |
52 | + $wantsurl = new moodle_url($SESSION->wantsurl); | |
53 | + if ($PAGE->url->compare($wantsurl, URL_MATCH_BASE)) { | |
54 | + $SESSION->wantsurl = $CFG->wwwroot . '/'; | |
55 | + } | |
56 | +} | |
57 | + | |
58 | +if (isloggedin() and !isguestuser()) { | |
59 | + // Prevent signing up when already logged in. | |
60 | + echo $OUTPUT->header(); | |
61 | + echo $OUTPUT->box_start(); | |
62 | + $logout = new single_button(new moodle_url($CFG->httpswwwroot . '/login/logout.php', | |
63 | + array('sesskey' => sesskey(), 'loginpage' => 1)), get_string('logout'), 'post'); | |
64 | + $continue = new single_button(new moodle_url('/'), get_string('cancel'), 'get'); | |
65 | + echo $OUTPUT->confirm(get_string('cannotsignup', 'error', fullname($USER)), $logout, $continue); | |
66 | + echo $OUTPUT->box_end(); | |
67 | + echo $OUTPUT->footer(); | |
68 | + exit; | |
69 | +} | |
70 | + | |
71 | +$mform_signup = $authplugin->signup_form(); | |
72 | + | |
73 | +if ($mform_signup->is_cancelled()) { | |
74 | + redirect(get_login_url()); | |
75 | + | |
76 | +} else if ($user = $mform_signup->get_data()) { | |
77 | + // Add missing required fields. | |
78 | + $user = signup_setup_new_user($user); | |
79 | + | |
80 | + $authplugin->user_signup($user, true); // prints notice and link to login/index.php | |
81 | + exit; //never reached | |
82 | +} | |
83 | + | |
84 | +// make sure we really are on the https page when https login required | |
85 | +$PAGE->verify_https_required(); | |
86 | + | |
87 | + | |
88 | +$newaccount = get_string('newaccount'); | |
89 | +$login = get_string('login'); | |
90 | + | |
91 | +$PAGE->navbar->add($login); | |
92 | +$PAGE->navbar->add($newaccount); | |
93 | + | |
94 | +$PAGE->set_pagelayout('login'); | |
95 | +$PAGE->set_title($newaccount); | |
96 | +$PAGE->set_heading($SITE->fullname); | |
97 | + | |
98 | +echo $OUTPUT->header(); | |
99 | + | |
100 | +if ($mform_signup instanceof renderable) { | |
101 | + // Try and use the renderer from the auth plugin if it exists. | |
102 | + try { | |
103 | + $renderer = $PAGE->get_renderer('auth_' . $authplugin->authtype); | |
104 | + } catch (coding_exception $ce) { | |
105 | + // Fall back on the general renderer. | |
106 | + $renderer = $OUTPUT; | |
107 | + } | |
108 | + echo $renderer->render($mform_signup); | |
109 | +} else { | |
110 | + // Fall back for auth plugins not using renderables. | |
111 | + $mform_signup->display(); | |
112 | +} | |
113 | +echo $OUTPUT->footer(); |
@@ -0,0 +1,162 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * User sign-up form. | |
20 | + * | |
21 | + * @package core | |
22 | + * @subpackage auth | |
23 | + * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com | |
24 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | + */ | |
26 | + | |
27 | +defined('MOODLE_INTERNAL') || die(); | |
28 | + | |
29 | +require_once($CFG->libdir.'/formslib.php'); | |
30 | +require_once($CFG->dirroot.'/user/profile/lib.php'); | |
31 | +require_once($CFG->dirroot . '/user/editlib.php'); | |
32 | + | |
33 | +class login_signup_form extends moodleform implements renderable, templatable { | |
34 | + function definition() { | |
35 | + global $USER, $CFG; | |
36 | + | |
37 | + $mform = $this->_form; | |
38 | + | |
39 | + $mform->addElement('header', 'createuserandpass', get_string('createuserandpass'), ''); | |
40 | + | |
41 | + | |
42 | + $mform->addElement('text', 'username', get_string('username'), 'maxlength="100" size="12"'); | |
43 | + $mform->setType('username', PARAM_RAW); | |
44 | + $mform->addRule('username', get_string('missingusername'), 'required', null, 'client'); | |
45 | + | |
46 | + if (!empty($CFG->passwordpolicy)){ | |
47 | + $mform->addElement('static', 'passwordpolicyinfo', '', print_password_policy()); | |
48 | + } | |
49 | + $mform->addElement('password', 'password', get_string('password'), 'maxlength="32" size="12"'); | |
50 | + $mform->setType('password', core_user::get_property_type('password')); | |
51 | + $mform->addRule('password', get_string('missingpassword'), 'required', null, 'client'); | |
52 | + | |
53 | + $mform->addElement('header', 'supplyinfo', get_string('supplyinfo'),''); | |
54 | + | |
55 | + $mform->addElement('text', 'email', get_string('email'), 'maxlength="100" size="25"'); | |
56 | + $mform->setType('email', core_user::get_property_type('email')); | |
57 | + $mform->addRule('email', get_string('missingemail'), 'required', null, 'client'); | |
58 | + $mform->setForceLtr('email'); | |
59 | + | |
60 | + $mform->addElement('text', 'email2', get_string('emailagain'), 'maxlength="100" size="25"'); | |
61 | + $mform->setType('email2', core_user::get_property_type('email')); | |
62 | + $mform->addRule('email2', get_string('missingemail'), 'required', null, 'client'); | |
63 | + $mform->setForceLtr('email2'); | |
64 | + | |
65 | + $namefields = useredit_get_required_name_fields(); | |
66 | + foreach ($namefields as $field) { | |
67 | + $mform->addElement('text', $field, get_string($field), 'maxlength="100" size="30"'); | |
68 | + $mform->setType($field, core_user::get_property_type('firstname')); | |
69 | + $stringid = 'missing' . $field; | |
70 | + if (!get_string_manager()->string_exists($stringid, 'moodle')) { | |
71 | + $stringid = 'required'; | |
72 | + } | |
73 | + $mform->addRule($field, get_string($stringid), 'required', null, 'client'); | |
74 | + } | |
75 | + | |
76 | + $mform->addElement('text', 'city', get_string('city'), 'maxlength="120" size="20"'); | |
77 | + $mform->setType('city', core_user::get_property_type('city')); | |
78 | + if (!empty($CFG->defaultcity)) { | |
79 | + $mform->setDefault('city', $CFG->defaultcity); | |
80 | + } | |
81 | + | |
82 | + $country = get_string_manager()->get_list_of_countries(); | |
83 | + $default_country[''] = get_string('selectacountry'); | |
84 | + $country = array_merge($default_country, $country); | |
85 | + $mform->addElement('select', 'country', get_string('country'), $country); | |
86 | + | |
87 | + if( !empty($CFG->country) ){ | |
88 | + $mform->setDefault('country', $CFG->country); | |
89 | + }else{ | |
90 | + $mform->setDefault('country', ''); | |
91 | + } | |
92 | + | |
93 | + profile_signup_fields($mform); | |
94 | + | |
95 | + if (signup_captcha_enabled()) { | |
96 | + $mform->addElement('recaptcha', 'recaptcha_element', get_string('security_question', 'auth'), array('https' => $CFG->loginhttps)); | |
97 | + $mform->addHelpButton('recaptcha_element', 'recaptcha', 'auth'); | |
98 | + $mform->closeHeaderBefore('recaptcha_element'); | |
99 | + } | |
100 | + | |
101 | + if (!empty($CFG->sitepolicy)) { | |
102 | + $mform->addElement('header', 'policyagreement', get_string('policyagreement'), ''); | |
103 | + $mform->setExpanded('policyagreement'); | |
104 | + $mform->addElement('static', 'policylink', '', '<a href="'.$CFG->sitepolicy.'" onclick="this.target=\'_blank\'">'.get_String('policyagreementclick').'</a>'); | |
105 | + $mform->addElement('checkbox', 'policyagreed', get_string('policyaccept')); | |
106 | + $mform->addRule('policyagreed', get_string('policyagree'), 'required', null, 'client'); | |
107 | + } | |
108 | + | |
109 | + // buttons | |
110 | + $this->add_action_buttons(true, get_string('createaccount')); | |
111 | + | |
112 | + } | |
113 | + | |
114 | + function definition_after_data(){ | |
115 | + $mform = $this->_form; | |
116 | + $mform->applyFilter('username', 'trim'); | |
117 | + | |
118 | + // Trim required name fields. | |
119 | + foreach (useredit_get_required_name_fields() as $field) { | |
120 | + $mform->applyFilter($field, 'trim'); | |
121 | + } | |
122 | + } | |
123 | + | |
124 | + function validation($data, $files) { | |
125 | + $errors = parent::validation($data, $files); | |
126 | + | |
127 | + if (signup_captcha_enabled()) { | |
128 | + $recaptcha_element = $this->_form->getElement('recaptcha_element'); | |
129 | + if (!empty($this->_form->_submitValues['recaptcha_challenge_field'])) { | |
130 | + $challenge_field = $this->_form->_submitValues['recaptcha_challenge_field']; | |
131 | + $response_field = $this->_form->_submitValues['recaptcha_response_field']; | |
132 | + if (true !== ($result = $recaptcha_element->verify($challenge_field, $response_field))) { | |
133 | + $errors['recaptcha'] = $result; | |
134 | + } | |
135 | + } else { | |
136 | + $errors['recaptcha'] = get_string('missingrecaptchachallengefield'); | |
137 | + } | |
138 | + } | |
139 | + | |
140 | + $errors += signup_validate_data($data, $files); | |
141 | + | |
142 | + return $errors; | |
143 | + | |
144 | + } | |
145 | + | |
146 | + /** | |
147 | + * Export this data so it can be used as the context for a mustache template. | |
148 | + * | |
149 | + * @param renderer_base $output Used to do a final render of any components that need to be rendered for export. | |
150 | + * @return array | |
151 | + */ | |
152 | + public function export_for_template(renderer_base $output) { | |
153 | + ob_start(); | |
154 | + $this->display(); | |
155 | + $formhtml = ob_get_contents(); | |
156 | + ob_end_clean(); | |
157 | + $context = [ | |
158 | + 'formhtml' => $formhtml | |
159 | + ]; | |
160 | + return $context; | |
161 | + } | |
162 | +} |
@@ -0,0 +1,105 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * Return token | |
19 | + * @package moodlecore | |
20 | + * @copyright 2011 Dongsheng Cai <dongsheng@moodle.com> | |
21 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
22 | + */ | |
23 | + | |
24 | +define('AJAX_SCRIPT', true); | |
25 | +define('REQUIRE_CORRECT_ACCESS', true); | |
26 | +define('NO_MOODLE_COOKIES', true); | |
27 | + | |
28 | +require_once(__DIR__ . '/../config.php'); | |
29 | +require_once($CFG->libdir . '/externallib.php'); | |
30 | + | |
31 | +// Allow CORS requests. | |
32 | +header('Access-Control-Allow-Origin: *'); | |
33 | + | |
34 | +$username = required_param('username', PARAM_USERNAME); | |
35 | +$password = required_param('password', PARAM_RAW); | |
36 | +$serviceshortname = required_param('service', PARAM_ALPHANUMEXT); | |
37 | + | |
38 | +echo $OUTPUT->header(); | |
39 | + | |
40 | +if (!$CFG->enablewebservices) { | |
41 | + throw new moodle_exception('enablewsdescription', 'webservice'); | |
42 | +} | |
43 | +$username = trim(core_text::strtolower($username)); | |
44 | +if (is_restored_user($username)) { | |
45 | + throw new moodle_exception('restoredaccountresetpassword', 'webservice'); | |
46 | +} | |
47 | + | |
48 | +$systemcontext = context_system::instance(); | |
49 | + | |
50 | +$user = authenticate_user_login($username, $password); | |
51 | +if (!empty($user)) { | |
52 | + | |
53 | + // Cannot authenticate unless maintenance access is granted. | |
54 | + $hasmaintenanceaccess = has_capability('moodle/site:maintenanceaccess', $systemcontext, $user); | |
55 | + if (!empty($CFG->maintenance_enabled) and !$hasmaintenanceaccess) { | |
56 | + throw new moodle_exception('sitemaintenance', 'admin'); | |
57 | + } | |
58 | + | |
59 | + if (isguestuser($user)) { | |
60 | + throw new moodle_exception('noguest'); | |
61 | + } | |
62 | + if (empty($user->confirmed)) { | |
63 | + throw new moodle_exception('usernotconfirmed', 'moodle', '', $user->username); | |
64 | + } | |
65 | + // check credential expiry | |
66 | + $userauth = get_auth_plugin($user->auth); | |
67 | + if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) { | |
68 | + $days2expire = $userauth->password_expire($user->username); | |
69 | + if (intval($days2expire) < 0 ) { | |
70 | + throw new moodle_exception('passwordisexpired', 'webservice'); | |
71 | + } | |
72 | + } | |
73 | + | |
74 | + // let enrol plugins deal with new enrolments if necessary | |
75 | + enrol_check_plugins($user); | |
76 | + | |
77 | + // setup user session to check capability | |
78 | + \core\session\manager::set_user($user); | |
79 | + | |
80 | + //check if the service exists and is enabled | |
81 | + $service = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1)); | |
82 | + if (empty($service)) { | |
83 | + // will throw exception if no token found | |
84 | + throw new moodle_exception('servicenotavailable', 'webservice'); | |
85 | + } | |
86 | + | |
87 | + // Get an existing token or create a new one. | |
88 | + $token = external_generate_token_for_current_user($service); | |
89 | + $privatetoken = $token->privatetoken; | |
90 | + external_log_token_request($token); | |
91 | + | |
92 | + $siteadmin = has_capability('moodle/site:config', $systemcontext, $USER->id); | |
93 | + | |
94 | + $usertoken = new stdClass; | |
95 | + $usertoken->token = $token->token; | |
96 | + // Private token, only transmitted to https sites and non-admin users. | |
97 | + if (is_https() and !$siteadmin) { | |
98 | + $usertoken->privatetoken = $privatetoken; | |
99 | + } else { | |
100 | + $usertoken->privatetoken = null; | |
101 | + } | |
102 | + echo json_encode($usertoken); | |
103 | +} else { | |
104 | + throw new moodle_exception('invalidlogin'); | |
105 | +} |
@@ -0,0 +1,54 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * Reset locked-out accounts. | |
19 | + * | |
20 | + * @package core_auth | |
21 | + * @copyright 2012 Petr Skoda {@link http://skodak.org} | |
22 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
23 | + */ | |
24 | + | |
25 | +require('../config.php'); | |
26 | +require_once($CFG->libdir.'/authlib.php'); | |
27 | + | |
28 | +$userid = optional_param('u', 0, PARAM_INT); | |
29 | +$secret = optional_param('s', '', PARAM_RAW); | |
30 | + | |
31 | +$PAGE->set_url('/login/unlock_account.php'); | |
32 | +$PAGE->set_context(context_system::instance()); | |
33 | + | |
34 | +// Override wanted URL, we do not want to end up here again after login! | |
35 | +$SESSION->wantsurl = "$CFG->wwwroot/"; | |
36 | + | |
37 | +// Do not disclose details about existence or status of user accounts here. | |
38 | + | |
39 | +if (!$user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'suspended'=>0))) { | |
40 | + print_error('lockouterrorunlock', 'admin', get_login_url()); | |
41 | +} | |
42 | + | |
43 | +$usersecret = get_user_preferences('login_lockout_secret', false, $user); | |
44 | + | |
45 | +if ($secret === $usersecret) { | |
46 | + login_unlock_account($user); | |
47 | + if ($USER->id == $user->id) { | |
48 | + redirect("$CFG->wwwroot/"); | |
49 | + } else { | |
50 | + redirect(get_login_url()); | |
51 | + } | |
52 | +} | |
53 | + | |
54 | +print_error('lockouterrorunlock', 'admin', get_login_url()); |
@@ -0,0 +1,173 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * My Moodle -- a user's personal dashboard | |
19 | + * | |
20 | + * - each user can currently have their own page (cloned from system and then customised) | |
21 | + * - only the user can see their own dashboard | |
22 | + * - users can add any blocks they want | |
23 | + * - the administrators can define a default site dashboard for users who have | |
24 | + * not created their own dashboard | |
25 | + * | |
26 | + * This script implements the user's view of the dashboard, and allows editing | |
27 | + * of the dashboard. | |
28 | + * | |
29 | + * @package moodlecore | |
30 | + * @subpackage my | |
31 | + * @copyright 2010 Remote-Learner.net | |
32 | + * @author Hubert Chathi <hubert@remote-learner.net> | |
33 | + * @author Olav Jordan <olav.jordan@remote-learner.net> | |
34 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
35 | + */ | |
36 | + | |
37 | +require_once(__DIR__ . '/../config.php'); | |
38 | +require_once($CFG->dirroot . '/my/lib.php'); | |
39 | + | |
40 | +redirect_if_major_upgrade_required(); | |
41 | + | |
42 | +// TODO Add sesskey check to edit | |
43 | +$edit = optional_param('edit', null, PARAM_BOOL); // Turn editing on and off | |
44 | +$reset = optional_param('reset', null, PARAM_BOOL); | |
45 | + | |
46 | +require_login(); | |
47 | + | |
48 | +$hassiteconfig = has_capability('moodle/site:config', context_system::instance()); | |
49 | +if ($hassiteconfig && moodle_needs_upgrading()) { | |
50 | + redirect(new moodle_url('/admin/index.php')); | |
51 | +} | |
52 | + | |
53 | +$strmymoodle = get_string('myhome'); | |
54 | + | |
55 | +if (isguestuser()) { // Force them to see system default, no editing allowed | |
56 | + // If guests are not allowed my moodle, send them to front page. | |
57 | + if (empty($CFG->allowguestmymoodle)) { | |
58 | + redirect(new moodle_url('/', array('redirect' => 0))); | |
59 | + } | |
60 | + | |
61 | + $userid = null; | |
62 | + $USER->editing = $edit = 0; // Just in case | |
63 | + $context = context_system::instance(); | |
64 | + $PAGE->set_blocks_editing_capability('moodle/my:configsyspages'); // unlikely :) | |
65 | + $header = "$SITE->shortname: $strmymoodle (GUEST)"; | |
66 | + $pagetitle = $header; | |
67 | + | |
68 | +} else { // We are trying to view or edit our own My Moodle page | |
69 | + $userid = $USER->id; // Owner of the page | |
70 | + $context = context_user::instance($USER->id); | |
71 | + $PAGE->set_blocks_editing_capability('moodle/my:manageblocks'); | |
72 | + $header = fullname($USER); | |
73 | + $pagetitle = $strmymoodle; | |
74 | +} | |
75 | + | |
76 | +// Get the My Moodle page info. Should always return something unless the database is broken. | |
77 | +if (!$currentpage = my_get_page($userid, MY_PAGE_PRIVATE)) { | |
78 | + print_error('mymoodlesetup'); | |
79 | +} | |
80 | + | |
81 | +// Start setting up the page | |
82 | +$params = array(); | |
83 | +$PAGE->set_context($context); | |
84 | +$PAGE->set_url('/my/index.php', $params); | |
85 | +$PAGE->set_pagelayout('mydashboard'); | |
86 | +$PAGE->set_pagetype('my-index'); | |
87 | +$PAGE->blocks->add_region('content'); | |
88 | +$PAGE->set_subpage($currentpage->id); | |
89 | +$PAGE->set_title($pagetitle); | |
90 | +$PAGE->set_heading($header); | |
91 | + | |
92 | +if (!isguestuser()) { // Skip default home page for guests | |
93 | + if (get_home_page() != HOMEPAGE_MY) { | |
94 | + if (optional_param('setdefaulthome', false, PARAM_BOOL)) { | |
95 | + set_user_preference('user_home_page_preference', HOMEPAGE_MY); | |
96 | + } else if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_USER) { | |
97 | + $frontpagenode = $PAGE->settingsnav->add(get_string('frontpagesettings'), null, navigation_node::TYPE_SETTING, null); | |
98 | + $frontpagenode->force_open(); | |
99 | + $frontpagenode->add(get_string('makethismyhome'), new moodle_url('/my/', array('setdefaulthome' => true)), | |
100 | + navigation_node::TYPE_SETTING); | |
101 | + } | |
102 | + } | |
103 | +} | |
104 | + | |
105 | +// Toggle the editing state and switches | |
106 | +if (empty($CFG->forcedefaultmymoodle) && $PAGE->user_allowed_editing()) { | |
107 | + if ($reset !== null) { | |
108 | + if (!is_null($userid)) { | |
109 | + require_sesskey(); | |
110 | + if (!$currentpage = my_reset_page($userid, MY_PAGE_PRIVATE)) { | |
111 | + print_error('reseterror', 'my'); | |
112 | + } | |
113 | + redirect(new moodle_url('/my')); | |
114 | + } | |
115 | + } else if ($edit !== null) { // Editing state was specified | |
116 | + $USER->editing = $edit; // Change editing state | |
117 | + } else { // Editing state is in session | |
118 | + if ($currentpage->userid) { // It's a page we can edit, so load from session | |
119 | + if (!empty($USER->editing)) { | |
120 | + $edit = 1; | |
121 | + } else { | |
122 | + $edit = 0; | |
123 | + } | |
124 | + } else { | |
125 | + // For the page to display properly with the user context header the page blocks need to | |
126 | + // be copied over to the user context. | |
127 | + if (!$currentpage = my_copy_page($USER->id, MY_PAGE_PRIVATE)) { | |
128 | + print_error('mymoodlesetup'); | |
129 | + } | |
130 | + $context = context_user::instance($USER->id); | |
131 | + $PAGE->set_context($context); | |
132 | + $PAGE->set_subpage($currentpage->id); | |
133 | + // It's a system page and they are not allowed to edit system pages | |
134 | + $USER->editing = $edit = 0; // Disable editing completely, just to be safe | |
135 | + } | |
136 | + } | |
137 | + | |
138 | + // Add button for editing page | |
139 | + $params = array('edit' => !$edit); | |
140 | + | |
141 | + $resetbutton = ''; | |
142 | + $resetstring = get_string('resetpage', 'my'); | |
143 | + $reseturl = new moodle_url("$CFG->wwwroot/my/index.php", array('edit' => 1, 'reset' => 1)); | |
144 | + | |
145 | + if (!$currentpage->userid) { | |
146 | + // viewing a system page -- let the user customise it | |
147 | + $editstring = get_string('updatemymoodleon'); | |
148 | + $params['edit'] = 1; | |
149 | + } else if (empty($edit)) { | |
150 | + $editstring = get_string('updatemymoodleon'); | |
151 | + } else { | |
152 | + $editstring = get_string('updatemymoodleoff'); | |
153 | + $resetbutton = $OUTPUT->single_button($reseturl, $resetstring); | |
154 | + } | |
155 | + | |
156 | + $url = new moodle_url("$CFG->wwwroot/my/index.php", $params); | |
157 | + $button = $OUTPUT->single_button($url, $editstring); | |
158 | + $PAGE->set_button($resetbutton . $button); | |
159 | + | |
160 | +} else { | |
161 | + $USER->editing = $edit = 0; | |
162 | +} | |
163 | + | |
164 | +echo $OUTPUT->header(); | |
165 | + | |
166 | +echo $OUTPUT->custom_block_region('content'); | |
167 | + | |
168 | +echo $OUTPUT->footer(); | |
169 | + | |
170 | +// Trigger dashboard has been viewed event. | |
171 | +$eventparams = array('context' => $context); | |
172 | +$event = \core\event\dashboard_viewed::create($eventparams); | |
173 | +$event->trigger(); |
@@ -0,0 +1,78 @@ | ||
1 | +<?php | |
2 | + | |
3 | +// This file is part of Moodle - http://moodle.org/ | |
4 | +// | |
5 | +// Moodle is free software: you can redistribute it and/or modify | |
6 | +// it under the terms of the GNU General Public License as published by | |
7 | +// the Free Software Foundation, either version 3 of the License, or | |
8 | +// (at your option) any later version. | |
9 | +// | |
10 | +// Moodle is distributed in the hope that it will be useful, | |
11 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | +// GNU General Public License for more details. | |
14 | +// | |
15 | +// You should have received a copy of the GNU General Public License | |
16 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | +/** | |
19 | + * My Moodle -- a user's personal dashboard | |
20 | + * | |
21 | + * - each user can currently have their own page (cloned from system and then customised) | |
22 | + * - only the user can see their own dashboard | |
23 | + * - users can add any blocks they want | |
24 | + * - the administrators can define a default site dashboard for users who have | |
25 | + * not created their own dashboard | |
26 | + * | |
27 | + * This script implements the user's view of the dashboard, and allows editing | |
28 | + * of the dashboard. | |
29 | + * | |
30 | + * @package moodlecore | |
31 | + * @subpackage my | |
32 | + * @copyright 2010 Remote-Learner.net | |
33 | + * @author Hubert Chathi <hubert@remote-learner.net> | |
34 | + * @author Olav Jordan <olav.jordan@remote-learner.net> | |
35 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
36 | + */ | |
37 | + | |
38 | +require_once(__DIR__ . '/../config.php'); | |
39 | +require_once($CFG->dirroot . '/my/lib.php'); | |
40 | +require_once($CFG->libdir.'/adminlib.php'); | |
41 | + | |
42 | +$resetall = optional_param('resetall', null, PARAM_BOOL); | |
43 | + | |
44 | +require_login(); | |
45 | + | |
46 | +$header = "$SITE->shortname: ".get_string('myhome')." (".get_string('mypage', 'admin').")"; | |
47 | + | |
48 | +$PAGE->set_blocks_editing_capability('moodle/my:configsyspages'); | |
49 | +admin_externalpage_setup('mypage', '', null, '', array('pagelayout' => 'mydashboard')); | |
50 | + | |
51 | +if ($resetall && confirm_sesskey()) { | |
52 | + my_reset_page_for_all_users(MY_PAGE_PRIVATE, 'my-index'); | |
53 | + redirect($PAGE->url, get_string('alldashboardswerereset', 'my')); | |
54 | +} | |
55 | + | |
56 | +// Override pagetype to show blocks properly. | |
57 | +$PAGE->set_pagetype('my-index'); | |
58 | + | |
59 | +$PAGE->set_title($header); | |
60 | +$PAGE->set_heading($header); | |
61 | +$PAGE->blocks->add_region('content'); | |
62 | + | |
63 | +// Get the My Moodle page info. Should always return something unless the database is broken. | |
64 | +if (!$currentpage = my_get_page(null, MY_PAGE_PRIVATE)) { | |
65 | + print_error('mymoodlesetup'); | |
66 | +} | |
67 | +$PAGE->set_subpage($currentpage->id); | |
68 | + | |
69 | +// Display a button to reset everyone's dashboard. | |
70 | +$url = new moodle_url($PAGE->url, array('resetall' => 1)); | |
71 | +$button = $OUTPUT->single_button($url, get_string('reseteveryonesdashboard', 'my')); | |
72 | +$PAGE->set_button($button . $PAGE->button); | |
73 | + | |
74 | +echo $OUTPUT->header(); | |
75 | + | |
76 | +echo $OUTPUT->custom_block_region('content'); | |
77 | + | |
78 | +echo $OUTPUT->footer(); |
@@ -0,0 +1,230 @@ | ||
1 | +<?php | |
2 | +// This file is part of Moodle - http://moodle.org/ | |
3 | +// | |
4 | +// Moodle is free software: you can redistribute it and/or modify | |
5 | +// it under the terms of the GNU General Public License as published by | |
6 | +// the Free Software Foundation, either version 3 of the License, or | |
7 | +// (at your option) any later version. | |
8 | +// | |
9 | +// Moodle is distributed in the hope that it will be useful, | |
10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | +// GNU General Public License for more details. | |
13 | +// | |
14 | +// You should have received a copy of the GNU General Public License | |
15 | +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | + | |
17 | +/** | |
18 | + * My Moodle -- a user's personal dashboard | |
19 | + * | |
20 | + * This file contains common functions for the dashboard and profile pages. | |
21 | + * | |
22 | + * @package moodlecore | |
23 | + * @subpackage my | |
24 | + * @copyright 2010 Remote-Learner.net | |
25 | + * @author Hubert Chathi <hubert@remote-learner.net> | |
26 | + * @author Olav Jordan <olav.jordan@remote-learner.net> | |
27 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
28 | + */ | |
29 | + | |
30 | +define('MY_PAGE_PUBLIC', 0); | |
31 | +define('MY_PAGE_PRIVATE', 1); | |
32 | + | |
33 | +require_once("$CFG->libdir/blocklib.php"); | |
34 | + | |
35 | +/* | |
36 | + * For a given user, this returns the $page information for their My Moodle page | |
37 | + * | |
38 | + */ | |
39 | +function my_get_page($userid, $private=MY_PAGE_PRIVATE) { | |
40 | + global $DB, $CFG; | |
41 | + | |
42 | + if (empty($CFG->forcedefaultmymoodle) && $userid) { // Ignore custom My Moodle pages if admin has forced them | |
43 | + // Does the user have their own page defined? If so, return it. | |
44 | + if ($customised = $DB->get_record('my_pages', array('userid' => $userid, 'private' => $private))) { | |
45 | + return $customised; | |
46 | + } | |
47 | + } | |
48 | + | |
49 | + // Otherwise return the system default page | |
50 | + return $DB->get_record('my_pages', array('userid' => null, 'name' => '__default', 'private' => $private)); | |
51 | +} | |
52 | + | |
53 | + | |
54 | +/* | |
55 | + * This copies a system default page to the current user | |
56 | + * | |
57 | + */ | |
58 | +function my_copy_page($userid, $private=MY_PAGE_PRIVATE, $pagetype='my-index') { | |
59 | + global $DB; | |
60 | + | |
61 | + if ($customised = $DB->get_record('my_pages', array('userid' => $userid, 'private' => $private))) { | |
62 | + return $customised; // We're done! | |
63 | + } | |
64 | + | |
65 | + // Get the system default page | |
66 | + if (!$systempage = $DB->get_record('my_pages', array('userid' => null, 'private' => $private))) { | |
67 | + return false; // error | |
68 | + } | |
69 | + | |
70 | + // Clone the basic system page record | |
71 | + $page = clone($systempage); | |
72 | + unset($page->id); | |
73 | + $page->userid = $userid; | |
74 | + $page->id = $DB->insert_record('my_pages', $page); | |
75 | + | |
76 | + // Clone ALL the associated blocks as well | |
77 | + $systemcontext = context_system::instance(); | |
78 | + $usercontext = context_user::instance($userid); | |
79 | + | |
80 | + $blockinstances = $DB->get_records('block_instances', array('parentcontextid' => $systemcontext->id, | |
81 | + 'pagetypepattern' => $pagetype, | |
82 | + 'subpagepattern' => $systempage->id)); | |
83 | + $newblockinstanceids = []; | |
84 | + foreach ($blockinstances as $instance) { | |
85 | + $originalid = $instance->id; | |
86 | + unset($instance->id); | |
87 | + $instance->parentcontextid = $usercontext->id; | |
88 | + $instance->subpagepattern = $page->id; | |
89 | + $instance->id = $DB->insert_record('block_instances', $instance); | |
90 | + $newblockinstanceids[$originalid] = $instance->id; | |
91 | + $blockcontext = context_block::instance($instance->id); // Just creates the context record | |
92 | + $block = block_instance($instance->blockname, $instance); | |
93 | + if (!$block->instance_copy($originalid)) { | |
94 | + debugging("Unable to copy block-specific data for original block instance: $originalid | |
95 | + to new block instance: $instance->id", DEBUG_DEVELOPER); | |
96 | + } | |
97 | + } | |
98 | + | |
99 | + // Clone block position overrides. | |
100 | + if ($blockpositions = $DB->get_records('block_positions', | |
101 | + ['subpage' => $systempage->id, 'pagetype' => $pagetype, 'contextid' => $systemcontext->id])) { | |
102 | + foreach ($blockpositions as &$positions) { | |
103 | + $positions->subpage = $page->id; | |
104 | + $positions->contextid = $usercontext->id; | |
105 | + if (array_key_exists($positions->blockinstanceid, $newblockinstanceids)) { | |
106 | + // For block instances that were defined on the default dashboard and copied to the user dashboard | |
107 | + // use the new blockinstanceid. | |
108 | + $positions->blockinstanceid = $newblockinstanceids[$positions->blockinstanceid]; | |
109 | + } | |
110 | + unset($positions->id); | |
111 | + } | |
112 | + $DB->insert_records('block_positions', $blockpositions); | |
113 | + } | |
114 | + | |
115 | + return $page; | |
116 | +} | |
117 | + | |
118 | +/* | |
119 | + * For a given user, this deletes their My Moodle page and returns them to the system default. | |
120 | + * | |
121 | + * @param int $userid the id of the user whose page should be reset | |
122 | + * @param int $private either MY_PAGE_PRIVATE or MY_PAGE_PUBLIC | |
123 | + * @param string $pagetype either my-index or user-profile | |
124 | + * @return mixed system page, or false on error | |
125 | + */ | |
126 | +function my_reset_page($userid, $private=MY_PAGE_PRIVATE, $pagetype='my-index') { | |
127 | + global $DB, $CFG; | |
128 | + | |
129 | + $page = my_get_page($userid, $private); | |
130 | + if ($page->userid == $userid) { | |
131 | + $context = context_user::instance($userid); | |
132 | + if ($blocks = $DB->get_records('block_instances', array('parentcontextid' => $context->id, | |
133 | + 'pagetypepattern' => $pagetype))) { | |
134 | + foreach ($blocks as $block) { | |
135 | + if (is_null($block->subpagepattern) || $block->subpagepattern == $page->id) { | |
136 | + blocks_delete_instance($block); | |
137 | + } | |
138 | + } | |
139 | + } | |
140 | + $DB->delete_records('block_positions', ['subpage' => $page->id, 'pagetype' => $pagetype, 'contextid' => $context->id]); | |
141 | + $DB->delete_records('my_pages', array('id' => $page->id)); | |
142 | + } | |
143 | + | |
144 | + // Get the system default page | |
145 | + if (!$systempage = $DB->get_record('my_pages', array('userid' => null, 'private' => $private))) { | |
146 | + return false; // error | |
147 | + } | |
148 | + | |
149 | + // Trigger dashboard has been reset event. | |
150 | + $eventparams = array( | |
151 | + 'context' => context_user::instance($userid), | |
152 | + 'other' => array( | |
153 | + 'private' => $private, | |
154 | + 'pagetype' => $pagetype, | |
155 | + ), | |
156 | + ); | |
157 | + $event = \core\event\dashboard_reset::create($eventparams); | |
158 | + $event->trigger(); | |
159 | + return $systempage; | |
160 | +} | |
161 | + | |
162 | +/** | |
163 | + * Resets the page customisations for all users. | |
164 | + * | |
165 | + * @param int $private Either MY_PAGE_PRIVATE or MY_PAGE_PUBLIC. | |
166 | + * @param string $pagetype Either my-index or user-profile. | |
167 | + * @return void | |
168 | + */ | |
169 | +function my_reset_page_for_all_users($private = MY_PAGE_PRIVATE, $pagetype = 'my-index') { | |
170 | + global $DB; | |
171 | + | |
172 | + // This may take a while. Raise the execution time limit. | |
173 | + core_php_time_limit::raise(); | |
174 | + | |
175 | + // Find all the user pages and all block instances in them. | |
176 | + $sql = "SELECT bi.id | |
177 | + FROM {my_pages} p | |
178 | + JOIN {context} ctx ON ctx.instanceid = p.userid AND ctx.contextlevel = :usercontextlevel | |
179 | + JOIN {block_instances} bi ON bi.parentcontextid = ctx.id AND | |
180 | + bi.pagetypepattern = :pagetypepattern AND | |
181 | + (bi.subpagepattern IS NULL OR bi.subpagepattern = " . $DB->sql_concat("''", 'p.id') . ") | |
182 | + WHERE p.private = :private"; | |
183 | + $params = array('private' => $private, | |
184 | + 'usercontextlevel' => CONTEXT_USER, | |
185 | + 'pagetypepattern' => $pagetype); | |
186 | + $blockids = $DB->get_fieldset_sql($sql, $params); | |
187 | + | |
188 | + // Wrap the SQL queries in a transaction. | |
189 | + $transaction = $DB->start_delegated_transaction(); | |
190 | + | |
191 | + // Delete the block instances. | |
192 | + if (!empty($blockids)) { | |
193 | + blocks_delete_instances($blockids); | |
194 | + } | |
195 | + | |
196 | + // Finally delete the pages. | |
197 | + $DB->delete_records_select('my_pages', 'userid IS NOT NULL AND private = :private', ['private' => $private]); | |
198 | + | |
199 | + // We should be good to go now. | |
200 | + $transaction->allow_commit(); | |
201 | + | |
202 | + // Trigger dashboard has been reset event. | |
203 | + $eventparams = array( | |
204 | + 'context' => context_system::instance(), | |
205 | + 'other' => array( | |
206 | + 'private' => $private, | |
207 | + 'pagetype' => $pagetype, | |
208 | + ), | |
209 | + ); | |
210 | + $event = \core\event\dashboards_reset::create($eventparams); | |
211 | + $event->trigger(); | |
212 | +} | |
213 | + | |
214 | +class my_syspage_block_manager extends block_manager { | |
215 | + // HACK WARNING! | |
216 | + // TODO: figure out a better way to do this | |
217 | + /** | |
218 | + * Load blocks using the system context, rather than the user's context. | |
219 | + * | |
220 | + * This is needed because the My Moodle pages set the page context to the | |
221 | + * user's context for access control, etc. But the blocks for the system | |
222 | + * pages are stored in the system context. | |
223 | + */ | |
224 | + public function load_blocks($includeinvisible = null) { | |
225 | + $origcontext = $this->page->context; | |
226 | + $this->page->context = context_system::instance(); | |
227 | + parent::load_blocks($includeinvisible); | |
228 | + $this->page->context = $origcontext; | |
229 | + } | |
230 | +} |