Skip to content

Commit d748262

Browse files
committed
db search: fix match in context in non-regex case.
1 parent bbea3b8 commit d748262

File tree

2 files changed

+48
-35
lines changed

2 files changed

+48
-35
lines changed

features/db-search.feature

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,3 +908,29 @@ Feature: Search through the database
908908
"""
909909
Warning: Unrecognized percent color code '%x' for 'match_color'.
910910
"""
911+
912+
Scenario: Search with matches within context
913+
Given a WP install
914+
And I run `wp option update matches_in_context '1234_XYXYX_2345678_XYXYX_2345678901_XYXYX_2345'`
915+
916+
When I run `wp db search XYXYX --before_context=10 --after_context=10 --stats`
917+
Then STDOUT should contain:
918+
"""
919+
Success: Found 3 matches
920+
"""
921+
And STDOUT should contain:
922+
"""
923+
:1234_XYXYX_2345678_X [...] X_2345678_XYXYX_234567890 [...] 345678901_XYXYX_2345
924+
"""
925+
And STDERR should be empty
926+
927+
When I run `wp db search XYXYX --before_context=10 --after_context=10 --regex --stats`
928+
Then STDOUT should contain:
929+
"""
930+
Success: Found 3 matches
931+
"""
932+
And STDOUT should contain:
933+
"""
934+
:1234_XYXYX_2345678_X [...] X_2345678_XYXYX_234567890 [...] 345678901_XYXYX_2345
935+
"""
936+
And STDERR should be empty

src/DB_Command.php

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -715,10 +715,10 @@ public function prefix() {
715715
* ---
716716
*
717717
* [--regex]
718-
* : Runs the search as a regular expression (without delimiters). The search becomes case-sensitive (i.e. no PCRE flags are added, except 'u' if the database charset is UTF-8). Delimiters must be escaped if they occur in the expression.
718+
* : Runs the search as a regular expression (without delimiters). The search becomes case-sensitive (i.e. no PCRE flags are added). Delimiters must be escaped if they occur in the expression.
719719
*
720720
* [--regex-flags=<regex-flags>]
721-
* : Pass PCRE modifiers to the regex search (e.g. 'i' for case-insensitivity). Note that 'u' (UTF-8 mode) will not be automatically added.
721+
* : Pass PCRE modifiers to the regex search (e.g. 'i' for case-insensitivity).
722722
*
723723
* [--regex-delimiter=<regex-delimiter>]
724724
* : The delimiter to use for the regex. It must be escaped if it appears in the search string.
@@ -845,24 +845,16 @@ public function search( $args, $assoc_args ) {
845845
if ( false === @preg_match( $search_regex, '' ) ) {
846846
WP_CLI::error( "The regex '$search_regex' fails." );
847847
}
848-
$encoding = null;
849-
if ( 0 === strpos( $wpdb->charset, 'utf8' ) ) {
850-
$encoding = 'UTF-8';
851-
if ( ! $regex_flags ) {
852-
$search_regex .= 'u';
853-
}
854-
}
855848
} else {
856-
$safe_search = preg_quote( $search, '#' );
857-
if ( 0 === strpos( $wpdb->charset, 'utf8' ) ) {
858-
$context_re = \cli\can_use_pcre_x() ? '\X' : '.';
859-
$search_regex = '#(' . $context_re . '{0,' . $before_context . '})(' . $safe_search .')(' . $context_re . '{0,' . $after_context . '})#iu';
860-
} else {
861-
$search_regex = '#(.{0,' . $before_context . '})(' . $safe_search .')(.{0,' . $after_context . '})#i';
862-
}
849+
$search_regex = '#' . preg_quote( $search, '#' ) . '#i';
863850
$esc_like_search = '%' . self::esc_like( $search ) . '%';
864851
}
865852

853+
$encoding = null;
854+
if ( 0 === strpos( $wpdb->charset, 'utf8' ) ) {
855+
$encoding = 'UTF-8';
856+
}
857+
866858
$tables = WP_CLI\Utils\wp_get_table_names( $args, $assoc_args );
867859

868860
$start_search_time = microtime( true );
@@ -904,34 +896,29 @@ public function search( $args, $assoc_args ) {
904896
$outputted_table_column_once = false;
905897
foreach ( $results as $result ) {
906898
$col_val = $result->$column;
907-
if ( preg_match_all( $search_regex, $col_val, $matches, $regex ? PREG_OFFSET_CAPTURE : PREG_PATTERN_ORDER ) ) {
899+
if ( preg_match_all( $search_regex, $col_val, $matches, PREG_OFFSET_CAPTURE ) ) {
908900
if ( ! $matches_only && ( ! $table_column_once || ! $outputted_table_column_once ) && ! $one_line ) {
909901
WP_CLI::log( $table_column_val );
910902
$outputted_table_column_once = true;
911903
}
912904
$pk_val = $primary_key ? ( $colors['id'][0] . $result->$primary_key . $colors['id'][1] . ':' ) : '';
913905

914906
$bits = array();
915-
if ( $regex ) {
916-
if ( null === $encoding ) {
917-
$encoding = false;
918-
if ( ( $before_context || $after_context ) && function_exists( 'mb_detect_encoding' ) ) {
919-
$encoding = mb_detect_encoding( $col_val, null, true /*strict*/ );
920-
}
921-
}
922-
foreach ( $matches[0] as $match_arr ) {
923-
$match = $match_arr[0];
924-
$offset = $match_arr[1];
925-
// Offsets are in bytes, so need to use `strlen()` and `substr()` before using `safe_substr()`.
926-
$before = $before_context && $offset ? \cli\safe_substr( substr( $col_val, 0, $offset ), -$before_context, null /*length*/, false /*is_width*/, $encoding ) : '';
927-
$after = $after_context ? \cli\safe_substr( substr( $col_val, $offset + strlen( $match ) ), 0, $after_context, false /*is_width*/, $encoding ) : '';
928-
$bits[] = $before . $colors['match'][0] . $match . $colors['match'][1] . $after;
929-
}
930-
} else {
931-
foreach ( $matches[0] as $key => $value ) {
932-
$bits[] = $matches[1][ $key ] . $colors['match'][0] . $matches[2][ $key ] . $colors['match'][1] . $matches[3][ $key ];
907+
$col_encoding = $encoding;
908+
if ( null === $col_encoding ) {
909+
$col_encoding = false;
910+
if ( ( $before_context || $after_context ) && function_exists( 'mb_detect_encoding' ) ) {
911+
$col_encoding = mb_detect_encoding( $col_val, null, true /*strict*/ );
933912
}
934913
}
914+
foreach ( $matches[0] as $match_arr ) {
915+
$match = $match_arr[0];
916+
$offset = $match_arr[1];
917+
// Offsets are in bytes, so need to use `strlen()` and `substr()` before using `safe_substr()`.
918+
$before = $before_context && $offset ? \cli\safe_substr( substr( $col_val, 0, $offset ), -$before_context, null /*length*/, false /*is_width*/, $col_encoding ) : '';
919+
$after = $after_context ? \cli\safe_substr( substr( $col_val, $offset + strlen( $match ) ), 0, $after_context, false /*is_width*/, $col_encoding ) : '';
920+
$bits[] = $before . $colors['match'][0] . $match . $colors['match'][1] . $after;
921+
}
935922
$match_count += count( $bits );
936923
$col_val = implode( ' [...] ', $bits );
937924

0 commit comments

Comments
 (0)