// Run automated backups if required.
require_once($CFG->dirroot.'/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot.'/backup/util/helper/backup_cron_helper.class.php');
-backup_cron_automated_helper::run_automated_backup(backup_cron_automated_helper::RUN_IMMEDIATLY);
+backup_cron_automated_helper::run_automated_backup(backup_cron_automated_helper::RUN_IMMEDIATELY);
mtrace("Automated cron backups completed correctly");
session_get_instance()->write_close(); // release session
- header('Content-Type: application/xhtml+xml');
+ header('Content-Type: application/xhtml+xml; charset=utf-8');
header('Content-Disposition: attachment; filename=database.xml');
header('Expires: 0');
header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
$settings = "";
}
- $count = $DB->count_records_select($module->name, "course<>0");
+ try {
+ $count = $DB->count_records_select($module->name, "course<>0");
+ } catch (dml_exception $e) {
+ $count = -1;
+ }
if ($count>0) {
$countlink = "<a href=\"{$CFG->wwwroot}/course/search.php?modulelist=$module->name" .
"&sesskey=".sesskey()."\" title=\"$strshowmodulecourse\">$count</a>";
- }
- else {
+ } else if ($count < 0) {
+ $countlink = get_string('error');
+ } else {
$countlink = "$count";
}
if (in_array($data->type, array('text','mediumtext','longtext','varchar'))) { // Text stuff only
// first find candidate records
$sql = "SELECT id, $column FROM $fulltable WHERE $column LIKE '%</lang>%' OR $column LIKE '%<span lang=%'";
- if ($rs = $DB->get_recordset_sql($sql)) {
- foreach ($rs as $data) {
- $text = $data->$column;
- $id = $data->id;
- if ($i % 600 == 0) {
- echo '<br />';
- }
- if ($i % 10 == 0) {
- echo '.';
- }
- $i++;
-
- if (empty($text) or is_numeric($text)) {
- continue; // nothing to do
- }
-
- $search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)+/is';
- $newtext = preg_replace_callback($search, 'multilangupgrade_impl', $text);
-
- if (is_null($newtext)) {
- continue; // regex error
- }
-
- if ($newtext != $text) {
- $DB->execute("UPDATE $fulltable SET $column=? WHERE id=?", array($newtext, $id));
- }
+ $rs = $DB->get_recordset_sql($sql);
+ foreach ($rs as $data) {
+ $text = $data->$column;
+ $id = $data->id;
+ if ($i % 600 == 0) {
+ echo '<br />';
+ }
+ if ($i % 10 == 0) {
+ echo '.';
+ }
+ $i++;
+
+ if (empty($text) or is_numeric($text)) {
+ continue; // nothing to do
+ }
+
+ $search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)+/is';
+ $newtext = preg_replace_callback($search, 'multilangupgrade_impl', $text);
+
+ if (is_null($newtext)) {
+ continue; // regex error
+ }
+
+ if ($newtext != $text) {
+ $DB->execute("UPDATE $fulltable SET $column=? WHERE id=?", array($newtext, $id));
}
- $rs->close();
}
+ $rs->close();
}
}
}
}
// Settings link, if available.
- if (file_exists($qtype->plugin_dir() . '/settings.php')) {
+ $settings = admin_get_root()->locate('qtypesetting' . $qtypename);
+ if ($settings instanceof admin_externalpage) {
+ $row[] = '<a href="' . $settings->url .
+ '">' . get_string('settings') . '</a>';
+ } else if ($settings instanceof admin_settingpage) {
$row[] = '<a href="' . admin_url('settings.php?section=qtypesetting' . $qtypename) .
'">' . get_string('settings') . '</a>';
} else {
}
}
+ /**
+ * Return the site secret for a given hub
+ * site identifier is assigned to Mooch
+ * each hub has a unique and personal site secret.
+ * @param string $huburl
+ * @return string site secret
+ */
+ public function get_site_secret_for_hub($huburl) {
+ global $DB;
+
+ $existingregistration = $DB->get_record('registration_hubs',
+ array('huburl' => $huburl));
+
+ if (!empty($existingregistration)) {
+ return $existingregistration->secret;
+ }
+
+ if ($huburl == HUB_MOODLEORGHUBURL) {
+ $siteidentifier = get_site_identifier();
+ } else {
+ $siteidentifier = random_string(32) . $_SERVER['HTTP_HOST'];
+ }
+
+ return $siteidentifier;
+
+ }
+
/**
* When the site register on a hub, he must call this function
* @param object $hub where the site is registered on
throw new moodle_exception('missingparameter');
}
-/* TO DO
- if DB config plugin table is not good for dealing with token reference and token confirmation
- => create other DB table
- -----------------------------------------------------------------------------
- Local Type | Token | Local WS | Remote Type | Remote URL | Confirmed
- -----------------------------------------------------------------------------
- HUB 4er4e server HUB-DIRECTORY http...moodle.org Yes
- HUB 73j53 client HUB-DIRECTORY http...moodle.org Yes
- SITE dfsd7 server HUB http...hub Yes
- SITE fd8fd client HUB http...hub Yes
- HUB ds78s server SITE http...site.com Yes
- HUB-DIR. d7d8s server HUB http...hub Yes
- -----------------------------------------------------------------------------
- */
-
$registrationmanager = new registration_manager();
$registeredhub = $registrationmanager->get_registeredhub($huburl);
if (empty($unconfirmedhub)) {
//we save the token into the communication table in order to have a reference
$unconfirmedhub = new stdClass();
- $unconfirmedhub->token = get_site_identifier();
+ $unconfirmedhub->token = $registrationmanager->get_site_secret_for_hub($huburl);
+ $unconfirmedhub->secret = $unconfirmedhub->token;
$unconfirmedhub->huburl = $huburl;
$unconfirmedhub->hubname = $hubname;
$unconfirmedhub->confirmed = 0;
--- /dev/null
+<?php
+
+///////////////////////////////////////////////////////////////////////////
+// //
+// This file is part of Moodle - http://moodle.org/ //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment //
+// //
+// Moodle is free software: you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation, either version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// Moodle is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>. //
+// //
+///////////////////////////////////////////////////////////////////////////
+
+/*
+ * @package moodle
+ * @subpackage registration
+ * @author Jerome Mouneyrac <jerome@mouneyrac.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL
+ * @copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com
+ *
+ * The administrator is redirect to this page from the hub to renew a registration
+ * process because
+ */
+
+require('../../config.php');
+require_once($CFG->libdir . '/adminlib.php');
+require_once($CFG->dirroot . '/' . $CFG->admin . '/registration/lib.php');
+
+$url = optional_param('url', '', PARAM_URL);
+$hubname = optional_param('hubname', '', PARAM_TEXT);
+$token = optional_param('token', '', PARAM_TEXT);
+
+admin_externalpage_setup('registrationindex');
+
+//check that we are waiting a confirmation from this hub, and check that the token is correct
+$registrationmanager = new registration_manager();
+$registeredhub = $registrationmanager->get_unconfirmedhub($url);
+if (!empty($registeredhub) and $registeredhub->token == $token) {
+
+ echo $OUTPUT->header();
+ echo $OUTPUT->heading(get_string('renewregistration', 'hub'), 3, 'main');
+ $hublink = html_writer::tag('a', $hubname, array('href' => $url));
+
+ $registrationmanager->delete_registeredhub($url);
+
+ //Mooch case, need to recreate the siteidentifier
+ if ($url == HUB_MOODLEORGHUBURL) {
+ $CFG->siteidentifier = null;
+ get_site_identifier();
+ }
+
+ $deletedregmsg = get_string('previousregistrationdeleted', 'hub', $hublink);
+
+ $button = new single_button(new moodle_url('/admin/registration/index.php'),
+ get_string('restartregistration', 'hub'));
+ $button->class = 'restartregbutton';
+
+ echo html_writer::tag('div', $deletedregmsg . $OUTPUT->render($button),
+ array('class' => 'mdl-align'));
+
+ echo $OUTPUT->footer();
+} else {
+ throw new moodle_exception('wrongtoken', 'hub',
+ $CFG->wwwroot . '/' . $CFG->admin . '/registration/index.php');
+}
+
+
$time = optional_param('time', 0, PARAM_INT);
$numcourses = optional_param('numcourses', 20, PARAM_INT);
- admin_externalpage_setup('reportcourseoverview');
- echo $OUTPUT->header();
-
if (empty($CFG->enablestats)) {
if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
}
}
+ admin_externalpage_setup('reportcourseoverview');
+ echo $OUTPUT->header();
+
$course = get_site();
stats_check_uptodate($course->id);
$select = new single_select($PAGE->url, 'roleid', $nameswithcounts, $roleid, null);
$select->label = get_string('assignanotherrole', 'role');
echo $OUTPUT->render($select);
- echo '<p><a href="' . $PAGE->url . '">' . get_string('backtoallroles', 'role') . '</a></p>';
+ $backurl = new moodle_url('/admin/roles/assign.php', array('contextid' => $contextid));
+ echo '<p><a href="' . $backurl->out() . '">' . get_string('backtoallroles', 'role') . '</a></p>';
echo '</div>';
} else if (empty($assignableroles)) {
global $OUTPUT;
// Extra fields at the top of the page.
echo '<div class="topfields clearfix">';
- $this->print_field('name', get_string('name'), $this->get_name_field('name'));
- $this->print_field('shortname', get_string('shortname'), $this->get_shortname_field('shortname'));
+ $this->print_field('name', get_string('rolefullname', 'role'), $this->get_name_field('name'));
+ $this->print_field('shortname', get_string('roleshortname', 'role'), $this->get_shortname_field('shortname'));
$this->print_field('edit-description', get_string('description'), $this->get_description_field('description'));
$this->print_field('menuarchetype', get_string('archetype', 'role').' '.$OUTPUT->help_icon('archetype', 'role'), $this->get_archetype_field('archetype'));
$this->print_field('', get_string('maybeassignedin', 'role'), $this->get_assignable_levels_control());
$table->head = array(
get_string('role') . ' ' . $OUTPUT->help_icon('roles', 'role'),
get_string('description'),
- get_string('shortname'),
+ get_string('roleshortname', 'role'),
get_string('edit')
);
$ADMIN->add('experimental', $temp);
// DB transfer related pages
- $ADMIN->add('experimental', new admin_externalpage('dbtransfer', get_string('dbtransfer', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/index.php', 'moodle/site:config'));
- $ADMIN->add('experimental', new admin_externalpage('dbexport', get_string('dbexport', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/dbexport.php', 'moodle/site:config'));
+ $ADMIN->add('experimental', new admin_externalpage('dbtransfer', get_string('dbtransfer', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/index.php', 'moodle/site:config', true));
+ $ADMIN->add('experimental', new admin_externalpage('dbexport', get_string('dbexport', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/dbexport.php', 'moodle/site:config', true));
// "debugging" settingpage
$temp = new admin_settingpage('debugging', get_string('debugging', 'admin'));
$options[99] = get_string('timezonenotforced', 'admin');
$temp->add(new admin_setting_configselect('forcetimezone', get_string('forcetimezone', 'admin'), get_string('helpforcetimezone', 'admin'), 99, $options));
$temp->add(new admin_settings_country_select('country', get_string('country', 'admin'), get_string('configcountry', 'admin'), 0));
+ $temp->add(new admin_setting_configtext('defaultcity', get_string('defaultcity', 'admin'), get_string('defaultcity_help', 'admin'), ''));
$temp->add(new admin_setting_heading('iplookup', get_string('iplookup', 'admin'), get_string('iplookupinfo', 'admin')));
$temp->add(new admin_setting_configfile('geoipfile', get_string('geoipfile', 'admin'), get_string('configgeoipfile', 'admin', $CFG->dataroot.'/geoip/'), $CFG->dataroot.'/geoip/GeoLiteCity.dat'));
// Question type settings.
$ADMIN->add('modules', new admin_category('qtypesettings', get_string('questiontypes', 'admin')));
$ADMIN->add('qtypesettings', new admin_page_manageqtypes());
- require_once($CFG->libdir . '/questionlib.php');
- global $QTYPES;
- foreach ($QTYPES as $qtype) {
- $settingsfile = $qtype->plugin_dir() . '/settings.php';
+ $qtypes = get_plugin_list('qtype');
+ foreach ($qtypes as $qtype => $path) {
+ $settingsfile = $path . '/settings.php';
if (file_exists($settingsfile)) {
- $settings = new admin_settingpage('qtypesetting' . $qtype->name(),
- $qtype->local_name(), 'moodle/question:config');
+ $settings = new admin_settingpage('qtypesetting' . $qtype,
+ get_string('pluginname', 'qtype_' . $qtype), 'moodle/question:config');
include($settingsfile);
if ($settings) {
$ADMIN->add('qtypesettings', $settings);
$ADMIN->add('server', new admin_externalpage('adminregistration', get_string('registration','admin'), "$CFG->wwwroot/$CFG->admin/registration/index.php"));
+$ADMIN->add('root', new admin_externalpage('bloglevelupgrade', get_string('bloglevelupgrade', 'admin'), $CFG->wwwroot.'/'.$CFG->admin.'/blocklevelupgrade.php', 'moodle/site:config', true));
} // end of speedup
$optionalsubsystems->add(new admin_setting_configcheckbox('enablecompletion',
get_string('enablecompletion','completion'),
get_string('configenablecompletion','completion'), 0));
- $optionalsubsystems->add(new admin_setting_pickroles('progresstrackedroles',
- get_string('progresstrackedroles','completion'),
- get_string('configprogresstrackedroles', 'completion'),
- array('student')));
$optionalsubsystems->add(new admin_setting_configcheckbox('enableavailability',
get_string('enableavailability','condition'),
get_string('configenableavailability','condition'), 0));
if (!during_initial_install()) {
$temp->add(new admin_setting_configselect('creatornewroleid', get_string('creatornewroleid', 'admin'),
- get_string('configcreatornewroleid', 'admin'), $defaultteacherid, $creatornewroles));
+ get_string('creatornewroleid_help', 'admin'), $defaultteacherid, $creatornewroles));
}
$temp->add(new admin_setting_configcheckbox('autologinguests', get_string('autologinguests', 'admin'), get_string('configautologinguests', 'admin'), 0));
}
if (isset($formdata->$field)) {
// process templates
- $user->$field = process_template($formdata->$field, $user);
+ if (is_array($formdata->$field)) {
+ foreach ($formdata->$field as $k=>$v) {
+ $user->$field[$k] = process_template($v, $user);
+ }
+ } else {
+ $user->$field = process_template($formdata->$field, $user);
+ }
}
}
$courseid = $ccache[$shortname]->id;
$coursecontext = get_context_instance(CONTEXT_COURSE, $courseid);
if (!isset($manualcache[$courseid])) {
- if ($instances = enrol_get_instances($courseid, false)) {
- $manualcache[$courseid] = reset($instances);
- } else {
- $manualcache[$courseid] = false;
+ $manualcache[$courseid] = false;
+ if ($manual) {
+ if ($instances = enrol_get_instances($courseid, false)) {
+ foreach ($instances as $instance) {
+ if ($instance->enrol === 'manual') {
+ $manualcache[$courseid] = $instance;
+ break;
+ }
+ }
+ }
}
}
$mform->addElement('text', 'city', get_string('city'), 'maxlength="100" size="25"');
$mform->setType('city', PARAM_MULTILANG);
- $mform->setDefault('city', $templateuser->city);
+ if (empty($CFG->defaultcity)) {
+ $mform->setDefault('city', $templateuser->city);
+ } else {
+ $mform->setDefault('city', $CFG->defaultcity);
+ }
$mform->addElement('select', 'country', get_string('selectacountry'), get_string_manager()->get_list_of_countries());
- $mform->setDefault('country', $templateuser->country);
+ if (empty($CFG->country)) {
+ $mform->setDefault('country', $templateuser->country);
+ } else {
+ $mform->setDefault('country', $CFG->country);
+ }
$mform->setAdvanced('country');
$choices = get_list_of_timezones();
list($sqlwhere, $params) = $ufiltering->get_sql_filter("id<>:exguest AND deleted <> 1", array('exguest'=>$CFG->siteguest));
- if ($rs = $DB->get_recordset_select('user', $sqlwhere, $params, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname')) {
- foreach ($rs as $user) {
- if (!isset($SESSION->bulk_users[$user->id])) {
- $SESSION->bulk_users[$user->id] = $user->id;
- }
+ $rs = $DB->get_recordset_select('user', $sqlwhere, $params, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname');
+ foreach ($rs as $user) {
+ if (!isset($SESSION->bulk_users[$user->id])) {
+ $SESSION->bulk_users[$user->id] = $user->id;
}
- $rs->close();
}
+ $rs->close();
}
function get_selection_data($ufiltering) {
if ($confirm and confirm_sesskey()) {
list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
- if ($rs = $DB->get_recordset_select('user', "id $in", $params, '', 'id, username, secret, confirmed, auth, firstname, lastname')) {
- foreach ($rs as $user) {
- if ($user->confirmed) {
- continue;
- }
- $auth = get_auth_plugin($user->auth);
- $result = $auth->user_confirm($user->username, $user->secret);
- if ($result != AUTH_CONFIRM_OK && $result != AUTH_CONFIRM_ALREADY) {
- echo $OUTPUT->notification(get_string('usernotconfirmed', '', fullname($user, true)));
- }
+ $rs = $DB->get_recordset_select('user', "id $in", $params, '', 'id, username, secret, confirmed, auth, firstname, lastname');
+ foreach ($rs as $user) {
+ if ($user->confirmed) {
+ continue;
+ }
+ $auth = get_auth_plugin($user->auth);
+ $result = $auth->user_confirm($user->username, $user->secret);
+ if ($result != AUTH_CONFIRM_OK && $result != AUTH_CONFIRM_ALREADY) {
+ echo $OUTPUT->notification(get_string('usernotconfirmed', '', fullname($user, true)));
}
- $rs->close();
}
+ $rs->close();
redirect($return, get_string('changessaved'));
} else {
if ($confirm and confirm_sesskey()) {
list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
- if ($rs = $DB->get_recordset_select('user', "id $in", $params)) {
- foreach ($rs as $user) {
- if (!is_siteadmin($user) and $USER->id != $user->id and delete_user($user)) {
- unset($SESSION->bulk_users[$user->id]);
- } else {
- echo $OUTPUT->notification(get_string('deletednot', '', fullname($user, true)));
- }
+ $rs = $DB->get_recordset_select('user', "id $in", $params);
+ foreach ($rs as $user) {
+ if (!is_siteadmin($user) and $USER->id != $user->id and delete_user($user)) {
+ unset($SESSION->bulk_users[$user->id]);
+ } else {
+ echo $OUTPUT->notification(get_string('deletednot', '', fullname($user, true)));
}
- $rs->close();
}
+ $rs->close();
session_gc(); // remove stale sessions
redirect($return, get_string('changessaved'));
$parts = array_chunk($SESSION->bulk_users, 300);
foreach ($parts as $users) {
list($in, $params) = $DB->get_in_or_equal($users);
- if ($rs = $DB->get_recordset_select('user', "id $in", $params)) {
- foreach ($rs as $user) {
- if (!empty($changeable[$user->auth])) {
- set_user_preference('auth_forcepasswordchange', 1, $user->id);
- unset($SESSION->bulk_users[$user->id]);
- } else {
- echo $OUTPUT->notification(get_string('forcepasswordchangenot', '', fullname($user, true)));
- }
+ $rs = $DB->get_recordset_select('user', "id $in", $params);
+ foreach ($rs as $user) {
+ if (!empty($changeable[$user->auth])) {
+ set_user_preference('auth_forcepasswordchange', 1, $user->id);
+ unset($SESSION->bulk_users[$user->id]);
+ } else {
+ echo $OUTPUT->notification(get_string('forcepasswordchangenot', '', fullname($user, true)));
}
- $rs->close();
}
+ $rs->close();
}
echo $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');
echo $OUTPUT->continue_button($return);
if ($confirm and !empty($msg) and confirm_sesskey()) {
list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
- if ($rs = $DB->get_recordset_select('user', "id $in", $params)) {
- foreach ($rs as $user) {
- //TODO we should probably support all text formats here or only FORMAT_MOODLE
- //For now bulk messaging is still using the html editor and its supplying html
- //so we have to use html format for it to be displayed correctly
- message_post_message($USER, $user, $msg, FORMAT_HTML, 'direct');
- }
- $rs->close();
+ $rs = $DB->get_recordset_select('user', "id $in", $params);
+ foreach ($rs as $user) {
+ //TODO we should probably support all text formats here or only FORMAT_MOODLE
+ //For now bulk messaging is still using the html editor and its supplying html
+ //so we have to use html format for it to be displayed correctly
+ message_post_message($USER, $user, $msg, FORMAT_HTML);
}
+ $rs->close();
redirect($return);
}
echo $OUTPUT->footer();
break;
case ACTION_GENERATE_XML:
- header('Content-type: application/xhtml+xml');
+ header('Content-type: application/xhtml+xml; charset=utf-8');
echo $xmldb_action->getOutput();
break;
}
// set to defaults if undefined
if (!isset($config->auth_instructions) or empty($config->user_attribute)) {
- $config->auth_instructions = get_string('shibboleth_instructions', 'auth', $CFG->wwwroot.'/auth/shibboleth/index.php');
+ $config->auth_instructions = get_string('auth_shib_instructions', 'auth_shibboleth', $CFG->wwwroot.'/auth/shibboleth/index.php');
}
if (!isset ($config->user_attribute)) {
$config->user_attribute = '';
} else {
// Check if integrated WAYF was enabled and is now turned off
// If it was and only then, reset the Moodle alternate URL
- if ($this->config->alt_login == 'on'){
+ if (isset($this->config->alt_login) and $this->config->alt_login == 'on'){
set_config('alt_login', 'off', 'auth/shibboleth');
set_config('alternateloginurl', '');
}
// Find out whether host supports https
$protocol = 'http://';
if ( isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'){
- $protocol = 'https://';
+ $protocol = 'https://';
}
// Front channel logout
/*****************************************************************************/
// Same function as in adodb, but cannot be used for file session for some reason...
-function unserializesession( $serialized_string ){
- $variables = array( );
- $a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
- for( $i = 0; $i < count( $a ); $i = $i+2 ) {
- $variables[$a[$i]] = unserialize( $a[$i+1] );
+function unserializesession($serialized_string) {
+ $variables = array();
+ $a = preg_split("/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
+ $counta = count($a);
+ for ($i = 0; $i < $counta; $i = $i+2) {
+ $variables[$a[$i]] = unserialize($a[$i+1]);
}
- return( $variables );
+ return $variables;
}
}
// Loop through all directory entries, and construct two temporary arrays containing files and sub directories
- while(false !== ($entry = readdir($handle))) {
+ while (false !== ($entry = readdir($handle))) {
if (is_dir($dir. $slash .$entry) && $entry != ".." && $entry != "." && $entry != $excludeddir) {
$dir_subdirs[] = $dir. $slash .$entry;
}
}
// Delete all files in the curent directory return false and halt if a file cannot be removed
- for($i=0; $i<count($dir_files); $i++) {
+ $countdirfiles = count($dir_files);
+ for ($i=0; $i<$countdirfiles; $i++) {
chmod($dir_files[$i], $CFG->directorypermissions);
if (((unlink($dir_files[$i]))) == FALSE) {
return false;
}
// Empty sub directories and then remove the directory
- for($i=0; $i<count($dir_subdirs); $i++) {
+ $countdirsubdirs = count($dir_subdirs);
+ for($i=0; $i<$countdirsubdirs; $i++) {
chmod($dir_subdirs[$i], $CFG->directorypermissions);
if (delete_dir_contents($dir_subdirs[$i]) == FALSE) {
return false;
--- /dev/null
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package moodlecore
+ * @subpackage backup-moodle2
+ * @copyright 2011 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Class extending standard backup_plugin in order to implement some
+ * helper methods related with the course formats (format plugin)
+ *
+ * TODO: Finish phpdocs
+ */
+abstract class backup_format_plugin extends backup_plugin {
+
+ protected $courseformat; // To store the format (course->format) of the instance
+
+ public function __construct($plugintype, $pluginname, $optigroup, $step) {
+
+ parent::__construct($plugintype, $pluginname, $optigroup, $step);
+
+ $this->courseformat = backup_plan_dbops::get_courseformat_from_courseid($this->task->get_courseid());
+
+ }
+
+ /**
+ * Return the condition encapsulated into sqlparam format
+ * to get evaluated by value, not by path nor processor setting
+ */
+ protected function get_format_condition() {
+ return array('sqlparam' => $this->courseformat);
+ }
+}
require_once($CFG->dirroot . '/backup/moodle2/backup_xml_transformer.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_qtype_plugin.class.php');
+require_once($CFG->dirroot . '/backup/moodle2/backup_format_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_subplugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_settingslib.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_stepslib.php');
protected $pluginname;
protected $connectionpoint;
protected $optigroup; // Optigroup, parent of all optigroup elements
+ protected $step;
+ protected $task;
- public function __construct($plugintype, $pluginname, $optigroup) {
+ public function __construct($plugintype, $pluginname, $optigroup, $step) {
$this->plugintype = $plugintype;
$this->pluginname = $pluginname;
- $this->optigroup = $optigroup;
+ $this->optigroup = $optigroup;
$this->connectionpoint = '';
+ $this->step = $step;
+ $this->task = $step->get_task();
}
public function define_plugin_structure($connectionpoint) {
}
}
+// Protected API starts here
+
+// backup_step/structure_step/task wrappers
+
+ /**
+ * Returns the value of one (task/plan) setting
+ */
+ protected function get_setting_value($name) {
+ if (is_null($this->task)) {
+ throw new backup_step_exception('not_specified_backup_task');
+ }
+ return $this->task->get_setting_value($name);
+ }
+
+// end of backup_step/structure_step/task wrappers
+
/**
* Factory method that will return one backup_plugin_element (backup_optigroup_element)
* with its name automatically calculated, based one the plugin being handled (type, name)
$backupfile = $subpluginsdir . '/backup/moodle2/' . $classname . '.class.php';
if (file_exists($backupfile)) {
require_once($backupfile);
- $backupsubplugin = new $classname($subplugintype, $name, $optigroup);
+ $backupsubplugin = new $classname($subplugintype, $name, $optigroup, $this);
// Add subplugin returned structure to optigroup
$backupsubplugin->define_subplugin_structure($element->get_name());
}
}
}
+ /**
+ * As far as activity backup steps are implementing backup_subplugin stuff, they need to
+ * have the parent task available for wrapping purposes (get course/context....)
+ */
+ public function get_task() {
+ return $this->task;
+ }
+
/**
* Wraps any activity backup structure within the common 'activity' element
* that will include common to all activities information like id, context...
$availability = new backup_nested_element('availability', array('id'), array(
'sourcecmid', 'requiredcompletion', 'gradeitemid', 'grademin', 'grademax'));
+ // attach format plugin structure to $module element, only one allowed
+ $this->add_plugin_structure('format', $module, false);
+
// Define the tree
$module->add_child($availinfo);
$availinfo->add_child($availability);
$section = new backup_nested_element('section', array('id'), array(
'number', 'name', 'summary', 'summaryformat', 'sequence', 'visible'));
+ // attach format plugin structure to $section element, only one allowed
+ $this->add_plugin_structure('format', $section, false);
+
// Define sources
$section->set_source_table('course_sections', array('id' => backup::VAR_SECTIONID));
$module = new backup_nested_element('module', array(), array('modulename'));
+ // attach format plugin structure to $course element, only one allowed
+ $this->add_plugin_structure('format', $course, false);
+
// Build the tree
$course->add_child($category);
protected $subpluginname;
protected $connectionpoint;
protected $optigroup; // Optigroup, parent of all optigroup elements
+ protected $step;
+ protected $task;
- public function __construct($subplugintype, $subpluginname, $optigroup) {
+ public function __construct($subplugintype, $subpluginname, $optigroup, $step) {
$this->subplugintype = $subplugintype;
$this->subpluginname = $subpluginname;
$this->optigroup = $optigroup;
$this->connectionpoint = '';
+ $this->step = $step;
+ $this->task = $step->get_task();
}
public function define_subplugin_structure($connectionpoint) {
}
}
+// Protected API starts here
+
+// backup_step/structure_step/task wrappers
+
+ /**
+ * Returns the value of one (task/plan) setting
+ */
+ protected function get_setting_value($name) {
+ if (is_null($this->task)) {
+ throw new backup_step_exception('not_specified_backup_task');
+ }
+ return $this->task->get_setting_value($name);
+ }
+
+// end of backup_step/structure_step/task wrappers
+
/**
* Factory method that will return one backup_subplugin_element (backup_optigroup_element)
* with its name automatically calculated, based one the subplugin being handled (type, name)
--- /dev/null
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package moodlecore
+ * @subpackage backup-moodle2
+ * @copyright 2011 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Class extending standard restore_plugin in order to implement some
+ * helper methods related with the course formats (format plugin)
+ *
+ * TODO: Finish phpdocs
+ */
+abstract class restore_format_plugin extends restore_plugin {
+ // Love these classes. :-) Nothing special to customize here for now
+}
require_once($CFG->dirroot . '/backup/moodle2/restore_default_block_task.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_qtype_plugin.class.php');
+require_once($CFG->dirroot . '/backup/moodle2/restore_format_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_qtype_plugin.class.php');
+require_once($CFG->dirroot . '/backup/moodle2/backup_format_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_subplugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_settingslib.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_stepslib.php');
return $this->step->apply_date_offset($value);
}
+ /**
+ * Returns the value of one (task/plan) setting
+ */
+ protected function get_setting_value($name) {
+ if (is_null($this->task)) {
+ throw new restore_step_exception('not_specified_restore_task');
+ }
+ return $this->task->get_setting_value($name);
+ }
+
+// end of restore_step/structure_step/task wrappers
+
/**
* Simple helper function that returns the name for the restore_path_element
* It's not mandatory to use it but recommended ;-)
$info->filequestionid = $oldquestionid;
$info->dbquestionid = $newquestionid;
$info->answer = $data->answertext;
- throw restore_step_exception('error_question_answers_missing_in_db', $info);
+ throw new restore_step_exception('error_question_answers_missing_in_db', $info);
}
}
// Create mapping (we'll use this intensively when restoring question_states. And also answerfeedback files)
protected $info; // info related to section gathered from backup file
protected $contextid; // course context id
+ protected $sectionid; // new (target) id of the course section
/**
* Constructor - instantiates one object of this class
*/
public function __construct($name, $info, $plan = null) {
$this->info = $info;
+ $this->sectionid = 0;
parent::__construct($name, $plan);
}
return $this->get_basepath() . '/sections/section_' . $this->info->sectionid;
}
+ public function set_sectionid($sectionid) {
+ $this->sectionid = $sectionid;
+ }
+
public function get_contextid() {
return $this->contextid;
}
+ public function get_sectionid() {
+ return $this->sectionid;
+ }
+
/**
* Create all the steps that will be part of this task
*/
$params = array('courseid' => $this->get_courseid(), 'grname' => $data->name);
if (!empty($data->description)) {
$description_clause = ' AND ' .
- $DB->sql_compare_text('description') . ' = ' . $DB->sql_compare_text(':desc');
- $params['desc'] = $data->description;
+ $DB->sql_compare_text('description') . ' = ' . $DB->sql_compare_text(':description');
+ $params['description'] = $data->description;
}
if (!$groupdb = $DB->get_record_sql("SELECT *
FROM {groups}
$params = array('courseid' => $this->get_courseid(), 'grname' => $data->name);
if (!empty($data->description)) {
$description_clause = ' AND ' .
- $DB->sql_compare_text('description') . ' = ' . $DB->sql_compare_text(':desc');
- $params['desc'] = $data->description;
+ $DB->sql_compare_text('description') . ' = ' . $DB->sql_compare_text(':description');
+ $params['description'] = $data->description;
}
if (!$groupingdb = $DB->get_record_sql("SELECT *
FROM {groupings}
class restore_section_structure_step extends restore_structure_step {
protected function define_structure() {
- return array(new restore_path_element('section', '/section'));
+ $section = new restore_path_element('section', '/section');
+
+ // Apply for 'format' plugins optional paths at section level
+ $this->add_plugin_structure('format', $section);
+
+ return array($section);
}
public function process_section($data) {
// Annotate the section mapping, with restorefiles option if needed
$this->set_mapping('course_section', $oldid, $newitemid, $restorefiles);
+ // set the new course_section id in the task
+ $this->task->set_sectionid($newitemid);
+
+
// Commented out. We never modify course->numsections as far as that is used
// by a lot of people to "hide" sections on purpose (so this remains as used to be in Moodle 1.x)
// Note: We keep the code here, to know about and because of the possibility of making this
protected function define_structure() {
- $course = new restore_path_element('course', '/course', true); // Grouped
+ $course = new restore_path_element('course', '/course');
$category = new restore_path_element('category', '/course/category');
$tag = new restore_path_element('tag', '/course/tags/tag');
- $allowed = new restore_path_element('allowed', '/course/allowed_modules/module');
+ $allowed_module = new restore_path_element('allowed_module', '/course/allowed_modules/module');
+
+ // Apply for 'format' plugins optional paths at course level
+ $this->add_plugin_structure('format', $course);
- return array($course, $category, $tag, $allowed);
+ return array($course, $category, $tag, $allowed_module);
}
/**
global $CFG, $DB;
$data = (object)$data;
- $coursetags = isset($data->tags['tag']) ? $data->tags['tag'] : array();
- $coursemodules = isset($data->allowed_modules['module']) ? $data->allowed_modules['module'] : array();
$oldid = $data->id; // We'll need this later
$fullname = $this->get_setting_value('course_fullname');
$data->shortname= $shortname;
$data->idnumber = '';
- // Category is set by UI when choosing the destination
- unset($data->category);
+ // Only restrict modules if original course was and target site too for new courses
+ $data->restrictmodules = $data->restrictmodules && !empty($CFG->restrictmodulesfor) && $CFG->restrictmodulesfor == 'all';
$data->startdate= $this->apply_date_offset($data->startdate);
if ($data->defaultgroupingid) {
// Course record ready, update it
$DB->update_record('course', $data);
- // Course tags
- if (!empty($CFG->usetags) && isset($coursetags)) { // if enabled in server and present in backup
+ // Role name aliases
+ restore_dbops::set_course_role_names($this->get_restoreid(), $this->get_courseid());
+ }
+
+ public function process_category($data) {
+ // Nothing to do with the category. UI sets it before restore starts
+ }
+
+ public function process_tag($data) {
+ global $CFG, $DB;
+
+ $data = (object)$data;
+
+ if (!empty($CFG->usetags)) { // if enabled in server
+ // TODO: This is highly inneficient. Each time we add one tag
+ // we fetch all the existing because tag_set() deletes them
+ // so everything must be reinserted on each call
$tags = array();
- foreach ($coursetags as $coursetag) {
- $coursetag = (object)$coursetag;
- $tags[] = $coursetag->rawname;
+ $existingtags = tag_get_tags('course', $this->get_courseid());
+ // Re-add all the existitng tags
+ foreach ($existingtags as $existingtag) {
+ $tags[] = $existingtag->rawname;
}
+ // Add the one being restored
+ $tags[] = $data->rawname;
+ // Send all the tags back to the course
tag_set('course', $this->get_courseid(), $tags);
}
- // Course allowed modules
- if (!empty($data->restrictmodules) && !empty($coursemodules)) {
+ }
+
+ public function process_allowed_module($data) {
+ global $CFG, $DB;
+
+ $data = (object)$data;
+
+ // only if enabled by admin setting
+ if (!empty($CFG->restrictmodulesfor) && $CFG->restrictmodulesfor == 'all') {
$available = get_plugin_list('mod');
- foreach ($coursemodules as $coursemodule) {
- $mname = $coursemodule['modulename'];
- if (array_key_exists($mname, $available)) {
- if ($module = $DB->get_record('modules', array('name' => $mname, 'visible' => 1))) {
- $rec = new stdclass();
- $rec->course = $this->get_courseid();
- $rec->module = $module->id;
- if (!$DB->record_exists('course_allowed_modules', (array)$rec)) {
- $DB->insert_record('course_allowed_modules', $rec);
- }
+ $mname = $data->modulename;
+ if (array_key_exists($mname, $available)) {
+ if ($module = $DB->get_record('modules', array('name' => $mname, 'visible' => 1))) {
+ $rec = new stdclass();
+ $rec->course = $this->get_courseid();
+ $rec->module = $module->id;
+ if (!$DB->record_exists('course_allowed_modules', (array)$rec)) {
+ $DB->insert_record('course_allowed_modules', $rec);
}
}
}
}
- // Role name aliases
- restore_dbops::set_course_role_names($this->get_restoreid(), $this->get_courseid());
}
protected function after_execute() {
$data->timecreated = $this->apply_date_offset($data->timecreated);
$data->timemodified = $this->apply_date_offset($data->timemodified);
- $gradeitem = new grade_item($data);
+ $gradeitem = new grade_item($data, false);
$gradeitem->insert('restore');
//sortorder is automatically assigned when inserting. Re-instate the previous sortorder
// TODO: Ask, all the rest of locktime/exported... work with time... to be rolled?
$data->overridden = $this->apply_date_offset($data->overridden);
- $grade = new grade_grade($data);
+ $grade = new grade_grade($data, false);
$grade->insert('restore');
// no need to save any grade_grade mapping
}
$paths = array();
- $paths[] = new restore_path_element('module', '/module');
+ $module = new restore_path_element('module', '/module');
+ $paths[] = $module;
if ($CFG->enableavailability) {
$paths[] = new restore_path_element('availability', '/module/availability_info/availability');
}
+ // Apply for 'format' plugins optional paths at module level
+ $this->add_plugin_structure('format', $module);
+
return $paths;
}
// Check we have one mapping for this category
if (!$mapping = $this->get_mapping('question_category', $oldid)) {
- return; // No mapping = this category doesn't need to be created/mapped
+ return self::SKIP_ALL_CHILDREN; // No mapping = this category doesn't need to be created/mapped
}
// Check we have to create the category (newitemid = 0)
return $this->step->apply_date_offset($value);
}
+ /**
+ * Returns the value of one (task/plan) setting
+ */
+ protected function get_setting_value($name) {
+ if (is_null($this->task)) {
+ throw new restore_step_exception('not_specified_restore_task');
+ }
+ return $this->task->get_setting_value($name);
+ }
+
+// end of restore_step/structure_step/task wrappers
+
/**
* Simple helper function that returns the name for the restore_path_element
* It's not mandatory to use it but recommended ;-)
$tagsarr = $info['BLOG']['#']['BLOG_TAGS']['0']['#']['BLOG_TAG'];
//Iterate over tags
$tags = array();
- for($i = 0; $i < sizeof($tagsarr); $i++) {
+ $sizetagsarr = sizeof($tagsarr);
+ for ($i = 0; $i < $sizetagsarr; $i++) {
$tag_info = $tagsarr[$i];
///traverse_xmlize($tag_info); //Debug
///print_object ($GLOBALS['traverse_array']); //Debug
return $sectionsarr;
}
+ /**
+ * Given one course id, return its format in DB
+ */
+ public static function get_courseformat_from_courseid($courseid) {
+ global $DB;
+
+ return $DB->get_field('course', 'format', array('id' => $courseid));
+ }
+
/**
* Return the wwwroot of the $CFG->mnet_localhost_id host
* caching it along the request
* Returns the default backup filename, based in passed params.
*
* Default format is (see MDL-22145)
- * backup word - format - type - name - date - info . mbz
+ * backup word - format - type - name - date - info . mbz
* where name is variable (course shortname, section name/id, activity modulename + cmid)
- * and info can be (nu = no user info, an = anonymized)
+ * and info can be (nu = no user info, an = anonymized). The last param $useidasname,
+ * defaulting to false, allows to replace the course shortname by the course id (used
+ * by automated backups, to avoid non-ascii chars in OS filesystem)
+ *
+ * @param string $format One of backup::FORMAT_
+ * @param string $type One of backup::TYPE_
+ * @param int $courseid/$sectionid/$cmid
+ * @param bool $users Should be true is users were included in the backup
+ * @param bool $anonymised Should be true is user information was anonymized.
+ * @param bool $useidasname true to use id, false to use strings (default)
+ * @return string The filename to use
*/
- public static function get_default_backup_filename($format, $type, $id, $users, $anonymised) {
+ public static function get_default_backup_filename($format, $type, $id, $users, $anonymised, $useidasname = false) {
global $DB;
// Calculate backup word
$backupword = str_replace(' ', '_', moodle_strtolower(get_string('backupfilename')));
$backupword = trim(clean_filename($backupword), '_');
- // Calculate proper name element (based on type)
- switch ($type) {
- case backup::TYPE_1COURSE:
- $shortname = $DB->get_field('course', 'shortname', array('id' => $id));
- break;
- case backup::TYPE_1SECTION:
- if (!$shortname = $DB->get_field('course_sections', 'name', array('id' => $id))) {
- $shortname = $DB->get_field('course_sections', 'section', array('id' => $id));
- }
- break;
- case backup::TYPE_1ACTIVITY:
- $cm = get_coursemodule_from_id(null, $id);
- $shortname = $cm->modname . $id;
- break;
+ $shortname = '';
+ // Not $useidasname, lets calculate it, else $id will be used
+ if (!$useidasname) {
+ // Calculate proper name element (based on type)
+ switch ($type) {
+ case backup::TYPE_1COURSE:
+ $shortname = $DB->get_field('course', 'shortname', array('id' => $id));
+ break;
+ case backup::TYPE_1SECTION:
+ if (!$shortname = $DB->get_field('course_sections', 'name', array('id' => $id))) {
+ $shortname = $DB->get_field('course_sections', 'section', array('id' => $id));
+ }
+ break;
+ case backup::TYPE_1ACTIVITY:
+ $cm = get_coursemodule_from_id(null, $id);
+ $shortname = $cm->modname . $id;
+ break;
+ }
+ $shortname = str_replace(' ', '_', $shortname);
+ $shortname = moodle_strtolower(trim(clean_filename($shortname), '_'));
}
- $shortname = str_replace(' ', '_', $shortname);
- $shortname = moodle_strtolower(trim(clean_filename($shortname), '_'));
+
$name = empty($shortname) ? $id : $shortname;
// Calculate date