Skip to content

Commit f31a3dd

Browse files
committed
add patch command to cache
1 parent eef8e56 commit f31a3dd

File tree

2 files changed

+180
-4
lines changed

2 files changed

+180
-4
lines changed

features/cache.feature

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,15 @@ Feature: Managed the WordPress object cache
211211
When I run `wp cache supports set_multiple`
212212
Then the return code should be 0
213213

214-
Scenario: Nested values can be retrieved at any depth.
214+
Scenario: Nested values from cache can be retrieved at any depth.
215215
Given a WP install
216216
And a wp-content/mu-plugins/test-harness.php file:
217217
"""
218218
<?php
219219
$set_foo = function(){
220220
wp_cache_set( 'my_key', ['foo' => 'bar'] );
221221
wp_cache_set( 'my_key_2', ['foo' => ['bar' => 'baz']] );
222-
wp_cache_set( 'my_key_custom', ['foo_custom' => ['bar_custom' => 'baz_custom']], 'my_custom_group' );
222+
wp_cache_set( 'my_key_3', ['foo' => 'bar_custom'], 'my_custom_group' );
223223
};
224224
225225
WP_CLI::add_hook( 'before_invoke:cache pluck', $set_foo );
@@ -237,8 +237,96 @@ Feature: Managed the WordPress object cache
237237
baz
238238
"""
239239

240-
When I try `wp cache pluck my_key_custom foo_custom bar_custom --group=my_custom_group`
240+
When I try `wp cache pluck my_key_3 foo --group=my_custom_group`
241241
Then STDOUT should be:
242242
"""
243-
baz_custom
243+
bar_custom
244+
"""
245+
246+
Scenario: Nested values from cache can be updated at any depth.
247+
Given a WP install
248+
And a wp-content/mu-plugins/test-harness.php file:
249+
"""
250+
<?php
251+
$set_foo = function(){
252+
wp_cache_set( 'my_key', ['foo' => 'bar'] );
253+
wp_cache_set( 'other_key', ['fuz' => 'biz'] );
254+
255+
$complex_key = (object) [
256+
'foo' => (object) [
257+
'bar' => (object) [
258+
'baz' => 2,
259+
],
260+
],
261+
];
262+
wp_cache_set( 'complex_key', $complex_key );
263+
};
264+
265+
WP_CLI::add_hook( 'before_invoke:cache patch', $set_foo );
266+
"""
267+
268+
When I try `wp cache patch insert my_key fuz baz`
269+
Then STDOUT should be:
270+
"""
271+
Success: Updated cache key 'my_key'.
272+
"""
273+
274+
When I try `wp cache patch insert complex_key foo bar fuz 34`
275+
Then STDOUT should be:
276+
"""
277+
Success: Updated cache key 'complex_key'.
278+
"""
279+
280+
When I try `wp cache patch insert unknown_key foo bar`
281+
Then STDERR should be:
282+
"""
283+
Error: Cannot create key "foo" on data type boolean
284+
"""
285+
286+
When I try `wp cache patch update my_key foo test`
287+
Then STDOUT should be:
288+
"""
289+
Success: Updated cache key 'my_key'.
290+
"""
291+
292+
When I try `wp cache patch update other_key fuz biz`
293+
Then STDOUT should be:
294+
"""
295+
Success: Value passed for cache key 'other_key' is unchanged.
296+
"""
297+
298+
When I try `wp cache patch update complex_key foo bar baz 34`
299+
Then STDOUT should be:
300+
"""
301+
Success: Updated cache key 'complex_key'.
302+
"""
303+
304+
When I try `wp cache patch update unknown_key foo test`
305+
Then STDERR should be:
306+
"""
307+
Error: No data exists for key "foo"
308+
"""
309+
310+
When I try `wp cache patch update my_key bar test`
311+
Then STDERR should be:
312+
"""
313+
Error: No data exists for key "bar"
314+
"""
315+
316+
When I try `wp cache patch delete my_key foo`
317+
Then STDOUT should be:
318+
"""
319+
Success: Updated cache key 'my_key'.
320+
"""
321+
322+
When I try `wp cache patch delete unknown_key foo`
323+
Then STDERR should be:
324+
"""
325+
Error: No data exists for key "foo"
326+
"""
327+
328+
When I try `wp cache patch delete my_key bar`
329+
Then STDERR should be:
330+
"""
331+
Error: No data exists for key "bar"
244332
"""

src/Cache_Command.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,4 +464,92 @@ public function pluck( $args, $assoc_args ) {
464464

465465
WP_CLI::print_value( $value, $assoc_args );
466466
}
467+
468+
/**
469+
* Update a nested value from the cache.
470+
*
471+
* ## OPTIONS
472+
*
473+
* <action>
474+
* : Patch action to perform.
475+
* ---
476+
* options:
477+
* - insert
478+
* - update
479+
* - delete
480+
* ---
481+
*
482+
* <key>
483+
* : Cache key.
484+
*
485+
* <key-path>...
486+
* : The name(s) of the keys within the value to locate the value to pluck.
487+
*
488+
* [<value>]
489+
* : The new value. If omitted, the value is read from STDIN.
490+
*
491+
* [--group=<group>]
492+
* : Method for grouping data within the cache which allows the same key to be used across groups.
493+
* ---
494+
* default: default
495+
* ---
496+
*
497+
* [--format=<format>]
498+
* : The serialization format for the value.
499+
* ---
500+
* default: plaintext
501+
* options:
502+
* - plaintext
503+
* - json
504+
* ---
505+
*/
506+
public function patch( $args, $assoc_args ) {
507+
list( $action, $key ) = $args;
508+
$group = Utils\get_flag_value( $assoc_args, 'group' );
509+
510+
$key_path = array_map( function ( $key ) {
511+
if ( is_numeric( $key ) && ( $key === (string) intval( $key ) ) ) {
512+
return (int) $key;
513+
}
514+
515+
return $key;
516+
}, array_slice( $args, 2 ) );
517+
518+
if ( 'delete' === $action ) {
519+
$patch_value = null;
520+
} elseif ( \WP_CLI\Entity\Utils::has_stdin() ) {
521+
$stdin_value = WP_CLI::get_value_from_arg_or_stdin( $args, - 1 );
522+
$patch_value = WP_CLI::read_value( trim( $stdin_value ), $assoc_args );
523+
} else {
524+
// Take the patch value as the last positional argument. Mutates $key_path to be 1 element shorter!
525+
$patch_value = WP_CLI::read_value( array_pop( $key_path ), $assoc_args );
526+
}
527+
528+
/* Need to make a copy of $current_value here as it is modified by reference */
529+
$old_value = wp_cache_get($key, $group);
530+
$current_value = $old_value;
531+
if (is_object($old_value)) {
532+
$current_value = clone $old_value;
533+
}
534+
535+
$traverser = new RecursiveDataStructureTraverser( $current_value );
536+
537+
try {
538+
$traverser->$action( $key_path, $patch_value );
539+
} catch ( \Exception $e ) {
540+
WP_CLI::error( $e->getMessage() );
541+
}
542+
543+
$patched_value = $traverser->value();
544+
545+
if ( $patched_value === $old_value ) {
546+
WP_CLI::success( "Value passed for cache key '$key' is unchanged." );
547+
} else {
548+
if ( wp_cache_set( $key, $patched_value, $group ) ) {
549+
WP_CLI::success( "Updated cache key '$key'." );
550+
} else {
551+
WP_CLI::error( "Could not update cache key '$key'." );
552+
}
553+
}
554+
}
467555
}

0 commit comments

Comments
 (0)