*
* Note that you should not use PARAM_FLOAT for numbers typed in by the user.
* It does not work for languages that use , as a decimal separator.
- * Instead, do something like
- * $rawvalue = required_param('name', PARAM_RAW);
- * // ... other code including require_login, which sets current lang ...
- * $realvalue = unformat_float($rawvalue);
- * // ... then use $realvalue
+ * Use PARAM_LOCALISEDFLOAT instead.
*/
define('PARAM_FLOAT', 'float');
+/**
+ * PARAM_LOCALISEDFLOAT - a localised real/floating point number.
+ * This is preferred over PARAM_FLOAT for numbers typed in by the user.
+ * Cleans localised numbers to computer readable numbers; false for invalid numbers.
+ */
+define('PARAM_LOCALISEDFLOAT', 'localisedfloat');
+
/**
* PARAM_HOST - expected fully qualified domain name (FQDN) or an IPv4 dotted quad (IP address)
*/
// Convert to float.
return (float)$param;
+ case PARAM_LOCALISEDFLOAT:
+ // Convert to float.
+ return unformat_float($param, true);
+
case PARAM_ALPHA:
// Remove everything not `a-z`.
return preg_replace('/[^a-zA-Z]/i', '', $param);
$CFG->forceclean = true;
}
+ $afterlogins = get_plugins_with_function('after_require_login', 'lib.php');
+
// Do not bother admins with any formalities, except for activities pending deletion.
if (is_siteadmin() && !($cm && $cm->deletioninprogress)) {
// Set the global $COURSE.
if (!WS_SERVER && !AJAX_SCRIPT) {
user_accesstime_log($course->id);
}
+
+ foreach ($afterlogins as $plugintype => $plugins) {
+ foreach ($plugins as $pluginfunction) {
+ $pluginfunction($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect);
+ }
+ }
return;
}
$USER->enrol['enrolled'][$course->id] = $until;
$access = true;
- } else {
+ } else if (core_course_category::can_view_course_info($course)) {
$params = array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED);
$instances = $DB->get_records('enrol', $params, 'sortorder, id ASC');
$enrols = enrol_get_plugins(true);
}
}
}
+ } else {
+ // User is not enrolled and is not allowed to browse courses here.
+ if ($preventredirect) {
+ throw new require_login_exception('Course is not available');
+ }
+ $PAGE->set_context(null);
+ // We need to override the navigation URL as the course won't have been added to the navigation and thus
+ // the navigation will mess up when trying to find it.
+ navigation_node::override_active_url(new moodle_url('/'));
+ notice(get_string('coursehidden'), $CFG->wwwroot .'/');
}
}
}
$PAGE->set_course($course);
}
+ foreach ($afterlogins as $plugintype => $plugins) {
+ foreach ($plugins as $pluginfunction) {
+ $pluginfunction($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect);
+ }
+ }
+
// Finally access granted, update lastaccess times.
// Do not update access time for webservice or ajax requests.
if (!WS_SERVER && !AJAX_SCRIPT) {
* @param string $field The user field to be checked for a given value.
* @param string $value The value to match for $field.
* @param int $mnethostid
+ * @param bool $throwexception If true, it will throw an exception when there's no record found or when there are multiple records
+ * found. Otherwise, it will just return false.
* @return mixed False, or A {@link $USER} object.
*/
-function get_complete_user_data($field, $value, $mnethostid = null) {
+function get_complete_user_data($field, $value, $mnethostid = null, $throwexception = false) {
global $CFG, $DB;
if (!$field || !$value) {
$field = core_text::strtolower($field);
// List of case insensitive fields.
- $caseinsensitivefields = ['username'];
+ $caseinsensitivefields = ['username', 'email'];
// Build the WHERE clause for an SQL query.
$params = array('fieldval' => $value);
}
// Get all the basic user data.
- if (! $user = $DB->get_record_select('user', $constraints, $params)) {
- return false;
+ try {
+ // Make sure that there's only a single record that matches our query.
+ // For example, when fetching by email, multiple records might match the query as there's no guarantee that email addresses
+ // are unique. Therefore we can't reliably tell whether the user profile data that we're fetching is the correct one.
+ $user = $DB->get_record_select('user', $constraints, $params, '*', MUST_EXIST);
+ } catch (dml_exception $exception) {
+ if ($throwexception) {
+ throw $exception;
+ } else {
+ // Return false when no records or multiple records were found.
+ return false;
+ }
}
// Get various settings and preferences.
'siteshortname' => $SITE->shortname,
'sitewwwroot' => $CFG->wwwroot,
'subject' => $subject,
+ 'prefix' => $CFG->emailsubjectprefix,
'to' => $user->email,
'toname' => fullname($user),
'from' => $mail->From,
}
/**
- * Sends an email containinginformation on how to change your password.
+ * Sends an email containing information on how to change your password.
*
* @param stdClass $user A {@link $USER} object
* @return bool Returns true if mail was sent OK and false if there was an error.
*/
function send_password_change_info($user) {
- global $CFG;
-
$site = get_site();
$supportuser = core_user::get_support_user();
- $systemcontext = context_system::instance();
$data = new stdClass();
$data->firstname = $user->firstname;
$data->sitename = format_string($site->fullname);
$data->admin = generate_email_signoff();
- $userauth = get_auth_plugin($user->auth);
-
- if (!is_enabled_auth($user->auth) or $user->auth == 'nologin') {
+ if (!is_enabled_auth($user->auth)) {
$message = get_string('emailpasswordchangeinfodisabled', '', $data);
$subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
// Directly email rather than using the messaging system to ensure its not routed to a popup or jabber.
return email_to_user($user, $supportuser, $subject, $message);
}
- if ($userauth->can_change_password() and $userauth->change_password_url()) {
- // We have some external url for password changing.
- $data->link .= $userauth->change_password_url();
-
- } else {
- // No way to change password, sorry.
- $data->link = '';
- }
-
- if (!empty($data->link) and has_capability('moodle/user:changeownpassword', $systemcontext, $user->id)) {
- $message = get_string('emailpasswordchangeinfo', '', $data);
- $subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
- } else {
- $message = get_string('emailpasswordchangeinfofail', '', $data);
- $subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
- }
+ $userauth = get_auth_plugin($user->auth);
+ ['subject' => $subject, 'message' => $message] = $userauth->get_password_change_info($user);
// Directly email rather than using the messaging system to ensure its not routed to a popup or jabber.
return email_to_user($user, $supportuser, $subject, $message);
-
}
/**
if ($singleton === null) {
if (empty($CFG->early_install_lang)) {
+ $transaliases = array();
if (empty($CFG->langlist)) {
$translist = array();
} else {
$translist = explode(',', $CFG->langlist);
$translist = array_map('trim', $translist);
+ // Each language in the $CFG->langlist can has an "alias" that would substitute the default language name.
+ foreach ($translist as $i => $value) {
+ $parts = preg_split('/\s*\|\s*/', $value, 2);
+ if (count($parts) == 2) {
+ $transaliases[$parts[0]] = $parts[1];
+ $translist[$i] = $parts[0];
+ }
+ }
}
if (!empty($CFG->config_php_settings['customstringmanager'])) {
$implements = class_implements($classname);
if (isset($implements['core_string_manager'])) {
- $singleton = new $classname($CFG->langotherroot, $CFG->langlocalroot, $translist);
+ $singleton = new $classname($CFG->langotherroot, $CFG->langlocalroot, $translist, $transaliases);
return $singleton;
} else {
}
}
- $singleton = new core_string_manager_standard($CFG->langotherroot, $CFG->langlocalroot, $translist);
+ $singleton = new core_string_manager_standard($CFG->langotherroot, $CFG->langlocalroot, $translist, $transaliases);
} else {
$singleton = new core_string_manager_install();
// Attempt to avoid devs debugging peformance issues, when its caused by css building and so on.
$info['html'] .= '<p><strong>Warning: Theme designer mode is enabled.</strong></p>';
}
- $info['html'] .= '<ul class="list-unstyled m-l-1 row">'; // Holds userfriendly HTML representation.
+ $info['html'] .= '<ul class="list-unstyled ml-1 row">'; // Holds userfriendly HTML representation.
$info['realtime'] = microtime_diff($PERF->starttime, microtime());
$info['txt'] .= 'memory_peak: '.$info['memory_peak'].'B (' . display_size($info['memory_peak']).') ';
}
- $info['html'] .= '</ul><ul class="list-unstyled m-l-1 row">';
+ $info['html'] .= '</ul><ul class="list-unstyled ml-1 row">';
$inc = get_included_files();
$info['includecount'] = count($inc);
$info['html'] .= '<li class="included col-sm-4">Included '.$info['includecount'].' files</li> ';
$info['html'] .= '</ul>';
if ($stats = cache_helper::get_stats()) {
- $html = '<ul class="cachesused list-unstyled m-l-1 row">';
+ $html = '<ul class="cachesused list-unstyled ml-1 row">';
$html .= '<li class="cache-stats-heading font-weight-bold">Caches used (hits/misses/sets)</li>';
- $html .= '</ul><ul class="cachesused list-unstyled m-l-1">';
+ $html .= '</ul><ul class="cachesused list-unstyled ml-1">';
$text = 'Caches used (hits/misses/sets): ';
$hits = 0;
$misses = 0;
$mode = ' <span title="request cache">[r]</span>';
break;
}
- $html .= '<ul class="cache-definition-stats list-unstyled m-l-1 m-b-1 cache-mode-'.$modeclass.' card d-inline-block">';
+ $html .= '<ul class="cache-definition-stats list-unstyled ml-1 mb-1 cache-mode-'.$modeclass.' card d-inline-block">';
$html .= '<li class="cache-definition-stats-heading p-t-1 card-header bg-dark bg-inverse font-weight-bold">' .
$definition . $mode.'</li>';
$text .= "$definition {";
return $name;
}
}
+
+/**
+ * Tries to guess if $CFG->wwwroot is publicly accessible or not.
+ * Never put your faith on this function and rely on its accuracy as there might be false positives.
+ * It just performs some simple checks, and mainly is used for places where we want to hide some options
+ * such as site registration when $CFG->wwwroot is not publicly accessible.
+ * Good thing is there is no false negative.
+ *
+ * @return bool
+ */
+function site_is_public() {
+ global $CFG;
+
+ $host = parse_url($CFG->wwwroot, PHP_URL_HOST);
+
+ if ($host === 'localhost' || preg_match('|^127\.\d+\.\d+\.\d+$|', $host)) {
+ $ispublic = false;
+ } else if (\core\ip_utils::is_ip_address($host) && !ip_is_public($host)) {
+ $ispublic = false;
+ } else {
+ $ispublic = true;
+ }
+
+ return $ispublic;
+}