balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-wp-widget-media-image.php (12037B)


      1 <?php
      2 /**
      3  * Widget API: WP_Widget_Media_Image class
      4  *
      5  * @package WordPress
      6  * @subpackage Widgets
      7  * @since 4.8.0
      8  */
      9 
     10 /**
     11  * Core class that implements an image widget.
     12  *
     13  * @since 4.8.0
     14  *
     15  * @see WP_Widget_Media
     16  * @see WP_Widget
     17  */
     18 class WP_Widget_Media_Image extends WP_Widget_Media {
     19 
     20 	/**
     21 	 * Constructor.
     22 	 *
     23 	 * @since 4.8.0
     24 	 */
     25 	public function __construct() {
     26 		parent::__construct(
     27 			'media_image',
     28 			__( 'Image' ),
     29 			array(
     30 				'description' => __( 'Displays an image.' ),
     31 				'mime_type'   => 'image',
     32 			)
     33 		);
     34 
     35 		$this->l10n = array_merge(
     36 			$this->l10n,
     37 			array(
     38 				'no_media_selected'          => __( 'No image selected' ),
     39 				'add_media'                  => _x( 'Add Image', 'label for button in the image widget' ),
     40 				'replace_media'              => _x( 'Replace Image', 'label for button in the image widget; should preferably not be longer than ~13 characters long' ),
     41 				'edit_media'                 => _x( 'Edit Image', 'label for button in the image widget; should preferably not be longer than ~13 characters long' ),
     42 				'missing_attachment'         => sprintf(
     43 					/* translators: %s: URL to media library. */
     44 					__( 'We can&#8217;t find that image. Check your <a href="%s">media library</a> and make sure it wasn&#8217;t deleted.' ),
     45 					esc_url( admin_url( 'upload.php' ) )
     46 				),
     47 				/* translators: %d: Widget count. */
     48 				'media_library_state_multi'  => _n_noop( 'Image Widget (%d)', 'Image Widget (%d)' ),
     49 				'media_library_state_single' => __( 'Image Widget' ),
     50 			)
     51 		);
     52 	}
     53 
     54 	/**
     55 	 * Get schema for properties of a widget instance (item).
     56 	 *
     57 	 * @since 4.8.0
     58 	 *
     59 	 * @see WP_REST_Controller::get_item_schema()
     60 	 * @see WP_REST_Controller::get_additional_fields()
     61 	 * @link https://core.trac.wordpress.org/ticket/35574
     62 	 *
     63 	 * @return array Schema for properties.
     64 	 */
     65 	public function get_instance_schema() {
     66 		return array_merge(
     67 			array(
     68 				'size'              => array(
     69 					'type'        => 'string',
     70 					'enum'        => array_merge( get_intermediate_image_sizes(), array( 'full', 'custom' ) ),
     71 					'default'     => 'medium',
     72 					'description' => __( 'Size' ),
     73 				),
     74 				'width'             => array( // Via 'customWidth', only when size=custom; otherwise via 'width'.
     75 					'type'        => 'integer',
     76 					'minimum'     => 0,
     77 					'default'     => 0,
     78 					'description' => __( 'Width' ),
     79 				),
     80 				'height'            => array( // Via 'customHeight', only when size=custom; otherwise via 'height'.
     81 					'type'        => 'integer',
     82 					'minimum'     => 0,
     83 					'default'     => 0,
     84 					'description' => __( 'Height' ),
     85 				),
     86 
     87 				'caption'           => array(
     88 					'type'                  => 'string',
     89 					'default'               => '',
     90 					'sanitize_callback'     => 'wp_kses_post',
     91 					'description'           => __( 'Caption' ),
     92 					'should_preview_update' => false,
     93 				),
     94 				'alt'               => array(
     95 					'type'              => 'string',
     96 					'default'           => '',
     97 					'sanitize_callback' => 'sanitize_text_field',
     98 					'description'       => __( 'Alternative Text' ),
     99 				),
    100 				'link_type'         => array(
    101 					'type'                  => 'string',
    102 					'enum'                  => array( 'none', 'file', 'post', 'custom' ),
    103 					'default'               => 'custom',
    104 					'media_prop'            => 'link',
    105 					'description'           => __( 'Link To' ),
    106 					'should_preview_update' => true,
    107 				),
    108 				'link_url'          => array(
    109 					'type'                  => 'string',
    110 					'default'               => '',
    111 					'format'                => 'uri',
    112 					'media_prop'            => 'linkUrl',
    113 					'description'           => __( 'URL' ),
    114 					'should_preview_update' => true,
    115 				),
    116 				'image_classes'     => array(
    117 					'type'                  => 'string',
    118 					'default'               => '',
    119 					'sanitize_callback'     => array( $this, 'sanitize_token_list' ),
    120 					'media_prop'            => 'extraClasses',
    121 					'description'           => __( 'Image CSS Class' ),
    122 					'should_preview_update' => false,
    123 				),
    124 				'link_classes'      => array(
    125 					'type'                  => 'string',
    126 					'default'               => '',
    127 					'sanitize_callback'     => array( $this, 'sanitize_token_list' ),
    128 					'media_prop'            => 'linkClassName',
    129 					'should_preview_update' => false,
    130 					'description'           => __( 'Link CSS Class' ),
    131 				),
    132 				'link_rel'          => array(
    133 					'type'                  => 'string',
    134 					'default'               => '',
    135 					'sanitize_callback'     => array( $this, 'sanitize_token_list' ),
    136 					'media_prop'            => 'linkRel',
    137 					'description'           => __( 'Link Rel' ),
    138 					'should_preview_update' => false,
    139 				),
    140 				'link_target_blank' => array(
    141 					'type'                  => 'boolean',
    142 					'default'               => false,
    143 					'media_prop'            => 'linkTargetBlank',
    144 					'description'           => __( 'Open link in a new tab' ),
    145 					'should_preview_update' => false,
    146 				),
    147 				'image_title'       => array(
    148 					'type'                  => 'string',
    149 					'default'               => '',
    150 					'sanitize_callback'     => 'sanitize_text_field',
    151 					'media_prop'            => 'title',
    152 					'description'           => __( 'Image Title Attribute' ),
    153 					'should_preview_update' => false,
    154 				),
    155 
    156 				/*
    157 				 * There are two additional properties exposed by the PostImage modal
    158 				 * that don't seem to be relevant, as they may only be derived read-only
    159 				 * values:
    160 				 * - originalUrl
    161 				 * - aspectRatio
    162 				 * - height (redundant when size is not custom)
    163 				 * - width (redundant when size is not custom)
    164 				 */
    165 			),
    166 			parent::get_instance_schema()
    167 		);
    168 	}
    169 
    170 	/**
    171 	 * Render the media on the frontend.
    172 	 *
    173 	 * @since 4.8.0
    174 	 *
    175 	 * @param array $instance Widget instance props.
    176 	 */
    177 	public function render_media( $instance ) {
    178 		$instance = array_merge( wp_list_pluck( $this->get_instance_schema(), 'default' ), $instance );
    179 		$instance = wp_parse_args(
    180 			$instance,
    181 			array(
    182 				'size' => 'thumbnail',
    183 			)
    184 		);
    185 
    186 		$attachment = null;
    187 
    188 		if ( $this->is_attachment_with_mime_type( $instance['attachment_id'], $this->widget_options['mime_type'] ) ) {
    189 			$attachment = get_post( $instance['attachment_id'] );
    190 		}
    191 
    192 		if ( $attachment ) {
    193 			$caption = '';
    194 			if ( ! isset( $instance['caption'] ) ) {
    195 				$caption = $attachment->post_excerpt;
    196 			} elseif ( trim( $instance['caption'] ) ) {
    197 				$caption = $instance['caption'];
    198 			}
    199 
    200 			$image_attributes = array(
    201 				'class' => sprintf( 'image wp-image-%d %s', $attachment->ID, $instance['image_classes'] ),
    202 				'style' => 'max-width: 100%; height: auto;',
    203 			);
    204 			if ( ! empty( $instance['image_title'] ) ) {
    205 				$image_attributes['title'] = $instance['image_title'];
    206 			}
    207 
    208 			if ( $instance['alt'] ) {
    209 				$image_attributes['alt'] = $instance['alt'];
    210 			}
    211 
    212 			$size = $instance['size'];
    213 
    214 			if ( 'custom' === $size || ! in_array( $size, array_merge( get_intermediate_image_sizes(), array( 'full' ) ), true ) ) {
    215 				$size  = array( $instance['width'], $instance['height'] );
    216 				$width = $instance['width'];
    217 			} else {
    218 				$caption_size = _wp_get_image_size_from_meta( $instance['size'], wp_get_attachment_metadata( $attachment->ID ) );
    219 				$width        = empty( $caption_size[0] ) ? 0 : $caption_size[0];
    220 			}
    221 
    222 			$image_attributes['class'] .= sprintf( ' attachment-%1$s size-%1$s', is_array( $size ) ? implode( 'x', $size ) : $size );
    223 
    224 			$image = wp_get_attachment_image( $attachment->ID, $size, false, $image_attributes );
    225 
    226 		} else {
    227 			if ( empty( $instance['url'] ) ) {
    228 				return;
    229 			}
    230 
    231 			$instance['size'] = 'custom';
    232 			$caption          = $instance['caption'];
    233 			$width            = $instance['width'];
    234 			$classes          = 'image ' . $instance['image_classes'];
    235 			if ( 0 === $instance['width'] ) {
    236 				$instance['width'] = '';
    237 			}
    238 			if ( 0 === $instance['height'] ) {
    239 				$instance['height'] = '';
    240 			}
    241 
    242 			$image = sprintf(
    243 				'<img class="%1$s" src="%2$s" alt="%3$s" width="%4$s" height="%5$s" />',
    244 				esc_attr( $classes ),
    245 				esc_url( $instance['url'] ),
    246 				esc_attr( $instance['alt'] ),
    247 				esc_attr( $instance['width'] ),
    248 				esc_attr( $instance['height'] )
    249 			);
    250 		} // End if().
    251 
    252 		$url = '';
    253 		if ( 'file' === $instance['link_type'] ) {
    254 			$url = $attachment ? wp_get_attachment_url( $attachment->ID ) : $instance['url'];
    255 		} elseif ( $attachment && 'post' === $instance['link_type'] ) {
    256 			$url = get_attachment_link( $attachment->ID );
    257 		} elseif ( 'custom' === $instance['link_type'] && ! empty( $instance['link_url'] ) ) {
    258 			$url = $instance['link_url'];
    259 		}
    260 
    261 		if ( $url ) {
    262 			$link = sprintf( '<a href="%s"', esc_url( $url ) );
    263 			if ( ! empty( $instance['link_classes'] ) ) {
    264 				$link .= sprintf( ' class="%s"', esc_attr( $instance['link_classes'] ) );
    265 			}
    266 			if ( ! empty( $instance['link_rel'] ) ) {
    267 				$link .= sprintf( ' rel="%s"', esc_attr( $instance['link_rel'] ) );
    268 			}
    269 			if ( ! empty( $instance['link_target_blank'] ) ) {
    270 				$link .= ' target="_blank"';
    271 			}
    272 			$link .= '>';
    273 			$link .= $image;
    274 			$link .= '</a>';
    275 			$image = wp_targeted_link_rel( $link );
    276 		}
    277 
    278 		if ( $caption ) {
    279 			$image = img_caption_shortcode(
    280 				array(
    281 					'width'   => $width,
    282 					'caption' => $caption,
    283 				),
    284 				$image
    285 			);
    286 		}
    287 
    288 		echo $image;
    289 	}
    290 
    291 	/**
    292 	 * Loads the required media files for the media manager and scripts for media widgets.
    293 	 *
    294 	 * @since 4.8.0
    295 	 */
    296 	public function enqueue_admin_scripts() {
    297 		parent::enqueue_admin_scripts();
    298 
    299 		$handle = 'media-image-widget';
    300 		wp_enqueue_script( $handle );
    301 
    302 		$exported_schema = array();
    303 		foreach ( $this->get_instance_schema() as $field => $field_schema ) {
    304 			$exported_schema[ $field ] = wp_array_slice_assoc( $field_schema, array( 'type', 'default', 'enum', 'minimum', 'format', 'media_prop', 'should_preview_update' ) );
    305 		}
    306 		wp_add_inline_script(
    307 			$handle,
    308 			sprintf(
    309 				'wp.mediaWidgets.modelConstructors[ %s ].prototype.schema = %s;',
    310 				wp_json_encode( $this->id_base ),
    311 				wp_json_encode( $exported_schema )
    312 			)
    313 		);
    314 
    315 		wp_add_inline_script(
    316 			$handle,
    317 			sprintf(
    318 				'
    319 					wp.mediaWidgets.controlConstructors[ %1$s ].prototype.mime_type = %2$s;
    320 					wp.mediaWidgets.controlConstructors[ %1$s ].prototype.l10n = _.extend( {}, wp.mediaWidgets.controlConstructors[ %1$s ].prototype.l10n, %3$s );
    321 				',
    322 				wp_json_encode( $this->id_base ),
    323 				wp_json_encode( $this->widget_options['mime_type'] ),
    324 				wp_json_encode( $this->l10n )
    325 			)
    326 		);
    327 	}
    328 
    329 	/**
    330 	 * Render form template scripts.
    331 	 *
    332 	 * @since 4.8.0
    333 	 */
    334 	public function render_control_template_scripts() {
    335 		parent::render_control_template_scripts();
    336 
    337 		?>
    338 		<script type="text/html" id="tmpl-wp-media-widget-image-fields">
    339 			<# var elementIdPrefix = 'el' + String( Math.random() ) + '_'; #>
    340 			<# if ( data.url ) { #>
    341 			<p class="media-widget-image-link">
    342 				<label for="{{ elementIdPrefix }}linkUrl"><?php esc_html_e( 'Link to:' ); ?></label>
    343 				<input id="{{ elementIdPrefix }}linkUrl" type="text" class="widefat link" value="{{ data.link_url }}" placeholder="https://" pattern="((\w+:)?\/\/\w.*|\w+:(?!\/\/$)|\/|\?|#).*">
    344 			</p>
    345 			<# } #>
    346 		</script>
    347 		<script type="text/html" id="tmpl-wp-media-widget-image-preview">
    348 			<# if ( data.error && 'missing_attachment' === data.error ) { #>
    349 				<div class="notice notice-error notice-alt notice-missing-attachment">
    350 					<p><?php echo $this->l10n['missing_attachment']; ?></p>
    351 				</div>
    352 			<# } else if ( data.error ) { #>
    353 				<div class="notice notice-error notice-alt">
    354 					<p><?php _e( 'Unable to preview media due to an unknown error.' ); ?></p>
    355 				</div>
    356 			<# } else if ( data.url ) { #>
    357 				<img class="attachment-thumb" src="{{ data.url }}" draggable="false" alt="{{ data.alt }}"
    358 					<# if ( ! data.alt && data.currentFilename ) { #>
    359 						aria-label="
    360 						<?php
    361 						echo esc_attr(
    362 							sprintf(
    363 								/* translators: %s: The image file name. */
    364 								__( 'The current image has no alternative text. The file name is: %s' ),
    365 								'{{ data.currentFilename }}'
    366 							)
    367 						);
    368 						?>
    369 						"
    370 					<# } #>
    371 				/>
    372 			<# } #>
    373 		</script>
    374 		<?php
    375 	}
    376 }