From d204ba3c00828fb0b699121da9c0a4a4bc9e6db5 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 19 Oct 2017 23:43:22 +0000 Subject: [PATCH] Widgets: Improve extensibility of the Gallery widget and of media widgets generally. * Introduce a `widget_{$id_base}_instance_schema` filter for plugins to add new properties to a media widget's instance schema. * Pass all of a gallery widget's instance props to the gallery media frame, not just the ones that core supports. See #32417, #41914. Fixes #42285. git-svn-id: https://develop.svn.wordpress.org/trunk@41951 602fd350-edb4-49c9-b593-d223f7449a82 --- .../js/widgets/media-gallery-widget.js | 2 +- .../widgets/class-wp-widget-media-gallery.php | 17 ++++++---- .../widgets/class-wp-widget-media.php | 14 +++++++- tests/phpunit/tests/widgets/media-widget.php | 32 +++++++++++++++++++ 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/wp-admin/js/widgets/media-gallery-widget.js b/src/wp-admin/js/widgets/media-gallery-widget.js index 7d0d191c20..ebba81cf86 100644 --- a/src/wp-admin/js/widgets/media-gallery-widget.js +++ b/src/wp-admin/js/widgets/media-gallery-widget.js @@ -201,7 +201,7 @@ }); mediaFrameProps = control.mapModelToMediaFrameProps( control.model.toJSON() ); - selection.gallery = new Backbone.Model( _.pick( mediaFrameProps, 'columns', 'link', 'size', '_orderbyRandom' ) ); + selection.gallery = new Backbone.Model( mediaFrameProps ); if ( mediaFrameProps.size ) { control.displaySettings.set( 'size', mediaFrameProps.size ); } diff --git a/src/wp-includes/widgets/class-wp-widget-media-gallery.php b/src/wp-includes/widgets/class-wp-widget-media-gallery.php index 3ac9cc910c..13ee9c2d6e 100644 --- a/src/wp-includes/widgets/class-wp-widget-media-gallery.php +++ b/src/wp-includes/widgets/class-wp-widget-media-gallery.php @@ -46,7 +46,7 @@ class WP_Widget_Media_Gallery extends WP_Widget_Media { * @return array Schema for properties. */ public function get_instance_schema() { - return array( + $schema = array( 'title' => array( 'type' => 'string', 'default' => '', @@ -87,6 +87,11 @@ class WP_Widget_Media_Gallery extends WP_Widget_Media { 'should_preview_update' => false, ), ); + + /** This filter is documented in wp-includes/widgets/class-wp-widget-media.php */ + $schema = apply_filters( "widget_{$this->id_base}_instance_schema", $schema, $this ); + + return $schema; } /** @@ -100,11 +105,11 @@ class WP_Widget_Media_Gallery extends WP_Widget_Media { public function render_media( $instance ) { $instance = array_merge( wp_list_pluck( $this->get_instance_schema(), 'default' ), $instance ); - $shortcode_atts = array( - 'ids' => $instance['ids'], - 'columns' => $instance['columns'], - 'link' => $instance['link_type'], - 'size' => $instance['size'], + $shortcode_atts = array_merge( + $instance, + array( + 'link' => $instance['link_type'], + ) ); // @codeCoverageIgnoreStart diff --git a/src/wp-includes/widgets/class-wp-widget-media.php b/src/wp-includes/widgets/class-wp-widget-media.php index 4d190da360..ec412d25f7 100644 --- a/src/wp-includes/widgets/class-wp-widget-media.php +++ b/src/wp-includes/widgets/class-wp-widget-media.php @@ -127,7 +127,7 @@ abstract class WP_Widget_Media extends WP_Widget { * @return array Schema for properties. */ public function get_instance_schema() { - return array( + $schema = array( 'attachment_id' => array( 'type' => 'integer', 'default' => 0, @@ -149,6 +149,18 @@ abstract class WP_Widget_Media extends WP_Widget { 'should_preview_update' => false, ), ); + + /** + * Filters the media widget instance schema to add additional properties. + * + * @since 4.9.0 + * + * @param array $schema Instance schema. + * @param WP_Widget_Media $this Widget object. + */ + $schema = apply_filters( "widget_{$this->id_base}_instance_schema", $schema, $this ); + + return $schema; } /** diff --git a/tests/phpunit/tests/widgets/media-widget.php b/tests/phpunit/tests/widgets/media-widget.php index 6620101a2f..f30d56e6f3 100644 --- a/tests/phpunit/tests/widgets/media-widget.php +++ b/tests/phpunit/tests/widgets/media-widget.php @@ -164,6 +164,29 @@ class Test_WP_Widget_Media extends WP_UnitTestCase { $this->assertEquals( $result, 'foo ibar NO' ); } + /** + * Instance schema args. + * + * @var array + */ + protected $filter_instance_schema_args; + + /** + * Filter instance schema. + * + * @param array $schema Schema. + * @param WP_Widget_Media $widget Widget. + * + * @return array + */ + public function filter_instance_schema( $schema, $widget ) { + $this->filter_instance_schema_args = compact( 'schema', 'widget' ); + $schema['injected'] = array( + 'type' => 'boolean', + ); + return $schema; + } + /** * Test get_instance_schema method. * @@ -178,6 +201,15 @@ class Test_WP_Widget_Media extends WP_UnitTestCase { 'title', 'url', ), array_keys( $schema ) ); + + // Check filter usage. + $this->filter_instance_schema_args = null; + add_filter( 'widget_mocked_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 ); + $schema = $widget->get_instance_schema(); + $this->assertInternalType( 'array', $this->filter_instance_schema_args ); + $this->assertSame( $widget, $this->filter_instance_schema_args['widget'] ); + $this->assertEqualSets( array( 'attachment_id', 'title', 'url' ), array_keys( $this->filter_instance_schema_args['schema'] ) ); + $this->assertArrayHasKey( 'injected', $schema ); } /**