Skip to content

Commit

Permalink
Merge pull request #248 from WordPress/fix/default-timing
Browse files Browse the repository at this point in the history
Ensure default modules are loaded regardless of setting registration
  • Loading branch information
felixarntz authored Mar 22, 2022
2 parents 4596be0 + e76dd32 commit 803a031
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 17 deletions.
44 changes: 31 additions & 13 deletions load.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,44 @@
* @since 1.0.0
*/
function perflab_register_modules_setting() {
// To set the default value for which modules are enabled, rely on this generated file.
$default_enabled_modules = require plugin_dir_path( __FILE__ ) . 'default-enabled-modules.php';
$default_option = array_reduce(
$default_enabled_modules,
function( $module_settings, $module_dir ) {
$module_settings[ $module_dir ] = array( 'enabled' => true );
return $module_settings;
},
array()
);

register_setting(
PERFLAB_MODULES_SCREEN,
PERFLAB_MODULES_SETTING,
array(
'type' => 'object',
'sanitize_callback' => 'perflab_sanitize_modules_setting',
'default' => $default_option,
'default' => perflab_get_modules_setting_default(),
)
);
}
add_action( 'init', 'perflab_register_modules_setting' );

/**
* Gets the default value for the performance modules setting.
*
* @since n.e.x.t
*/
function perflab_get_modules_setting_default() {
// Since the default relies on some minimal logic that includes requiring an additional file,
// the result is "cached" in a static variable.
static $default_option = null;

if ( null === $default_option ) {
// To set the default value for which modules are enabled, rely on this generated file.
$default_enabled_modules = require plugin_dir_path( __FILE__ ) . 'default-enabled-modules.php';
$default_option = array_reduce(
$default_enabled_modules,
function( $module_settings, $module_dir ) {
$module_settings[ $module_dir ] = array( 'enabled' => true );
return $module_settings;
},
array()
);
}

return $default_option;
}

/**
* Sanitizes the performance modules setting.
*
Expand Down Expand Up @@ -87,7 +102,10 @@ function( $module_settings ) {
* @return array Associative array of module settings keyed by module slug.
*/
function perflab_get_module_settings() {
return (array) get_option( PERFLAB_MODULES_SETTING );
// Even though a default value is registered for this setting, the default must be explicitly
// passed here, to support scenarios where this function is called before the 'init' action,
// for example when loading the active modules.
return (array) get_option( PERFLAB_MODULES_SETTING, perflab_get_modules_setting_default() );
}

/**
Expand Down
37 changes: 33 additions & 4 deletions tests/load-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function test_perflab_register_modules_setting() {
}

// Assert that registered default works correctly.
$this->assertSame( $this->get_expected_default_option(), get_option( PERFLAB_MODULES_SETTING ) );
$this->assertSame( perflab_get_modules_setting_default(), get_option( PERFLAB_MODULES_SETTING ) );

// Assert that most basic sanitization works correctly (an array is required).
update_option( PERFLAB_MODULES_SETTING, 'invalid' );
Expand Down Expand Up @@ -56,10 +56,39 @@ public function test_perflab_sanitize_modules_setting() {
$this->assertSame( array( 'my-module' => array( 'enabled' => false ) ), $sanitized );
}

public function test_perflab_get_modules_setting_default() {
$default_enabled_modules = require plugin_dir_path( PERFLAB_MAIN_FILE ) . 'default-enabled-modules.php';
$expected = array();
foreach ( $default_enabled_modules as $default_enabled_module ) {
$expected[ $default_enabled_module ] = array( 'enabled' => true );
}

$this->assertSame( $expected, perflab_get_modules_setting_default() );
}

public function test_perflab_get_module_settings() {
// Assert that by default the settings are an empty array.
// Assert that by default the settings are using the same value as the registered default.
$settings = perflab_get_module_settings();
$this->assertSame( perflab_get_modules_setting_default(), $settings );

// More specifically though, assert that the default is also passed through to the
// get_option() call, to support scenarios where the function is called before 'init'.
// Unhook the registered default logic to verify the default comes from the passed value.
remove_all_filters( 'default_option_' . PERFLAB_MODULES_SETTING );
$has_passed_default = false;
add_filter(
'default_option_' . PERFLAB_MODULES_SETTING,
function( $default, $option, $passed_default ) use ( &$has_passed_default ) {
// This callback just records whether there is a default value being passed.
$has_passed_default = $passed_default;
return $default;
},
10,
3
);
$settings = perflab_get_module_settings();
$this->assertSame( $this->get_expected_default_option(), $settings );
$this->assertTrue( $has_passed_default );
$this->assertSame( perflab_get_modules_setting_default(), $settings );

// Assert that option updates are reflected in the settings correctly.
$new_value = array( 'my-module' => array( 'enabled' => true ) );
Expand All @@ -73,7 +102,7 @@ public function test_perflab_get_active_modules() {
$active_modules = perflab_get_active_modules();
$expected_active_modules = array_keys(
array_filter(
$this->get_expected_default_option(),
perflab_get_modules_setting_default(),
function( $module_settings ) {
return $module_settings['enabled'];
}
Expand Down

0 comments on commit 803a031

Please sign in to comment.