diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 8f6ec1cef4e26..6d92129e9134e 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -2720,6 +2720,8 @@ function img_caption_shortcode( $attr, $content = '' ) { * @type int $columns Number of columns of images to display. Default 3. * @type string|int[] $size Size of the images to display. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. + * @type int $limit Maximum number of images to display. Values less than 1 display all images. + * Default -1. * @type string $ids A comma-separated list of IDs of attachments to display. Default empty. * @type string $include A comma-separated list of IDs of attachments to include. Default empty. * @type string $exclude A comma-separated list of IDs of attachments to exclude. Default empty. @@ -2774,6 +2776,7 @@ function gallery_shortcode( $attr ) { 'captiontag' => $html5 ? 'figcaption' : 'dd', 'columns' => 3, 'size' => 'thumbnail', + 'limit' => -1, 'include' => '', 'exclude' => '', 'link' => '', @@ -2782,7 +2785,11 @@ function gallery_shortcode( $attr ) { 'gallery' ); - $id = (int) $atts['id']; + $id = (int) $atts['id']; + $limit = (int) $atts['limit']; + if ( $limit < 1 ) { + $limit = -1; + } if ( ! empty( $atts['include'] ) ) { $_attachments = get_posts( @@ -2800,6 +2807,12 @@ function gallery_shortcode( $attr ) { foreach ( $_attachments as $key => $val ) { $attachments[ $val->ID ] = $_attachments[ $key ]; } + + // Limit is applied via array_slice because get_posts() ignores + // the numberposts parameter when include is specified. + if ( $limit > 0 ) { + $attachments = array_slice( $attachments, 0, $limit, true ); + } } elseif ( ! empty( $atts['exclude'] ) ) { $post_parent_id = $id; $attachments = get_children( @@ -2811,6 +2824,7 @@ function gallery_shortcode( $attr ) { 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], + 'numberposts' => $limit, ) ); } else { @@ -2823,6 +2837,7 @@ function gallery_shortcode( $attr ) { 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], + 'numberposts' => $limit, ) ); } @@ -6446,4 +6461,3 @@ function wp_get_image_editor_output_format( $filename, $mime_type ) { */ return apply_filters( 'image_editor_output_format', $output_format, $filename, $mime_type ); } - diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 060a7295f6bb4..9f9728e125be0 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -3808,6 +3808,178 @@ public function test_gallery_shortcode_when_is_feed_true() { $this->assertStringNotContainsString( 'post->create( + array( + 'post_status' => 'publish', + ) + ); + + $attachment_ids = array(); + for ( $i = 0; $i < 5; $i++ ) { + $attachment_ids[] = self::factory()->attachment->create_object( + array( + 'post_parent' => $post_id, + 'post_status' => 'inherit', + 'post_type' => 'attachment', + 'post_mime_type' => 'image/jpeg', + ) + ); + } + + $actual = gallery_shortcode( + array( + 'id' => $post_id, + 'limit' => $limit, + ) + ); + + $count = substr_count( $actual, 'assertSame( $expected_count, $count ); + } + + /** + * @ticket 12799 + */ + public function test_gallery_shortcode_limit_with_ids() { + $attachment_ids = array(); + for ( $i = 0; $i < 5; $i++ ) { + $attachment_ids[] = self::factory()->attachment->create_object( + array( + 'post_status' => 'inherit', + 'post_type' => 'attachment', + 'post_mime_type' => 'image/jpeg', + ) + ); + } + + $actual = gallery_shortcode( + array( + 'ids' => implode( ',', $attachment_ids ), + 'limit' => 2, + ) + ); + + $count = substr_count( $actual, 'assertSame( 2, $count ); + } + + /** + * @ticket 12799 + */ + public function test_gallery_shortcode_limit_with_include() { + $post_id = self::factory()->post->create( + array( + 'post_status' => 'publish', + ) + ); + + $attachment_ids = array(); + for ( $i = 0; $i < 5; $i++ ) { + $attachment_ids[] = self::factory()->attachment->create_object( + array( + 'post_parent' => $post_id, + 'post_status' => 'inherit', + 'post_type' => 'attachment', + 'post_mime_type' => 'image/jpeg', + ) + ); + } + + $actual = gallery_shortcode( + array( + 'id' => $post_id, + 'include' => implode( ',', $attachment_ids ), + 'limit' => 3, + ) + ); + + $count = substr_count( $actual, 'assertSame( 3, $count ); + } + + /** + * @ticket 12799 + */ + public function test_gallery_shortcode_limit_with_exclude() { + $post_id = self::factory()->post->create( + array( + 'post_status' => 'publish', + ) + ); + + $attachment_ids = array(); + for ( $i = 0; $i < 5; $i++ ) { + $attachment_ids[] = self::factory()->attachment->create_object( + array( + 'post_parent' => $post_id, + 'post_status' => 'inherit', + 'post_type' => 'attachment', + 'post_mime_type' => 'image/jpeg', + ) + ); + } + + $actual = gallery_shortcode( + array( + 'id' => $post_id, + 'exclude' => $attachment_ids[0], + 'limit' => 2, + ) + ); + + $count = substr_count( $actual, 'assertSame( 2, $count ); + } + + /** + * @ticket 12799 + */ + public function test_gallery_shortcode_limit_with_orderby_rand() { + $post_id = self::factory()->post->create( + array( + 'post_status' => 'publish', + ) + ); + + for ( $i = 0; $i < 5; $i++ ) { + self::factory()->attachment->create_object( + array( + 'post_parent' => $post_id, + 'post_status' => 'inherit', + 'post_type' => 'attachment', + 'post_mime_type' => 'image/jpeg', + ) + ); + } + + $actual = gallery_shortcode( + array( + 'id' => $post_id, + 'limit' => 2, + 'orderby' => 'rand', + ) + ); + + $count = substr_count( $actual, 'assertSame( 2, $count ); + } + + public static function data_gallery_shortcode_limit() { + return array( + 'default no limit' => array( -1, 5 ), + 'zero means no limit' => array( 0, 5 ), + 'limit of 2' => array( 2, 2 ), + 'limit of 5 same as total' => array( 5, 5 ), + 'limit greater than total' => array( 10, 5 ), + ); + } + /** * Test attachment permalinks based on parent post status. *