Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add embed handler for gfycat. #1136

Merged
merged 6 commits into from
May 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ function amp_get_content_embed_handlers( $post = null ) {
'AMP_Reddit_Embed_Handler' => array(),
'AMP_Tumblr_Embed_Handler' => array(),
'AMP_Gallery_Embed_Handler' => array(),
'AMP_Gfycat_Embed_Handler' => array(),
'WPCOM_AMP_Polldaddy_Embed' => array(),
),
$post
Expand Down
1 change: 1 addition & 0 deletions includes/class-amp-autoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class AMP_Autoloader {
'AMP_DailyMotion_Embed_Handler' => 'includes/embeds/class-amp-dailymotion-embed',
'AMP_Facebook_Embed_Handler' => 'includes/embeds/class-amp-facebook-embed',
'AMP_Gallery_Embed_Handler' => 'includes/embeds/class-amp-gallery-embed',
'AMP_Gfycat_Embed_Handler' => 'includes/embeds/class-amp-gfycat-embed-handler',
'AMP_Core_Block_Handler' => 'includes/embeds/class-amp-core-block-handler',
'AMP_Instagram_Embed_Handler' => 'includes/embeds/class-amp-instagram-embed',
'AMP_Issuu_Embed_Handler' => 'includes/embeds/class-amp-issuu-embed-handler',
Expand Down
81 changes: 81 additions & 0 deletions includes/embeds/class-amp-gfycat-embed-handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
/**
* Class AMP_Gfycat_Embed_Handler
*
* @package AMP
* @since 1.0
*/

/**
* Class AMP_Gfycat_Embed_Handler
*/
class AMP_Gfycat_Embed_Handler extends AMP_Base_Embed_Handler {
/**
* Regex matched to produce output amp-gfycat.
*
* @var string
*/
const URL_PATTERN = '#https?://(www\.)?gfycat\.com/.*#i';

/**
* Register embed.
*/
public function register_embed() {
add_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10, 3 );
}

/**
* Unregister embed.
*/
public function unregister_embed() {
remove_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10 );
}

/**
* Filter oEmbed HTML for Gfycat to prepare it for AMP.
*
* @param mixed $return The shortcode callback function to call.
* @param string $url The attempted embed URL.
* @param array $attr An array of shortcode attributes.
* @return string Embed.
*/
public function filter_embed_oembed_html( $return, $url, $attr ) {
$parsed_url = wp_parse_url( $url );
if ( false !== strpos( $parsed_url['host'], 'gfycat.com' ) ) {
if ( preg_match( '/width=["\']?(\d+)/', $return, $matches ) ) {
$attr['width'] = $matches[1];
}
if ( preg_match( '/height=["\']?(\d+)/', $return, $matches ) ) {
$attr['height'] = $matches[1];
}

if ( empty( $attr['height'] ) ) {
return $return;
}

$attributes = wp_array_slice_assoc( $attr, array( 'width', 'height' ) );

if ( empty( $attr['width'] ) ) {
$attributes['layout'] = 'fixed-height';
$attributes['width'] = 'auto';
}

$pieces = explode( '/detail/', $parsed_url['path'] );
if ( ! isset( $pieces[1] ) ) {
if ( ! preg_match( '/\/([A-Za-z0-9]+)/', $parsed_url['path'], $matches ) ) {
return $return;
}
$attributes['data-gfyid'] = $matches[1];
} else {
$attributes['data-gfyid'] = $pieces[1];
}

$return = AMP_HTML_Utils::build_tag(
'amp-gfycat',
$attributes
);
}
return $return;
}
}

118 changes: 118 additions & 0 deletions tests/test-class-amp-gfycat-embed-handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
/**
* Test Gfycat embed.
*
* @package AMP.
*/

/**
* Class AMP_Gfycat_Embed_Test
*/
class AMP_Gfycat_Embed_Test extends WP_UnitTestCase {

/**
* Set up.
*
* @global WP_Post $post
*/
public function setUp() {
global $post;
parent::setUp();

/*
* As #34115 in 4.9 a post is not needed for context to run oEmbeds. Prior ot 4.9, the WP_Embed::shortcode()
* method would short-circuit when this is the case:
* https://github.com/WordPress/wordpress-develop/blob/4.8.4/src/wp-includes/class-wp-embed.php#L192-L193
* So on WP<4.9 we set a post global to ensure oEmbeds get processed.
*/
if ( version_compare( strtok( get_bloginfo( 'version' ), '-' ), '4.9', '<' ) ) {
$post = $this->factory()->post->create_and_get();
}
}

/**
* Get conversion data.
*
* @return array
*/
public function get_conversion_data() {
return array(
'no_embed' => array(
'<p>Hello world.</p>',
'<p>Hello world.</p>' . PHP_EOL,
),

'url_simple' => array(
'https://gfycat.com/tautwhoppingcougar' . PHP_EOL,
'<p><amp-gfycat width="500" height="281" data-gfyid="tautwhoppingcougar"></amp-gfycat></p>' . PHP_EOL,
),

'url_with_detail' => array(
'https://gfycat.com/gifs/detail/tautwhoppingcougar' . PHP_EOL,
'<p><amp-gfycat width="500" height="281" data-gfyid="tautwhoppingcougar"></amp-gfycat></p>' . PHP_EOL,
),

'url_with_params' => array(
'https://gfycat.com/gifs/detail/tautwhoppingcougar?foo=bar' . PHP_EOL,
'<p><amp-gfycat width="500" height="281" data-gfyid="tautwhoppingcougar"></amp-gfycat></p>' . PHP_EOL,
),

);
}

/**
* Test conversion.
*
* @param string $source Source.
* @param string $expected Expected.
* @dataProvider get_conversion_data
*/
public function test__conversion( $source, $expected ) {
$embed = new AMP_Gfycat_Embed_Handler();
$embed->register_embed();
$filtered_content = apply_filters( 'the_content', $source );

$this->assertEquals( $expected, $filtered_content );
}

/**
* Get scripts data.
*
* @return array
*/
public function get_scripts_data() {
return array(
'not_converted' => array(
'<p>Hello World.</p>',
array(),
),
'converted' => array(
'https://www.gfycat.com/gifs/detail/tautwhoppingcougar' . PHP_EOL,
array( 'amp-gfycat' => true ),
),
);
}

/**
* Test scripts.
*
* @param string $source Source.
* @param string $expected Expected.
* @dataProvider get_scripts_data
*/
public function test__get_scripts( $source, $expected ) {
$embed = new AMP_Gfycat_Embed_Handler();
$embed->register_embed();
$source = apply_filters( 'the_content', $source );

$whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( AMP_DOM_Utils::get_dom_from_content( $source ) );
$whitelist_sanitizer->sanitize();

$scripts = array_merge(
$embed->get_scripts(),
$whitelist_sanitizer->get_scripts()
);

$this->assertEquals( $expected, $scripts );
}
}