Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"widget delete",
"widget list",
"widget move",
"widget patch",
"widget reset",
"widget update",
"sidebar",
Expand Down
44 changes: 44 additions & 0 deletions features/widget.feature
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,50 @@ Feature: Manage widgets in WordPress sidebar
| name | position | options |
| archives | 2 | {"title":"New Archives","count":0,"dropdown":0} |

Scenario: Patch widget options
When I run `wp widget patch update archives-1 title "Patched Archives"`
Then STDOUT should be:
"""
Success: Widget updated.
"""
And STDERR should be empty
And the return code should be 0

When I run `wp widget list sidebar-1 --fields=name,position,options`
Then STDOUT should be a table containing rows:
| name | position | options |
| archives | 2 | {"title":"Patched Archives","count":0,"dropdown":0} |

When I run `wp widget patch insert archives-1 new_key "inserted value"`
Comment thread
swissspidy marked this conversation as resolved.
Then STDOUT should be:
"""
Success: Widget updated.
"""
And STDERR should be empty
And the return code should be 0

When I run `wp widget patch delete archives-1 new_key`
Then STDOUT should be:
"""
Success: Widget updated.
"""
And STDERR should be empty
And the return code should be 0

When I try `wp widget patch update calendar-999 title "Nope"`
Then STDERR should be:
"""
Error: Widget doesn't exist.
"""
And the return code should be 1

When I try `wp widget patch update archives-1 title`
Then STDERR should be:
"""
Error: Please provide value to update.
Comment thread
swissspidy marked this conversation as resolved.
Outdated
"""
And the return code should be 1

Scenario: Validate sidebar widgets
When I try `wp widget update calendar-999`
Then STDERR should be:
Expand Down
107 changes: 106 additions & 1 deletion src/Widget_Command.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php

use WP_CLI\Utils;
use WP_CLI\Formatter;
use WP_CLI\Traverser\RecursiveDataStructureTraverser;
use WP_CLI\Utils;

/**
* Manages widgets, including adding and moving them within sidebars.
Expand Down Expand Up @@ -206,6 +207,110 @@ public function update( $args, $assoc_args ) {
WP_CLI::success( 'Widget updated.' );
}

/**
* Updates a nested value in a widget's options.
*
* ## OPTIONS
*
* <action>
* : Patch action to perform.
* ---
* options:
* - insert
* - update
* - delete
* ---
*
* <widget-id>
* : Unique ID for the widget.
*
* <key-path>...
* : The name(s) of the keys within the value to locate the value to patch.
*
* [<value>]
* : The new value. If omitted, the value is read from STDIN.
*
* [--format=<format>]
* : The serialization format for the value.
* ---
* default: plaintext
* options:
* - plaintext
* - json
* ---
*
* ## EXAMPLES
*
* # Update a nested value in the options of the archives-1 widget
* $ wp widget patch update archives-1 title "My Archives"
* Success: Widget updated.
*
* # Insert a new nested value into the options of the archives-1 widget
* $ wp widget patch insert archives-1 new_key "New Value"
* Success: Widget updated.
*
* # Delete a nested value from the options of the archives-1 widget
* $ wp widget patch delete archives-1 title
* Success: Widget updated.
*
* @subcommand patch
*/
public function patch( $args, $assoc_args ) {
list( $action, $widget_id ) = $args;

if ( ! $this->validate_sidebar_widget( $widget_id ) ) {
WP_CLI::error( "Widget doesn't exist." );
}

$key_path = array_map(
function ( $key ) {
if ( is_numeric( $key ) && ( (string) intval( $key ) === $key ) ) {
return (int) $key;
}
return $key;
},
array_slice( $args, 2 )
);

if ( 'delete' === $action ) {
$patch_value = null;
} else {
$stdin_value = Utils\has_stdin()
? trim( WP_CLI::get_value_from_arg_or_stdin( $args, -1 ) )
: null;

if ( ! empty( $stdin_value ) ) {
$patch_value = WP_CLI::read_value( $stdin_value, $assoc_args );
Comment thread
swissspidy marked this conversation as resolved.
Outdated
} elseif ( count( $key_path ) > 1 ) {
$patch_value = WP_CLI::read_value( array_pop( $key_path ), $assoc_args );
} else {
$patch_value = null;
}

if ( null === $patch_value ) {
Comment thread
swissspidy marked this conversation as resolved.
WP_CLI::error( 'Please provide value to update.' );
Comment thread
swissspidy marked this conversation as resolved.
Outdated
}
}

list( $name, $option_index ) = $this->get_widget_data( $widget_id );

$widget_options = $this->get_widget_options( $name );
$instance_options = isset( $widget_options[ $option_index ] ) ? $widget_options[ $option_index ] : array();

$traverser = new RecursiveDataStructureTraverser( $instance_options );

try {
$traverser->$action( $key_path, $patch_value );
} catch ( Exception $exception ) {
WP_CLI::error( $exception->getMessage() );
}

$widget_options[ $option_index ] = $traverser->value();
$this->update_widget_options( $name, $widget_options );

WP_CLI::success( 'Widget updated.' );
}

/**
* Moves the position of a widget.
*
Expand Down
Loading