From: sam_marshall Date: Mon, 11 Dec 2006 15:47:23 +0000 (+0000) Subject: MDL-7401 Course format database/backup/lang/stylesheet/capability support X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=ae628043a0ccf3b04a940667181bc30359fb5509;p=moodle.git MDL-7401 Course format database/backup/lang/stylesheet/capability support --- diff --git a/admin/index.php b/admin/index.php index fecf7fedd4..070ba8d122 100644 --- a/admin/index.php +++ b/admin/index.php @@ -347,6 +347,9 @@ /// first old *.php update and then the new upgrade.php script upgrade_plugins('enrol', 'enrol', "$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards +/// Check all course formats and upgrade if necessary + upgrade_plugins('format','course/format',"$CFG->wwwroot/$CFG->admin/index.php"); + /// Check for local database customisations /// first old *.php update and then the new upgrade.php script require_once("$CFG->dirroot/lib/locallib.php"); diff --git a/backup/backup_execute.html b/backup/backup_execute.html index dabed9e04d..681dc8e512 100644 --- a/backup/backup_execute.html +++ b/backup/backup_execute.html @@ -232,6 +232,14 @@ } } + //Backup course format data, if any. + echo '
  • '.get_string("courseformatdata").'
  • '; + if($status) { + if (!$status = backup_format_data($backup_file,$preferences)) { + notify("An error occurred while backing up the course format data"); + } + } + //Prints course end if ($status) { if (!$status = backup_course_end($backup_file,$preferences)) { diff --git a/backup/backuplib.php b/backup/backuplib.php index ac5f62db08..611e932122 100644 --- a/backup/backuplib.php +++ b/backup/backuplib.php @@ -966,6 +966,35 @@ } + //Prints course's format data (any data the format might want to save). + function backup_format_data ($bf,$preferences) { + global $CFG; + + // Check course format + if(!($format=get_field('course','format','id',$preferences->backup_course))) { + return false; + } + // Write appropriate tag. Note that we always put this tag there even if + // blank, it makes parsing easier + fwrite ($bf,start_tag("FORMATDATA",2,true)); + + $file=$CFG->dirroot."/course/format/$format/backuplib.php"; + if(file_exists($file)) { + // If the file is there, the function must be or it's an error. + require_once($file); + $function=$format.'_backup_format_data'; + if(!function_exists($function)) { + return false; + } + if(!$function($bf,$preferences)) { + return false; + } + } + + // This last return just checks the file writing has been ok (ish) + return fwrite ($bf,end_tag("FORMATDATA",2,true)); + } + //Prints course's modules info (table course_modules) //Only for selected mods in preferences function backup_course_modules ($bf,$preferences,$section) { diff --git a/backup/restorelib.php b/backup/restorelib.php index 5be575c374..a4a6f74a36 100644 --- a/backup/restorelib.php +++ b/backup/restorelib.php @@ -208,6 +208,15 @@ return $info; } + //This function read the xml file and store its data from the course format in an object + function restore_read_xml_formatdata ($xml_file) { + + //We call the main read_xml function, with todo = FORMATDATA + $info = restore_read_xml ($xml_file,'FORMATDATA',false); + + return $info; + } + //This function read the xml file and store its data from the metacourse in a object function restore_read_xml_metacourse ($xml_file) { @@ -979,6 +988,42 @@ return $status; } + //Called to set up any course-format specific data that may be in the file + function restore_set_format_data($restore,$xml_file) { + global $CFG,$db; + + $status = true; + //Check it exists + if (!file_exists($xml_file)) { + return false; + } + //Load data from XML to info + if(!($info = restore_read_xml_formatdata($xml_file))) { + return false; + } + + //Process format data if there is any + if (isset($info->format_data)) { + if(!$format=get_field('course','format','id',$restore->course_id)) { + return false; + } + // If there was any data then it must have a restore method + $file=$CFG->dirroot."/course/format/$format/restorelib.php"; + if(!file_exists($file)) { + return false; + } + require_once($file); + $function=$format.'_restore_format_data'; + if(!function_exists($function)) { + return false; + } + return $function($restore,$info->format_data); + } + + // If we got here then there's no data, but that's cool + return true; + } + //This function creates all the metacourse data from xml, notifying //about each incidence function restore_create_metacourse($restore,$xml_file) { @@ -3090,6 +3135,28 @@ // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName.">
    \n"; //Debug } + //This is the startTag handler we use where we are reading the optional format data zone (todo="FORMATDATA") + function startElementFormatData($parser, $tagName, $attrs) { + //Refresh properties + $this->level++; + $this->tree[$this->level] = $tagName; + + //Output something to avoid browser timeouts... + backup_flush(); + + //Accumulate all the data inside this tag + if (isset($this->tree[3]) && $this->tree[3] == "FORMATDATA") { + if (!isset($this->temp)) { + $this->temp = ''; + } + $this->temp .= "<".$tagName.">"; + } + + //Check if we are into FORMATDATA zone + //if ($this->tree[3] == "FORMATDATA") //Debug + // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName.">
    \n"; //Debug + } + //This is the startTag handler we use where we are reading the metacourse zone (todo="METACOURSE") function startElementMetacourse($parser, $tagName, $attrs) { @@ -4069,6 +4136,36 @@ } + //This is the endTag handler we use where we are reading the optional format data zone (todo="FORMATDATA") + function endElementFormatData($parser, $tagName) { + //Check if we are into FORMATDATA zone + if ($this->tree[3] == 'FORMATDATA') { + if (!isset($this->temp)) { + $this->temp = ''; + } + $this->temp .= htmlspecialchars(trim($this->content)).""; + } + + if($tagName=='FORMATDATA') { + //Did we have any data? If not don't bother + if($this->temp!='') { + //Prepend XML standard header to info gathered + $xml_data = "\n".$this->temp; + $this->temp=''; + + //Call to xmlize for this portion of xml data (the FORMATDATA block) + $this->info->format_data = xmlize($xml_data,0); + } + //Stop parsing at end of FORMATDATA + $this->finished=true; + } + + //Clear things + $this->tree[$this->level] = ""; + $this->level--; + $this->content = ""; + } + //This is the endTag handler we use where we are reading the metacourse zone (todo="METACOURSE") function endElementMetacourse($parser, $tagName) { //Check if we are into METACOURSE zone @@ -5028,6 +5125,9 @@ } else if ($todo == "SECTIONS") { //Define handlers to that zone xml_set_element_handler($xml_parser, "startElementSections", "endElementSections"); + } else if ($todo == 'FORMATDATA') { + //Define handlers to that zone + xml_set_element_handler($xml_parser, "startElementFormatData", "endElementFormatData"); } else if ($todo == "METACOURSE") { //Define handlers to that zone xml_set_element_handler($xml_parser, "startElementMetacourse", "endElementMetacourse"); @@ -5767,6 +5867,24 @@ } } + if($status) { + //If we are deleting and bringing into a course or making a new course, same situation + if($restore->restoreto == 0 || $restore->restoreto == 2) { + if (!defined('RESTORE_SILENTLY')) { + echo '
  • '.get_string('courseformatdata').'
  • '; + } + if (!$status = restore_set_format_data($restore, $xml_file)) { + $error = "Error while setting the course format data"; + if (!defined('RESTORE_SILENTLY')) { + notify($error); + } else { + $errorstr=$error; + return false; + } + } + } + } + //Now create log entries as needed if ($status and ($restore->logs)) { if (!defined('RESTORE_SILENTLY')) { diff --git a/course/edit_form.php b/course/edit_form.php index 63289d08af..7660bf9529 100644 --- a/course/edit_form.php +++ b/course/edit_form.php @@ -89,7 +89,10 @@ class course_edit_form extends moodleform { $courseformats = get_list_of_plugins('course/format'); $formcourseformats = array(); foreach ($courseformats as $courseformat) { - $formcourseformats["$courseformat"] = get_string("format$courseformat"); + $formcourseformats["$courseformat"] = get_string("format$courseformat","format_$courseformat"); + if($formcourseformats["$courseformat"]=="[[format$courseformat]]") { + $formcourseformats["$courseformat"] = get_string("format$courseformat"); + } } $mform->addElement('select', 'format', get_string('format'), $formcourseformats); $mform->setHelpButton('format', array('courseformats', get_string('courseformats')), true); diff --git a/course/format/README.txt b/course/format/README.txt index 52d1568012..efc3a9b5d1 100644 --- a/course/format/README.txt +++ b/course/format/README.txt @@ -1,9 +1,140 @@ Course formats +============== + +To create a new course format, make another folder in here. + +If you want a basic format, you only need to write the 'standard files' listed +below. + +If you want to store information in the database for your format, or control +access to features of your format, you need some of the optional files too. + +All names below assume that your format is called 'yourformat'. + + +Standard files -------------- -To add a new course format, just duplicate one of the -existing folders in here with a new name (eg coollayout). -Then edit lang/en/moodle and add a new string like: +* yourformat/format.php + + Code that actually displays the course view page. See existing formats for + examples. + +* yourformat/config.php + + Configuration file, mainly controlling default blocks for the format. + See existing formats for examples. + +* yourformat/lang/en_utf8/format_yourformat.php + + Language file containing basic language strings for your format. Here + is a minimal language file: + + + + The first string is used in the dropdown menu of course settings. The second + is used when editing an activity within a course of your format. + + Note that existing formats store their language strings in the main + moodle.php, which you can also do, but this separate file is recommended + for contributed formats. + + You can also store other strings in this file if you wish. They can be + accessed as follows, for example to get the section name: + + get_string('nameyourformat','format_yourformat'); + + Of course you can have other folders as well as just English if you want + to provide multiple languages. + + +Optional files (database access) +-------------------------------- + +If these files exist, Moodle will use them to set up database tables when you +visit the admin page. + +* yourformat/db/install.xml + + Database table definitions. Use your format name at the start of the table + names to increase the chance that they are unique. + +* yourformat/db/upgrade.php + + Database upgrade instructions. Similar to other upgrade.php files, so look + at those for modules etc. if you want to see. + + The function must look like: + + function xmldb_format_yourformat_upgrade($oldversion=0) { + ... + +* yourformat/version.php + + Required if you use database tables. + + version = 2006120100; // Plugin version (update when tables change) + $plugin->requires = 2006092801; // Required Moodle version + ?> + + +Optional files (backup) +----------------------- + +If these files exist, backup and restore run automatically when backing up +the course. You can't back up the course format data independently. + +* yourformat/backuplib.php + + Similar to backup code for other plugins. Must have a function: + + function yourformat_backup_format_data($bf,$preferences) { + ... + +* yourformat/restorelib.php + + Similar to restore code for other plugins. Must have a function: + + function yourformat_restore_format_data($restore,$data) { + ... + + ($data is the xmlized data underneath FORMATDATA in the backup XML file. + Do print_object($data); while testing to see how it looks.) + + +Optional file (capabilities) +---------------------------- + +If this file exists, Moodle refreshes your format's capabilities +(checks that they are all included in the database) whenever you increase +the version in yourformat/version.php. + +* yourformat/db/access.php + + Contains capability entries similar to other access.php files. + + The array definition must look like: + + $format_yourformat_capabilities = array( + ... + + Format names must look like: + + format/yourformat:specialpower + + Capability definitions in your language file must look like: + + $string['yourformat:specialpower']='Revolutionise the world'; + + + +Optional file (styles) +---------------------- -$string['formatcoollayout'] = 'Cool Layout'; +* yourformat/styles.php + If this file exists it will be included in the CSS Moodle generates. diff --git a/course/lib.php b/course/lib.php index 199c3a2925..305462136b 100644 --- a/course/lib.php +++ b/course/lib.php @@ -2197,4 +2197,16 @@ function move_courses ($courseids, $categoryid) { return true; } +/** + * @param string $format Course format ID e.g. 'weeks' + * @return Name that the course format prefers for sections + */ +function get_section_name($format) { + $sectionname = get_string("name$format","format_$format"); + if($sectionname == "[[name$format]]") { + $sectionname = get_string("name$format"); + } + return $sectionname; +} + ?> diff --git a/course/mod.php b/course/mod.php index 168ac63555..ef157f5a0c 100644 --- a/course/mod.php +++ b/course/mod.php @@ -526,7 +526,7 @@ $form->mode = "update"; $form->sesskey = !empty($USER->id) ? $USER->sesskey : ''; - $sectionname = get_string("name$course->format"); + $sectionname = get_section_name($course->format); $fullmodulename = get_string("modulename", $module->name); if ($form->section && $course->format != 'site') { diff --git a/course/modedit.php b/course/modedit.php index 0de4746333..6eb81e3eb6 100644 --- a/course/modedit.php +++ b/course/modedit.php @@ -45,7 +45,7 @@ $form->type = $type; } - $sectionname = get_string("name$course->format"); + $sectionname = get_section_name($course->format); $fullmodulename = get_string("modulename", $module->name); if ($form->section && $course->format != 'site') { @@ -92,7 +92,7 @@ $form->return = $return; $form->update = $update; - $sectionname = get_string("name$course->format"); + $sectionname = get_section_name($course->format); $fullmodulename = get_string("modulename", $module->name); if ($form->section && $course->format != 'site') { diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index 6d02f424ae..a75c455290 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -252,6 +252,7 @@ $string['coursecategory'] = 'Course category'; $string['coursecreators'] = 'Course creator'; $string['coursecreatorsdescription'] = 'Course creators can create new courses and teach in them.'; $string['coursefiles'] = 'Course files'; +$string['courseformatdata'] = 'Course format data'; $string['courseformats'] = 'Course formats'; $string['coursegrades'] = 'Course grades'; $string['coursehidden'] = 'This course is currently unavailable to students'; diff --git a/lib/accesslib.php b/lib/accesslib.php index ea0ab155c0..0340091144 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -2140,6 +2140,11 @@ function load_capability_def($component) { $defpath = $CFG->dirroot.'/'.$compparts[0]. 's/'.$compparts[1].'/db/access.php'; $varprefix = $compparts[0].'_'.$compparts[1]; + } else if ($compparts[0] == 'format') { + // Similar to the above, course formats are 'format' while they + // are stored in 'course/format'. + $defpath = $CFG->dirroot.'/course/'.$component.'/db/access.php'; + $varprefix = $compparts[0].'_'.$compparts[1]; } else { $defpath = $CFG->dirroot.'/'.$component.'/db/access.php'; $varprefix = str_replace('/', '_', $component); @@ -2694,6 +2699,10 @@ function get_capability_string($capabilityname) { case 'enrol': $string = get_string($stringname, 'enrol_'.$componentname); break; + + case 'format': + $string = get_string($stringname, 'format_'.$componentname); + break; default: $string = get_string($stringname); diff --git a/lib/adminlib.php b/lib/adminlib.php index 30d5940a82..1124512a4f 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -113,7 +113,7 @@ function upgrade_plugins($type, $dir, $return) { if ($status) { // OK so far, now update the plugins record set_config($pluginversion, $plugin->version); - if (!update_capabilities($dir.'/'.$plug)) { + if (!update_capabilities($type.'/'.$plug)) { error('Could not set up the capabilities for '.$module->name.'!'); } notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess'); @@ -150,7 +150,7 @@ function upgrade_plugins($type, $dir, $return) { if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed // OK so far, now update the plugins record set_config($pluginversion, $plugin->version); - if (!update_capabilities($dir.'/'.$plug)) { + if (!update_capabilities($type.'/'.$plug)) { error('Could not update '.$plugin->name.' capabilities!'); } notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess'); diff --git a/lib/moodlelib.php b/lib/moodlelib.php index d9e1d5202a..567446c3d6 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -4310,6 +4310,8 @@ function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) { } else if (strpos($module, 'report_') === 0) { // It's a report lang file $locations[] = $CFG->dirroot .'/'.$CFG->admin.'/report/'.substr($module, 7).'/lang/'; $locations[] = $CFG->dirroot .'/course/report/'.substr($module, 7).'/lang/'; + } else if (strpos($module, 'format_') === 0) { // Course format + $locations[] = $CFG->dirroot .'/course/format/'.substr($module,7).'/lang/'; } else { // It's a normal activity $locations[] = $CFG->dirroot .'/mod/'.$module.'/lang/'; } diff --git a/lib/weblib.php b/lib/weblib.php index 58da7d0034..6ac2cfdbf4 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -2445,6 +2445,16 @@ function style_sheet_setup($lastmodified=0, $lifetime=300, $themename='', $force } } + if (!isset($THEME->courseformatsheets) || $THEME->courseformatsheets) { // Search for styles.php in course formats + if ($mods = get_list_of_plugins('format','',$CFG->dirroot.'/course')) { + foreach ($mods as $mod) { + if (file_exists($CFG->dirroot.'/course/format/'.$mod.'/styles.php')) { + $files[] = array($CFG->dirroot, '/course/format/'.$mod.'/styles.php'); + } + } + } + } + if (!empty($THEME->langsheets)) { // Search for styles.php within the current language if (file_exists($CFG->dirroot.'/lang/'.$lang.'/styles.php')) { $files[] = array($CFG->dirroot, '/lang/'.$lang.'/styles.php'); diff --git a/theme/standard/config.php b/theme/standard/config.php index 8628ae95b9..5e38df1d8e 100644 --- a/theme/standard/config.php +++ b/theme/standard/config.php @@ -80,6 +80,14 @@ $THEME->langsheets = false; /// different styles. +$THEME->courseformatsheets = true; + +/// When this is enabled, this theme will search for files +/// named "styles.php" inside all course formats and +/// include them. This allows course formats to provide +/// their own default styles. + + $THEME->navmenuwidth = 50; /// You can use this to control the cutoff point for strings