@@ -9,6 +9,7 @@ class Search_Replace_Command extends WP_CLI_Command {
9
9
private $ regex ;
10
10
private $ regex_flags ;
11
11
private $ regex_delimiter ;
12
+ private $ regex_limit = -1 ;
12
13
private $ skip_tables ;
13
14
private $ skip_columns ;
14
15
private $ include_columns ;
@@ -22,7 +23,6 @@ class Search_Replace_Command extends WP_CLI_Command {
22
23
private $ log_prefixes = array ( '< ' , '> ' );
23
24
private $ log_colors ;
24
25
private $ log_encoding ;
25
- private $ log_run_data = array ();
26
26
27
27
/**
28
28
* Searches/replaces strings in the database.
@@ -108,6 +108,9 @@ class Search_Replace_Command extends WP_CLI_Command {
108
108
* [--regex-delimiter=<regex-delimiter>]
109
109
* : The delimiter to use for the regex. It must be escaped if it appears in the search string. The default value is the result of `chr(1)`.
110
110
*
111
+ * [--regex-limit=<regex-limit>]
112
+ * : The maximum possible replacements for the regex per row (or per unserialized data bit per row). Defaults to -1 (no limit).
113
+ *
111
114
* [--format=<format>]
112
115
* : Render output in a particular format.
113
116
* ---
@@ -165,7 +168,7 @@ public function __invoke( $args, $assoc_args ) {
165
168
$ total = 0 ;
166
169
$ report = array ();
167
170
$ this ->dry_run = \WP_CLI \Utils \get_flag_value ( $ assoc_args , 'dry-run ' );
168
- $ php_only = \WP_CLI \Utils \get_flag_value ( $ assoc_args , 'precise ' );
171
+ $ php_only = \WP_CLI \Utils \get_flag_value ( $ assoc_args , 'precise ' );
169
172
$ this ->recurse_objects = \WP_CLI \Utils \get_flag_value ( $ assoc_args , 'recurse-objects ' , true );
170
173
$ this ->verbose = \WP_CLI \Utils \get_flag_value ( $ assoc_args , 'verbose ' );
171
174
$ this ->format = \WP_CLI \Utils \get_flag_value ( $ assoc_args , 'format ' );
@@ -180,6 +183,13 @@ public function __invoke( $args, $assoc_args ) {
180
183
}
181
184
}
182
185
186
+ if ( null !== ( $ regex_limit = \WP_CLI \Utils \get_flag_value ( $ assoc_args , 'regex-limit ' ) ) ) {
187
+ if ( ! preg_match ( '/^(?:[0-9]+|-1)$/ ' , $ regex_limit ) || 0 === (int ) $ regex_limit ) {
188
+ WP_CLI ::error ( '`--regex-limit` expects a non-zero positive integer or -1. ' );
189
+ }
190
+ $ this ->regex_limit = (int ) $ regex_limit ;
191
+ }
192
+
183
193
if ( ! empty ( $ this ->regex ) ) {
184
194
if ( '' === $ this ->regex_delimiter ) {
185
195
$ this ->regex_delimiter = chr ( 1 );
@@ -402,7 +412,7 @@ private function php_export_table( $table, $old, $new ) {
402
412
'chunk_size ' => $ chunk_size
403
413
);
404
414
405
- $ replacer = new \WP_CLI \SearchReplacer ( $ old , $ new , $ this ->recurse_objects , $ this ->regex , $ this ->regex_flags , $ this ->regex_delimiter );
415
+ $ replacer = new \WP_CLI \SearchReplacer ( $ old , $ new , $ this ->recurse_objects , $ this ->regex , $ this ->regex_flags , $ this ->regex_delimiter , false , $ this -> regex_limit );
406
416
$ col_counts = array_fill_keys ( $ all_columns , 0 );
407
417
if ( $ this ->verbose && 'table ' === $ this ->format ) {
408
418
$ this ->start_time = microtime ( true );
@@ -476,7 +486,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) {
476
486
global $ wpdb ;
477
487
478
488
$ count = 0 ;
479
- $ replacer = new \WP_CLI \SearchReplacer ( $ old , $ new , $ this ->recurse_objects , $ this ->regex , $ this ->regex_flags , $ this ->regex_delimiter , null !== $ this ->log_handle );
489
+ $ replacer = new \WP_CLI \SearchReplacer ( $ old , $ new , $ this ->recurse_objects , $ this ->regex , $ this ->regex_flags , $ this ->regex_delimiter , null !== $ this ->log_handle , $ this -> regex_limit );
480
490
481
491
$ table_sql = self ::esc_sql_ident ( $ table );
482
492
$ col_sql = self ::esc_sql_ident ( $ col );
@@ -798,12 +808,11 @@ private function log_bits( $search_regex, $old_data, $old_matches, $new ) {
798
808
$ diff += strlen ( $ new ) - strlen ( $ old_matches [0 ][ $ i ][0 ] );
799
809
$ i ++;
800
810
return $ new ;
801
- }, $ old_data );
811
+ }, $ old_data, $ this -> regex_limit , $ match_cnt );
802
812
803
813
$ old_bits = $ new_bits = array ();
804
814
$ append_next = false ;
805
815
$ last_old_offset = $ last_new_offset = 0 ;
806
- $ match_cnt = count ( $ old_matches [0 ] );
807
816
for ( $ i = 0 ; $ i < $ match_cnt ; $ i ++ ) {
808
817
$ old_match = $ old_matches [0 ][ $ i ][0 ];
809
818
$ old_offset = $ old_matches [0 ][ $ i ][1 ];
@@ -828,8 +837,8 @@ private function log_bits( $search_regex, $old_data, $old_matches, $new ) {
828
837
$ new_after = \cli \safe_substr ( substr ( $ new_data , $ new_end_offset ), 0 , $ this ->log_after_context , false /*is_width*/ , $ encoding );
829
838
// To lessen context duplication in output, shorten the after context if it overlaps with the next match.
830
839
if ( $ i + 1 < $ match_cnt && $ old_end_offset + strlen ( $ old_after ) > $ old_matches [0 ][ $ i + 1 ][1 ] ) {
831
- $ old_after = substr ( $ old_after , 0 , $ old_matches [0 ][ $ i + 1 ][1 ] - $ old_end_offset );
832
- $ new_after = substr ( $ new_after , 0 , $ new_matches [0 ][ $ i + 1 ][1 ] - $ new_end_offset );
840
+ $ old_after = substr ( $ old_after , 0 , $ old_matches [0 ][ $ i + 1 ][1 ] - $ old_end_offset );
841
+ $ new_after = substr ( $ new_after , 0 , $ new_matches [0 ][ $ i + 1 ][1 ] - $ new_end_offset );
833
842
$ after_shortened = true ;
834
843
// On the next iteration, will append with no before context.
835
844
}
0 commit comments