MDL-61268 blocks: Fix corrupt configdata in block instances.
authorAdrian Greeve <adrian@moodle.com>
Wed, 31 Jan 2018 10:57:06 +0000 (18:57 +0800)
committerAdrian Greeve <adrian@moodle.com>
Fri, 2 Mar 2018 01:22:05 +0000 (09:22 +0800)
Old configuration data in the block instances is base64 encoded with
the deprecated object class instead of stdClass.

blocks/html/backup/moodle1/lib.php
lib/db/upgrade.php
lib/db/upgradelib.php
version.php

index 3830ba9..da215c2 100644 (file)
@@ -30,9 +30,13 @@ defined('MOODLE_INTERNAL') || die();
 class moodle1_block_html_handler extends moodle1_block_handler {
     private $fileman = null;
     protected function convert_configdata(array $olddata) {
+        global $CFG;
+        require_once($CFG->libdir . '/db/upgradelib.php');
         $instanceid = $olddata['id'];
         $contextid  = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);
-        $configdata = unserialize(base64_decode($olddata['configdata']));
+        $decodeddata = base64_decode($olddata['configdata']);
+        list($updated, $configdata) = upgrade_fix_serialized_objects($decodeddata);
+        $configdata = unserialize($configdata);
 
         // get a fresh new file manager for this instance
         $this->fileman = $this->converter->get_file_manager($contextid, 'block_html');
index 6b6dc90..7e68ae1 100644 (file)
@@ -1973,5 +1973,14 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2018020500.00);
     }
 
+    if ($oldversion < 2018022800.01) {
+
+        // Fix old block configurations that use the deprecated (and now removed) object class.
+        upgrade_fix_block_instance_configuration();
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2018022800.01);
+    }
+
     return true;
 }
index 134d4c0..e0913a5 100644 (file)
@@ -502,3 +502,40 @@ function upgrade_block_positions() {
     WHERE pagetype IN ('my-index', 'user-profile') AND subpage NOT IN (SELECT $id FROM {my_pages})";
     $DB->execute($sql, ['']);
 }
+
+/**
+ * Fix configdata in block instances that are using the old object class that has been removed (deprecated).
+ */
+function upgrade_fix_block_instance_configuration() {
+    global $DB;
+
+    $sql = "SELECT *
+              FROM {block_instances}
+             WHERE configdata <> ''";
+    $blockinstances = $DB->get_recordset_sql($sql);
+    foreach ($blockinstances as $blockinstance) {
+        $configdata = base64_decode($blockinstance->configdata);
+        list($updated, $configdata) = upgrade_fix_serialized_objects($configdata);
+        if ($updated) {
+            $blockinstance->configdata = base64_encode($configdata);
+            $DB->update_record('block_instances', $blockinstance);
+        }
+    }
+    $blockinstances->close();
+}
+
+/**
+ * Provides a way to check and update a serialized string that uses the deprecated object class.
+ *
+ * @param  string $serializeddata Serialized string which may contain the now deprecated object.
+ * @return array Returns an array where the first variable is a bool with a status of whether the initial data was changed
+ * or not. The second variable is the said data.
+ */
+function upgrade_fix_serialized_objects($serializeddata) {
+    $updated = false;
+    if (strpos($serializeddata, ":6:\"object") !== false) {
+        $serializeddata = str_replace(":6:\"object", ":8:\"stdClass", $serializeddata);
+        $updated = true;
+    }
+    return [$updated, $serializeddata];
+}
index bdba231..641e285 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2018022800.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2018022800.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.