MDL-69746 tool_replace: additional skip tables
authorNathan Nguyen <nathannguyen@catalyst-au.net>
Fri, 2 Oct 2020 03:10:51 +0000 (13:10 +1000)
committerNathan Nguyen <nathannguyen@catalyst-au.net>
Fri, 2 Oct 2020 04:57:18 +0000 (14:57 +1000)
admin/tool/replace/classes/form.php
admin/tool/replace/cli/replace.php
admin/tool/replace/index.php
admin/tool/replace/lang/en/tool_replace.php
lib/adminlib.php
lib/tests/adminlib_test.php

index 5c60510..d42fbe2 100644 (file)
@@ -46,6 +46,13 @@ class tool_replace_form extends moodleform {
         $mform->addElement('text', 'replace', get_string('replacewith', 'tool_replace'), 'size="50"', PARAM_RAW);
         $mform->addElement('static', 'replacest', '', get_string('replacewithhelp', 'tool_replace'));
         $mform->setType('replace', PARAM_RAW);
+
+        $mform->addElement('textarea', 'additionalskiptables', get_string("additionalskiptables", "tool_replace"),
+            array('rows' => 5, 'cols' => 50));
+        $mform->addElement('static', 'additionalskiptables_desc', '', get_string('additionalskiptables_desc', 'tool_replace'));
+        $mform->setType('additionalskiptables', PARAM_RAW);
+        $mform->setDefault('additionalskiptables', '');
+
         $mform->addElement('checkbox', 'shorten', get_string('shortenoversized', 'tool_replace'));
         $mform->addRule('replace', get_string('required'), 'required', null, 'client');
 
index 1f9e74b..b4244aa 100644 (file)
@@ -34,6 +34,7 @@ $help =
 Options:
 --search=STRING       String to search for.
 --replace=STRING      String to replace with.
+--skiptables=STRING   Skip these tables (comma separated list of tables).
 --shorten             Shorten result if necessary.
 --non-interactive     Perform the replacement without confirming.
 -h, --help            Print out this help.
@@ -46,6 +47,7 @@ list($options, $unrecognized) = cli_get_params(
     array(
         'search'  => null,
         'replace' => null,
+        'skiptables' => '',
         'shorten' => false,
         'non-interactive' => false,
         'help'    => false,
@@ -71,6 +73,7 @@ if (empty($options['shorten']) && core_text::strlen($options['search']) < core_t
 try {
     $search = validate_param($options['search'], PARAM_RAW);
     $replace = validate_param($options['replace'], PARAM_RAW);
+    $skiptables = validate_param($options['skiptables'], PARAM_RAW);
 } catch (invalid_parameter_exception $e) {
     cli_error(get_string('invalidcharacter', 'tool_replace'));
 }
@@ -85,7 +88,7 @@ if (!$options['non-interactive']) {
     }
 }
 
-if (!db_replace($search, $replace)) {
+if (!db_replace($search, $replace, $skiptables)) {
     cli_heading(get_string('error'));
     exit(1);
 }
index b3013d2..e4f2900 100644 (file)
@@ -57,7 +57,7 @@ if (!$data = $form->get_data()) {
 $PAGE->requires->js_init_code("window.scrollTo(0, 5000000);");
 
 echo $OUTPUT->box_start();
-db_replace($data->search, $data->replace);
+db_replace($data->search, $data->replace, $data->additionalskiptables);
 echo $OUTPUT->box_end();
 
 // Course caches are now rebuilt on the fly.
index 6117521..e8dce48 100644 (file)
@@ -22,7 +22,8 @@
  * @copyright  2011 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-
+$string['additionalskiptables'] = 'Additional skip tables';
+$string['additionalskiptables_desc'] = 'Please specify the additional tables (comma separated list) you want to skip while running DB search and replace.';
 $string['cannotfit'] = 'The replacement is longer than the original and shortening is not allowed; cannot continue.';
 $string['disclaimer'] = 'I understand the risks of this operation';
 $string['doit'] = 'Yes, do it!';
index 3a7045d..59531c3 100644 (file)
@@ -9069,12 +9069,17 @@ function any_new_admin_settings($node) {
  * @param string $column name
  * @return bool success or fail
  */
-function db_should_replace($table, $column = ''): bool {
+function db_should_replace($table, $column = '', $additionalskiptables = ''): bool {
 
     // TODO: this is horrible hack, we should do whitelisting and each plugin should be responsible for proper replacing...
     $skiptables = ['config', 'config_plugins', 'filter_config', 'sessions',
         'events_queue', 'repository_instance_config', 'block_instances', 'files'];
 
+    // Additional skip tables.
+    if (!empty($additionalskiptables)) {
+        $skiptables = array_merge($skiptables, explode(',', str_replace(' ', '',  $additionalskiptables)));
+    }
+
     // Don't process these.
     if (in_array($table, $skiptables)) {
         return false;
@@ -9103,7 +9108,7 @@ function db_should_replace($table, $column = ''): bool {
  * @param string $replace string to replace
  * @return bool success or fail
  */
-function db_replace($search, $replace) {
+function db_replace($search, $replace, $additionalskiptables = '') {
     global $DB, $CFG, $OUTPUT;
 
     // Turn off time limits, sometimes upgrades can be slow.
@@ -9114,7 +9119,7 @@ function db_replace($search, $replace) {
     }
     foreach ($tables as $table) {
 
-        if (!db_should_replace($table)) {
+        if (!db_should_replace($table, '', $additionalskiptables)) {
             continue;
         }
 
index 3f65921..89e29e3 100644 (file)
@@ -85,5 +85,48 @@ class core_adminlib_testcase extends advanced_testcase {
         $this->assertSame($actual, $expected);
     }
 
-}
+    /**
+     * Data provider for additional skip tables.
+     *
+     * @return array
+     */
+    public function db_should_replace_additional_skip_tables_dataprovider() {
+        return [
+            // Skipped tables.
+            ['block_instances', '', false],
+            ['config',          '', false],
+            ['config_plugins',  '', false],
+            ['config_log',      '', false],
+            ['events_queue',    '', false],
+            ['filter_config',   '', false],
+            ['log',             '', false],
+            ['repository_instance_config', '', false],
+            ['sessions',        '', false],
+            ['upgrade_log',     '', false],
+
+            // Additional skipped tables.
+            ['context',      '', false],
+            ['quiz_attempts',     '', false],
+            ['role_assignments',     '', false],
+
+            // Normal tables.
+            ['assign',          '', true],
+            ['book',          '', true],
+        ];
+    }
 
+    /**
+     * Test additional skip tables.
+     *
+     * @dataProvider db_should_replace_additional_skip_tables_dataprovider
+     * @param string $table name
+     * @param string $column name
+     * @param bool $expected whether it should be replaced
+     */
+    public function test_db_should_replace_additional_skip_tables(string $table, string $column, bool $expected) {
+        $this->resetAfterTest();
+        $additionalskiptables = 'context, quiz_attempts, role_assignments ';
+        $actual = db_should_replace($table, $column, $additionalskiptables);
+        $this->assertSame($actual, $expected);
+    }
+}