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

Medium: update embed method to reflect Medium changes #12170

Merged
merged 8 commits into from
May 8, 2019
80 changes: 67 additions & 13 deletions modules/shortcodes/medium.php
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
<?php

// Embed support for Medium https://medium.com/p/3eaed64aed8a

/**
* Faux-oembed support for Medium permalinks
* Embed support for Medium
*
* Supported formats:
* - Profiles: https://medium.com/@jeherve
* - Stories: https://medium.com/@jeherve/this-is-a-story-19f582daaf5b
* - And all the above in shortcode formats:
* [medium url="https://medium.com/@jeherve/this-is-a-story-19f582daaf5b" width="100%" border="false" collapsed="true"]
*
* e.g.
* https://medium.com/help-center
* https://medium.com/@richroll
* @package Jetpack
*/

// Faux-oembed support for Medium permalinks.
wp_embed_register_handler( 'medium', '#^https?://medium.com/([a-zA-z0-9-_@]+)#', 'jetpack_embed_medium_oembed' );

/**
* Callback to modify output of embedded Medium posts.
*
* @param array $matches Regex partial matches against the URL passed.
* @param array $attr Attributes received in embed response.
* @param array $url Requested URL to be embedded.
*/
function jetpack_embed_medium_oembed( $matches, $attr, $url ) {
$attr = jetpack_embed_medium_args( $attr );
$attr['url'] = $url;

return jetpack_embed_medium_embed_html( $attr );
}

/**
* Return custom markup to display a Medium profile, collection, or story.
*
* @param array $args Attributes received in embed response.
*/
function jetpack_embed_medium_embed_html( $args ) {
$args = jetpack_embed_medium_args( $args );

Expand All @@ -27,36 +42,75 @@ function jetpack_embed_medium_embed_html( $args ) {

$args['type'] = jetpack_embed_medium_get_embed_type( $args['url'] );

return sprintf( '<script async src="https://static.medium.com/embed.js"></script><a class="m-%1$s" href="%2$s" target="_blank" data-width="%3$s" data-border="%4$s" data-collapsed="%5$s">View %1$s at Medium.com</a>', esc_attr( $args['type'] ), esc_url( $args['url'] ), esc_attr( $args['width'] ), esc_attr( $args['border'] ), esc_attr( $args['collapsed'] ) );
if ( 'collection' === $args['type'] ) {
return sprintf(
'<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
esc_url( $args['url'] ),
esc_html__( 'View this collection on Medium.com', 'jetpack' )
);
}

wp_enqueue_script(
'medium-embed',
'https://static.medium.com/embed.js',
array(),
JETPACK__VERSION,
true
);

return sprintf(
'<a class="m-%1$s" href="%2$s" target="_blank" data-width="%3$s" data-border="%4$s" data-collapsed="%5$s">%6$s</a>',
esc_attr( $args['type'] ),
esc_url( $args['url'] ),
esc_attr( $args['width'] ),
esc_attr( $args['border'] ),
esc_attr( $args['collapsed'] ),
esc_html__( 'View at Medium.com', 'jetpack' )
);
}

/**
* Shortcode support that allows passing in URL
*
* [medium url="https://medium.com/help-center" width="100%" border="false" collapsed="true"]
* @param array $atts Shortcode attributes.
*/
add_shortcode( 'medium', 'jetpack_embed_medium_shortcode' );

function jetpack_embed_medium_shortcode( $atts ) {
$atts = jetpack_embed_medium_args( $atts );

if ( ! empty( $atts['url'] ) ) {
global $wp_embed;
return $wp_embed->shortcode( $atts, $atts['url'] );
} else {
if ( current_user_can( 'edit_posts' ) ) {
return esc_html__( 'You did not provide a valid Medium URL.', 'jetpack' );
} else {
return '<!-- Missing Medium URL -->';
}
}
}
add_shortcode( 'medium', 'jetpack_embed_medium_shortcode' );

/**
* Get embed type (profile, collection, or story) based on Medium URL.
*
* @param string $url Medium URL.
*/
function jetpack_embed_medium_get_embed_type( $url ) {
$url_path = parse_url( $url, PHP_URL_PATH );
$url_path = wp_parse_url( $url, PHP_URL_PATH );
if ( preg_match( '/^\/@[\.\w]+$/', $url_path ) ) {
return 'profile';
} elseif ( preg_match( '/^\/[\da-zA-Z-]+$/', $url_path ) ) {
} elseif ( preg_match( '/^\/(?:s)\/(.+)$/', $url_path ) ) {
return 'collection';
}

return 'story';
}

/**
* Process Medium shortcode attributes.
*
* @param array $atts Shortcode attributes.
*/
function jetpack_embed_medium_args( $atts ) {
return shortcode_atts(
array(
Expand Down
75 changes: 75 additions & 0 deletions tests/php/modules/shortcodes/test-class.medium.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

class WP_Test_Jetpack_Shortcodes_Medium extends WP_UnitTestCase {

/**
* Verify that [medium] exists.
*
* @since 7.4.0
*/
public function test_shortcodes_medium_exists() {
$this->assertEquals( shortcode_exists( 'medium' ), true );
}

/**
* Verify that calling do_shortcode with the shortcode doesn't return the same content.
*
* @since 7.4.0
*/
public function test_shortcodes_medium_empty() {
$content = '[medium]';

$shortcode_content = do_shortcode( $content );

$this->assertNotEquals( $content, $shortcode_content );
$this->assertEquals( '<!-- Missing Medium URL -->', $shortcode_content );
}

/**
* Verify that a post with a link to a Profile page displays profile markup.
*
* @since 7.4.0
*/
public function test_shortcode_medium_faux_embed_profile() {
$profile_url = 'https://medium.com/@jeherve';

$content = apply_filters( 'the_content', $profile_url );

$this->assertContains(
'<a class="m-profile" href="' . $profile_url,
$content
);
}

/**
* Verify that a post with a link to a Medium story displays story markup.
*
* @since 7.4.0
*/
public function test_shortcode_medium_faux_embed_story() {
$story_url = 'https://medium.com/@jeherve/this-is-a-story-19f582daaf5b';

$content = apply_filters( 'the_content', $story_url );

$this->assertContains(
'<a class="m-story" href="' . $story_url,
$content
);
}

/**
* Verify that a post with a link to a Medium collection displays link (collection embeds are not supported anymore).
*
* @since 7.4.0
*/
public function test_shortcode_medium_faux_embed_collection() {
$collection_url = 'https://medium.com/s/user-friendly';

$content = apply_filters( 'the_content', $collection_url );

$this->assertContains(
'<a href="' . $collection_url . '" target="_blank" rel="noopener noreferrer">View this collection on Medium.com</a>',
$content
);
}
}