diff --git a/src/wp-includes/compat.php b/src/wp-includes/compat.php index 7377a384c8..77762cb6f6 100644 --- a/src/wp-includes/compat.php +++ b/src/wp-includes/compat.php @@ -505,3 +505,21 @@ endif; if ( ! function_exists( 'spl_autoload_register' ) ) { require_once ABSPATH . WPINC . '/spl-autoload-compat.php'; } + +if ( ! function_exists( 'is_countable' ) ) { + /** + * Polyfill for is_countable() function added in PHP 7.3. + * + * Verify that the content of a variable is an array or an object + * implementing Countable. + * + * @since 4.9.6 + * + * @param mixed $var The value to check. + * + * @return bool True if `$var` is countable, false otherwise. + */ + function is_countable( $var ) { + return ( is_array( $var ) || $var instanceof Countable ); + } +} diff --git a/tests/phpunit/tests/compat.php b/tests/phpunit/tests/compat.php index 3d873745b9..43f1600f25 100644 --- a/tests/phpunit/tests/compat.php +++ b/tests/phpunit/tests/compat.php @@ -186,6 +186,50 @@ EOT; $this->assertEquals( '["foo"]', $json->encodeUnsafe( array( 'foo' ) ) ); $this->assertEquals( array( 'foo' ), $json->decode( '["foo"]' ) ); } + + /** + * @ticket 43583 + */ + function test_is_countable_availability() { + $this->assertTrue( function_exists( 'is_countable' ) ); + } + + /** + * Test is_countable() polyfill. + * + * @ticket 43583 + * + * @dataProvider countable_variable_test_data + */ + function test_is_countable_functionality( $variable, $is_countable ) { + $this->assertEquals( is_countable( $variable ), $is_countable ); + } + + /** + * Data provider for test_is_countable_functionality(). + * + * @ticket 43583 + * + * @return array { + * @type array { + * @type mixed $variable Variable to check. + * @type bool $is_countable The expected return value of PHP 7.3 is_countable() function. + * } + * } + */ + public function countable_variable_test_data() { + return array( + array( true, false ), + array( new stdClass(), false ), + array( new ArrayIteratorFake(), true ), + array( new CountableFake(), true ), + array( 16, false ), + array( null, false ), + array( array( 1, 2, 3 ), true ), + array( (array) 1, true ), + array( (object) array( 'foo', 'bar', 'baz' ), false ), + ); + } } /* used in test_mb_substr_phpcore */ @@ -194,3 +238,12 @@ class classA { return 'Class A object'; } } + +class ArrayIteratorFake extends ArrayIterator { +} + +class CountableFake implements Countable { + public function count() { + return 16; + } +}