Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
21 changes: 21 additions & 0 deletions features/sidebar.feature
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ Feature: Manage WordPress sidebars
4
"""

Scenario: List inactive sidebars
When I run `wp sidebar list --inactive --format=count`
Then STDOUT should be:
"""
0
"""

When I run `wp eval 'update_option( "sidebars_widgets", array_merge( wp_get_sidebars_widgets(), [ "orphaned-sidebar-1" => [] ] ) );'`
And I run `wp sidebar list --inactive --fields=id --format=csv`
Then STDOUT should be:
"""
id
orphaned-sidebar-1
"""

When I run `wp sidebar list --fields=id --format=ids`
Then STDOUT should not contain:
"""
orphaned-sidebar-1
"""

Scenario: Get sidebar details
When I run `wp sidebar get sidebar-1`
Then STDOUT should contain:
Expand Down
36 changes: 35 additions & 1 deletion features/widget-reset.feature
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Feature: Reset WordPress sidebars
When I try `wp widget reset`
Then STDERR should be:
"""
Error: Please specify one or more sidebars, or use --all.
Error: Please specify one or more sidebars, or use --all or --inactive.
"""

When I try `wp widget reset sidebar-1`
Expand Down Expand Up @@ -153,3 +153,37 @@ Feature: Reset WordPress sidebars
"""
calendar-1 search-1
"""

Scenario: Reset inactive sidebars
When I try `wp widget reset --inactive`
Then STDERR should be:
"""
Error: No inactive sidebars found.
"""
And the return code should be 1

When I run `wp widget add calendar sidebar-1 --title="Calendar"`
Then STDOUT should not be empty

# Simulate an inactive (unregistered) sidebar by moving widget data to an orphaned key
When I run `wp eval '$w = wp_get_sidebars_widgets(); $w["orphaned-sidebar-1"] = $w["sidebar-1"]; $w["sidebar-1"] = []; update_option( "sidebars_widgets", $w );'`

And I run `wp sidebar list --inactive --fields=id --format=ids`
Then STDOUT should be:
"""
orphaned-sidebar-1
"""

When I run `wp widget reset --inactive`
Then STDOUT should be:
"""
Sidebar 'orphaned-sidebar-1' reset.
Success: Reset 1 of 1 sidebars.
"""
And the return code should be 0

When I run `wp widget list wp_inactive_widgets --format=ids`
Then STDOUT should contain:
"""
calendar-1
"""
57 changes: 55 additions & 2 deletions src/Sidebar_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class Sidebar_Command extends WP_CLI_Command {
*
* ## OPTIONS
*
* [--inactive]
* : If set, only inactive sidebars will be listed.
*
* [--fields=<fields>]
* : Limit the output to specific object fields.
*
Expand Down Expand Up @@ -68,23 +71,73 @@ class Sidebar_Command extends WP_CLI_Command {
* "Widget Area",sidebar-1
* "Inactive Widgets",wp_inactive_widgets
*
* $ wp sidebar list --inactive --fields=id --format=csv
* id
* old-sidebar-1
*
* @subcommand list
*/
public function list_( $args, $assoc_args ) {
global $wp_registered_sidebars;

Utils\wp_register_unused_sidebar();

if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) {
$sidebars = wp_list_pluck( $wp_registered_sidebars, 'id' );
$inactive = Utils\get_flag_value( $assoc_args, 'inactive', false );

if ( $inactive ) {
$sidebars = [];
foreach ( self::get_inactive_sidebar_ids() as $sidebar_id ) {
$sidebars[ $sidebar_id ] = [
'name' => $sidebar_id,
'id' => $sidebar_id,
'description' => '',
'class' => '',
'before_widget' => '',
'after_widget' => '',
'before_title' => '',
'after_title' => '',
];
}
} else {
$sidebars = $wp_registered_sidebars;
}

if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) {
$sidebars = wp_list_pluck( $sidebars, 'id' );
}

$formatter = new Formatter( $assoc_args, $this->fields );
$formatter->display_items( $sidebars );
}

/**
* Returns the IDs of sidebars that exist in the database but are not currently registered.
*
* @return string[]
*/
public static function get_inactive_sidebar_ids() {
global $wp_registered_sidebars;

$sidebars_widgets = get_option( 'sidebars_widgets', [] );
if ( ! is_array( $sidebars_widgets ) ) {
$sidebars_widgets = [];
}
if ( isset( $sidebars_widgets['array_version'] ) ) {
unset( $sidebars_widgets['array_version'] );
}

$registered_ids = array_keys( $wp_registered_sidebars );

return array_values(
array_filter(
array_diff( array_keys( $sidebars_widgets ), $registered_ids ),
static function ( $id ) {
return 'wp_inactive_widgets' !== $id;
}
)
);
}

/**
* Get details about a specific sidebar.
*
Expand Down
68 changes: 50 additions & 18 deletions src/Widget_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -478,53 +478,85 @@ public function delete( $args, $assoc_args ) {
* [--all]
* : If set, all sidebars will be reset.
*
* [--inactive]
* : If set, all inactive sidebars will also be reset, in addition to any sidebars specified via <sidebar-id>... or selected with --all.
*
* ## EXAMPLES
*
* # Reset a sidebar
* $ wp widget reset sidebar-1
* Success: Sidebar 'sidebar-1' reset.
* Sidebar 'sidebar-1' reset.
*
* # Reset multiple sidebars
* $ wp widget reset sidebar-1 sidebar-2
* Success: Sidebar 'sidebar-1' reset.
* Success: Sidebar 'sidebar-2' reset.
* Sidebar 'sidebar-1' reset.
* Sidebar 'sidebar-2' reset.
*
* # Reset all sidebars
* $ wp widget reset --all
* Success: Sidebar 'sidebar-1' reset.
* Success: Sidebar 'sidebar-2' reset.
* Success: Sidebar 'sidebar-3' reset.
* Sidebar 'sidebar-1' reset.
* Sidebar 'sidebar-2' reset.
* Sidebar 'sidebar-3' reset.
*
* # Reset all inactive sidebars
* $ wp widget reset --inactive
* Sidebar 'old-sidebar-1' reset.
*/
public function reset( $args, $assoc_args ) {

global $wp_registered_sidebars;

$all = Utils\get_flag_value( $assoc_args, 'all', false );
$all = Utils\get_flag_value( $assoc_args, 'all', false );
$inactive = Utils\get_flag_value( $assoc_args, 'inactive', false );

// Bail if no arguments and no all flag.
if ( ! $all && empty( $args ) ) {
WP_CLI::error( 'Please specify one or more sidebars, or use --all.' );
// Bail if no arguments and no --all or --inactive flag.
if ( ! $all && ! $inactive && empty( $args ) ) {
WP_CLI::error( 'Please specify one or more sidebars, or use --all or --inactive.' );
}

// Fetch all sidebars if all flag is set.
// Explicitly handle reserved sidebar ID for inactive widgets.
if ( in_array( 'wp_inactive_widgets', $args, true ) ) {
WP_CLI::error( "Sidebar 'wp_inactive_widgets' is reserved for inactive widgets and cannot be reset with this command. The --inactive flag only targets widgets from orphaned or unregistered sidebars, not 'wp_inactive_widgets' itself." );
}

// Fetch all registered sidebars if --all flag is set.
if ( $all ) {
$args = array_keys( $wp_registered_sidebars );
}

// Sidebar ID wp_inactive_widgets is reserved by WP core for inactive widgets.
if ( isset( $args['wp_inactive_widgets'] ) ) {
unset( $args['wp_inactive_widgets'] );
$args = array_values(
array_filter(
$args,
static function ( $id ) {
return 'wp_inactive_widgets' !== $id;
}
)
);

// Collect inactive (unregistered) sidebar IDs if --inactive flag is set.
$inactive_args = [];
if ( $inactive ) {
$inactive_args = Sidebar_Command::get_inactive_sidebar_ids();
}

// Check if no registered sidebar.
if ( empty( $args ) ) {
$all_args = array_merge( $args, $inactive_args );
$all_args = array_values( array_unique( $all_args ) );

// Check if there are no sidebars to reset.
if ( empty( $all_args ) ) {
if ( $inactive && empty( $inactive_args ) ) {
WP_CLI::error( 'No inactive sidebars found.' );
}
WP_CLI::error( 'No sidebar registered.' );
}

$count = 0;
$errors = 0;
foreach ( $args as $sidebar_id ) {
if ( ! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) {
foreach ( $all_args as $sidebar_id ) {
// Skip registration validation for sidebars resolved via --inactive.
if ( ! in_array( $sidebar_id, $inactive_args, true ) &&
! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) {
WP_CLI::warning( sprintf( 'Invalid sidebar: %s', $sidebar_id ) );
++$errors;
continue;
Expand All @@ -550,7 +582,7 @@ public function reset( $args, $assoc_args ) {
}
}

Utils\report_batch_operation_results( 'sidebar', 'reset', count( $args ), $count, $errors );
Utils\report_batch_operation_results( 'sidebar', 'reset', count( $all_args ), $count, $errors );
}

/**
Expand Down
Loading