$temp->add(new admin_setting_heading('automatedsettings', get_string('automatedsettings','backup'), ''));
- $temp->add(new admin_setting_configcheckbox('backup/backup_auto_users', get_string('users'), get_string('backupusershelp'), 1));
+ $temp->add(new admin_setting_configcheckbox('backup/backup_auto_users', get_string('generalusers', 'backup'), get_string('configgeneralusers', 'backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_role_assignments', get_string('generalroleassignments','backup'), get_string('configgeneralroleassignments','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_user_files', get_string('generaluserfiles', 'backup'), get_string('configgeneraluserfiles','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_activities', get_string('generalactivities','backup'), get_string('configgeneralactivities','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_filters', get_string('generalfilters','backup'), get_string('configgeneralfilters','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_comments', get_string('generalcomments','backup'), get_string('configgeneralcomments','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_userscompletion', get_string('generaluserscompletion','backup'), get_string('configgeneraluserscompletion','backup'), 1));
- $temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', get_string('logs'), get_string('backuplogshelp'), 0));
+ $temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', get_string('generallogs', 'backup'), get_string('configgenerallogs', 'backup'), 0));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_histories', get_string('generalhistories','backup'), get_string('configgeneralhistories','backup'), 0));
protected function apply_defaults() {
$this->log('applying plan defaults', backup::LOG_DEBUG);
- backup_controller_dbops::apply_general_config_defaults($this);
+ backup_controller_dbops::apply_config_defaults($this);
$this->set_status(backup::STATUS_CONFIGURED);
}
}
// Note: all the checks along the function MUST be performed for $userid, that
// is the user who "requested" the course backup, not current $USER at all!!
- // First of all, check the main backup[course|section|activity] principal caps
- // Lacking the corresponding one makes this to break with exception always
+ // First of all, decide which caps/contexts are we going to check
+ // for common backups (general, automated...) based exclusively
+ // in the type (course, section, activity). And store them into
+ // one capability => context array structure
+ $typecapstocheck = array();
switch ($type) {
case backup::TYPE_1COURSE :
$DB->get_record('course', array('id' => $id), '*', MUST_EXIST); // course exists
- if (!has_capability('moodle/backup:backupcourse', $coursectx, $userid)) {
- $a = new stdclass();
- $a->userid = $userid;
- $a->courseid = $courseid;
- $a->capability = 'moodle/backup:backupcourse';
- throw new backup_controller_exception('backup_user_missing_capability', $a);
- }
+ $typecapstocheck['moodle/backup:backupcourse'] = $coursectx;
break;
case backup::TYPE_1SECTION :
$DB->get_record('course_sections', array('course' => $courseid, 'id' => $id), '*', MUST_EXIST); // sec exists
- if (!has_capability('moodle/backup:backupsection', $coursectx, $userid)) {
- $a = new stdclass();
- $a->userid = $userid;
- $a->courseid = $courseid;
- $a->capability = 'moodle/backup:backupsection';
- throw new backup_controller_exception('backup_user_missing_capability', $a);
- }
+ $typecapstocheck['moodle/backup:backupsection'] = $coursectx;
break;
case backup::TYPE_1ACTIVITY :
get_coursemodule_from_id(null, $id, $courseid, false, MUST_EXIST); // cm exists
$modulectx = get_context_instance(CONTEXT_MODULE, $id);
- if (!has_capability('moodle/backup:backupactivity', $modulectx, $userid)) {
- $a = new stdclass();
- $a->userid = $userid;
- $a->cmid = $id;
- $a->capability = 'moodle/backup:backupactivity';
- throw new backup_controller_exception('backup_user_missing_capability', $a);
- }
+ $typecapstocheck['moodle/backup:backupactivity'] = $modulectx;
break;
default :
- print_error('unknownbackuptype');
+ throw new backup_controller_exception('backup_unknown_backup_type', $type);
}
// Now, if backup mode is hub or import, check userid has permissions for those modes
+ // other modes will perform common checks only (backupxxxx capabilities in $typecapstocheck)
switch ($mode) {
case backup::MODE_HUB:
if (!has_capability('moodle/backup:backuptargethub', $coursectx, $userid)) {
throw new backup_controller_exception('backup_user_missing_capability', $a);
}
break;
+ // Common backup (general, automated...), let's check all the $typecapstocheck
+ // capability => context pairs
+ default:
+ foreach ($typecapstocheck as $capability => $context) {
+ if (!has_capability($capability, $context, $userid)) {
+ $a = new stdclass();
+ $a->userid = $userid;
+ $a->courseid = $courseid;
+ $a->capability = $capability;
+ throw new backup_controller_exception('backup_user_missing_capability', $a);
+ }
+ }
}
// Now, enforce 'moodle/backup:userinfo' to 'users' setting, applying changes if allowed,
}
// Check the user has the ability to configure the backup. If not then we need
- // to lock all settings by permission so that no changes can be made.
- $hasconfigcap = has_capability('moodle/backup:configure', $coursectx, $userid);
- if (!$hasconfigcap) {
- $settings = $backup_controller->get_plan()->get_settings();
- foreach ($settings as $setting) {
- if ($setting->get_name()=='filename') {
- continue;
+ // to lock all settings by permission so that no changes can be made. This does
+ // not apply to the import facility, where the activities must be always enabled
+ // to be able to pick them
+ if ($mode != backup::MODE_IMPORT) {
+ $hasconfigcap = has_capability('moodle/backup:configure', $coursectx, $userid);
+ if (!$hasconfigcap) {
+ $settings = $backup_controller->get_plan()->get_settings();
+ foreach ($settings as $setting) {
+ if ($setting->get_name() == 'filename') {
+ continue;
+ }
+ $setting->set_status(base_setting::LOCKED_BY_PERMISSION);
}
- $setting->set_status(base_setting::LOCKED_BY_PERMISSION);
}
}
// Note: all the checks along the function MUST be performed for $userid, that
// is the user who "requested" the course restore, not current $USER at all!!
- // First of all, check the main restore[course|section|activity] principal caps
- // Lacking the corresponding one makes this to break with exception always
+ // First of all, decide which caps/contexts are we going to check
+ // for common backups (general, automated...) based exclusively
+ // in the type (course, section, activity). And store them into
+ // one capability => context array structure
+ $typecapstocheck = array();
switch ($type) {
case backup::TYPE_1COURSE :
- if (!has_capability('moodle/restore:restorecourse', $coursectx, $userid)) {
- $a = new stdclass();
- $a->userid = $userid;
- $a->courseid = $courseid;
- $a->capability = 'moodle/restore:restorecourse';
- throw new restore_controller_exception('restore_user_missing_capability', $a);
- }
+ $typecapstocheck['moodle/restore:restorecourse'] = $coursectx;
break;
case backup::TYPE_1SECTION :
- if (!has_capability('moodle/restore:restoresection', $coursectx, $userid)) {
- $a = new stdclass();
- $a->userid = $userid;
- $a->courseid = $courseid;
- $a->capability = 'moodle/restore:restoresection';
- throw new restore_controller_exception('restore_user_missing_capability', $a);
- }
+ $typecapstocheck['moodle/restore:restoresection'] = $coursectx;
break;
case backup::TYPE_1ACTIVITY :
- if (!has_capability('moodle/restore:restoreactivity', $coursectx, $userid)) {
- $a = new stdclass();
- $a->userid = $userid;
- $a->courseid = $courseid;
- $a->capability = 'moodle/restore:restoreactivity';
- throw new restore_controller_exception('restore_user_missing_capability', $a);
- }
+ $typecapstocheck['moodle/restore:restoreactivity'] = $coursectx;
break;
default :
- print_error('unknownrestoretype');
+ throw new restore_controller_exception('restore_unknown_restore_type', $type);
}
// Now, if restore mode is hub or import, check userid has permissions for those modes
+ // other modes will perform common checks only (restorexxxx capabilities in $typecapstocheck)
switch ($mode) {
case backup::MODE_HUB:
if (!has_capability('moodle/restore:restoretargethub', $coursectx, $userid)) {
throw new restore_controller_exception('restore_user_missing_capability', $a);
}
break;
+ // Common backup (general, automated...), let's check all the $typecapstocheck
+ // capability => context pairs
+ default:
+ foreach ($typecapstocheck as $capability => $context) {
+ if (!has_capability($capability, $context, $userid)) {
+ $a = new stdclass();
+ $a->userid = $userid;
+ $a->courseid = $courseid;
+ $a->capability = $capability;
+ throw new restore_controller_exception('restore_user_missing_capability', $a);
+ }
+ }
}
// Now, enforce 'moodle/restore:userinfo' to 'users' setting, applying changes if allowed,
}
// Check the user has the ability to configure the restore. If not then we need
- // to lock all settings by permission so that no changes can be made.
- $hasconfigcap = has_capability('moodle/restore:configure', $coursectx, $userid);
- if (!$hasconfigcap) {
- $settings = $restore_controller->get_plan()->get_settings();
- foreach ($settings as $setting) {
- $setting->set_status(base_setting::LOCKED_BY_PERMISSION);
+ // to lock all settings by permission so that no changes can be made. This does
+ // not apply to the import facility, where all the activities (picked on backup)
+ // are restored automatically without restore UI
+ if ($mode != backup::MODE_IMPORT) {
+ $hasconfigcap = has_capability('moodle/restore:configure', $coursectx, $userid);
+ if (!$hasconfigcap) {
+ $settings = $restore_controller->get_plan()->get_settings();
+ foreach ($settings as $setting) {
+ $setting->set_status(base_setting::LOCKED_BY_PERMISSION);
+ }
}
}
return $DB->get_record('course', array('id' => $courseid), 'fullname, shortname, startdate');
}
+ /**
+ * Sets the default values for the settings in a backup operation
+ *
+ * Based on the mode of the backup it will delegate the process to
+ * other methods like {@link apply_general_config_defaults} ...
+ * to get proper defaults loaded
+ *
+ * @param backup_controller $controller
+ */
+ public static function apply_config_defaults(backup_controller $controller) {
+ // Based on the mode of the backup (general, automated, import, hub...)
+ // decide the action to perform to get defaults loaded
+ $mode = $controller->get_mode();
+
+ switch ($mode) {
+ case backup::MODE_GENERAL:
+ // Load the general defaults
+ self::apply_general_config_defaults($controller);
+ break;
+ case backup::MODE_AUTOMATED:
+ // TODO: Move the loading from automatic stuff to here
+ break;
+ default:
+ // Nothing to do for other modes (IMPORT/HUB...). Some day we
+ // can define defaults (admin UI...) for them if we want to
+ }
+ }
+
/**
* Sets the controller settings default values from the backup config.
*
* @param backup_controller $controller
*/
- public static function apply_general_config_defaults(backup_controller $controller) {
+ private static function apply_general_config_defaults(backup_controller $controller) {
$settings = array(
// Config name => Setting name
'backup_general_users' => 'users',
array('class' => 'editing_update', 'title' => $str->update)
);
- // Duplicate
- $actions[] = new action_link(
- new moodle_url($baseurl, array('duplicate' => $mod->id)),
- new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall')),
- null,
- array('class' => 'editing_duplicate', 'title' => $str->duplicate)
- );
+ // Duplicate (require both target import caps to be able to duplicate, see modduplicate.php)
+ $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
+ if (has_all_capabilities($dupecaps, $coursecontext)) {
+ $actions[] = new action_link(
+ new moodle_url($baseurl, array('duplicate' => $mod->id)),
+ new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall')),
+ null,
+ array('class' => 'editing_duplicate', 'title' => $str->duplicate)
+ );
+ }
// Delete
$actions[] = new action_link(
require_login($course);
require_sesskey();
require_capability('moodle/course:manageactivities', $context);
+// Require both target import caps to be able to duplicate, see make_editing_buttons()
require_capability('moodle/backup:backuptargetimport', $context);
require_capability('moodle/restore:restoretargetimport', $context);
$string['backupkeephelp'] = 'How many recent backups for each course do you want to keep? (older ones will be deleted automatically)';
$string['backuplogdetailed'] = 'Detailed execution log';
$string['backuploglaststatus'] = 'Last execution log';
-$string['backuplogshelp'] = 'If enabled, then course logs will be included in automated backups';
$string['backupmissinguserinfoperms'] = 'Note: This backup contains no user data. Exercise and Workshop activities will not be included in the backup, since these modules are not compatible with this type of backup.';
$string['backupnext'] = 'Next backup';
$string['backupnonisowarning'] = 'Warning: this backup is from a non-Unicode version of Moodle (pre 1.6). If this backup contains any non-ISO-8859-1 texts then they may be CORRUPTED if you try to restore them to this Unicode version of Moodle. See the <a href="http://docs.moodle.org/en/Backup_FAQ">Backup FAQ</a> for more information about how to recover this backup correctly.';
$string['backuptakealook'] = 'Please take a look at your backup logs in:
{$a}';
$string['backupuserfileshelp'] = 'Choose whether user files (eg profile images) should be included in automated backups';
-$string['backupusershelp'] = 'Select whether you want to include all the users in the server or only the needed users for each course';
$string['backupversion'] = 'Backup version';
$string['block'] = 'Block';
$string['blockconfiga'] = 'Configuring a {$a} block';
// Define field secret to be added to registration_hubs
$table = new xmldb_table('registration_hubs');
$field = new xmldb_field('secret', XMLDB_TYPE_CHAR, '255', null, null, null,
- $CFG->siteidentifier, 'confirmed');
+ null, 'confirmed');
- // Conditionally launch add field secret
+ // Conditionally launch add field secret and set its value
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
+ $DB->set_field('registration_hubs', 'secret', $CFG->siteidentifier);
}
// Main savepoint reached
upgrade_main_savepoint(true, 2011083100.02);
}
+ if ($oldversion < 2011090700.01) {
+ // Changing the default of field secret on table registration_hubs to NULL
+ $table = new xmldb_table('registration_hubs');
+ $field = new xmldb_field('secret', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'confirmed');
+
+ // Launch change of default for field secret
+ $dbman->change_field_default($table, $field);
+
+ // Main savepoint reached
+ upgrade_main_savepoint(true, 2011090700.01);
+ }
+
return true;
}
* @param array $link_array an array of filterobjects
* @param array $ignoretagsopen an array of opening tags that we should ignore while filtering
* @param array $ignoretagsclose an array of corresponding closing tags
+ * @param bool $overridedefaultignore True to only use tags provided by arguments
* @return string
**/
-function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagsclose=NULL) {
+function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagsclose=NULL,
+ $overridedefaultignore=false) {
global $CFG;
$ignoretags = array(); //To store all the enclosig tags to be completely ignored
$tags = array(); //To store all the simple tags to be ignored
-/// A list of open/close tags that we should not replace within
-/// No reason why you can't put full preg expressions in here too
-/// eg '<script(.+?)>' to match any type of script tag
- $filterignoretagsopen = array('<head>' , '<nolink>' , '<span class="nolink">');
- $filterignoretagsclose = array('</head>', '</nolink>', '</span>');
+ if (!$overridedefaultignore) {
+ // A list of open/close tags that we should not replace within
+ // Extended to include <script>, <textarea>, <select> and <a> tags
+ // Regular expression allows tags with or without attributes
+ $filterignoretagsopen = array('<head>' , '<nolink>' , '<span class="nolink">',
+ '<script(\s[^>]*?)?>', '<textarea(\s[^>]*?)?>',
+ '<select(\s[^>]*?)?>', '<a(\s[^>]*?)?>');
+ $filterignoretagsclose = array('</head>', '</nolink>', '</span>',
+ '</script>', '</textarea>', '</select>','</a>');
+ } else {
+ // Set an empty default list
+ $filterignoretagsopen = array();
+ $filterignoretagsclose = array();
+ }
+
+ // Add the user defined ignore tags to the default list
+ if ( is_array($ignoretagsopen) ) {
+ foreach ($ignoretagsopen as $open) {
+ $filterignoretagsopen[] = $open;
+ }
+ foreach ($ignoretagsclose as $close) {
+ $filterignoretagsclose[] = $close;
+ }
+ }
/// Invalid prefixes and suffixes for the fullmatch searches
/// Every "word" character, but the underscore, is a invalid suffix or prefix.
$filterinvalidprefixes = '([^\W_])';
$filterinvalidsuffixes = '([^\W_])';
-/// Add the user defined ignore tags to the default list
-/// Unless specified otherwise, we will not replace within <a></a> tags
- if ( $ignoretagsopen === NULL ) {
- //$ignoretagsopen = array('<a(.+?)>');
- $ignoretagsopen = array('<a\s[^>]+?>');
- $ignoretagsclose = array('</a>');
- }
-
- if ( is_array($ignoretagsopen) ) {
- foreach ($ignoretagsopen as $open) $filterignoretagsopen[] = $open;
- foreach ($ignoretagsclose as $close) $filterignoretagsclose[] = $close;
- }
-
//// Double up some magic chars to avoid "accidental matches"
$text = preg_replace('/([#*%])/','\1\1',$text);
$collator = new Collator($locale);
if (!empty($collator) && $collator instanceof Collator) {
// Check for non fatal error messages. This has to be done immediately
- // after instantiation as any futher calls to collation will cause
- // it to reset to 0 again (or another error code if one occured)
+ // after instantiation as any further calls to collation will cause
+ // it to reset to 0 again (or another error code if one occurred)
$errorcode = $collator->getErrorCode();
$errormessage = $collator->getErrorMessage();
- // Check for an error code, 0 means no error occured
+ // Check for an error code, 0 means no error occurred
if ($errorcode !== 0) {
// Get the actual locale being used, e.g. en, he, zh
$localeinuse = $collator->getLocale(Locale::ACTUAL_LOCALE);
- // Check for the common fallback wardning error code. If this occured
- // there is normally little to worry about. (U_USING_FALLBACK_WARNING)
- if ($errorcode === -128) {
- // Check if the local in use is anything like the locale we asked for
- if (strpos($locale, $localeinuse) !== 0) {
+ // Check for the common fallback warning error codes. If this occurred
+ // there is normally little to worry about:
+ // - U_USING_DEFAULT_WARNING (127) - default fallback locale used (pt => UCA)
+ // - U_USING_FALLBACK_WARNING (128) - fallback locale used (de_CH => de)
+ // (UCA: Unicode Collation Algorithm http://unicode.org/reports/tr10/)
+ if ($errorcode === -127 || $errorcode === -128) {
+ // Check if the locale in use is UCA default one ('root') or
+ // if it is anything like the locale we asked for
+ if ($localeinuse !== 'root' && strpos($locale, $localeinuse) !== 0) {
// The locale we asked for is completely different to the locale
- // we have recieved, let the user know via debugging
- debugging('Invalid locale, falling back to the system default locale "'.$collator->getLocale(Locale::VALID_LOCALE).'"');
+ // we have received, let the user know via debugging
+ debugging('Invalid locale: "' . $locale . '", with warning (not fatal) "' . $errormessage .
+ '", falling back to "' . $collator->getLocale(Locale::VALID_LOCALE) . '"');
} else {
// Nothing to do here, this is expected!
// The Moodle locale setting isn't what the collator expected but
// it is smart enough to match the first characters of our locale
- // to find the correct locale
- // debugging('Invalid locale, falling back to closest match "'.$localeinuse.'" which may not be the exact locale');
+ // to find the correct locale or to use UCA collation
}
} else {
// We've recieved some other sort of non fatal warning - let the
// user know about it via debugging.
- debugging('Locale collator generated warnings (not fatal) "'.$errormessage.'" falling back to '.$collator->getLocale(Locale::VALID_LOCALE));
+ debugging('Problem with locale: "' . $locale . '", with message "' . $errormessage .
+ '", falling back to "' . $collator->getLocale(Locale::VALID_LOCALE) . '"');
}
}
- // Store the collator object now that we can be sure it is in a workable condition.
+ // Store the collator object now that we can be sure it is in a workable condition
self::$collator = $collator;
} else {
- // Fatal error while trying to instantiate the collator... who know what went wrong.
- debugging('Error instantiating collator: ['.collator_get_error_code($collator).']'.collator_get_error_message($collator));
+ // Fatal error while trying to instantiate the collator... something went wrong
+ debugging('Error instantiating collator for locale: "' . $locale . '", with error [' .
+ intl_get_error_code() . '] ' . intl_get_error_message($collator));
}
}
}
-webkit-border-radius:6px 6px 0px 0px; /* Safari, Chrome */
border-radius:6px 6px 0px 0px; /* CSS3 */
}
+
#page-content {
/* arrotonadamento angolo in basso a sx */
/* -moz-border-radius:0px 0px 0px 6px; /* Firefox */
background-color:[[setting:lblockcolumnbgc]]; /* colore della colonna di sinistra */
float:none;
}
+
#page-content #region-main-box {
left:[[setting:blockcolumnwidth]];
background-color:#FFF;
}
+
#page-content #region-post-box {
margin-left:[[setting:minusdoubleblockcolumnwidth]]; /*-2*[[setting:blockcolumnwidth]]*/
/* arrotonadamento angolo in basso a dx */
/* border-radius:0px 0px 6px 0px; /* CSS3 */
background-color:[[setting:rblockcolumnbgc]]; /* colore della colonna di destra */
}
+
#page-content #region-main {
margin-left:[[setting:doubleblockcolumnwidth]];/*2*[[setting:blockcolumnwidth]]*/
background-color:white; /* questo serve a togliere la curvatura dagli angoli della zona centrale */
}
+
#page-content #region-pre {
left:[[setting:blockcolumnwidth]]; /*400-[[setting:blockcolumnwidth]]*/
width:[[setting:blockcolumnwidth]];
background-color:[[setting:lblockcolumnbgc]]; /* colore della colonna di sx */
}
+
#page-content #region-post {
width:[[setting:blockcolumnwidth]];
/* arrotonadamento angolo in basso a dx */
/* border-radius:0px 0px 6px 0px; /* CSS3 */
background-color:[[setting:rblockcolumnbgc]]; /* colore del fondo della parte occupata dai contenuti della colonna centrale e della colonna dx */
}
+
#page-content .region-content {
padding:0.6em 8px 0.1em 8px; /* definisco lo spazio sopra e sotto ai blocchi */
}
+.pagelayout-report #page-content .region-content {
+ overflow: auto;
+}
+
/** Only side pre **/
.side-pre-only #page-content #region-post-box {margin-left:-[[setting:blockcolumnwidth]];}
.side-pre-only #page-content #region-main {margin-left:[[setting:blockcolumnwidth]];}
-$version = 2011090700.00; // YYYYMMDD = weekly release date of this DEV branch
+$version = 2011090700.01; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches
// .XX = incremental changes