[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/widgets/ -> class-wp-widget-media-image.php (source)

   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                      __( 'That image cannot be found. Check your <a href="%s">media library</a> and make sure it was not 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  }


Generated: Tue Mar 19 01:00:02 2024 Cross-referenced by PHPXref 0.7.1