diff --git a/backup/backuplib.php b/backup/backuplib.php
index 150526a720c..d5043575502 100644
--- a/backup/backuplib.php
+++ b/backup/backuplib.php
@@ -929,27 +929,31 @@
$pages = array();
$pages[] = page_create_object(PAGE_COURSE_VIEW, $preferences->backup_course);
- // Let's see if we have to backup blocks from modules
- $modulerecords = get_records_sql('SELECT name, id FROM '.$CFG->prefix.'modules');
+ if (!empty($CFG->showblocksonmodpages)) {
+ // get course structure
+ $course = get_record('course', 'id', $preferences->backup_course);
+ $modinfo =& get_fast_modinfo($course);
- foreach($preferences->mods as $module) {
- if(!$module->backup) {
- continue;
- }
+ foreach($preferences->mods as $module) {
+ if (!$module->backup) {
+ continue;
+ }
- $cmods = get_records_select('course_modules', 'course = '.$preferences->backup_course.' AND module = '.$modulerecords[$module->name]->id);
- if(empty($cmods)) {
- continue;
- }
+ if (empty($modinfo->instances[$module->name])) {
+ continue;
+ }
- $pagetypes = page_import_types('mod/'.$module->name.'/');
- if(empty($pagetypes)) {
- continue;
- }
+ $pagetypes = page_import_types('mod/'.$module->name.'/');
+ if (empty($pagetypes)) {
+ continue;
+ }
- foreach($pagetypes as $pagetype) {
- foreach($cmods as $cmod) {
- $pages[] = page_create_object($pagetype, $cmod->instance);
+ foreach($pagetypes as $pagetype) {
+ foreach($modinfo->instances[$module->name] as $cm) {
+ if (!empty($module->instances[$cm->instance]->backup)) {
+ $pages[] = page_create_object($pagetype, $cm->instance);
+ }
+ }
}
}
}
@@ -957,7 +961,7 @@
//Blocks open tag
fwrite ($bf,start_tag('BLOCKS',2,true));
- while($page = array_pop($pages)) {
+ foreach($pages as $page) {
if ($instances = blocks_get_by_page($page)) {
//Iterate over every block
foreach ($instances as $position) {
@@ -967,26 +971,32 @@
if(empty($blocks[$instance->blockid]->name)) {
continue;
}
+ $blockname = $blocks[$instance->blockid]->name;
- //Give the block a chance to process any links in configdata.
- if (!isset($blocks[$instance->blockid]->blockobject)) {
- $blocks[$instance->blockid]->blockobject = block_instance($blocks[$instance->blockid]->name);
+ if (!$blockobj = block_instance($blockname, $instance)) {
+ // Invalid block
+ continue;
}
- $config = unserialize(base64_decode($instance->configdata));
- $blocks[$instance->blockid]->blockobject->backup_encode_absolute_links_in_config($config);
- $instance->configdata = base64_encode(serialize($config));
+
+ // encode absolute links in block config
+ $instance->configdata = $blockobj->get_backup_encoded_config();
//Begin Block
fwrite ($bf,start_tag('BLOCK',3,true));
fwrite ($bf,full_tag('ID', 4, false,$instance->id));
- fwrite ($bf,full_tag('NAME',4,false,$blocks[$instance->blockid]->name));
+ fwrite ($bf,full_tag('NAME',4,false,$blockname));
fwrite ($bf,full_tag('PAGEID',4,false,$instance->pageid));
fwrite ($bf,full_tag('PAGETYPE',4,false,$instance->pagetype));
fwrite ($bf,full_tag('POSITION',4,false,$instance->position));
fwrite ($bf,full_tag('WEIGHT',4,false,$instance->weight));
fwrite ($bf,full_tag('VISIBLE',4,false,$instance->visible));
fwrite ($bf,full_tag('CONFIGDATA',4,false,$instance->configdata));
-
+ // Write instance data if needed
+ if ($blockobj->backuprestore_instancedata_used()) {
+ fwrite ($bf,start_tag('INSTANCEDATA',4,true));
+ $status = $blockobj->instance_backup($bf, $preferences);
+ fwrite ($bf,end_tag('INSTANCEDATA',4,true));
+ }
$context = get_context_instance(CONTEXT_BLOCK, $instance->id);
write_role_overrides_xml($bf, $context, 4);
/// write role_assign code here
@@ -1484,7 +1494,7 @@
JOIN {$CFG->prefix}grade_items gi
ON (gi.iteminstance = gc.id)
WHERE gc.courseid = $preferences->backup_course
- AND (gi.itemtype='course' OR gi.itemtype='category')
+ AND (gi.itemtype='course' OR gi.itemtype='category')
ORDER BY gi.sortorder ASC");
if ($grade_categories) {
@@ -2227,6 +2237,25 @@
}
}
+ // For each block, call its encode_content_links method.
+ // This encodes forexample links to blocks/something/viewphp?id=666
+ // that are stored in other activities.
+ static $blockobjects = null;
+ if (!isset($blockobjects)) {
+ $blockobjects = array();
+ if ($blocks = get_records('block', 'visible', 1)) {
+ foreach ($blocks as $block) {
+ if ($blockobject = block_instance($block->name)) {
+ $blockobjects[] = $blockobject;
+ }
+ }
+ }
+ }
+
+ foreach ($blockobjects as $blockobject) {
+ $result = $blockobject->encode_content_links($result,$mypreferences);
+ }
+
if ($result != $content) {
debugging('
'.s($content).'
changed to
'.s($result).'
');
}
diff --git a/backup/restorelib.php b/backup/restorelib.php
index 45a6f5d4651..09b0e47f4b8 100644
--- a/backup/restorelib.php
+++ b/backup/restorelib.php
@@ -104,7 +104,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
if (!defined('RESTORE_SILENTLY')) {
echo "".get_string ("from")." ".get_string("modulenameplural",$name);
}
- $status = $function_name($restore);
+ $status = $function_name($restore) && $status;
if (!defined('RESTORE_SILENTLY')) {
echo '';
}
@@ -114,22 +114,16 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
// Process all html text also in blocks too
if (!defined('RESTORE_SILENTLY')) {
- echo '' . get_string ('from') . ' ' . get_string('blocks');
+ echo ''.get_string ('from').' '.get_string('blocks');
}
- if (!empty($restore->blockinstanceids)) {
- $blocks = blocks_get_record();
- $instances = get_records_list('block_instance', 'id', implode(',', $restore->blockinstanceids), '', 'id,blockid,configdata');
- foreach ($instances as $instance) {
- if (!isset($blocks[$instance->blockid]->blockobject)) {
- $blocks[$instance->blockid]->blockobject = block_instance($blocks[$instance->blockid]->name);
- }
- $config = unserialize(base64_decode($instance->configdata));
- if ($blocks[$instance->blockid]->blockobject->restore_decode_absolute_links_in_config($config)) {
- $instance->configdata = base64_encode(serialize($config));
- $status = $status && update_record('block_instance', $instance);
- }
+
+ if ($blocks = get_records('block', 'visible', 1)) {
+ foreach ($blocks as $block) {
+ $blockobject = block_instance($block->name);
+ $blockobject->decode_content_links_caller($restore);
}
}
+
if (!defined('RESTORE_SILENTLY')) {
echo '';
}
@@ -139,7 +133,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
if (!defined('RESTORE_SILENTLY')) {
echo '' . get_string('from') . ' ' . get_string('questions', 'quiz');
}
- $status = question_decode_content_links_caller($restore);
+ $status = question_decode_content_links_caller($restore) && $status;
if (!defined('RESTORE_SILENTLY')) {
echo '';
}
@@ -161,6 +155,24 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
$content = $function_name($content,$restore);
}
}
+
+ // For each block, call its encode_content_links method
+ static $blockobjects = null;
+ if (!isset($blockobjects)) {
+ $blockobjects = array();
+ if ($blocks = get_records('block', 'visible', 1)) {
+ foreach ($blocks as $block) {
+ if ($blockobject = block_instance($block->name)) {
+ $blockobjects[] = $blockobject;
+ }
+ }
+ }
+ }
+
+ foreach ($blockobjects as $blockobject) {
+ $content = $blockobject->decode_content_links($content,$restore);
+ }
+
return $content;
}
@@ -248,10 +260,10 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
}
//This function read the xml file and store its data from the blocks in a object
- function restore_read_xml_blocks ($xml_file) {
+ function restore_read_xml_blocks ($restore, $xml_file) {
//We call the main read_xml function, with todo = BLOCKS
- $info = restore_read_xml ($xml_file,'BLOCKS',false);
+ $info = restore_read_xml ($xml_file,'BLOCKS',$restore);
return $info;
}
@@ -762,7 +774,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
// Looks like it's from Moodle < 1.3. Let's give the course default blocks...
$newpage = page_create_object(PAGE_COURSE_VIEW, $restore->course_id);
blocks_repopulate_page($newpage);
- } else {
+ } else if (!empty($CFG->showblocksonmodpages)) {
// We just have a blockinfo field, this is a legacy 1.4 or 1.3 backup
$blockrecords = get_records_select('block', '', '', 'name, id');
$temp_blocks_l = array();
@@ -810,17 +822,13 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
$status = true;
- // Tracks which blocks we create during the restore.
- // This is used in restore_decode_content_links.
- $restore->blockinstanceids = array();
-
//Check it exists
if (!file_exists($xml_file)) {
$status = false;
}
//Get info from xml
if ($status) {
- $info = restore_read_xml_blocks($xml_file);
+ $info = restore_read_xml_blocks($restore,$xml_file);
}
if(empty($info->instances)) {
@@ -838,8 +846,8 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
if($instance->pagetype == PAGE_COURSE_VIEW) {
// This one's easy...
$instance->pageid = $restore->course_id;
- }
- else {
+
+ } else if (!empty($CFG->showblocksonmodpages)) {
$parts = explode('-', $instance->pagetype);
if($parts[0] == 'mod') {
if(!$restore->mods[$parts[1]]->restore) {
@@ -857,6 +865,10 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
// Not invented here ;-)
continue;
}
+
+ } else {
+ // do not restore activity blocks if disabled
+ continue;
}
if(!isset($pageinstances[$instance->pagetype])) {
@@ -869,7 +881,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
$pageinstances[$instance->pagetype][$instance->pageid][] = $instance;
}
- $blocks = get_records_select('block', '', '', 'name, id, multiple');
+ $blocks = get_records_select('block', 'visible = 1', '', 'name, id, multiple');
// For each type of page we have restored
foreach($pageinstances as $thistypeinstances) {
@@ -907,11 +919,35 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
//Add this instance
$instance->blockid = $blocks[$instance->name]->id;
- if ($newid = insert_record('block_instance', $instance)) {
- if (!empty($instance->id)) { // this will only be set if we come from 1.7 and above backups
- backup_putid ($restore->backup_unique_code,"block_instance",$instance->id,$newid);
+ // This will only be set if we come from 1.7 and above backups
+ // Also, must do this before insert (insert_record unsets id)
+ if (!empty($instance->id)) {
+ $oldid = $instance->id;
+ } else {
+ $oldid = 0;
+ }
+
+ if ($instance->id = insert_record('block_instance', $instance)) {
+ // Create block instance
+ if (!$blockobj = block_instance($instance->name, $instance)) {
+ $status = false;
+ break;
}
- $restore->blockinstanceids[] = $newid;
+ // Run the block restore if needed
+ if ($blockobj->backuprestore_instancedata_used()) {
+ // Get restore information
+ $data = backup_getid($restore->backup_unique_code,'block_instance',$oldid);
+ $data->new_id = $instance->id; // For completeness
+ if (!$blockobj->instance_restore($restore, $data)) {
+ $status = false;
+ break;
+ }
+ }
+ // Save oldid after block restore process because info will be over-written with blank string
+ if ($oldid) {
+ backup_putid ($restore->backup_unique_code,"block_instance",$oldid,$instance->id);
+ }
+
} else {
$status = false;
break;
@@ -919,8 +955,9 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
//Get an object for the block and tell it it's been restored so it can update dates
//etc. if necessary
- $blockobj=block_instance($instance->name,$instance);
- $blockobj->after_restore($restore);
+ if ($blockobj = block_instance($instance->name,$instance)) {
+ $blockobj->after_restore($restore);
+ }
//Now we can increment the weight counter
++$maxweights[$instance->position];
@@ -4286,6 +4323,16 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
//Check if we are into BLOCKS zone
//if ($this->tree[3] == "BLOCKS") //Debug
// echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName.">
\n"; //Debug
+
+ //If we are under a BLOCK tag under a BLOCKS zone, accumule it
+ if (isset($this->tree[4]) and isset($this->tree[3])) { //
+ if ($this->tree[4] == "BLOCK" and $this->tree[3] == "BLOCKS") {
+ if (!isset($this->temp)) {
+ $this->temp = "";
+ }
+ $this->temp .= "<".$tagName.">";
+ }
+ }
}
//This is the startTag handler we use where we are reading the sections zone (todo="SECTIONS")
@@ -5077,6 +5124,13 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
//if (trim($this->content)) //Debug
// echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."
\n"; //Debug
//echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName.">
\n"; //Debug
+
+ // Collect everything into $this->temp
+ if (!isset($this->temp)) {
+ $this->temp = "";
+ }
+ $this->temp .= htmlspecialchars(trim($this->content))."".$tagName.">";
+
//Dependig of different combinations, do different things
if ($this->level == 4) {
switch ($tagName) {
@@ -5084,6 +5138,37 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
//We've finalized a block, get it
$this->info->instances[] = $this->info->tempinstance;
unset($this->info->tempinstance);
+
+ //Also, xmlize INSTANCEDATA and save to db
+ //Prepend XML standard header to info gathered
+ $xml_data = "\n".$this->temp;
+ //Call to xmlize for this portion of xml data (one BLOCK)
+ //echo "-XMLIZE: ".strftime ("%X",time()),"-"; //Debug
+ $data = xmlize($xml_data,0);
+ //echo strftime ("%X",time()).""; //Debug
+ //traverse_xmlize($data); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+ //Check for instancedata, is exists, then save to DB
+ if (isset($data['BLOCK']['#']['INSTANCEDATA']['0']['#'])) {
+ //Get old id
+ $oldid = $data['BLOCK']['#']['ID']['0']['#'];
+ //Get instancedata
+
+ if ($data = $data['BLOCK']['#']['INSTANCEDATA']['0']['#']) {
+ //Restore code calls this multiple times - so might already have the newid
+ if ($newid = backup_getid($this->preferences->backup_unique_code,'block_instance',$oldid)) {
+ $newid = $newid->new_id;
+ } else {
+ $newid = null;
+ }
+ //Save to DB, we will use it later
+ $status = backup_putid($this->preferences->backup_unique_code,'block_instance',$oldid,$newid,$data);
+ }
+ }
+ //Reset temp
+ unset($this->temp);
+
break;
default:
die($tagName);
@@ -8105,7 +8190,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
if (!defined('RESTORE_SILENTLY')) {
echo "
".get_string("creatingblocksroles").'';
}
- $blocks = restore_read_xml_blocks($xmlfile);
+ $blocks = restore_read_xml_blocks($restore, $xmlfile);
if (isset($blocks->instances)) {
foreach ($blocks->instances as $instance) {
if (isset($instance->roleassignments) && !$isimport) {
diff --git a/blocks/html/block_html.php b/blocks/html/block_html.php
index 8e610049fe8..f0a60ef8b8b 100755
--- a/blocks/html/block_html.php
+++ b/blocks/html/block_html.php
@@ -36,14 +36,51 @@ class block_html extends block_base {
return $this->content;
}
- function backup_encode_absolute_links_in_config(&$config) {
- $config->text = backup_encode_absolute_links($config->text);
+ /**
+ * Will be called before an instance of this block is backed up, so that any links in
+ * any links in any HTML fields on config can be encoded.
+ * @return string
+ */
+ function get_backup_encoded_config() {
+ $data = clone($this->config);
+ $data->text = backup_encode_absolute_links($data->text);
+ return base64_encode(serialize($data));
}
- function restore_decode_absolute_links_in_config(&$config) {
- $oldtext = $config->text;
- $config->text = restore_decode_absolute_links($oldtext);
- return $config->text != $oldtext;
+ /**
+ * This function makes all the necessary calls to {@link restore_decode_content_links_worker()}
+ * function in order to decode contents of this block from the backup
+ * format to destination site/course in order to mantain inter-activities
+ * working in the backup/restore process.
+ *
+ * This is called from {@link restore_decode_content_links()} function in the restore process.
+ *
+ * NOTE: There is no block instance when this method is called.
+ *
+ * @param object $restore Standard restore object
+ * @return boolean
+ **/
+ function decode_content_links_caller($restore) {
+ global $CFG;
+
+ if ($restored_blocks = get_records_select("backup_ids","table_name = 'block_instance' AND backup_code = $restore->backup_unique_code AND new_id > 0", "", "new_id")) {
+ $restored_blocks = implode(',', array_keys($restored_blocks));
+ $sql = "SELECT bi.*
+ FROM {$CFG->prefix}block_instance bi
+ JOIN {$CFG->prefix}block b ON b.id = bi.blockid
+ WHERE b.name = 'html' AND bi.id IN ($restored_blocks)";
+
+ if ($instances = get_records_sql($sql)) {
+ foreach ($instances as $instance) {
+ $blockobject = block_instance('html', $instance);
+ $blockobject->config->text = restore_decode_absolute_links($blockobject->config->text);
+ $blockobject->config->text = restore_decode_content_links_worker($blockobject->config->text, $restore);
+ $blockobject->instance_config_commit($blockobject->pinned);
+ }
+ }
+ }
+
+ return true;
}
}
?>
diff --git a/blocks/moodleblock.class.php b/blocks/moodleblock.class.php
index 3fdc945ae53..4afe7d79757 100644
--- a/blocks/moodleblock.class.php
+++ b/blocks/moodleblock.class.php
@@ -130,25 +130,102 @@ class block_base {
}
/**
- * Will be called before an instance of this block is backed up, so that any links in
- * any links in any HTML fields on config can be encoded. For example, for the HTML block
- * we need to do $config->text = backup_encode_absolute_links($config->text);.
+ * Enable custom instance data section in backup and restore.
+ *
+ * If return true, then {@link instance_backup()} and
+ * {@link instance_restore()} will be called during
+ * backup/restore routines.
*
- * @param object $config the config field for an insance of this class.
- */
- function backup_encode_absolute_links_in_config(&$config) {
+ * @return boolean
+ **/
+ function backuprestore_instancedata_used() {
+ return false;
}
/**
- * Undo the effect of backup_encode_absolute_links_in_config. For exmaple, in the
- * HTML block we need to do $config->text = restore_decode_absolute_links($config->text);
+ * Allows the block class to have a backup routine. Handy
+ * when the block has its own tables that have foreign keys to
+ * other tables (example: user table).
+ *
+ * Note: at the time of writing this comment, the indent level
+ * for the {@link full_tag()} should start at 5.
*
- * @param object $config the config field for an insance of this class.
- * @return boolean return true if something has changed, so the database can be updated,
- * false if not, for efficiency reasons.
+ * @param resource $bf Backup File
+ * @param object $preferences Backup preferences
+ * @return boolean
+ **/
+ function instance_backup($bf, $preferences) {
+ return true;
+ }
+
+ /**
+ * Allows the block class to restore its backup routine.
+ *
+ * Should not return false if data is empty
+ * because old backups would not contain block instance backup data.
+ *
+ * @param object $restore Standard restore object
+ * @param object $data Object from backup_getid for this block instance
+ * @return boolean
+ **/
+ function instance_restore($restore, $data) {
+ return true;
+ }
+
+ /**
+ * Will be called before an instance of this block is backed up, so that any links in
+ * in config can be encoded. For example config->text, for the HTML block
+ * @return string
*/
- function restore_decode_absolute_links_in_config(&$config) {
- return false;
+ function get_backup_encoded_config() {
+ return base64_encode(serialize($this->config));
+ }
+
+ /**
+ * Return the content encoded to support interactivities linking. This function is
+ * called automatically from the backup procedure by {@link backup_encode_absolute_links()}.
+ *
+ * NOTE: There is no block instance when this method is called.
+ *
+ * @param string $content Content to be encoded
+ * @param object $restore Restore preferences object
+ * @return string The encoded content
+ **/
+ function encode_content_links($content, $restore) {
+ return $content;
+ }
+
+ /**
+ * This function makes all the necessary calls to {@link restore_decode_content_links_worker()}
+ * function in order to decode contents of this block from the backup
+ * format to destination site/course in order to mantain inter-activities
+ * working in the backup/restore process.
+ *
+ * This is called from {@link restore_decode_content_links()} function in the restore process.
+ *
+ * NOTE: There is no block instance when this method is called.
+ *
+ * @param object $restore Standard restore object
+ * @return boolean
+ **/
+ function decode_content_links_caller($restore) {
+ return true;
+ }
+
+ /**
+ * Return content decoded to support interactivities linking.
+ * This is called automatically from
+ * {@link restore_decode_content_links_worker()} function
+ * in the restore process.
+ *
+ * NOTE: There is no block instance when this method is called.
+ *
+ * @param string $content Content to be dencoded
+ * @param object $restore Restore preferences object
+ * @return string The dencoded content
+ **/
+ function decode_content_links($content, $restore) {
+ return $content;
}
/**