Skip to content

Commit 41bbda5

Browse files
Copilotswissspidy
andcommitted
Add progress bar support to search-replace command
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent 6b308fd commit 41bbda5

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

src/Search_Replace_Command.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ class Search_Replace_Command extends WP_CLI_Command {
119119
*/
120120
private $start_time;
121121

122+
/**
123+
* @var \cli\progress\Bar|null
124+
*/
125+
private $progress_bar;
126+
122127
/**
123128
* Searches/replaces strings in the database.
124129
*
@@ -557,6 +562,18 @@ private function php_export_table( $table, $old, $new ) {
557562
WP_CLI::log( sprintf( 'Checking: %s', $table ) );
558563
}
559564

565+
// Set up progress bar if appropriate
566+
$progress = null;
567+
if ( $this->should_show_progress_bar() ) {
568+
global $wpdb;
569+
$table_sql = self::esc_sql_ident( $table );
570+
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
571+
$total_rows = $wpdb->get_var( "SELECT COUNT(*) FROM {$table_sql}" );
572+
if ( $total_rows > 0 ) {
573+
$progress = \WP_CLI\Utils\make_progress_bar( sprintf( 'Exporting %s', $table ), $total_rows );
574+
}
575+
}
576+
560577
$rows = array();
561578
foreach ( new Iterators\Table( $args ) as $i => $row ) {
562579
$row_fields = array();
@@ -572,9 +589,17 @@ private function php_export_table( $table, $old, $new ) {
572589
$row_fields[ $col ] = $value;
573590
}
574591
$rows[] = $row_fields;
592+
593+
if ( $progress ) {
594+
$progress->tick();
595+
}
575596
}
576597
$this->write_sql_row_fields( $table, $rows );
577598

599+
if ( $progress ) {
600+
$progress->finish();
601+
}
602+
578603
$table_report = array();
579604
$total_rows = 0;
580605
$total_cols = 0;
@@ -650,6 +675,17 @@ static function ( $key ) {
650675
$order_by_sql = 'ORDER BY ' . implode( ',', $order_by_keys );
651676
$limit = 1000;
652677

678+
// Set up progress bar if appropriate
679+
$progress = null;
680+
if ( $this->should_show_progress_bar() ) {
681+
// Count total rows to process
682+
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
683+
$total_rows = $wpdb->get_var( "SELECT COUNT(*) FROM {$table_sql} {$where_key}" );
684+
if ( $total_rows > 0 ) {
685+
$progress = \WP_CLI\Utils\make_progress_bar( sprintf( 'Updating %s.%s', $table, $col ), $total_rows );
686+
}
687+
}
688+
653689
// 2 errors:
654690
// - WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
655691
// - WordPress.CodeAnalysis.AssignmentInCondition -- no reason to do copy-paste for a single valid assignment in while
@@ -668,18 +704,27 @@ static function ( $key ) {
668704
$col_value = $wpdb->get_var( "SELECT {$col_sql} FROM {$table_sql} WHERE {$where_sql}" );
669705

670706
if ( '' === $col_value ) {
707+
if ( $progress ) {
708+
$progress->tick();
709+
}
671710
continue;
672711
}
673712

674713
$value = $replacer->run( $col_value );
675714

676715
if ( $value === $col_value ) {
716+
if ( $progress ) {
717+
$progress->tick();
718+
}
677719
continue;
678720
}
679721

680722
// In case a needed re-serialization was unsuccessful, we should not update the value,
681723
// as this implies we hit an exception while processing.
682724
if ( gettype( $value ) !== gettype( $col_value ) ) {
725+
if ( $progress ) {
726+
$progress->tick();
727+
}
683728
continue;
684729
}
685730

@@ -697,6 +742,10 @@ static function ( $key ) {
697742

698743
$wpdb->update( $table, [ $col => $value ], $update_where );
699744
}
745+
746+
if ( $progress ) {
747+
$progress->tick();
748+
}
700749
}
701750

702751
// Because we are ordering by primary keys from least to greatest,
@@ -735,6 +784,10 @@ static function ( $key ) {
735784
$where_key = 'WHERE ' . implode( ' AND ', $where_key_conditions );
736785
}
737786

787+
if ( $progress ) {
788+
$progress->finish();
789+
}
790+
738791
if ( $this->verbose && 'table' === $this->format ) {
739792
$time = round( microtime( true ) - $this->start_time, 3 );
740793
WP_CLI::log( sprintf( '%d rows affected using PHP (in %ss).', $count, $time ) );
@@ -850,6 +903,40 @@ private static function is_text_col( $type ) {
850903
return false;
851904
}
852905

906+
/**
907+
* Determines whether a progress bar should be shown.
908+
*
909+
* @return bool True if progress bar should be shown.
910+
*/
911+
private function should_show_progress_bar() {
912+
// Don't show progress bar if in quiet mode
913+
if ( WP_CLI::get_config( 'quiet' ) ) {
914+
return false;
915+
}
916+
917+
// Don't show progress bar if exporting to STDOUT
918+
if ( STDOUT === $this->export_handle ) {
919+
return false;
920+
}
921+
922+
// Don't show progress bar if logging to STDOUT
923+
if ( STDOUT === $this->log_handle ) {
924+
return false;
925+
}
926+
927+
// Don't show progress bar if verbose mode is enabled (it shows row-by-row updates)
928+
if ( $this->verbose ) {
929+
return false;
930+
}
931+
932+
// Don't show progress bar if format is 'count'
933+
if ( 'count' === $this->format ) {
934+
return false;
935+
}
936+
937+
return true;
938+
}
939+
853940
private static function esc_like( $old ) {
854941
global $wpdb;
855942

0 commit comments

Comments
 (0)