From 6ced7617c58eaefe06389e7e355c97c424723802 Mon Sep 17 00:00:00 2001 From: Nathan Nguyen Date: Fri, 2 Oct 2020 13:10:51 +1000 Subject: [PATCH 1/1] MDL-69746 tool_replace: additional skip tables --- admin/tool/replace/classes/form.php | 7 ++++ admin/tool/replace/cli/replace.php | 5 ++- admin/tool/replace/index.php | 2 +- admin/tool/replace/lang/en/tool_replace.php | 3 +- lib/adminlib.php | 11 +++-- lib/tests/adminlib_test.php | 45 ++++++++++++++++++++- 6 files changed, 66 insertions(+), 7 deletions(-) diff --git a/admin/tool/replace/classes/form.php b/admin/tool/replace/classes/form.php index 5c605107265..d42fbe2ae97 100644 --- a/admin/tool/replace/classes/form.php +++ b/admin/tool/replace/classes/form.php @@ -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'); diff --git a/admin/tool/replace/cli/replace.php b/admin/tool/replace/cli/replace.php index 1f9e74bce76..b4244aa1c9a 100644 --- a/admin/tool/replace/cli/replace.php +++ b/admin/tool/replace/cli/replace.php @@ -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); } diff --git a/admin/tool/replace/index.php b/admin/tool/replace/index.php index b3013d232be..e4f2900e4f5 100644 --- a/admin/tool/replace/index.php +++ b/admin/tool/replace/index.php @@ -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. diff --git a/admin/tool/replace/lang/en/tool_replace.php b/admin/tool/replace/lang/en/tool_replace.php index 6117521591d..e8dce48ddff 100644 --- a/admin/tool/replace/lang/en/tool_replace.php +++ b/admin/tool/replace/lang/en/tool_replace.php @@ -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!'; diff --git a/lib/adminlib.php b/lib/adminlib.php index 3a7045d3880..59531c3c073 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -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; } diff --git a/lib/tests/adminlib_test.php b/lib/tests/adminlib_test.php index 3f65921e0ba..89e29e3e096 100644 --- a/lib/tests/adminlib_test.php +++ b/lib/tests/adminlib_test.php @@ -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); + } +} -- 2.43.0