diff --git a/classes/helper.php b/classes/helper.php index 4d7f4d1..45c5740 100644 --- a/classes/helper.php +++ b/classes/helper.php @@ -36,14 +36,25 @@ class helper { * * @param string $table The table to search. * @param array $searchingcolumns The columns to search. + * @param array $skiptables The tables to skip. + * @param array $skipcolumns The columns to skip. * @param string $searchstring The string to search for. * @return array The columns to search. */ - public static function get_columns(string $table, array $searchingcolumns = [], string $searchstring = ''): array { + public static function get_columns(string $table, array $searchingcolumns = [], + array $skiptables = [], array $skipcolumns = [], string $searchstring = ''): array { global $DB; + + // Skip tables that are in the skip list. + if (in_array($table, $skiptables)) { + return []; + } + + // Get the columns in the table. $columns = $DB->get_columns($table); // Make sure the table has id field. + // There could be some custom tables that do not have id field. $hasid = false; foreach ($columns as $col) { if ($col->name == 'id') { @@ -57,13 +68,10 @@ public static function get_columns(string $table, array $searchingcolumns = [], return []; } - // Knowns tables to skip. - $skiptables = ['grade_grades_history']; - - // Skip tables that are in the skip list. - if (in_array($table, $skiptables)) { - return []; - } + // Skip columns that are in the skip list. + $columns = array_filter($columns, function($col) use ($skipcolumns) { + return !in_array($col->name, $skipcolumns); + }); // Only search the specified columns. foreach ($searchingcolumns as $column) { @@ -84,12 +92,9 @@ public static function get_columns(string $table, array $searchingcolumns = [], return $col->meta_type === 'X' || $col->meta_type === 'C'; }); - // Known columns to skip. - $skipcolumns = ['introformat']; - - // Skip columns that are in the skip list. - $columns = array_filter($columns, function($col) use ($skipcolumns) { - return !in_array($col->name, $skipcolumns); + // Skip columns which has 'format' in the name. + $columns = array_filter($columns, function($col) { + return strpos($col->name, 'format') === false; }); // Exclude columns that has max length less than the search string. @@ -108,9 +113,14 @@ public static function get_columns(string $table, array $searchingcolumns = [], * Build searching list * * @param string $tables A comma separated list of tables and columns to search. + * @param string $skiptables A comma separated list of tables to skip. + * @param string $skipcolumns A comma separated list of columns to skip. + * @param string $searchstring The string to search for, used to exclude columns having max length less than this. + * * @return array */ - public static function build_searching_list(string $tables = '', string $searchstring = ''): array { + public static function build_searching_list(string $tables = '', string $skiptables = '', string $skipcolumns = '', + string $searchstring = ''): array { global $DB; // Build a list of tables and columns to search. @@ -153,11 +163,15 @@ public static function build_searching_list(string $tables = '', string $searchs } } + // Skip tables and columns. + $skiptables = explode(',', $skiptables); + $skipcolumns = explode(',', $skipcolumns); + // Return the list of tables and actual columns to search. $count = 0; $actualsearchlist = []; foreach ($searchlist as $table => $columns) { - $actualcolumns = self::get_columns($table, $columns, $searchstring); + $actualcolumns = self::get_columns($table, $columns, $skiptables, $skipcolumns, $searchstring); sort($actualcolumns); $count += sizeof($actualcolumns); if (!empty($actualcolumns)) { @@ -199,10 +213,9 @@ public static function find_course_field(string $table): string { * @param string $search The text to search for. * @param string $table The table to search. * @param database_column_info $column The column to search. - * @param int $limit The maximum number of results to return. - * @param $stream The resource to write the results to. If null, the results are returned. + * @param bool $summary Whether to return a summary of the search. + * @param null $stream The resource to write the results to. If null, the results are returned. * @return array The results of the search. - * @throws \dml_exception */ public static function plain_text_search(string $search, string $table, database_column_info $column, bool $summary = false, @@ -273,8 +286,8 @@ public static function plain_text_search(string $search, string $table, * @param string $search The regular expression to search for. * @param string $table The table to search. * @param database_column_info $column The column to search. - * @param int $limit The maximum number of results to return. - * @param $stream The resource to write the results to. If null, the results are returned. + * @param bool $summary Whether to return a summary of the search. + * @param null $stream The resource to write the results to. If null, the results are returned. * @return array */ public static function regular_expression_search(string $search, string $table, diff --git a/cli/find.php b/cli/find.php index f5a16fb..5c64df9 100644 --- a/cli/find.php +++ b/cli/find.php @@ -36,7 +36,7 @@ Options: --search=STRING Required if --regex-match is not specified. String to search for. --regex-match=STRING Required if --search is not specified. Use regular expression to match the search string. ---output=FILE Required. .Output file. If not specified, output to stdout. +--output=FILE Required output file. If not specified, output to stdout. --tables=tablename:columnname Tables and columns to search. Separate multiple tables/columns with a comma. If not specified, search all tables and columns. If specify table only, search all columns in the table. @@ -44,6 +44,12 @@ --tables=user:username,user:email --tables=user,assign_submission:submission --tables=user,assign_submission +--skip-tables=tablenname Tables to skip. Separate multiple tables with a comma. + Example: + --skip-tables=user,config +--skip-columns=columnname Columns to skip. Separate multiple columns with a comma. + Example: + --skip-columns=firstname,lastname --summary Summary mode, only shows column/table where the text is found. If not specified, run in detail mode, which shows the full text where the search string is found. -h, --help Print out this help. @@ -55,12 +61,14 @@ list($options, $unrecognized) = cli_get_params( [ - 'search' => null, - 'regex-match' => null, - 'output' => null, - 'tables' => '', - 'summary' => false, - 'help' => false, + 'search' => null, + 'regex-match' => null, + 'output' => null, + 'tables' => '', + 'skip-tables' => '', + 'skip-columns' => '', + 'summary' => false, + 'help' => false, ], [ 'h' => 'help', @@ -95,8 +103,11 @@ } $tables = validate_param($options['tables'], PARAM_RAW); $output = validate_param($options['output'], PARAM_RAW); + $skiptables = validate_param($options['skip-tables'], PARAM_RAW); + $skipcolumns = validate_param($options['skip-columns'], PARAM_RAW); + $summary = validate_param($options['summary'], PARAM_RAW); } catch (invalid_parameter_exception $e) { - cli_error(get_string('invalidcharacter', 'tool_advancedreplace')); + cli_error(get_string('errorinvalidparam', 'tool_advancedreplace')); } // Start output. @@ -110,7 +121,7 @@ } // Perform the search. -[$count,$searchlist] = helper::build_searching_list($tables, ); +[$count, $searchlist] = helper::build_searching_list($tables, $skiptables, $skipcolumns); $progress = new progress_bar(); $progress->create(); @@ -124,9 +135,9 @@ // Perform the search. if (!empty($options['regex-match'])) { - helper::regular_expression_search($search, $table, $column, $options['summary'], $fp); + helper::regular_expression_search($search, $table, $column, $summary, $fp); } else { - helper::plain_text_search($search, $table, $column, $options['summary'], $fp); + helper::plain_text_search($search, $table, $column, $summary, $fp); } $columncount++; diff --git a/lang/en/tool_advancedreplace.php b/lang/en/tool_advancedreplace.php index b40cbcb..4c7fb9b 100644 --- a/lang/en/tool_advancedreplace.php +++ b/lang/en/tool_advancedreplace.php @@ -24,5 +24,6 @@ $string['errorregexnotsupported'] = 'Regular expression searches are not supported by this database.'; $string['errorsearchmethod'] = 'Please choose one of the search methods: plain text or regular expression.'; +$string['errorinvalidparam'] = 'Invalid parameter.'; $string['pluginname'] = 'Advanced DB search and replace'; $string['privacy:metadata'] = 'The plugin does not store any personal data.';