wp-cli / entity-command

Manage WordPress comments, menus, options, posts, sites, terms, and users.
MIT License
100 stars 89 forks source link

Network meta command accessing the incorrect caches #504

Open spacedmonkey opened 2 months ago

spacedmonkey commented 2 months ago

Bug Report

Describe the current, buggy behavior

Originally reported https://core.trac.wordpress.org/ticket/61467.

Describe how other contributors can replicate this bug

It appears that there are multiple ways to work with wp_sitemeta and each use different cache keys and groups, resulting in inconsistent behavior and out-of-sync cached values. One method is using update_site_option()/update_network_option() which uses "$network_id:$option" for the cache key, and site-options for the group. The other method is update_metadata( 'site', ... ) which uses the object ID (here the network ID) for the cache key, and site_meta for the cache group. Normally, in the code, we use update_site_option()/update_network_option(), however, WP CLI's wp network meta ... uses the *_metadata() functions, and when using both we end up with out of sync cached values.

Steps to reproduce the issue via WP CLI:

wp eval 'update_network_option( 1, "mykey", "123" );'
wp eval 'echo get_network_option( 1, "mykey" );' #Displays 123

wp network meta update 1 mykey 456
wp network meta get 1 mykey #Displays 456

wp eval 'echo get_network_option( 1, "mykey" );' #Still displays 123, but 456 is the expected value
// You can also use code snippets if needed.

Describe what you would expect as the correct outcome

That network option caches are used and not meta data caches. This means for those using object caches that presist, that the correct cache is updated.

Let us know what environment you are running this on

(Paste the output of "wp cli info" into this box)

Provide a possible solution

Use network option function / api instead of metadata apis for CRUD.

class Network_Meta_Command extends CommandWithMeta {
    protected $meta_type = 'site';

    protected function get_metadata( $object_id, $meta_key = '', $single = false ) {
        return get_network_option( $object_id, $meta_key );
    }

        protected function delete_metadata( $object_id, $meta_key, $meta_value = '' ) {
        return delete_network_option( $object_id, $meta_key );
    }

        protected function add_metadata( $object_id, $meta_key, $meta_value, $unique = false ) {
        return add_network_option( $object_id, $meta_key, $meta_value );
    }

    protected function update_metadata( $object_id, $meta_key, $meta_value, $prev_value = '' ) {
        return update_network_option( $object_id, $meta_key, $meta_value );
    }
}

This would require WordPress 4.4 as a min supported version.