diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php index 54c3f0eac1..1a9c1c5523 100644 --- a/src/wp-includes/class-wp-customize-manager.php +++ b/src/wp-includes/class-wp-customize-manager.php @@ -3491,7 +3491,7 @@ final class WP_Customize_Manager { 'frame_title' => __( 'Select Video' ), 'frame_button' => __( 'Choose Video' ), ), - 'active_callback' => 'is_front_page', + 'active_callback' => 'is_header_video_active', ) ) ); $this->add_control( 'external_header_video', array( diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index 66e10b24e8..9ca52735cb 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -1400,13 +1400,45 @@ function get_header_video_settings() { * @return bool True if a custom header is set. False if not. */ function has_custom_header() { - if ( has_header_image() || ( is_front_page() && has_header_video() ) ) { + if ( has_header_image() || ( has_header_video() && is_header_video_active() ) ) { return true; } return false; } +/** + * Checks whether the custom header video is eligible to show on the current page. + * + * @since 4.7.0 + * + * @return bool True if the custom header video should be shown. False if not. + */ +function is_header_video_active() { + if ( ! get_theme_support( 'custom-header', 'video' ) ) { + return false; + } + + $video_active_cb = get_theme_support( 'custom-header', 'video-active-callback' ); + + if ( empty( $video_active_cb ) || ! is_callable( $video_active_cb ) ) { + $show_video = true; + } else { + $show_video = call_user_func( $video_active_cb ); + } + + /** + * Modify whether the custom header video is eligible to show on the current page. + * + * @since 4.7.0 + * + * @param bool $show_video Whether the custom header video should be shown. Returns the value + * of the theme setting for the `custom-header`'s `video-active-callback`. + * If no callback is set, the default value is that of `is_front_page()`. + */ + return apply_filters( 'is_header_video_active', $show_video ); +} + /** * Retrieve the markup for a custom header. * @@ -1442,7 +1474,7 @@ function the_custom_header_markup() { echo $custom_header; - if ( is_front_page() && ( has_header_video() || is_customize_preview() ) ) { + if ( is_header_video_active() && ( has_header_video() || is_customize_preview() ) ) { wp_enqueue_script( 'wp-custom-header' ); wp_localize_script( 'wp-custom-header', '_wpCustomHeaderSettings', get_header_video_settings() ); } @@ -2058,6 +2090,7 @@ function add_theme_support( $feature ) { 'admin-head-callback' => '', 'admin-preview-callback' => '', 'video' => false, + 'video-active-callback' => 'is_front_page', ); $jit = isset( $args[0]['__jit'] ); @@ -2319,10 +2352,13 @@ function _remove_theme_support( $feature ) { if ( ! did_action( 'wp_loaded' ) ) break; $support = get_theme_support( 'custom-header' ); - if ( $support[0]['wp-head-callback'] ) + if ( isset( $support[0]['wp-head-callback'] ) ) { remove_action( 'wp_head', $support[0]['wp-head-callback'] ); - remove_action( 'admin_menu', array( $GLOBALS['custom_image_header'], 'init' ) ); - unset( $GLOBALS['custom_image_header'] ); + } + if ( isset( $GLOBALS['custom_image_header'] ) ) { + remove_action( 'admin_menu', array( $GLOBALS['custom_image_header'], 'init' ) ); + unset( $GLOBALS['custom_image_header'] ); + } break; case 'custom-background' : diff --git a/tests/phpunit/tests/theme/customHeader.php b/tests/phpunit/tests/theme/customHeader.php new file mode 100644 index 0000000000..875c8ba79d --- /dev/null +++ b/tests/phpunit/tests/theme/customHeader.php @@ -0,0 +1,125 @@ +post->create( array( + 'post_status' => 'publish', + ) ); + } + + function tearDown() { + remove_theme_support( 'custom-header' ); + parent::tearDown(); + } + + /** + * @ticket 38738 + */ + function test_video_header_callback_front_page_from_front_page() { + $this->_add_theme_support( array( + 'video' => true, + ) ); + + $this->go_to( home_url() ); + + $result = is_header_video_active(); + + $this->assertTrue( $result ); + } + + /** + * @ticket 38738 + */ + function test_video_header_callback_front_page_from_elsewhere() { + $this->_add_theme_support( array( + 'video' => true, + ) ); + + $this->go_to( get_permalink( self::$post ) ); + + $result = is_header_video_active(); + + $this->assertFalse( $result ); + } + + /** + * @ticket 38738 + */ + function test_video_header_callback_globally_from_front_page() { + $this->_add_theme_support( array( + 'video' => true, + 'video-active-callback' => '__return_true', + ) ); + + $this->go_to( home_url() ); + + $result = is_header_video_active(); + + $this->assertTrue( $result ); + } + + /** + * @ticket 38738 + */ + function test_video_header_callback_globally_from_elsewhere() { + $this->_add_theme_support( array( + 'video' => true, + 'video-active-callback' => '__return_true', + ) ); + + $this->go_to( get_permalink( self::$post ) ); + + $result = is_header_video_active(); + + $this->assertTrue( $result ); + } + + /** + * @ticket 38738 + */ + function test_video_header_callback_globally_with_negative_filter() { + $this->_add_theme_support( array( + 'video' => true, + 'video-active-callback' => '__return_true', + ) ); + + $this->go_to( get_permalink( self::$post ) ); + + add_filter( 'is_header_video_active', '__return_false' ); + $result = is_header_video_active(); + remove_filter( 'is_header_video_active', '__return_false' ); + + $this->assertFalse( $result ); + } + + /** + * Adds arguments directly to the $_wp_theme_features global. Calling + * add_theme_support( 'custom-header' ) will poison subsequent tests since + * it defines constants. + */ + function _add_theme_support( $args = array() ) { + global $_wp_theme_features; + + $_wp_theme_features['custom-header'][0] = wp_parse_args( $args, array( + 'default-image' => '', + 'random-default' => false, + 'width' => 0, + 'height' => 0, + 'flex-height' => false, + 'flex-width' => false, + 'default-text-color' => '', + 'header-text' => true, + 'uploads' => true, + 'wp-head-callback' => '', + 'admin-head-callback' => '', + 'admin-preview-callback' => '', + 'video' => false, + 'video-active-callback' => 'is_front_page', + ) ); + } +}