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() ); + } }