home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / widgets / class-wp-widget-media-image.php < prev    next >
Encoding:
PHP Script  |  2018-01-21  |  11.0 KB  |  350 lines

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