Skip to content

Commit bd13459

Browse files
petitphpschlessera
authored andcommitted
add patch command to transient
1 parent 6e286af commit bd13459

File tree

2 files changed

+251
-0
lines changed

2 files changed

+251
-0
lines changed

features/transient.feature

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,3 +654,161 @@ Feature: Manage WordPress transient cache
654654
"""
655655
Warning: Transient with key "my_key" is not set.
656656
"""
657+
658+
Scenario: Nested values from transient can be updated at any depth.
659+
Given a WP install
660+
And a wp-content/mu-plugins/test-harness.php file:
661+
"""
662+
<?php
663+
$set_foo = function(){
664+
set_transient( 'my_key', ['foo' => 'bar'] );
665+
set_transient( 'my_key_2', ['foo' => ['bar' => 'baz']] );
666+
};
667+
668+
WP_CLI::add_hook( 'before_invoke:transient patch', $set_foo );
669+
"""
670+
671+
When I try `wp transient patch insert my_key fuz baz`
672+
Then STDOUT should be:
673+
"""
674+
Success: Updated transient 'my_key'.
675+
"""
676+
677+
When I try `wp transient patch insert my_key_2 foo fuz bar`
678+
Then STDOUT should be:
679+
"""
680+
Success: Updated transient 'my_key_2'.
681+
"""
682+
683+
When I try `wp transient patch insert unknown_key foo bar`
684+
Then STDERR should be:
685+
"""
686+
Error: Cannot create key "foo" on data type boolean
687+
"""
688+
689+
When I try `wp transient patch insert my_key foo bar`
690+
Then STDOUT should be:
691+
"""
692+
Success: Value passed for transient 'my_key' is unchanged.
693+
"""
694+
695+
When I try `wp transient patch update my_key foo biz`
696+
Then STDOUT should be:
697+
"""
698+
Success: Updated transient 'my_key'.
699+
"""
700+
701+
When I try `wp transient patch update my_key_2 foo bar biz`
702+
Then STDOUT should be:
703+
"""
704+
Success: Updated transient 'my_key_2'.
705+
"""
706+
707+
When I try `wp transient patch update unknown_key foo bar`
708+
Then STDERR should be:
709+
"""
710+
Error: No data exists for key "foo"
711+
"""
712+
713+
When I try `wp transient patch update my_key foo bar`
714+
Then STDOUT should be:
715+
"""
716+
Success: Value passed for transient 'my_key' is unchanged.
717+
"""
718+
719+
When I try `wp transient patch delete my_key foo`
720+
Then STDOUT should be:
721+
"""
722+
Success: Updated transient 'my_key'.
723+
"""
724+
725+
When I try `wp transient patch delete my_key_2 foo bar`
726+
Then STDOUT should be:
727+
"""
728+
Success: Updated transient 'my_key_2'.
729+
"""
730+
731+
When I try `wp transient patch delete unknown_key foo`
732+
Then STDERR should be:
733+
"""
734+
Error: No data exists for key "foo"
735+
"""
736+
737+
Scenario: Nested values from site transient can be updated at any depth.
738+
Given a WP install
739+
And a wp-content/mu-plugins/test-harness.php file:
740+
"""
741+
<?php
742+
$set_foo = function(){
743+
set_site_transient( 'my_key', ['foo' => 'bar'] );
744+
set_site_transient( 'my_key_2', ['foo' => ['bar' => 'baz']] );
745+
};
746+
747+
WP_CLI::add_hook( 'before_invoke:transient patch', $set_foo );
748+
"""
749+
750+
When I try `wp transient patch insert my_key fuz baz --network`
751+
Then STDOUT should be:
752+
"""
753+
Success: Updated transient 'my_key'.
754+
"""
755+
756+
When I try `wp transient patch insert my_key_2 foo fuz bar --network`
757+
Then STDOUT should be:
758+
"""
759+
Success: Updated transient 'my_key_2'.
760+
"""
761+
762+
When I try `wp transient patch insert unknown_key foo bar --network`
763+
Then STDERR should be:
764+
"""
765+
Error: Cannot create key "foo" on data type boolean
766+
"""
767+
768+
When I try `wp transient patch insert my_key foo bar --network`
769+
Then STDOUT should be:
770+
"""
771+
Success: Value passed for transient 'my_key' is unchanged.
772+
"""
773+
774+
When I try `wp transient patch update my_key foo biz --network`
775+
Then STDOUT should be:
776+
"""
777+
Success: Updated transient 'my_key'.
778+
"""
779+
780+
When I try `wp transient patch update my_key_2 foo bar biz --network`
781+
Then STDOUT should be:
782+
"""
783+
Success: Updated transient 'my_key_2'.
784+
"""
785+
786+
When I try `wp transient patch update unknown_key foo bar --network`
787+
Then STDERR should be:
788+
"""
789+
Error: No data exists for key "foo"
790+
"""
791+
792+
When I try `wp transient patch update my_key foo bar --network`
793+
Then STDOUT should be:
794+
"""
795+
Success: Value passed for transient 'my_key' is unchanged.
796+
"""
797+
798+
When I try `wp transient patch delete my_key foo --network`
799+
Then STDOUT should be:
800+
"""
801+
Success: Updated transient 'my_key'.
802+
"""
803+
804+
When I try `wp transient patch delete my_key_2 foo bar --network`
805+
Then STDOUT should be:
806+
"""
807+
Success: Updated transient 'my_key_2'.
808+
"""
809+
810+
When I try `wp transient patch delete unknown_key foo --network`
811+
Then STDERR should be:
812+
"""
813+
Error: No data exists for key "foo"
814+
"""

src/Transient_Command.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,99 @@ public function pluck( $args, $assoc_args ) {
460460
WP_CLI::print_value( $value, $assoc_args );
461461
}
462462

463+
/**
464+
* Update a nested value from a transient.
465+
*
466+
* ## OPTIONS
467+
*
468+
* <action>
469+
* : Patch action to perform.
470+
* ---
471+
* options:
472+
* - insert
473+
* - update
474+
* - delete
475+
* ---
476+
*
477+
* <key>
478+
* : Key for the transient.
479+
*
480+
* <key-path>...
481+
* : The name(s) of the keys within the value to locate the value to pluck.
482+
*
483+
* [<value>]
484+
* : The new value. If omitted, the value is read from STDIN.
485+
*
486+
* [--format=<format>]
487+
* : The serialization format for the value.
488+
* ---
489+
* default: plaintext
490+
* options:
491+
* - plaintext
492+
* - json
493+
* ---
494+
*
495+
* [--expiration=<expiration>]
496+
* : Time until expiration, in seconds.
497+
*
498+
* [--network]
499+
* : Get the value of a network|site transient. On single site, this is
500+
* a specially-named cache key. On multisite, this is a global cache
501+
* (instead of local to the site).
502+
*/
503+
public function patch( $args, $assoc_args ) {
504+
list( $action, $key ) = $args;
505+
$expiration = (int) Utils\get_flag_value($assoc_args, 'expiration', 0);
506+
507+
$read_func = Utils\get_flag_value( $assoc_args, 'network' ) ? 'get_site_transient' : 'get_transient';
508+
$write_func = Utils\get_flag_value( $assoc_args, 'network' ) ? 'set_site_transient' : 'set_transient';
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 = $read_func( $key );
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 transient '$key' is unchanged." );
547+
} else {
548+
if ( $write_func( $key, $patched_value, $expiration ) ) {
549+
WP_CLI::success( "Updated transient '$key'." );
550+
} else {
551+
WP_CLI::error( "Could not update transient '$key'." );
552+
}
553+
}
554+
}
555+
463556
/**
464557
* Retrieves the expiration time.
465558
*

0 commit comments

Comments
 (0)