Skip to content

Commit

Permalink
Merges changes to the GettyImages shortcode from WordPress.com.
Browse files Browse the repository at this point in the history
This is a merge of changes from WordPress.com related to the new format of markup returned by GettyImages oembed endpoints. D9498-wpcom is the mirror change.
  • Loading branch information
zinigor committed Jan 22, 2018
1 parent e259393 commit 5a107ce
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 35 deletions.
119 changes: 97 additions & 22 deletions modules/shortcodes/getty.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ function jetpack_getty_enable_embeds( $site = 'wpcom' ) {
: 'wordpress.com';

// Support their oEmbed Endpoint
wp_oembed_add_provider( '#https?://www\.gettyimages\.com/detail/.*#i', "https://embed.gettyimages.com/oembed/?caller=$caller", true );
wp_oembed_add_provider( '#https?://(www\.)?gty\.im/.*#i', "https://embed.gettyimages.com/oembed/?caller=$caller", true );
wp_oembed_add_provider( '#https?://www\.gettyimages\.com/detail/.*#i', "https://embed.gettyimages.com/oembed/", true );
wp_oembed_add_provider( '#https?://(www\.)?gty\.im/.*#i', "https://embed.gettyimages.com/oembed/", true );

// Allow iframes to be filtered to short code (so direct copy+paste can be done)
add_filter( 'pre_kses', 'wpcom_shortcodereverse_getty' );
Expand All @@ -37,6 +37,41 @@ function jetpack_getty_enable_embeds( $site = 'wpcom' ) {
add_shortcode( 'getty', 'jetpack_getty_shortcode' );
}

/**
* Filters the oEmbed provider URL for Getty URLs to include site URL host as
* caller if available, falling back to "wordpress.com". Must be applied at
* time of embed in case that `init` is too early (WP.com REST API).
*
* @module shortcodes
*
* @since 5.8.0
*
* @see WP_oEmbed::fetch
*
* @return string oEmbed provider URL
*/
add_filter( 'oembed_fetch_url', 'getty_add_oembed_endpoint_caller' );

function getty_add_oembed_endpoint_caller( $provider ) {
// By time filter is called, original provider URL has had url, maxwidth,
// maxheight query parameters added.
if ( 0 !== strpos( $provider, 'https://embed.gettyimages.com/oembed/' ) ) {
return $provider;
}

// Only include caller for non-private sites
if ( ! function_exists( 'is_private_blog' ) || ! is_private_blog() ) {
$host = parse_url( get_bloginfo( 'url' ), PHP_URL_HOST );
}

// Fall back to WordPress.com
if ( empty( $host ) ) {
$host = 'wordpress.com';
}

return add_query_arg( 'caller', $host, $provider );
}

/**
* Compose shortcode based on Getty iframes.
*
Expand All @@ -47,39 +82,73 @@ function jetpack_getty_enable_embeds( $site = 'wpcom' ) {
* @return mixed
*/
function wpcom_shortcodereverse_getty( $content ) {
if ( ! is_string( $content ) || false === stripos( $content, 'embed.gettyimages.com/embed' ) ) {
if ( ! is_string( $content ) || false === stripos( $content, '.gettyimages.com/' ) ) {
return $content;
}

$regexp = '!<iframe\s+src=[\'"](https?:)?//embed\.gettyimages\.com/embed(/|/?\?assets=)(\d+(,\d+)*)[^\'"]*?[\'"]((?:\s+\w+=[\'"][^\'"]*[\'"])*)((?:[\s\w]*))></iframe>!i';
$regexp = '!<iframe\s+src=[\'"](https?:)?//embed\.gettyimages\.com/embed(/|/?\?assets=)([a-z0-9_-]+(,[a-z0-9_-]+)*)[^\'"]*?[\'"]((?:\s+\w+=[\'"][^\'"]*[\'"])*)((?:[\s\w]*))></iframe>!i';
$regexp_ent = str_replace( '&amp;#0*58;', '&amp;#0*58;|&#0*58;', htmlspecialchars( $regexp, ENT_NOQUOTES ) );

foreach ( array( 'regexp', 'regexp_ent' ) as $reg ) {
/**
* Context: http://wp.me/p5j4vm-1y7
*
* @hide-in-jetpack
*/

// Markup pattern for 2017 embed syntax with significant differences from
// the prior pattern:
$regexp_2017 = '!<a.+?class=\'gie-(single|slideshow)\'.+?gie\.widgets\.load\({([^}]+)}\).+?embed-cdn\.gettyimages\.com/widgets\.js.+?</script>!';
$regexp_2017_ent = str_replace( '&amp;#0*58;', '&amp;#0*58;|&#0*58;', htmlspecialchars( $regexp_2017, ENT_NOQUOTES ) );

foreach ( array( 'regexp_2017', 'regexp_2017_ent', 'regexp', 'regexp_ent' ) as $reg ) {
if ( ! preg_match_all( $$reg, $content, $matches, PREG_SET_ORDER ) ) {
continue;
}

foreach ( $matches as $match ) {
$ids = esc_html( $match[3] );

$params = $match[5];

if ( 'regexp_ent' == $reg ) {
$params = html_entity_decode( $params );
if ( 'regexp_2017' === $reg || 'regexp_2017_ent' === $reg ) {
// Extract individual keys from the matched JavaScript object
$params = $match[2];
if ( ! preg_match_all( '!(?P<key>\w+)\s*:\s*([\'"](?P<value>[^\'"]*?)(px)?[\'"])!', $params, $key_matches, PREG_SET_ORDER ) ) {
continue;
}

foreach ( $key_matches as $key_match ) {
switch ( $key_match['key'] ) {
case 'items': $ids = $key_match['value']; break;
case 'w': $width = (int) $key_match['value']; break;
case 'h': $height = (int) $key_match['value']; break;
case 'tld': $tld = $key_match['value']; break;
}
}
} else {
$params = $match[5];
if ( 'regexp_ent' === $reg ) {
$params = html_entity_decode( $params );
}
$params = wp_kses_hair( $params, array( 'http' ) );

$ids = esc_html( $match[3] );
$width = isset( $params['width'] ) ? (int) $params['width']['value'] : 0;
$height = isset( $params['height'] ) ? (int) $params['height']['value'] : 0;
}

$params = wp_kses_hair( $params, array( 'http' ) );

$width = isset( $params['width'] ) ? (int) $params['width']['value'] : 0;
$height = isset( $params['height'] ) ? (int) $params['height']['value'] : 0;
if ( empty( $ids ) ) {
continue;
}

$shortcode = '[getty src="' . esc_attr( $ids ) . '"';
if ( $width ) {
if ( ! empty( $width ) ) {
$shortcode .= ' width="' . esc_attr( $width ) . '"';
}
if ( $height ) {
if ( ! empty( $height ) ) {
$shortcode .= ' height="' . esc_attr( $height ) . '"';
}
// While it does not appear to have any practical impact, Getty has
// requested that we include TLD in the embed request
if ( ! empty( $tld ) ) {
$shortcode .= ' tld="' . esc_attr( $tld ). '"';
}
$shortcode .= ']';

$content = str_replace( $match[0], $shortcode, $content );
Expand All @@ -89,6 +158,7 @@ function wpcom_shortcodereverse_getty( $content ) {
// strip out enclosing div and any other markup
$regexp = '%<div class="getty\s[^>]*+>.*?<div[^>]*+>(\[getty[^\]]*+\])\s*</div>.*?</div>%is';
$regexp_ent = str_replace( array( '&amp;#0*58;', '[^&gt;]' ), array( '&amp;#0*58;|&#0*58;', '[^&]' ), htmlspecialchars( $regexp, ENT_NOQUOTES ) );
$regexp_ent = str_replace( array( '&amp;#0*58;', '[^&gt;]' ), array( '&amp;#0*58;|&#0*58;', '[^&]' ), htmlspecialchars( $regexp, ENT_NOQUOTES ) );

foreach ( array( 'regexp', 'regexp_ent' ) as $reg ) {
if ( ! preg_match_all( $$reg, $content, $matches, PREG_SET_ORDER ) ) {
Expand Down Expand Up @@ -128,11 +198,16 @@ function jetpack_getty_shortcode( $atts, $content = '' ) {
return '<!-- Missing Getty Source ID -->';
}

$src = preg_replace( '/^(\d+(,\d+)*).*$/', '$1', $src );
$src = preg_replace( '/^([\da-z-]+(,[\da-z-]+)*).*$/', '$1', $src );

$params = array(
'width' => isset( $atts['width'] ) ? (int) $atts['width'] : null,
'height' => isset( $atts['height'] ) ? (int) $atts['height'] : null
);

$args = array();
$args['width'] = isset( $atts['width'] ) ? (int) $atts['width'] : '462';
$args['height'] = isset( $atts['height'] ) ? (int) $atts['height'] : '370';
if ( ! empty( $atts['tld'] ) ) {
$params['tld'] = $atts['tld'];
}

return wp_oembed_get( 'https://gty.im/' . $src, $args );
return wp_oembed_get( 'https://gty.im/' . $src, array_filter( $params ) );
}
116 changes: 103 additions & 13 deletions tests/php/modules/shortcodes/test_class.getty.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,42 @@

class WP_Test_Jetpack_Shortcodes_Getty extends WP_UnitTestCase {

const GETTY_IDENTIFIER = '82278805';

const GETTY_SHORTCODE = '[getty src="82278805" width="462" height="370"]';

const GETTY_SHORTCODE_TLD = '[getty src="82278805" width="462" height="370" tld="com"]';

const GETTY_SHORTCODE_SLIDESHOW = '[getty src="601312382,sb10068163bs-001,157480765,sb10068163br-001,157480920" width="457" height="377" tld="com"]';

const GETTY_SHORTCODE_MULTI = '[getty src="125972920,83421977" width="507" height="337"]';

const GETTY_SHORTCODE_ALPHANUMERIC_DASHED_ID = '[getty src="sb10065012a-001" width="426" height="400"]';

const GETTY_SHORTCODE_WITH_ARGS = '[getty src="82278805?et=wi6iT1Wqn0yYxEh6Ocx_aA&amp;sig=G63PuQ-eKJqGCnssk8rsSu1wcGoyUsgwqL8Jfu83wis=&amp;viewMoreLink%3Don" width="462" height="370"]';

const GETTY_EMBED = '<div class="getty embed image" style="background-color:#fff;display:inline-block;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;color:#a7a7a7;font-size:11px;width:100%;max-width:462px;"><div style="padding:0;margin:0;text-align:left;"><a href="http://www.gettyimages.com/detail/82278805" target="_blank" style="color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;">Embed from Getty Images</a></div><div style="overflow:hidden;position:relative;height:0;padding:80.086580% 0 0 0;width:100%;"><iframe src="//embed.gettyimages.com/embed/82278805?et=wi6iT1Wqn0yYxEh6Ocx_aA&amp;sig=G63PuQ-eKJqGCnssk8rsSu1wcGoyUsgwqL8Jfu83wis=&tld=com" width="462" height="370" scrolling="no" frameborder="0" style="display:inline-block;position:absolute;top:0;left:0;width:100%;height:100%;margin:0;" ></iframe></div><p style="margin:0;"></p></div>';

const GETTY_EMBED_MULTI = '<div class="getty embed image" style="background-color:#fff;display:inline-block;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;color:#a7a7a7;font-size:11px;width:100%;max-width:507px;"><div style="padding:0;margin:0;text-align:left;"><a href="http://www.gettyimages.com/detail/125972920" target="_blank" style="color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;">Embed from Getty Images</a></div><div style="overflow:hidden;position:relative;height:0;padding:66.469428% 0 0 0;width:100%;"><iframe src="//embed.gettyimages.com/embed?assets=125972920,83421977&et=mRtKtGrSS9RpMnENPzEAIQ&tld=com&sig=7cbyy8qX5L-4wrESym68jkKwv98QuF_RbdI4q6Sa_3s=" width="507" height="337" scrolling="no" frameborder="0" style="display:inline-block;position:absolute;top:0;left:0;width:100%;height:100%;margin:0;" ></iframe></div><p style="margin:0;"></p></div>';

const GETTY_EMBED_2017 = '<a id=\'giY-P3UyQ7NgmhoUs69FfA\' class=\'gie-single\' href=\'http://www.gettyimages.com/detail/82278805\' target=\'_blank\' style=\'color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;\'>Embed from Getty Images</a><script>window.gie=window.gie||function(c){(gie.q=gie.q||[]).push(c)};gie(function(){gie.widgets.load({id:\'giY-P3UyQ7NgmhoUs69FfA\',sig:\'7_gkXdhdHtVWWsyemkD0qPEuDZVBmfepEDjfqlTi61M=\',w:\'462px\',h:\'370px\',items:\'82278805\',caption: true ,tld:\'com\',is360: false })});</script><script src=\'//embed-cdn.gettyimages.com/widgets.js\' charset=\'utf-8\' async></script>';

const GETTY_EMBED_2017_SLIDESHOW = '<a id=\'CEIWqB2vSz5lH9pABhmy0A\' class=\'gie-slideshow\' href=\'http://www.gettyimages.com/detail/601312382\' style=\'color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;\'>Embed from Getty Images</a><script>window.gie=window.gie||function(c){(gie.q=gie.q||[]).push(c)};gie(function(){gie.widgets.load({id:\'CEIWqB2vSz5lH9pABhmy0A\',sig:\'cDACdf5bJZlDWoauJkdbDwvhtdjhQ5kn4GDr2nBQ9iA=\',w:\'457px\',h:\'377px\',items:\'601312382,sb10068163bs-001,157480765,sb10068163br-001,157480920\',caption: true ,tld:\'com\',is360: false })});</script><script src=\'//embed-cdn.gettyimages.com/widgets.js\' charset=\'utf-8\' async></script>';

const GETTY_EMBED_ALPHANUMERIC_DASHED_ID = '<div class="getty embed image" style="background-color:#fff;display:inline-block;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;color:#a7a7a7;font-size:11px;width:100%;max-width:426px;"><div style="padding:0;margin:0;text-align:left;"><a href="http://www.gettyimages.com/detail/sb10065012a-001" target="_blank" style="color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;">Embed from Getty Images</a></div><div style="overflow:hidden;position:relative;height:0;padding:93.896714% 0 0 0;width:100%;"><iframe src="//embed.gettyimages.com/embed/sb10065012a-001?et=kbBO9dIMTBZzGVtzySE_7g&viewMoreLink=off&sig=gFY-3rZCMdUEiVCbM2wqVAKDkGwskGl3W8pSn_4QCQc=&caption=true" width="426" height="400" scrolling="no" frameborder="0" style="display:inline-block;position:absolute;top:0;left:0;width:100%;height:100%;margin:0;"></iframe></div><p style="margin:0;"></p></div>';

const GETTY_OLD_EMBED = '<iframe src="//embed.gettyimages.com/embed/82278805?et=wi6iT1Wqn0yYxEh6Ocx_aA&sig=G63PuQ-eKJqGCnssk8rsSu1wcGoyUsgwqL8Jfu83wis=" width="462" height="370" scrolling="no" frameborder="0" style="display:inline-block;"></iframe>';

const GETTY_ESCAPED_EMBED = '&lt;div class="getty embed image" style="background-color:#fff;display:inline-block;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;color:#a7a7a7;font-size:11px;width:100%;max-width:462px;"&gt;&lt;div style="padding:0;margin:0;text-align:left;"&gt;&lt;a href="http://www.gettyimages.com/detail/82278805" target="_blank" style="color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;"&gt;Embed from Getty Images&lt;/a&gt;&lt;/div&gt;&lt;div style="overflow:hidden;position:relative;height:0;padding:80.086580% 0 0 0;width:100%;"&gt;&lt;iframe src="//embed.gettyimages.com/embed/82278805?et=wi6iT1Wqn0yYxEh6Ocx_aA&amp;sig=G63PuQ-eKJqGCnssk8rsSu1wcGoyUsgwqL8Jfu83wis=" width="462" height="370" scrolling="no" frameborder="0" style="display:inline-block;position:absolute;top:0;left:0;width:100%;height:100%;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;&lt;/p&gt;&lt;/div&gt;';

const GETTY_ESCAPED_EMBED_2017 = '&lt;a id=\'giY-P3UyQ7NgmhoUs69FfA\' class=\'gie-single\' href=\'http://www.gettyimages.com/detail/82278805\' target=\'_blank\' style=\'color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;\'&gt;Embed from Getty Images&lt;/a&gt;&lt;script&gt;window.gie=window.gie||function(c){(gie.q=gie.q||[]).push(c)};gie(function(){gie.widgets.load({id:\'giY-P3UyQ7NgmhoUs69FfA\',sig:\'7_gkXdhdHtVWWsyemkD0qPEuDZVBmfepEDjfqlTi61M=\',w:\'462px\',h:\'370px\',items:\'82278805\',caption: true ,tld:\'com\',is360: false })});&lt;/script&gt;&lt;script src=\'//embed-cdn.gettyimages.com/widgets.js\' charset=\'utf-8\' async&gt;&lt;/script&gt;';

const GETTY_EXAMPLE_PROCESSED = '<div class="getty embed image" style="background-color:#fff;display:inline-block;font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;color:#a7a7a7;font-size:11px;width:100%;max-width:462px;"><div style="padding:0;margin:0;text-align:left;"><a href="http://www.gettyimages.com/detail/82278805" target="_blank" style="color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;">Embed from Getty Images</a></div><div style="overflow:hidden;position:relative;height:0;padding:80.086580% 0 0 0;width:100%;"><iframe src="//embed.gettyimages.com/embed/82278805?et=wi6iT1Wqn0yYxEh6Ocx_aA&amp;sig=G63PuQ-eKJqGCnssk8rsSu1wcGoyUsgwqL8Jfu83wis=&tld=com" width="462" height="370" scrolling="no" frameborder="0" style="display:inline-block;position:absolute;top:0;left:0;width:100%;height:100%;margin:0;" ></iframe></div><p style="margin:0;"></p></div>';

static function strip_url_signature_args( $str ) {
return preg_replace( '/((id=\'[:alpha:\-]+)|[\?&]|&amp;|&#038;)(et=[\w-]+|sig=[\w-=]+)/', '', $str );
}

/**
* Verify that [getty] exists.
*
Expand All @@ -11,18 +47,74 @@ public function test_shortcodes_getty_exists() {
$this->assertEquals( shortcode_exists( 'getty' ), true );
}

/**
* Verify that calling do_shortcode with the shortcode doesn't return the same content.
*
* @since 4.5.0
*/
public function test_shortcodes_getty() {
$content = '[getty]';
function test_getty_shortcode() {
$parsed = do_shortcode( self::GETTY_SHORTCODE );

$shortcode_content = do_shortcode( $content );
$doc = new DOMDocument();
$doc->loadHTML( $parsed );
$links = $doc->getElementsByTagName( 'a' );

foreach( $links as $link ) {
$this->assertTrue( $link->hasAttribute( 'href' ) );
$this->assertContains( self::GETTY_IDENTIFIER, $link->getAttribute( 'href' ) );
}
}

function test_getty_reverse_shortcode() {
$shortcode = wpcom_shortcodereverse_getty( self::GETTY_EMBED );
$this->assertEquals( self::GETTY_SHORTCODE, $shortcode );
}

function test_getty_reverse_multi_shortcode() {
$shortcode = wpcom_shortcodereverse_getty( self::GETTY_EMBED_MULTI );
$this->assertEquals( self::GETTY_SHORTCODE_MULTI, $shortcode );
}

function test_getty_reverse_alphanumeric_daashed_id_shortcode() {
$shortcode = wpcom_shortcodereverse_getty( self::GETTY_EMBED_ALPHANUMERIC_DASHED_ID );
$this->assertEquals( self::GETTY_SHORTCODE_ALPHANUMERIC_DASHED_ID, $shortcode );
}

function test_getty_reverse_shortcode_works_on_escaped_html() {
$shortcode = wpcom_shortcodereverse_getty( self::GETTY_ESCAPED_EMBED );
$this->assertEquals( self::GETTY_SHORTCODE, $shortcode );
}

$this->assertNotEquals( $content, $shortcode_content );
$this->assertEquals( '<!-- Missing Getty Source ID -->', $shortcode_content );
function test_getty_reverse_shortcode_works_on_old_embed() {
$shortcode = wpcom_shortcodereverse_getty( self::GETTY_OLD_EMBED );
$this->assertEquals( self::GETTY_SHORTCODE, $shortcode );
}

function test_getty_reverse_shortcode_2017() {
$shortcode = wpcom_shortcodereverse_getty( self::GETTY_EMBED_2017 );
$this->assertEquals( self::GETTY_SHORTCODE_TLD, $shortcode );
}

function test_getty_reverse_shortcode_2017_works_on_escaped_html() {
$shortcode = wpcom_shortcodereverse_getty( self::GETTY_ESCAPED_EMBED_2017 );
$this->assertEquals( self::GETTY_SHORTCODE_TLD, $shortcode );
}

function test_getty_reverse_shortcode_doesnt_remove_too_much() {
$before = '<div class="something else">test<div class=\'something\'>another div';
$after = 'blah</div></div>';
$shortcode = wpcom_shortcodereverse_getty( $before . self::GETTY_EMBED . $after );
$expected = $before . self::GETTY_SHORTCODE . $after;
$this->assertEquals( $expected, $shortcode );
}

function test_getty_add_oembed_endpoint_caller_non_getty() {
$provider_url = apply_filters(
'oembed_fetch_url',
'https://www.youtube.com/oembed?maxwidth=471&maxheight=594&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ',
'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
''
);

$this->assertEquals(
$provider_url,
'https://www.youtube.com/oembed?maxwidth=471&maxheight=594&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ'
);
}

/**
Expand All @@ -31,13 +123,11 @@ public function test_shortcodes_getty() {
* @since 4.5.0
*/
public function test_shortcodes_getty_image() {
$this->markTestSkipped();

$image_id = '82278805';
$content = "[getty src='$image_id']";

$shortcode_content = do_shortcode( $content );

$this->assertContains( '<iframe src="//embed.gettyimages.com/embed/' . $image_id, $shortcode_content );
$this->assertContains( $image_id, $shortcode_content );
}
}

0 comments on commit 5a107ce

Please sign in to comment.