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

Issue #864: Support <amp-carousel> in 'Gallery' widget. #917

Merged
merged 5 commits into from Jan 30, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions includes/class-amp-autoloader.php
Expand Up @@ -86,6 +86,7 @@ class AMP_Autoloader {
'AMP_WP_Utils' => 'includes/utils/class-amp-wp-utils',
'AMP_Widget_Archives' => 'includes/widgets/class-amp-widget-archives',
'AMP_Widget_Categories' => 'includes/widgets/class-amp-widget-categories',
'AMP_Widget_Media_Gallery' => 'includes/widgets/class-amp-widget-media-gallery',
'AMP_Widget_Recent_Comments' => 'includes/widgets/class-amp-widget-recent-comments',
'WPCOM_AMP_Polldaddy_Embed' => 'wpcom/class-amp-polldaddy-embed',
'AMP_Test_Stub_Sanitizer' => 'tests/stubs',
Expand Down
109 changes: 75 additions & 34 deletions includes/embeds/class-amp-gallery-embed.php
Expand Up @@ -7,17 +7,31 @@

/**
* Class AMP_Gallery_Embed_Handler
*
* @since 0.2
*/
class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {

/**
* Register embed.
*/
public function register_embed() {
add_shortcode( 'gallery', array( $this, 'shortcode' ) );
}

/**
* Unregister embed.
*/
public function unregister_embed() {
remove_shortcode( 'gallery' );
}

/**
* Shortcode handler.
*
* @param array $attr Shortcode attributes.
* @return string Rendered gallery.
*/
public function shortcode( $attr ) {
$post = get_post();

Expand All @@ -30,46 +44,47 @@ public function shortcode( $attr ) {
}

$atts = shortcode_atts( array(
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post ? $post->ID : 0,
'include' => '',
'exclude' => '',
'size' => array( $this->args['width'], $this->args['height'] ),
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post ? $post->ID : 0,
'include' => '',
'exclude' => '',
'size' => array( $this->args['width'], $this->args['height'] ),
'link' => 'none',
), $attr, 'gallery' );

$id = intval( $atts['id'] );

if ( ! empty( $atts['include'] ) ) {
$attachments = get_posts( array(
'include' => $atts['include'],
'post_status' => 'inherit',
'post_type' => 'attachment',
'include' => $atts['include'],
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => $atts['order'],
'orderby' => $atts['orderby'],
'fields' => 'ids',
'order' => $atts['order'],
'orderby' => $atts['orderby'],
'fields' => 'ids',
) );
} elseif ( ! empty( $atts['exclude'] ) ) {
$attachments = get_children( array(
'post_parent' => $id,
'exclude' => $atts['exclude'],
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_parent' => $id,
'exclude' => $atts['exclude'],
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => $atts['order'],
'orderby' => $atts['orderby'],
'fields' => 'ids',
'order' => $atts['order'],
'orderby' => $atts['orderby'],
'fields' => 'ids',
) );
} else {
$attachments = get_children( array(
'post_parent' => $id,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_parent' => $id,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => $atts['order'],
'orderby' => $atts['orderby'],
'fields' => 'ids',
'order' => $atts['order'],
'orderby' => $atts['orderby'],
'fields' => 'ids',
) );
}

Expand All @@ -85,9 +100,17 @@ public function shortcode( $attr ) {
continue;
}

$href = null;
if ( ! empty( $atts['link'] ) && 'file' === $atts['link'] ) {
$href = $url;
} elseif ( ! empty( $atts['link'] ) && 'post' === $atts['link'] ) {
$href = get_attachment_link( $attachment_id );
}

$urls[] = array(
'url' => $url,
'width' => $width,
'href' => $href,
'url' => $url,
'width' => $width,
'height' => $height,
);
}
Expand All @@ -97,6 +120,12 @@ public function shortcode( $attr ) {
) );
}

/**
* Render.
*
* @param array $args Args.
* @return string Rendered.
*/
public function render( $args ) {
$this->did_convert_elements = true;

Expand All @@ -109,24 +138,36 @@ public function render( $args ) {
}

$images = array();
foreach ( $args['images'] as $image ) {
$images[] = AMP_HTML_Utils::build_tag(
foreach ( $args['images'] as $props ) {
$image = AMP_HTML_Utils::build_tag(
'amp-img',
array(
'src' => $image['url'],
'width' => $image['width'],
'height' => $image['height'],
'src' => $props['url'],
'width' => $props['width'],
'height' => $props['height'],
'layout' => 'responsive',
)
);

if ( ! empty( $props['href'] ) ) {
$image = AMP_HTML_Utils::build_tag(
'a',
array(
'href' => $props['href'],
),
$image
);
}

$images[] = $image;
}

return AMP_HTML_Utils::build_tag(
'amp-carousel',
array(
'width' => $this->args['width'],
'width' => $this->args['width'],
'height' => $this->args['height'],
'type' => 'slides',
'type' => 'slides',
'layout' => 'responsive',
),
implode( PHP_EOL, $images )
Expand Down
67 changes: 67 additions & 0 deletions includes/widgets/class-amp-widget-media-gallery.php
@@ -0,0 +1,67 @@
<?php
/**
* Class AMP_Widget_Media_Gallery
*
* @since 0.7.0
* @package AMP
*/

if ( class_exists( 'WP_Widget_Media_Gallery' ) ) {
/**
* Class AMP_Widget_Media_Gallery
*
* @todo This subclass can eventually be eliminated once #25435 is merged and the WP_Widget_Media_Gallery::render_media() does do_single_shortcode( 'gallery', $instance ).
* @link https://core.trac.wordpress.org/ticket/25435
* @since 0.7.0
* @package AMP
*/
class AMP_Widget_Media_Gallery extends WP_Widget_Media_Gallery {

/**
* Renders the markup of the widget.
*
* Mainly copied from WP_Widget_Media_Gallery::render_media().
* But instead of calling shortcode_gallery(), it calls do_shortcode().
*
* @since 0.7.0
*
* @param array $instance Data for widget.
* @return void
*/
public function render_media( $instance ) {
if ( ! is_amp_endpoint() ) {
parent::render_media( $instance );
return;
}

$instance = array_merge( wp_list_pluck( $this->get_instance_schema(), 'default' ), $instance );
$shortcode_atts = array_merge(
$instance,
array(
'link' => $instance['link_type'],
)
);

if ( isset( $instance['orderby_random'] ) && ( true === $instance['orderby_random'] ) ) {
$shortcode_atts['orderby'] = 'rand';
}

/*
* The following calls do_shortcode() in case another plugin overrides the gallery shortcode.
* The AMP_Gallery_Embed_Handler in the plugin is doing this itself, but other plugins may
* do it as well, so this ensures that a plugin has the option to override the gallery behavior
* via registering a different gallery shortcode handler. The shortcode serialization can be
* eliminated once WP Trac #25435 is merged and the Gallery widget uses the proposed do_single_shortcode().
*/
$shortcode_atts_str = '';
if ( is_array( $shortcode_atts['ids'] ) ) {
$shortcode_atts['ids'] = join( ',', $shortcode_atts['ids'] );
}
foreach ( $shortcode_atts as $key => $value ) {
$shortcode_atts_str .= sprintf( ' %s="%s"', $key, esc_attr( $value ) );
}
echo do_shortcode( "[gallery $shortcode_atts_str]" ); // WPCS: XSS ok.
}

}
}
77 changes: 77 additions & 0 deletions tests/test-class-amp-widget-media-gallery.php
@@ -0,0 +1,77 @@
<?php
/**
* Tests for class AMP_Widget_Media_Gallery.
*
* @package AMP
*/

/**
* Tests for class AMP_Widget_Media_Gallery.
*
* @package AMP
*/
class Test_AMP_Widget_Media_Gallery extends WP_UnitTestCase {

/**
* Instance of the widget.
*
* @var object
*/
public $instance;

/**
* Setup.
*
* @inheritdoc
*/
public function setUp() {
if ( ! class_exists( 'AMP_Widget_Media_Gallery' ) ) {
$this->markTestSkipped( 'This WordPress version does not have a Gallery widget.' );
}
parent::setUp();
AMP_Theme_Support::register_widgets();
$this->instance = new AMP_Widget_Media_Gallery();
}

/**
* Test render_media().
*
* @see AMP_Widget_Media_Gallery::widget().
*/
public function test_render_media() {
$first_test_image = '/tmp/test-image.jpg';
copy( DIR_TESTDATA . '/images/test-image.jpg', $first_test_image );
$first_attachment_id = self::factory()->attachment->create_object( array(
'file' => $first_test_image,
'post_parent' => 0,
'post_mime_type' => 'image/jpeg',
'post_title' => 'Test Image',
) );
wp_update_attachment_metadata( $first_attachment_id, wp_generate_attachment_metadata( $first_attachment_id, $first_test_image ) );
$ids[] = $first_attachment_id;

$second_test_image = '/tmp/test-image.jpg';
copy( DIR_TESTDATA . '/images/test-image.jpg', $second_test_image );
$second_attachment_id = self::factory()->attachment->create_object( array(
'file' => $second_test_image,
'post_parent' => 0,
'post_mime_type' => 'image/jpeg',
'post_title' => 'Test Image',
) );
wp_update_attachment_metadata( $second_attachment_id, wp_generate_attachment_metadata( $second_attachment_id, $second_test_image ) );
$ids[] = $second_attachment_id;
$instance = array(
'title' => 'Test Gallery Widget',
'ids' => $ids,
);

ob_start();
$this->instance->render_media( $instance );
$output = ob_get_clean();

$this->assertContains( 'amp-carousel', $output );
$this->assertContains( $first_test_image, $output );
$this->assertContains( $second_test_image, $output );
}

}