Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions features/search-replace.feature
Original file line number Diff line number Diff line change
Expand Up @@ -1392,3 +1392,29 @@ Feature: Do global search/replace
"""
Success: Made 0 replacements.
"""

@require-mysql
Scenario: Progress bar shows when not in verbose mode
Given a WP install
And I run `wp post generate --count=100`

When I run `wp search-replace http://example.com http://example.org --precise`
Then STDOUT should contain:
"""
Updating
"""

@require-mysql
Scenario: Progress bar does not show in verbose mode
Given a WP install
And I run `wp post generate --count=10`

When I run `wp search-replace http://example.com http://example.org --verbose`
Then STDOUT should contain:
"""
Checking:
"""
And STDOUT should not contain:
"""
Updating
"""
112 changes: 89 additions & 23 deletions src/Search_Replace_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,18 @@ private function php_export_table( $table, $old, $new ) {
WP_CLI::log( sprintf( 'Checking: %s', $table ) );
}

// Set up progress bar if appropriate
$progress = null;
if ( $this->should_show_progress_bar() ) {
global $wpdb;
$table_sql = self::esc_sql_ident( $table );
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
$total_rows = $wpdb->get_var( "SELECT COUNT(*) FROM {$table_sql}" );
if ( $total_rows > 0 ) {
$progress = \WP_CLI\Utils\make_progress_bar( sprintf( 'Exporting %s', $table ), $total_rows );
}
}

$rows = array();
foreach ( new Iterators\Table( $args ) as $i => $row ) {
$row_fields = array();
Expand All @@ -572,9 +584,17 @@ private function php_export_table( $table, $old, $new ) {
$row_fields[ $col ] = $value;
}
$rows[] = $row_fields;

if ( $progress ) {
$progress->tick();
}
}
$this->write_sql_row_fields( $table, $rows );

if ( $progress ) {
$progress->finish();
}

$table_report = array();
$total_rows = 0;
$total_cols = 0;
Expand Down Expand Up @@ -650,6 +670,17 @@ static function ( $key ) {
$order_by_sql = 'ORDER BY ' . implode( ',', $order_by_keys );
$limit = 1000;

// Set up progress bar if appropriate
$progress = null;
if ( $this->should_show_progress_bar() ) {
// Count total rows to process
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
$total_rows = $wpdb->get_var( "SELECT COUNT(*) FROM {$table_sql} {$where_key}" );
if ( $total_rows > 0 ) {
$progress = \WP_CLI\Utils\make_progress_bar( sprintf( 'Updating %s.%s', $table, $col ), $total_rows );
}
}

// 2 errors:
// - WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
// - WordPress.CodeAnalysis.AssignmentInCondition -- no reason to do copy-paste for a single valid assignment in while
Expand All @@ -667,35 +698,32 @@ static function ( $key ) {
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
$col_value = $wpdb->get_var( "SELECT {$col_sql} FROM {$table_sql} WHERE {$where_sql}" );

if ( '' === $col_value ) {
continue;
}

$value = $replacer->run( $col_value );
if ( '' !== $col_value ) {
$value = $replacer->run( $col_value );

if ( $value === $col_value ) {
continue;
}
if ( $value !== $col_value && gettype( $value ) === gettype( $col_value ) ) {
// In case a needed re-serialization was unsuccessful, we should not update the value,
// as this implies we hit an exception while processing.

// In case a needed re-serialization was unsuccessful, we should not update the value,
// as this implies we hit an exception while processing.
if ( gettype( $value ) !== gettype( $col_value ) ) {
continue;
}
if ( $this->log_handle ) {
$this->log_php_diff( $col, $keys, $table, $old, $new, $replacer->get_log_data() );
$replacer->clear_log_data();
}

if ( $this->log_handle ) {
$this->log_php_diff( $col, $keys, $table, $old, $new, $replacer->get_log_data() );
$replacer->clear_log_data();
}
++$count;
if ( ! $this->dry_run ) {
$update_where = array();
foreach ( (array) $keys as $k => $v ) {
$update_where[ $k ] = $v;
}

++$count;
if ( ! $this->dry_run ) {
$update_where = array();
foreach ( (array) $keys as $k => $v ) {
$update_where[ $k ] = $v;
$wpdb->update( $table, [ $col => $value ], $update_where );
}
}
}

$wpdb->update( $table, [ $col => $value ], $update_where );
if ( $progress ) {
$progress->tick();
}
}

Expand Down Expand Up @@ -735,6 +763,10 @@ static function ( $key ) {
$where_key = 'WHERE ' . implode( ' AND ', $where_key_conditions );
}

if ( $progress ) {
$progress->finish();
}

if ( $this->verbose && 'table' === $this->format ) {
$time = round( microtime( true ) - $this->start_time, 3 );
WP_CLI::log( sprintf( '%d rows affected using PHP (in %ss).', $count, $time ) );
Expand Down Expand Up @@ -850,6 +882,40 @@ private static function is_text_col( $type ) {
return false;
}

/**
* Determines whether a progress bar should be shown.
*
* @return bool True if progress bar should be shown.
*/
private function should_show_progress_bar() {
// Don't show progress bar if in quiet mode
if ( WP_CLI::get_config( 'quiet' ) ) {
return false;
}

// Don't show progress bar if exporting to STDOUT
if ( STDOUT === $this->export_handle ) {
return false;
}

// Don't show progress bar if logging to STDOUT
if ( STDOUT === $this->log_handle ) {
return false;
}

// Don't show progress bar if verbose mode is enabled (it shows row-by-row updates)
if ( $this->verbose ) {
return false;
}

// Don't show progress bar if format is 'count'
if ( 'count' === $this->format ) {
return false;
}

return true;
}

private static function esc_like( $old ) {
global $wpdb;

Expand Down
Loading