Skip to content

Commit 67bb805

Browse files
CopilotswissspidyCopilot
authored
Add --inactive flag to wp sidebar list and wp widget reset (#75)
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Pascal Birchler <pascal.birchler@gmail.com>
1 parent dfdf6fb commit 67bb805

4 files changed

Lines changed: 161 additions & 21 deletions

File tree

features/sidebar.feature

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,27 @@ Feature: Manage WordPress sidebars
2323
4
2424
"""
2525

26+
Scenario: List inactive sidebars
27+
When I run `wp sidebar list --inactive --format=count`
28+
Then STDOUT should be:
29+
"""
30+
0
31+
"""
32+
33+
When I run `wp eval 'update_option( "sidebars_widgets", array_merge( wp_get_sidebars_widgets(), [ "orphaned-sidebar-1" => [] ] ) );'`
34+
And I run `wp sidebar list --inactive --fields=id --format=csv`
35+
Then STDOUT should be:
36+
"""
37+
id
38+
orphaned-sidebar-1
39+
"""
40+
41+
When I run `wp sidebar list --fields=id --format=ids`
42+
Then STDOUT should not contain:
43+
"""
44+
orphaned-sidebar-1
45+
"""
46+
2647
Scenario: Get sidebar details
2748
When I run `wp sidebar get sidebar-1`
2849
Then STDOUT should contain:

features/widget-reset.feature

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Feature: Reset WordPress sidebars
2424
When I try `wp widget reset`
2525
Then STDERR should be:
2626
"""
27-
Error: Please specify one or more sidebars, or use --all.
27+
Error: Please specify one or more sidebars, or use --all or --inactive.
2828
"""
2929

3030
When I try `wp widget reset sidebar-1`
@@ -153,3 +153,37 @@ Feature: Reset WordPress sidebars
153153
"""
154154
calendar-1 search-1
155155
"""
156+
157+
Scenario: Reset inactive sidebars
158+
When I try `wp widget reset --inactive`
159+
Then STDERR should be:
160+
"""
161+
Error: No inactive sidebars found.
162+
"""
163+
And the return code should be 1
164+
165+
When I run `wp widget add calendar sidebar-1 --title="Calendar"`
166+
Then STDOUT should not be empty
167+
168+
# Simulate an inactive (unregistered) sidebar by moving widget data to an orphaned key
169+
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 );'`
170+
171+
And I run `wp sidebar list --inactive --fields=id --format=ids`
172+
Then STDOUT should be:
173+
"""
174+
orphaned-sidebar-1
175+
"""
176+
177+
When I run `wp widget reset --inactive`
178+
Then STDOUT should be:
179+
"""
180+
Sidebar 'orphaned-sidebar-1' reset.
181+
Success: Reset 1 of 1 sidebars.
182+
"""
183+
And the return code should be 0
184+
185+
When I run `wp widget list wp_inactive_widgets --format=ids`
186+
Then STDOUT should contain:
187+
"""
188+
calendar-1
189+
"""

src/Sidebar_Command.php

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class Sidebar_Command extends WP_CLI_Command {
2929
*
3030
* ## OPTIONS
3131
*
32+
* [--inactive]
33+
* : If set, only inactive sidebars will be listed.
34+
*
3235
* [--fields=<fields>]
3336
* : Limit the output to specific object fields.
3437
*
@@ -68,23 +71,73 @@ class Sidebar_Command extends WP_CLI_Command {
6871
* "Widget Area",sidebar-1
6972
* "Inactive Widgets",wp_inactive_widgets
7073
*
74+
* $ wp sidebar list --inactive --fields=id --format=csv
75+
* id
76+
* old-sidebar-1
77+
*
7178
* @subcommand list
7279
*/
7380
public function list_( $args, $assoc_args ) {
7481
global $wp_registered_sidebars;
7582

7683
Utils\wp_register_unused_sidebar();
7784

78-
if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) {
79-
$sidebars = wp_list_pluck( $wp_registered_sidebars, 'id' );
85+
$inactive = Utils\get_flag_value( $assoc_args, 'inactive', false );
86+
87+
if ( $inactive ) {
88+
$sidebars = [];
89+
foreach ( self::get_inactive_sidebar_ids() as $sidebar_id ) {
90+
$sidebars[ $sidebar_id ] = [
91+
'name' => $sidebar_id,
92+
'id' => $sidebar_id,
93+
'description' => '',
94+
'class' => '',
95+
'before_widget' => '',
96+
'after_widget' => '',
97+
'before_title' => '',
98+
'after_title' => '',
99+
];
100+
}
80101
} else {
81102
$sidebars = $wp_registered_sidebars;
82103
}
83104

105+
if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) {
106+
$sidebars = wp_list_pluck( $sidebars, 'id' );
107+
}
108+
84109
$formatter = new Formatter( $assoc_args, $this->fields );
85110
$formatter->display_items( $sidebars );
86111
}
87112

113+
/**
114+
* Returns the IDs of sidebars that exist in the database but are not currently registered.
115+
*
116+
* @return string[]
117+
*/
118+
public static function get_inactive_sidebar_ids() {
119+
global $wp_registered_sidebars;
120+
121+
$sidebars_widgets = get_option( 'sidebars_widgets', [] );
122+
if ( ! is_array( $sidebars_widgets ) ) {
123+
$sidebars_widgets = [];
124+
}
125+
if ( isset( $sidebars_widgets['array_version'] ) ) {
126+
unset( $sidebars_widgets['array_version'] );
127+
}
128+
129+
$registered_ids = array_keys( $wp_registered_sidebars );
130+
131+
return array_values(
132+
array_filter(
133+
array_diff( array_keys( $sidebars_widgets ), $registered_ids ),
134+
static function ( $id ) {
135+
return 'wp_inactive_widgets' !== $id;
136+
}
137+
)
138+
);
139+
}
140+
88141
/**
89142
* Get details about a specific sidebar.
90143
*

src/Widget_Command.php

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -478,53 +478,85 @@ public function delete( $args, $assoc_args ) {
478478
* [--all]
479479
* : If set, all sidebars will be reset.
480480
*
481+
* [--inactive]
482+
* : If set, all inactive sidebars will also be reset, in addition to any sidebars specified via <sidebar-id>... or selected with --all.
483+
*
481484
* ## EXAMPLES
482485
*
483486
* # Reset a sidebar
484487
* $ wp widget reset sidebar-1
485-
* Success: Sidebar 'sidebar-1' reset.
488+
* Sidebar 'sidebar-1' reset.
486489
*
487490
* # Reset multiple sidebars
488491
* $ wp widget reset sidebar-1 sidebar-2
489-
* Success: Sidebar 'sidebar-1' reset.
490-
* Success: Sidebar 'sidebar-2' reset.
492+
* Sidebar 'sidebar-1' reset.
493+
* Sidebar 'sidebar-2' reset.
491494
*
492495
* # Reset all sidebars
493496
* $ wp widget reset --all
494-
* Success: Sidebar 'sidebar-1' reset.
495-
* Success: Sidebar 'sidebar-2' reset.
496-
* Success: Sidebar 'sidebar-3' reset.
497+
* Sidebar 'sidebar-1' reset.
498+
* Sidebar 'sidebar-2' reset.
499+
* Sidebar 'sidebar-3' reset.
500+
*
501+
* # Reset all inactive sidebars
502+
* $ wp widget reset --inactive
503+
* Sidebar 'old-sidebar-1' reset.
497504
*/
498505
public function reset( $args, $assoc_args ) {
499506

500507
global $wp_registered_sidebars;
501508

502-
$all = Utils\get_flag_value( $assoc_args, 'all', false );
509+
$all = Utils\get_flag_value( $assoc_args, 'all', false );
510+
$inactive = Utils\get_flag_value( $assoc_args, 'inactive', false );
503511

504-
// Bail if no arguments and no all flag.
505-
if ( ! $all && empty( $args ) ) {
506-
WP_CLI::error( 'Please specify one or more sidebars, or use --all.' );
512+
// Bail if no arguments and no --all or --inactive flag.
513+
if ( ! $all && ! $inactive && empty( $args ) ) {
514+
WP_CLI::error( 'Please specify one or more sidebars, or use --all or --inactive.' );
507515
}
508516

509-
// Fetch all sidebars if all flag is set.
517+
// Explicitly handle reserved sidebar ID for inactive widgets.
518+
if ( in_array( 'wp_inactive_widgets', $args, true ) ) {
519+
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." );
520+
}
521+
522+
// Fetch all registered sidebars if --all flag is set.
510523
if ( $all ) {
511524
$args = array_keys( $wp_registered_sidebars );
512525
}
513526

514527
// Sidebar ID wp_inactive_widgets is reserved by WP core for inactive widgets.
515-
if ( isset( $args['wp_inactive_widgets'] ) ) {
516-
unset( $args['wp_inactive_widgets'] );
528+
$args = array_values(
529+
array_filter(
530+
$args,
531+
static function ( $id ) {
532+
return 'wp_inactive_widgets' !== $id;
533+
}
534+
)
535+
);
536+
537+
// Collect inactive (unregistered) sidebar IDs if --inactive flag is set.
538+
$inactive_args = [];
539+
if ( $inactive ) {
540+
$inactive_args = Sidebar_Command::get_inactive_sidebar_ids();
517541
}
518542

519-
// Check if no registered sidebar.
520-
if ( empty( $args ) ) {
543+
$all_args = array_merge( $args, $inactive_args );
544+
$all_args = array_values( array_unique( $all_args ) );
545+
546+
// Check if there are no sidebars to reset.
547+
if ( empty( $all_args ) ) {
548+
if ( $inactive && empty( $inactive_args ) ) {
549+
WP_CLI::error( 'No inactive sidebars found.' );
550+
}
521551
WP_CLI::error( 'No sidebar registered.' );
522552
}
523553

524554
$count = 0;
525555
$errors = 0;
526-
foreach ( $args as $sidebar_id ) {
527-
if ( ! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) {
556+
foreach ( $all_args as $sidebar_id ) {
557+
// Skip registration validation for sidebars resolved via --inactive.
558+
if ( ! in_array( $sidebar_id, $inactive_args, true ) &&
559+
! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) {
528560
WP_CLI::warning( sprintf( 'Invalid sidebar: %s', $sidebar_id ) );
529561
++$errors;
530562
continue;
@@ -550,7 +582,7 @@ public function reset( $args, $assoc_args ) {
550582
}
551583
}
552584

553-
Utils\report_batch_operation_results( 'sidebar', 'reset', count( $args ), $count, $errors );
585+
Utils\report_batch_operation_results( 'sidebar', 'reset', count( $all_args ), $count, $errors );
554586
}
555587

556588
/**

0 commit comments

Comments
 (0)