You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
4.3 KiB
PHTML

<?php
/**
* Class Oembed
*
* @link https://github.com/googleforcreators/web-stories-wp
*
* @copyright 2020 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
*/
/**
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare(strict_types = 1);
namespace Google\Web_Stories\Renderer;
use Google\Web_Stories\Service_Base;
use Google\Web_Stories\Story_Post_Type;
use WP_Post;
/**
* Class Oembed
*/
class Oembed extends Service_Base {
/**
* Filter to render oembed.
*
* @since 1.7.0
*/
public function register(): void {
add_filter( 'embed_template', [ $this, 'filter_embed_template' ] );
add_filter( 'embed_html', [ $this, 'filter_embed_html' ], 10, 4 );
// So it runs after get_oembed_response_data_rich().
add_filter( 'oembed_response_data', [ $this, 'filter_oembed_response_data' ], 20, 3 );
}
/**
* Filters the path of the queried template by type.
*
* @since 1.7.0
*
* @param string|mixed $template Path to the template. See locate_template().
* @return string|mixed $template
*/
public function filter_embed_template( $template ) {
if ( get_post_type() === Story_Post_Type::POST_TYPE_SLUG ) {
$template = WEBSTORIES_PLUGIN_DIR_PATH . 'includes/templates/frontend/embed-web-story.php';
}
return $template;
}
/**
* Filters the embed code for a specific post.
*
* For stories, changes the aspect ratio from 16/9 to 3/5.
*
* @since 1.7.0
*
* @param string|mixed $output Embed code.
* @param WP_Post $post Post object.
* @param int $width The width for the response.
* @param int $height The height for the response.
* @return string|mixed Filtered embed code.
*
* @phpstan-return ($output is string ? string : mixed)
*/
public function filter_embed_html( $output, WP_Post $post, int $width, int $height ) {
if ( ! \is_string( $output ) ) {
return $output;
}
if ( Story_Post_Type::POST_TYPE_SLUG !== $post->post_type ) {
return $output;
}
if ( ! has_post_thumbnail( $post ) ) {
return $output;
}
$new_data = $this->get_embed_height_width( $width );
$new_width = $new_data['width'];
$new_height = $new_data['height'];
return str_replace(
[ "width=\"$width\"", "height=\"$height\"" ],
[
"width=\"$new_width\"",
"height=\"$new_height\"",
],
$output
);
}
/**
* Filters the oEmbed response data for a specific post.
*
* For stories, changes the aspect ratio from 16/9 to 3/5.
*
* @since 1.7.0
*
* @param array|mixed $data The response data.
* @param WP_Post $post The post object.
* @param int $width The requested width.
* @return array|mixed The modified response data.
*
* @template T
*
* @phpstan-return ($data is array<T> ? array<T> : mixed)
*/
public function filter_oembed_response_data( $data, WP_Post $post, int $width ) {
if ( Story_Post_Type::POST_TYPE_SLUG !== $post->post_type ) {
return $data;
}
if ( ! has_post_thumbnail( $post ) ) {
return $data;
}
if ( ! \is_array( $data ) ) {
return $data;
}
$new_data = $this->get_embed_height_width( $width );
return array_merge( $data, $new_data );
}
/**
* Generate new height and width for embed.
*
* @since 1.7.0
*
* @param int $old_width Old width, used to generate new height and width.
* @return array{width: int, height: int}
*/
protected function get_embed_height_width( int $old_width ): array {
/** This filter is documented in wp-includes/embed.php */
$min_max_width = apply_filters(
'oembed_min_max_width',
[
'min' => 200,
'max' => 360,
]
);
$width = (int) min( max( $min_max_width['min'], $old_width ), $min_max_width['max'] );
$height = (int) max( ceil( $width / 3 * 5 ), 330 );
return compact( 'width', 'height' );
}
}