Networks and Sites: Use metadata api in `*_network_options functions.

Replace logic found in `get_network_option`, `update_network_option` and `delete_network_option` to use the metadata api. Using the metadata api has a number of benefits, such as consistency, default values and useful filters. This change also improves performance by priming the caches of all network options in a single database request. 

Props spacedmonkey, swissspidy, sc0ttkclark, johnjamesjacoby, flixos90, jeremyfelt, pento, peterwilsoncc, mukesh27, desrosj.
Fixes #37181

git-svn-id: https://develop.svn.wordpress.org/trunk@54080 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonny Harris
2022-09-06 11:26:45 +00:00
parent bb0cbe3f55
commit bfbbf4928f
9 changed files with 330 additions and 272 deletions

View File

@@ -154,7 +154,7 @@ class Tests_Ajax_CompressionTest extends WP_Ajax_UnitTestCase {
}
// Check the site option is not changed due to lack of nonce.
$this->assertSame( 0, get_site_option( 'can_compress_scripts' ) );
$this->assertSame( 0, (int) get_site_option( 'can_compress_scripts' ) );
// Add a nonce.
$_GET['_ajax_nonce'] = wp_create_nonce( 'update_can_compress_scripts' );
@@ -167,7 +167,7 @@ class Tests_Ajax_CompressionTest extends WP_Ajax_UnitTestCase {
}
// Check the site option is changed.
$this->assertSame( 1, get_site_option( 'can_compress_scripts' ) );
$this->assertSame( 1, (int) get_site_option( 'can_compress_scripts' ) );
}
/**
@@ -194,7 +194,7 @@ class Tests_Ajax_CompressionTest extends WP_Ajax_UnitTestCase {
}
// Check the site option is not changed due to lack of nonce.
$this->assertSame( 1, get_site_option( 'can_compress_scripts' ) );
$this->assertSame( 1, (int) get_site_option( 'can_compress_scripts' ) );
// Add a nonce.
$_GET['_ajax_nonce'] = wp_create_nonce( 'update_can_compress_scripts' );
@@ -207,7 +207,7 @@ class Tests_Ajax_CompressionTest extends WP_Ajax_UnitTestCase {
}
// Check the site option is changed.
$this->assertSame( 0, get_site_option( 'can_compress_scripts' ) );
$this->assertSame( 0, (int) get_site_option( 'can_compress_scripts' ) );
}
/**

View File

@@ -152,28 +152,6 @@ if ( is_multisite() ) :
// $this->assertFalse( get_option( $key2 ) ); // Check get_option().
}
/**
* @group multisite
*
* @covers ::get_site_option
*/
public function test_site_notoptions() {
$network_id = get_current_network_id();
$notoptions_key = "{$network_id}:notoptions";
$_notoptions = wp_cache_get( 'notoptions', 'site-options' );
$this->assertEmpty( $_notoptions );
$_notoptions1 = wp_cache_get( $notoptions_key, 'site-options' );
$this->assertEmpty( $_notoptions1 );
get_site_option( 'burrito' );
$notoptions = wp_cache_get( 'notoptions', 'site-options' );
$this->assertEmpty( $notoptions );
$notoptions1 = wp_cache_get( $notoptions_key, 'site-options' );
$this->assertNotEmpty( $notoptions1 );
}
/**
* @covers ::users_can_register_signup_filter
* @covers ::get_site_option

View File

@@ -137,58 +137,124 @@ class Tests_Option_NetworkOption extends WP_UnitTestCase {
}
/**
* @ticket 43506
* @ticket 37181
*
* @group ms-required
*
* @covers ::get_network_option
* @covers ::wp_cache_get
* @covers ::wp_cache_delete
*/
public function test_get_network_option_sets_notoptions_if_option_found() {
$network_id = get_current_network_id();
$notoptions_key = "$network_id:notoptions";
public function test_meta_api_use_values_in_network_option() {
$network_id = self::factory()->network->create();
$option = __FUNCTION__;
$value = __FUNCTION__;
$original_cache = wp_cache_get( $notoptions_key, 'site-options' );
if ( false !== $original_cache ) {
wp_cache_delete( $notoptions_key, 'site-options' );
}
// Retrieve any existing option.
get_network_option( $network_id, 'site_name' );
$cache = wp_cache_get( $notoptions_key, 'site-options' );
if ( false !== $original_cache ) {
wp_cache_set( $notoptions_key, $original_cache, 'site-options' );
}
$this->assertSame( array(), $cache );
add_metadata( 'site', $network_id, $option, $value, true );
$this->assertEqualSets( get_metadata( 'site', $network_id, $option ), array( get_network_option( $network_id, $option, true ) ) );
}
/**
* @ticket 43506
* @ticket 37181
*
* @group ms-required
*/
function test_funky_network_meta() {
$network_id = self::factory()->network->create();
$option = __FUNCTION__;
$classy = new StdClass();
$classy->ID = 1;
$classy->stringy = 'I love slashes\\\\';
$funky_meta[] = $classy;
$classy = new StdClass();
$classy->ID = 2;
$classy->stringy = 'I love slashes\\\\ more';
$funky_meta[] = $classy;
// Add a network meta item.
$this->assertIsInt( add_metadata( 'site', $network_id, $option, $funky_meta, true ) );
// Check they exists.
$this->assertEquals( $funky_meta, get_network_option( $network_id, $option ) );
}
/**
* @ticket 37181
*
* @group ms-required
*/
public function test_meta_api_multiple_values_in_network_option() {
$network_id = self::factory()->network->create();
$option = __FUNCTION__;
add_metadata( 'site', $network_id, $option, 'monday', true );
add_metadata( 'site', $network_id, $option, 'tuesday', true );
add_metadata( 'site', $network_id, $option, 'wednesday', true );
$this->assertEquals( 'monday', get_network_option( $network_id, $option, true ) );
}
/**
* @ticket 37181
*
* @group ms-required
*
* @covers ::get_network_option
* @covers ::wp_cache_get
*/
public function test_get_network_option_sets_notoptions_if_option_not_found() {
$network_id = get_current_network_id();
$notoptions_key = "$network_id:notoptions";
public function test_network_option_count_queries_on_non_existing() {
$network_id = self::factory()->network->create();
$option = __FUNCTION__;
add_network_option( $network_id, $option, 'monday' );
get_network_option( $network_id, $option );
$num_queries_pre_get = get_num_queries();
get_network_option( $network_id, 'do_not_exist' );
$num_queries_after_get = get_num_queries();
$original_cache = wp_cache_get( $notoptions_key, 'site-options' );
if ( false !== $original_cache ) {
wp_cache_delete( $notoptions_key, 'site-options' );
}
$this->assertSame( $num_queries_pre_get, $num_queries_after_get );
}
// Retrieve any non-existing option.
get_network_option( $network_id, 'this_does_not_exist' );
/**
* @ticket 37181
*
* @group ms-required
*/
public function test_register_meta_network_option_single_false() {
$network_id = self::factory()->network->create();
$option = __FUNCTION__;
$value = __FUNCTION__;
register_meta(
'site',
$option,
array(
'type' => 'string',
'default' => $value,
'single' => false,
)
);
$cache = wp_cache_get( $notoptions_key, 'site-options' );
if ( false !== $original_cache ) {
wp_cache_set( $notoptions_key, $original_cache, 'site-options' );
}
$this->assertSame( $value, get_network_option( $network_id, $option ) );
}
$this->assertSame( array( 'this_does_not_exist' => true ), $cache );
/**
* @ticket 37181
*
* @group ms-required
*/
public function test_register_meta_network_option_single_true() {
$network_id = self::factory()->network->create();
$option = __FUNCTION__;
$value = __FUNCTION__;
register_meta(
'site',
$option,
array(
'type' => 'string',
'default' => $value,
'single' => true,
)
);
$this->assertSame( $value, get_network_option( $network_id, $option ) );
}
/**
@@ -196,9 +262,13 @@ class Tests_Option_NetworkOption extends WP_UnitTestCase {
*
* @ticket 44956
*
* @group ms-required
*
* @covers ::update_network_option
*/
public function test_update_network_option_array_with_object() {
$network_id = self::factory()->network->create();
$option = __FUNCTION__;
$array_w_object = array(
'url' => 'http://src.wordpress-develop.dev/wp-content/uploads/2016/10/cropped-Blurry-Lights.jpg',
'meta_data' => (object) array(
@@ -208,24 +278,140 @@ class Tests_Option_NetworkOption extends WP_UnitTestCase {
),
);
$array_w_object_2 = array(
'url' => 'http://src.wordpress-develop.dev/wp-content/uploads/2016/10/cropped-Blurry-Lights.jpg',
'meta_data' => (object) array(
'attachment_id' => 292,
'height' => 708,
'width' => 1260,
add_metadata( 'site', $network_id, $option, $array_w_object, true );
$this->assertEquals( $array_w_object, get_network_option( $network_id, $option ) );
}
/**
* @ticket 37181
*
* @group ms-required
*
* @covers ::add_network_option
*
* @dataProvider data_types_options
*/
public function test_type_add_network_option( $name, $value, $expected ) {
$result = add_network_option( null, $name, $value );
$this->assertTrue( $result, 'Network option was not added' );
$test_value = get_network_option( null, $name );
$this->assertSame( $expected, $test_value, 'Values do not match' );
}
/**
* @ticket 37181
*
* @covers ::add_network_option
*
* @dataProvider data_slashed_options
*/
public function test_slash_add_network_option( $name, $value ) {
$result = add_network_option( null, $name, $value );
$this->assertTrue( $result, 'Network option was not added' );
$this->assertSame( $value, get_network_option( null, $name ), 'Values do not match' );
}
/**
* @ticket 37181
*
* @covers ::update_network_option
*
* @dataProvider data_slashed_options
*/
public function test_slash_update_network_option( $name, $value ) {
$result = update_network_option( null, $name, $value );
$this->assertTrue( $result, 'Network option was not updated' );
$this->assertSame( $value, get_network_option( null, $name ), 'Values do not match' );
}
/**
* @ticket 37181
*
* @covers ::delete_network_option()
*
* @dataProvider data_slashed_options
*/
public function test_slash_delete_network_option( $name, $value ) {
$result = add_network_option( null, $name, $value );
$this->assertTrue( $result, 'Network option was not added' );
$this->assertSame( $value, get_network_option( null, $name ) );
$result = delete_network_option( null, $name );
$this->assertTrue( $result, 'Network option was not deleted' );
$this->assertFalse( get_network_option( null, $name ), 'Network option was not deleted' );
}
public function data_slashed_options() {
return array(
'slashed option name' => array(
'option' => 'String with 1 slash \\',
'value' => 'foo',
),
'slashed in middle option name' => array(
'option' => 'String\\thing',
'value' => 'foo',
),
'slashed option value' => array(
'option' => 'bar',
'value' => 'String with 1 slash \\',
),
'slashed option name and value' => array(
'option' => 'String with 1 slash \\',
'value' => 'String with 1 slash \\',
),
'slashed 4 times option name and value' => array(
'option' => 'String with 4 slashes \\\\\\\\',
'value' => 'String with 4 slashes \\\\\\\\',
),
'slashed 7 times option name and value' => array(
'option' => 'String with 7 slashes \\\\\\\\\\\\\\',
'value' => 'String with 7 slashes \\\\\\\\\\\\\\',
),
);
}
// Add the option, it did not exist before this.
add_network_option( null, 'array_w_object', $array_w_object );
$num_queries_pre_update = get_num_queries();
// Update the option using the same array with an object for the value.
$this->assertFalse( update_network_option( null, 'array_w_object', $array_w_object_2 ) );
// Check that no new database queries were performed.
$this->assertSame( $num_queries_pre_update, get_num_queries() );
public function data_types_options() {
return array(
'array' => array(
'option' => 'array',
'value' => array(),
'expected' => array(),
),
'array_keys' => array(
'option' => 'array',
'value' => array( 'key' => 'value' ),
'expected' => array( 'key' => 'value' ),
),
'int' => array(
'option' => 'int',
'value' => 33,
'expected' => '33',
),
'string' => array(
'option' => 'string',
'value' => 'foo',
'expected' => 'foo',
),
'string_bool' => array(
'option' => 'string',
'value' => 'true',
'expected' => 'true',
),
'float' => array(
'option' => 'float',
'value' => 33.5555,
'expected' => '33.5555',
),
'bool' => array(
'option' => 'bool',
'value' => true,
'expected' => '1',
),
'null' => array(
'option' => 'null',
'value' => null,
'expected' => null,
),
);
}
}