]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-7401 Course format database/backup/lang/stylesheet/capability support
authorsam_marshall <sam_marshall>
Mon, 11 Dec 2006 15:47:23 +0000 (15:47 +0000)
committersam_marshall <sam_marshall>
Mon, 11 Dec 2006 15:47:23 +0000 (15:47 +0000)
15 files changed:
admin/index.php
backup/backup_execute.html
backup/backuplib.php
backup/restorelib.php
course/edit_form.php
course/format/README.txt
course/lib.php
course/mod.php
course/modedit.php
lang/en_utf8/moodle.php
lib/accesslib.php
lib/adminlib.php
lib/moodlelib.php
lib/weblib.php
theme/standard/config.php

index fecf7fedd46a0d655d3cc5e19df16704f6826879..070ba8d1226a2f2bb45276e7d7fe135d3a6b72b5 100644 (file)
 /// 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");
index dabed9e04dfe9ee950c827410206aee4e1f536e1..681dc8e51294db1ae75bc7f551ee1d290d09b9e4 100644 (file)
             }
         }
 
+        //Backup course format data, if any. 
+        echo '<li>'.get_string("courseformatdata").'</li>';
+        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)) {
index ac5f62db087f645dfd8d4b9e5e82f2bc917811cc..611e9321228908f1149cd2f21f6a9151cba0e0e3 100644 (file)
 
     }
 
+    //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) {
index 5be575c37493f8805bbeba3dd2e055c8b2f51956..a4a6f74a363b7f003f76c601912d08c3a1301940 100644 (file)
         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) {
 
         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) {
             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\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("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
+        }
+
         //This is the startTag handler we use where we are reading the metacourse zone (todo="METACOURSE")
         function startElementMetacourse($parser, $tagName, $attrs) {
 
 
         }
 
+        //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))."</".$tagName.">";            
+            }
+
+            if($tagName=='FORMATDATA') {
+                //Did we have any data? If not don't bother
+                if($this->temp!='<FORMATDATA></FORMATDATA>') {
+                    //Prepend XML standard header to info gathered
+                    $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\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
         } 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");
             }
         }
 
+        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 '<li>'.get_string('courseformatdata').'</li>';
+                }
+                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')) {
index 63289d08af888d39e7fc267bf63012bc9baaca01..7660bf952937b8ce91953a18a46bb5ecce71fb3e 100644 (file)
@@ -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);
index 52d1568012143f950af290dc924e062452f4bcfc..efc3a9b5d1f73ccb173846b5ff50fe87dd81c6cf 100644 (file)
@@ -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:
+  
+<?php
+$string['formatyourformat']='Your format'; // Name to display for format
+$string['nameyourformat']='section'; // Name of a section within your format
+?>
+
+  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.
+
+  <?php
+  $plugin->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.
index 199c3a29251956b70dc1bdbb06be9db9cf7b115e..305462136b94ab3a0b0c43196d9b2adae9a35481 100644 (file)
@@ -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;
+}
+
 ?>
index 168ac635555b5d4af6b4ad1aa59ac69c9af3f678..ef157f5a0ce53b61898bec453ed2a2384744d5ce 100644 (file)
         $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') {
index 0de47463333e92823093e996fb18a116740c5adb..6eb81e3eb695724820321e9fc01074db55cb025f 100644 (file)
@@ -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') {
index 6d02f424ae538dbc4d0c18418cc732fc194f659b..a75c45529058d8ac363d2f2b29313f7d39b1c94a 100644 (file)
@@ -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';
index ea0ab155c0fbb72e37510007a7db396f6587c6a4..03400911444e2c686d98bc17771d1afbcc2c4a6f 100755 (executable)
@@ -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);
index 30d5940a829f29959e41a93de5ee52db25612700..1124512a4f678fd720c02f43f5cc6c7b62c5cf16 100644 (file)
@@ -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');
index d9e1d5202a717a9d82f8dbb36d2014e0e635b6b0..567446c3d64f120670ddd875633a3677fea5d75d 100644 (file)
@@ -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/';
         }
index 58da7d00342a939663385faf6ebbaec1dc56f384..6ac2cfdbf44f6c186936c1be87c95060d2c20b23 100644 (file)
@@ -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');
index 8628ae95b9fbb2a8f92748a814aa06fe6d42a8ed..5e38df1d8ef0f5a3a8b60e31f707888e9f001528 100644 (file)
@@ -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