From 9bde2e9f2628b297c82e8ce2c575727b0713398c Mon Sep 17 00:00:00 2001 From: David Baumwald Date: Tue, 13 Sep 2022 19:27:19 +0000 Subject: [PATCH] Options, Meta APIs: Add a new `pre-option` filter. Although a `pre_option_{$option}` filter already exists, this change adds a more general `pre_option` filter that will run on every `get_option` call. This brings the control flow into similar flow as `update_option`. Props flixos90, NathanAtmoz, desrosj, spacedmonkey, pbearne. Fixes #37930. git-svn-id: https://develop.svn.wordpress.org/trunk@54145 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/option.php | 18 ++++++++++++++++++ tests/phpunit/tests/option/option.php | 15 +++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php index c6ecb3bfde..3deb035758 100644 --- a/src/wp-includes/option.php +++ b/src/wp-includes/option.php @@ -131,6 +131,24 @@ function get_option( $option, $default = false ) { */ $pre = apply_filters( "pre_option_{$option}", false, $option, $default ); + /** + * Filters the value of all existing options before it is retrieved. + * + * Returning a truthy value from the filter will effectively short-circuit retrieval + * and return the passed value instead. + * + * @since 6.1.0 + * + * @param mixed $pre_option The value to return instead of the option value. This differs + * from `$default`, which is used as the fallback value in the event + * the option doesn't exist elsewhere in get_option(). + * Default false (to skip past the short-circuit). + * @param string $option Name of the option. + * @param mixed $default The fallback value to return if the option does not exist. + * Default false. + */ + $pre = apply_filters( 'pre_option', $pre, $option, $default ); + if ( false !== $pre ) { return $pre; } diff --git a/tests/phpunit/tests/option/option.php b/tests/phpunit/tests/option/option.php index db20253b86..656fe086a9 100644 --- a/tests/phpunit/tests/option/option.php +++ b/tests/phpunit/tests/option/option.php @@ -297,4 +297,19 @@ class Tests_Option_Option extends WP_UnitTestCase { array( 'autoload_false', false, 'no' ), ); } + + /** + * @ticket 37930 + * + * @covers ::get_option + */ + public function test_filter_pre_option_all_filter_is_called() { + $filter = new MockAction(); + + add_filter( 'pre_option', array( $filter, 'filter' ) ); + + get_option( 'ignored' ); + + $this->assertSame( 1, $filter->get_call_count() ); + } }