diff --git a/admin/index.php b/admin/index.php index b077d44e311..676c0423105 100644 --- a/admin/index.php +++ b/admin/index.php @@ -699,6 +699,7 @@ if (!$cache and moodle_needs_upgrading()) { if (during_initial_install()) { set_config('rolesactive', 1); // after this, during_initial_install will return false. set_config('adminsetuppending', 1); + set_config('registrationpending', 1); // Remind to register site after all other setup is finished. // we need this redirect to setup proper session upgrade_finished("index.php?sessionstarted=1&lang=$CFG->lang"); } @@ -814,6 +815,9 @@ if (isset($SESSION->pluginuninstallreturn)) { } } +// If site registration needs updating, redirect. +\core\hub\registration::registration_reminder('/admin/index.php'); + // Everything should now be set up, and the user is an admin // Print default admin page with notifications. diff --git a/admin/registration/confirmregistration.php b/admin/registration/confirmregistration.php index 7fe7689e90c..6b20e8db068 100644 --- a/admin/registration/confirmregistration.php +++ b/admin/registration/confirmregistration.php @@ -64,8 +64,10 @@ echo $OUTPUT->heading(get_string('registrationconfirmed', 'hub'), 3, 'main'); echo $OUTPUT->notification(get_string('registrationconfirmedon', 'hub'), 'notifysuccess'); // Display continue button. -$registrationpage = new moodle_url('/admin/registration/index.php'); -$continuebutton = $OUTPUT->render(new single_button($registrationpage, get_string('continue'))); +$returnurl = !empty($SESSION->registrationredirect) ? clean_param($SESSION->registrationredirect, PARAM_LOCALURL) : null; +unset($SESSION->registrationredirect); +$continueurl = new moodle_url($returnurl ?: '/admin/registration/index.php'); +$continuebutton = $OUTPUT->render(new single_button($continueurl, get_string('continue'))); $continuebutton = html_writer::tag('div', $continuebutton, array('class' => 'mdl-align')); echo $continuebutton; diff --git a/admin/registration/index.php b/admin/registration/index.php index 0adb27ba71d..dee1ba00416 100644 --- a/admin/registration/index.php +++ b/admin/registration/index.php @@ -53,17 +53,25 @@ if ($unregistration && \core\hub\registration::is_registered()) { exit; } +$isinitialregistration = \core\hub\registration::show_after_install(true); +if (!$returnurl = optional_param('returnurl', null, PARAM_LOCALURL)) { + $returnurl = $isinitialregistration ? '/admin/index.php' : '/admin/registration/index.php'; +} + $siteregistrationform = new \core\hub\site_registration_form(); +$siteregistrationform->set_data(['returnurl' => $returnurl]); if ($fromform = $siteregistrationform->get_data()) { // Save the settings. \core\hub\registration::save_site_info($fromform); if (\core\hub\registration::is_registered()) { - \core\hub\registration::update_manual(); - redirect(new moodle_url('/admin/registration/index.php')); + if (\core\hub\registration::update_manual()) { + redirect(new moodle_url($returnurl)); + } + redirect(new moodle_url('/admin/registration/index.php', ['returnurl' => $returnurl])); } else { - \core\hub\registration::register(); + \core\hub\registration::register($returnurl); // This method will redirect away. } @@ -80,13 +88,15 @@ if (\core\hub\registration::is_registered()) { $lastupdated = \core\hub\registration::get_last_updated(); if ($lastupdated == 0) { $registrationmessage = get_string('pleaserefreshregistrationunknown', 'admin'); + } else if (\core\hub\registration::get_new_registration_fields()) { + $registrationmessage = get_string('pleaserefreshregistrationnewdata', 'admin'); } else { $lastupdated = userdate($lastupdated, get_string('strftimedate', 'langconfig')); $registrationmessage = get_string('pleaserefreshregistration', 'admin', $lastupdated); $notificationtype = \core\output\notification::NOTIFY_INFO; } echo $OUTPUT->notification($registrationmessage, $notificationtype); -} else { +} else if (!$isinitialregistration) { $registrationmessage = get_string('registrationwarning', 'admin'); echo $OUTPUT->notification($registrationmessage, $notificationtype); } @@ -94,6 +104,8 @@ if (\core\hub\registration::is_registered()) { // Heading. if (\core\hub\registration::is_registered()) { echo $OUTPUT->heading(get_string('updatesite', 'hub', 'Moodle.net')); +} else if ($isinitialregistration) { + echo $OUTPUT->heading(get_string('completeregistration', 'hub')); } else { echo $OUTPUT->heading(get_string('registerwithmoodleorg', 'admin')); } @@ -107,5 +119,7 @@ if (\core\hub\registration::is_registered()) { // Unregister link. $unregisterhuburl = new moodle_url("/admin/registration/index.php", ['unregistration' => 1]); echo html_writer::div(html_writer::link($unregisterhuburl, get_string('unregister', 'hub')), 'unregister'); +} else if ($isinitialregistration) { + echo html_writer::div(html_writer::link(new moodle_url($returnurl), get_string('skipregistration', 'hub')), 'skipregistration'); } echo $OUTPUT->footer(); diff --git a/admin/search.php b/admin/search.php index 623cf1cfcf2..dfb60433cd8 100644 --- a/admin/search.php +++ b/admin/search.php @@ -18,6 +18,9 @@ if ($hassiteconfig && moodle_needs_upgrading()) { redirect(new moodle_url('/admin/index.php')); } +// If site registration needs updating, redirect. +\core\hub\registration::registration_reminder('/admin/search.php'); + admin_externalpage_setup('search', '', array('query' => $query)); // now hidden page $adminroot = admin_get_root(); // need all settings here diff --git a/index.php b/index.php index c7bed108852..e95b0bb0d13 100644 --- a/index.php +++ b/index.php @@ -66,6 +66,9 @@ if ($hassiteconfig && moodle_needs_upgrading()) { redirect($CFG->wwwroot .'/'. $CFG->admin .'/index.php'); } +// If site registration needs updating, redirect. +\core\hub\registration::registration_reminder('/index.php'); + if (get_home_page() != HOMEPAGE_SITE) { // Redirect logged-in users to My Moodle overview if required. $redirect = optional_param('redirect', 1, PARAM_BOOL); diff --git a/lang/en/admin.php b/lang/en/admin.php index 3ca6c876a4a..278bebeb37b 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -843,6 +843,7 @@ $string['pgclusterdescription'] = 'PostgreSQL version/cluster parameter for comm $string['phpfloatproblem'] = 'Detected unexpected problem in handling of PHP float numbers - {$a}'; $string['pleaserefreshregistration'] = 'Your site is registered. Registration last updated {$a}.
The \'Site registration\' scheduled task keeps your registration up to date. You can also manually update your registration at any time.'; $string['pleaserefreshregistrationunknown'] = 'Your site has been registered but the registration date is unknown. Please update your registration using the \'Update registration\' button or ensure that the \'Site registration\' scheduled task is enabled so your registration is automatically updated.'; +$string['pleaserefreshregistrationnewdata'] = 'Registration information has been changed. Please confirm it using the \'Update registration\' button.'; $string['plugin'] = 'Plugin'; $string['plugins'] = 'Plugins'; $string['pluginscheck'] = 'Plugin dependencies check'; diff --git a/lang/en/hub.php b/lang/en/hub.php index 8644b4e6328..1ce9b7cdac8 100644 --- a/lang/en/hub.php +++ b/lang/en/hub.php @@ -36,6 +36,7 @@ $string['audiencestudents'] = 'Students'; $string['audienceadmins'] = 'Moodle administrators'; $string['badgesnumber'] = 'Number of badges ({$a})'; $string['communityremoved'] = 'That course link has been removed from your list'; +$string['completeregistration'] = 'Complete registration with Moodle.net'; $string['confirmregistration'] = 'Confirm registration'; $string['contributornames'] = 'Other contributors'; $string['contributornames_help'] = 'You can use this field to list the names of anyone else who contributed to this course.'; @@ -185,6 +186,7 @@ $string['siteurl'] = 'Site URL'; $string['siteurl_help'] = 'The URL is the address of this site. If privacy settings allow people to see site addresses then this is the URL that will be used.'; $string['siteversion'] = 'Moodle version'; $string['siteversion_help'] = 'The Moodle version of this site.'; +$string['skipregistration'] = 'Skip'; $string['subject'] = 'Subject'; $string['subject_help'] = 'Select the main subject area which the course covers.'; $string['status'] = 'Listing status'; diff --git a/lib/classes/hub/registration.php b/lib/classes/hub/registration.php index 9bca6fb0564..30817b0fc6a 100644 --- a/lib/classes/hub/registration.php +++ b/lib/classes/hub/registration.php @@ -40,10 +40,23 @@ use html_writer; */ class registration { - /** @var Fields used in a site registration form */ + /** @var Fields used in a site registration form. + * IMPORTANT: any new fields with non-empty defaults have to be added to CONFIRM_NEW_FIELDS */ const FORM_FIELDS = ['name', 'description', 'contactname', 'contactemail', 'contactphone', 'imageurl', 'privacy', 'street', 'regioncode', 'countrycode', 'geolocation', 'contactable', 'emailalert', 'emailalertemail', 'commnews', 'commnewsemail', 'language']; + /** @var List of new FORM_FIELDS or siteinfo fields added indexed by the version when they were added. + * If site was already registered, admin will be promted to confirm new registration data manually. Until registration is manually confirmed, + * the scheduled task updating registration will be paused. + * Keys of this array are not important as long as they increment, use current date to avoid confusions. + */ + const CONFIRM_NEW_FIELDS = [ + 2017092200 => [ + 'commnews', // Receive communication news. This was added in 3.4 and is "On" by default. Admin must confirm or opt-out. + 'mobileservicesenabled', 'mobilenotificationsenabled', 'registereduserdevices', 'registeredactiveuserdevices' // Mobile stats added in 3.4. + ], + ]; + /** @var Site privacy: not displayed */ const HUB_SITENOTPUBLISHED = 'notdisplayed'; @@ -182,6 +195,8 @@ class registration { } } + // IMPORTANT: any new fields in siteinfo have to be added to the constant CONFIRM_NEW_FIELDS. + return $siteinfo; } @@ -192,6 +207,7 @@ class registration { * @return string */ public static function get_stats_summary($siteinfo) { + $fieldsneedconfirm = self::get_new_registration_fields(); $summary = html_writer::tag('p', get_string('sendfollowinginfo_help', 'hub')) . html_writer::start_tag('ul'); @@ -222,7 +238,8 @@ class registration { ]; foreach ($senddata as $key => $str) { - $summary .= html_writer::tag('li', $str, ['class' => 'site' . $key]); + $class = in_array($key, $fieldsneedconfirm) ? ' needsconfirmation mark' : ''; + $summary .= html_writer::tag('li', $str, ['class' => 'site' . $key . $class]); } $summary .= html_writer::end_tag('ul'); return $summary; @@ -238,6 +255,9 @@ class registration { foreach (self::FORM_FIELDS as $field) { set_config('site_' . $field . '_' . $cleanhuburl, $formdata->$field, 'hub'); } + // Even if the the connection with moodle.net fails, admin has manually submitted the form which means they don't need + // to be redirected to the site registration page any more. + set_config('site_regupdateversion_' . $cleanhuburl, max(array_keys(self::CONFIRM_NEW_FIELDS)), 'hub'); } /** @@ -278,6 +298,11 @@ class registration { return; } + if (self::get_new_registration_fields()) { + mtrace(get_string('pleaserefreshregistrationnewdata', 'admin')); + return; + } + $siteinfo = self::get_site_info(); api::update_registration($siteinfo); $DB->update_record('registration_hubs', ['id' => $registration->id, 'timemodified' => time()]); @@ -329,10 +354,11 @@ class registration { * Moodle.net will check that the site is accessible, register it and redirect back * to /admin/registration/confirmregistration.php * + * @param string $returnurl * @throws \coding_exception */ - public static function register() { - global $DB; + public static function register($returnurl) { + global $DB, $SESSION; if (self::is_registered()) { // Caller of this method must make sure that site is not registered. @@ -356,6 +382,7 @@ class registration { $params = self::get_site_info(); $params['token'] = $hub->token; + $SESSION->registrationredirect = $returnurl; redirect(new moodle_url(HUB_MOODLEORGHUBURL . '/local/hub/siteregistration.php', $params)); } @@ -450,4 +477,72 @@ class registration { return null; } } + + /** + * Does admin need to be redirected to the registration page after install? + * + * @param bool|null $markasviewed if set to true will mark the registration form as viewed and admin will not be redirected + * to the registration form again (regardless of whether the site was registered or not). + * @return bool + */ + public static function show_after_install($markasviewed = null) { + global $CFG; + if (self::is_registered()) { + $showregistration = false; + $markasviewed = true; + } else { + $showregistration = !empty($CFG->registrationpending); + if ($showregistration) { + $host = parse_url($CFG->wwwroot, PHP_URL_HOST); + if ($host === 'localhost' || preg_match('|^127\.\d+\.\d+\.\d+$|', $host)) { + // If it's a localhost, don't redirect to registration, it won't work anyway. + $showregistration = false; + $markasviewed = true; + } + } + } + if ($markasviewed !== null) { + set_config('registrationpending', !$markasviewed); + } + return $showregistration; + } + + /** + * Returns the list of the fields in the registration form that were added since registration or last manual update + * + * If this list is not empty the scheduled task will be paused and admin will be reminded to update registration manually. + * + * @return array + */ + public static function get_new_registration_fields() { + $fieldsneedconfirm = []; + if (!self::is_registered()) { + // Nothing to update if site is not registered. + return $fieldsneedconfirm; + } + + $cleanhuburl = clean_param(HUB_MOODLEORGHUBURL, PARAM_ALPHANUMEXT); + $lastupdated = (int)get_config('hub', 'site_regupdateversion_' . $cleanhuburl); + foreach (self::CONFIRM_NEW_FIELDS as $version => $fields) { + if ($version > $lastupdated) { + $fieldsneedconfirm = array_merge($fieldsneedconfirm, $fields); + } + } + return $fieldsneedconfirm; + } + + /** + * Redirect to the site registration form if it's a new install or registration needs updating + * + * @param string|moodle_url $url + */ + public static function registration_reminder($url) { + if (!has_capability('moodle/site:config', context_system::instance())) { + return; + } + if (self::show_after_install() || self::get_new_registration_fields()) { + $returnurl = new moodle_url($url); + redirect(new moodle_url('/admin/registration/index.php', ['returnurl' => $returnurl->out_as_local_url(false)])); + } + } } \ No newline at end of file diff --git a/lib/classes/hub/site_registration_form.php b/lib/classes/hub/site_registration_form.php index 3b8a6fd89f0..317862eea14 100644 --- a/lib/classes/hub/site_registration_form.php +++ b/lib/classes/hub/site_registration_form.php @@ -68,6 +68,9 @@ class site_registration_form extends \moodleform { ]); + // Fields that need to be highlighted. + $highlightfields = registration::get_new_registration_fields(); + $mform->addElement('header', 'moodle', get_string('registrationinfo', 'hub')); $mform->addElement('text', 'name', get_string('sitename', 'hub'), @@ -142,14 +145,14 @@ class site_registration_form extends \moodleform { $this->add_select_with_email('commnews', 'sitecommnews', [ 0 => get_string('sitecommnewsno', 'hub'), 1 => get_string('sitecommnewsyes', 'hub'), - ]); + ], in_array('commnews', $highlightfields)); // TODO site logo. $mform->addElement('hidden', 'imageurl', ''); // TODO: temporary. $mform->setType('imageurl', PARAM_URL); $mform->addElement('header', 'sitestats', get_string('sendfollowinginfo', 'hub')); - $mform->setExpanded('sitestats', false); + $mform->setExpanded('sitestats', !empty($highlightfields)); $mform->addElement('static', 'urlstring', get_string('siteurl', 'hub'), $siteinfo['url']); $mform->addHelpButton('urlstring', 'siteurl', 'hub'); @@ -167,6 +170,9 @@ class site_registration_form extends \moodleform { $this->add_action_buttons(false, $buttonlabel); + $mform->addElement('hidden', 'returnurl'); + $mform->setType('returnurl', PARAM_LOCALURL); + $this->set_data($siteinfo); } @@ -176,8 +182,9 @@ class site_registration_form extends \moodleform { * @param string $elementname * @param string $stridentifier * @param array|null $options options for the select element + * @param bool $highlight highlight as a new field */ - protected function add_select_with_email($elementname, $stridentifier, $options = null) { + protected function add_select_with_email($elementname, $stridentifier, $options = null, $highlight = false) { $mform = $this->_form; if ($options === null) { @@ -192,7 +199,10 @@ class site_registration_form extends \moodleform { $mform->createElement('text', $elementname . 'email', get_string('email')) ]; - $mform->addElement('group', $elementname . 'group', get_string($stridentifier, 'hub'), $group, '', false); + $element = $mform->addElement('group', $elementname . 'group', get_string($stridentifier, 'hub'), $group, '', false); + if ($highlight) { + $element->setAttributes(['class' => $element->getAttribute('class') . ' needsconfirmation mark']); + } $mform->hideIf($elementname . 'email', $elementname, 'eq', 0); $mform->hideIf($elementname . 'newemail', $elementname, 'eq', 0); $mform->hideIf($elementname . 'email', $elementname . 'newemail', 'notchecked'); @@ -260,6 +270,17 @@ class site_registration_form extends \moodleform { unset($data->commnewsnewemail); // Always return 'contactable'. $data->contactable = empty($data->contactable) ? 0 : 1; + + if (debugging('', DEBUG_DEVELOPER)) { + // Display debugging message for developers who added fields to the form and forgot to add them to registration::FORM_FIELDS. + $keys = array_diff(array_keys((array)$data), ['returnurl', 'mform_isexpanded_id_sitestats', 'submitbutton', 'update']); + if ($extrafields = array_diff($keys, registration::FORM_FIELDS)) { + debugging('Found extra fields in the form results: ' . join(', ', $extrafields), DEBUG_DEVELOPER); + } + if ($missingfields = array_diff(registration::FORM_FIELDS, $keys)) { + debugging('Some fields are missing in the form results: ' . join(', ', $missingfields), DEBUG_DEVELOPER); + } + } } return $data; } diff --git a/lib/installlib.php b/lib/installlib.php index 63aff6f0c74..88bfaafeeb9 100644 --- a/lib/installlib.php +++ b/lib/installlib.php @@ -525,4 +525,7 @@ function install_cli_database(array $options, $interactive) { if (isset($options['summary'])) { $DB->set_field('course', 'summary', $options['summary'], array('format' => 'site')); } + + // Redirect to site registration on first login. + set_config('registrationpending', 1); } diff --git a/theme/bootstrapbase/less/moodle/admin.less b/theme/bootstrapbase/less/moodle/admin.less index bd85e2b695f..ce5e5c3a8c4 100644 --- a/theme/bootstrapbase/less/moodle/admin.less +++ b/theme/bootstrapbase/less/moodle/admin.less @@ -854,3 +854,7 @@ img.iconsmall { #overriderolestable .overriddenpermission { background-color: @warningBackground; } + +#page-admin-registration-index form .mark { + background-color: @warningBackground; +} diff --git a/theme/bootstrapbase/style/moodle.css b/theme/bootstrapbase/style/moodle.css index 3514e0520e9..562897d0c3a 100644 --- a/theme/bootstrapbase/style/moodle.css +++ b/theme/bootstrapbase/style/moodle.css @@ -5562,6 +5562,9 @@ img.iconsmall { #overriderolestable .overriddenpermission { background-color: #fcf8e3; } +#page-admin-registration-index form .mark { + background-color: #fcf8e3; +} /* calendar.less */ .calendar_event_category { background-color: #d8bfd8;