From b486ef1ae31726e502ddd6cfaff9aca7896d5993 Mon Sep 17 00:00:00 2001 From: toyomoyo Date: Thu, 15 Nov 2007 05:00:44 +0000 Subject: [PATCH] MDL-8270, full block backup/restore routine with code --- backup/backuplib.php | 14 +++++- backup/restorelib.php | 97 ++++++++++++++++++++++++++++++++---- blocks/moodleblock.class.php | 43 ++++++++++++++++ 3 files changed, 142 insertions(+), 12 deletions(-) diff --git a/backup/backuplib.php b/backup/backuplib.php index 99f0697d74..f703cc3285 100644 --- a/backup/backuplib.php +++ b/backup/backuplib.php @@ -957,6 +957,11 @@ if(empty($blocks[$instance->blockid]->name)) { continue; } + + if (!$blockobj = block_instance($blocks[$instance->blockid]->name, $instance)) { + // Invalid block + continue; + } //Give the block a chance to process any links in configdata. if (!isset($blocks[$instance->blockid]->blockobject)) { @@ -975,8 +980,13 @@ 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)); - + fwrite ($bf,full_tag('CONFIGDATA',4,false,$instance->configdata)); + // Write instance data if needed+ + if ($blockobj->backuprestore_enabled()) { + 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 diff --git a/backup/restorelib.php b/backup/restorelib.php index f8759ddb79..b4b6b1dfc7 100644 --- a/backup/restorelib.php +++ b/backup/restorelib.php @@ -227,10 +227,10 @@ echo '

Updating config for block ', $instance->id, '.

'; } //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; } @@ -778,8 +778,9 @@ echo '

Updating config for block ', $instance->id, '.

'; //This function creates all the block_instances from xml when restoring in a //new course function restore_create_block_instances($restore,$xml_file) { - + global $CFG; $status = true; + $CFG->restore_blockinstanceids = array(); // Tracks which blocks we create during the restore. // This is used in restore_decode_content_links. @@ -791,7 +792,7 @@ echo '

Updating config for block ', $instance->id, '.

'; } //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)) { @@ -873,9 +874,35 @@ echo '

Updating config for block ', $instance->id, '.

'; //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)) { + // Save the new ID for later+ + $CFG->restore_blockinstanceids[] = $instance->id; + // Create block instance + if (!$blockobj = block_instance($instance->name, $instance)) { + $status = false; + break; + } + // Run the block restore if needed + if ($blockobj->backuprestore_enabled()) { + // 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); } $restore->blockinstanceids[] = $newid; } else { @@ -885,8 +912,9 @@ echo '

Updating config for block ', $instance->id, '.

'; //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]; @@ -4043,6 +4071,17 @@ echo '

Updating config for block ', $instance->id, '.

'; //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") @@ -4806,6 +4845,13 @@ echo '

Updating config for block ', $instance->id, '.

'; //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)).""; + //Dependig of different combinations, do different things if ($this->level == 4) { switch ($tagName) { @@ -4813,6 +4859,37 @@ echo '

Updating config for block ', $instance->id, '.

'; //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); @@ -7684,7 +7761,7 @@ echo '

Updating config for block ', $instance->id, '.

'; 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/moodleblock.class.php b/blocks/moodleblock.class.php index c0af39efe4..c6d2b44b26 100644 --- a/blocks/moodleblock.class.php +++ b/blocks/moodleblock.class.php @@ -125,6 +125,49 @@ class block_base { function after_restore($restore) { } + /** + * Enable the block for backup and restore. + * + * If return true, then {@link instance_backup()} and + * {@link instance_restore()} will be called during + * backup/restore routines. + * + * @return boolean + **/ + function backuprestore_enabled() { + return false; + } + + /** + * 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 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 * any links in any HTML fields on config can be encoded. For example, for the HTML block -- 2.39.5