PluginProbe ʕ •ᴥ•ʔ
Image Widget / 4.4.7
Image Widget v4.4.7
trunk 1.0 2.0 2.1 2.2 2.2.1 2.2.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.2 3.2.1 3.2.10 3.2.11 3.2.2 3.2.3 3.2.4 3.2.5 3.2.7 3.2.8 3.2.9 3.3 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1 4.1.1 4.1.2 4.2 4.2.1 4.2.2 4.3 4.3.1 4.4 4.4.1 4.4.11 4.4.12 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9
image-widget / image-widget.php
image-widget Last commit date
lang 8 years ago lib 8 years ago resources 8 years ago views 8 years ago .gitignore 8 years ago image-widget.php 5 years ago index.php 8 years ago readme.txt 5 years ago
image-widget.php
618 lines
1 <?php
2 /*
3 Plugin Name: Image Widget
4 Plugin URI: https://wordpress.org/plugins/image-widget/
5 Description: A simple image widget that uses the native WordPress media manager to add image widgets to your site. <strong><a href="https://evnt.is/19my">Image Widget Plus</a> - Multiple images, slider and more.</strong>
6 Author: The Events Calendar
7 Version: 4.4.7
8 Author URI: https://evnt.is/1aor
9 Text Domain: image-widget
10 Domain Path: /lang
11 */
12
13 // Block direct requests
14 if ( ! defined( 'ABSPATH' ) ) {
15 die( '-1' );
16 }
17
18 // Load the widget on widgets_init
19 function tribe_load_image_widget() {
20 register_widget( 'Tribe_Image_Widget' );
21 }
22 add_action( 'widgets_init', 'tribe_load_image_widget' );
23
24 class Tribe_Image_Widget extends WP_Widget {
25
26 const VERSION = '4.4.7';
27
28 const CUSTOM_IMAGE_SIZE_SLUG = 'tribe_image_widget_custom';
29
30 const VERSION_KEY = '_image_widget_version';
31
32 /**
33 * Tribe Image Widget constructor
34 */
35 public function __construct() {
36 load_plugin_textdomain( 'image-widget', false, trailingslashit( basename( dirname( __FILE__ ) ) ) . 'lang/' );
37
38 $widget_ops = array( 'classname' => 'widget_sp_image', 'description' => __( 'Showcase a single image with a Title, URL, and a Description', 'image-widget' ) );
39 $control_ops = array( 'id_base' => 'widget_sp_image' );
40
41 parent::__construct( 'widget_sp_image', __( 'Image Widget', 'image-widget' ), $widget_ops, $control_ops );
42
43 if ( $this->use_old_uploader() ) {
44 require_once( 'lib/ImageWidgetDeprecated.php' );
45 new ImageWidgetDeprecated( $this );
46 } else {
47 add_action( 'sidebar_admin_setup', array( $this, 'admin_setup' ) );
48 }
49
50 // fire admin_setup if we are in the customizer
51 add_action( 'admin_enqueue_scripts', array( $this, 'maybe_admin_setup' ) );
52
53 add_action( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
54
55 if ( ! defined( 'I_HAVE_SUPPORTED_THE_IMAGE_WIDGET' ) )
56 add_action( 'admin_notices', array( $this, 'post_upgrade_nag' ) );
57
58 add_action( 'network_admin_notices', array( $this, 'post_upgrade_nag' ) );
59 add_action( 'wp_ajax_dismissed_image_widget_notice_handler', array( $this, 'ajax_notice_handler' ) );
60 }
61
62 /**
63 * Test to see if this version of WordPress supports the new image manager.
64 *
65 * @return bool True if the current version of WordPress does NOT support the current image management tech.
66 */
67 private function use_old_uploader() {
68 if ( defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) ) {
69 return true;
70 }
71
72 return ! function_exists( 'wp_enqueue_media' );
73 }
74
75 /**
76 * Enqueue all the javascript and CSS.
77 */
78 public function admin_setup() {
79 wp_enqueue_media();
80
81 wp_enqueue_style( 'tribe-image-widget', plugins_url( 'resources/css/admin.css', __FILE__ ), array(), self::VERSION );
82 wp_enqueue_script( 'tribe-image-widget', plugins_url( 'resources/js/image-widget.js', __FILE__ ), array( 'jquery', 'media-upload', 'media-views' ), self::VERSION );
83
84 wp_localize_script( 'tribe-image-widget', 'TribeImageWidget', array(
85 'frame_title' => __( 'Select an Image', 'image-widget' ),
86 'button_title' => __( 'Insert Into Widget', 'image-widget' ),
87 ) );
88 }
89
90 /**
91 * Trigger the enqueueing of admin scripts and styles on widget admin page and in the "Customizer" view.
92 */
93 public function maybe_admin_setup() {
94 $screen = get_current_screen();
95
96 if ( 'customize' !== $screen->base ) {
97 return;
98 }
99
100 $this->admin_setup();
101 }
102
103 /**
104 * Widget frontend output
105 *
106 * @param array $args
107 * @param array $instance
108 */
109 public function widget( $args, $instance ) {
110 extract( $args );
111
112 $instance = wp_parse_args( (array) $instance, self::get_defaults() );
113
114 if ( ! empty( $instance['imageurl'] ) || ! empty( $instance['attachment_id'] ) ) {
115
116 $instance['title'] = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'] );
117 $instance['description'] = apply_filters( 'widget_text', $instance['description'], $args, $instance );
118 $instance['link'] = apply_filters( 'image_widget_image_link', esc_url( $instance['link'] ), $args, $instance );
119 $instance['linkid'] = apply_filters( 'image_widget_image_link_id', esc_attr( $instance['linkid'] ), $args, $instance );
120 $instance['linktitle'] = apply_filters( 'image_widget_image_link_title', esc_attr( $instance['linktitle'] ), $args, $instance );
121 $instance['linktarget'] = apply_filters( 'image_widget_image_link_target', esc_attr( $instance['linktarget'] ), $args, $instance );
122 $instance['width'] = apply_filters( 'image_widget_image_width', abs( $instance['width'] ), $args, $instance );
123 $instance['height'] = apply_filters( 'image_widget_image_height', abs( $instance['height'] ), $args, $instance );
124 $instance['maxwidth'] = apply_filters( 'image_widget_image_maxwidth', esc_attr( $instance['maxwidth'] ), $args, $instance );
125 $instance['maxheight'] = apply_filters( 'image_widget_image_maxheight', esc_attr( $instance['maxheight'] ), $args, $instance );
126 $instance['align'] = apply_filters( 'image_widget_image_align', esc_attr( $instance['align'] ), $args, $instance );
127 $instance['alt'] = apply_filters( 'image_widget_image_alt', esc_attr( $instance['alt'] ), $args, $instance );
128 $instance['rel'] = apply_filters( 'image_widget_image_rel', esc_attr( $instance['rel'] ), $args, $instance );
129
130 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) ) {
131 $instance['attachment_id'] = ( $instance['attachment_id'] > 0 ) ? $instance['attachment_id'] : $instance['image'];
132 $instance['attachment_id'] = apply_filters( 'image_widget_image_attachment_id', abs( $instance['attachment_id'] ), $args, $instance );
133 $instance['size'] = apply_filters( 'image_widget_image_size', esc_attr( $instance['size'] ), $args, $instance );
134 }
135
136 $instance['imageurl'] = apply_filters( 'image_widget_image_url', esc_url( $instance['imageurl'] ), $args, $instance );
137
138 // No longer using extracted vars. This is here for backwards compatibility.
139 extract( $instance );
140
141 include( $this->getTemplateHierarchy( 'widget' ) );
142 }
143 }
144
145 /**
146 * Update widget options
147 *
148 * @param object $new_instance Widget Instance
149 * @param object $old_instance Widget Instance
150 * @return object
151 */
152 public function update( $new_instance, $old_instance ) {
153
154 $instance = $old_instance;
155 $new_instance = wp_parse_args( (array) $new_instance, self::get_defaults() );
156
157 $instance['title'] = strip_tags( $new_instance['title'] );
158
159 if ( current_user_can( 'unfiltered_html' ) ) {
160 $instance['description'] = $new_instance['description'];
161 } else {
162 $instance['description'] = wp_kses_post( $new_instance['description'] );
163 }
164
165 /**
166 * Make the description filterable; especially useful for working with allowing/disallowing HTML and other content.
167 *
168 * @since 4.4.6
169 *
170 * @param $description The current value of $instance['description'].
171 * @param $new_instance The new instance of the widget, i.e. the new values being saved for it.
172 * @param $old_instance The pre-existing instance of the widget, i.e. the values that are potentially being updated.
173 */
174 $instance['description'] = apply_filters( 'tribe_image_widget_instance_description', $instance['description'], $new_instance, $old_instance );
175
176 $instance['link'] = $new_instance['link'];
177 $instance['linktitle'] = $new_instance['linktitle'];
178 $instance['linkid'] = $new_instance['linkid'];
179 $instance['linktarget'] = $new_instance['linktarget'];
180 $instance['width'] = abs( $new_instance['width'] );
181 $instance['height'] = abs( $new_instance['height'] );
182
183 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) ) {
184 $instance['size'] = $new_instance['size'];
185 }
186
187 $instance['align'] = $new_instance['align'];
188 $instance['alt'] = $new_instance['alt'];
189 $instance['rel'] = $new_instance['rel'];
190
191 // Reverse compatibility with $image, now called $attachement_id
192 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) && $new_instance['attachment_id'] > 0 ) {
193 $instance['attachment_id'] = abs( $new_instance['attachment_id'] );
194 } elseif ( $new_instance['image'] > 0 ) {
195 $instance['attachment_id'] = $instance['image'] = abs( $new_instance['image'] );
196 if ( class_exists( 'ImageWidgetDeprecated' ) ) {
197 $instance['imageurl'] = ImageWidgetDeprecated::get_image_url( $instance['image'], $instance['width'], $instance['height'] ); // image resizing not working right now
198 }
199 }
200
201 $instance['imageurl'] = $new_instance['imageurl']; // deprecated
202 $instance['aspect_ratio'] = $this->get_image_aspect_ratio( $instance );
203
204 return $instance;
205 }
206
207 /**
208 * Form UI
209 *
210 * @param object $instance Widget Instance
211 */
212 public function form( $instance ) {
213 $instance = wp_parse_args( (array) $instance, self::get_defaults() );
214 if ( $this->use_old_uploader() ) {
215 include( $this->getTemplateHierarchy( 'widget-admin.deprecated' ) );
216 } else {
217 include( $this->getTemplateHierarchy( 'widget-admin' ) );
218 }
219 }
220
221 /**
222 * Render an array of default values.
223 *
224 * @return array default values
225 */
226 private static function get_defaults() {
227
228 $defaults = array(
229 'title' => '',
230 'description' => '',
231 'link' => '',
232 'linkid' => '',
233 'linktitle' => '',
234 'linktarget' => '',
235 'width' => 0,
236 'height' => 0,
237 'maxwidth' => '100%',
238 'maxheight' => '',
239 'image' => 0, // reverse compatible - now attachement_id
240 'imageurl' => '', // reverse compatible.
241 'align' => 'none',
242 'alt' => '',
243 'rel' => '',
244 );
245
246 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) ) {
247 $defaults['size'] = self::CUSTOM_IMAGE_SIZE_SLUG;
248 $defaults['attachment_id'] = 0;
249 }
250 /**
251 * Allow users to customize the default values of various Image Widget options.
252 *
253 * @since 4.4.7
254 *
255 * @param array $defaults The array of default option values.
256 */
257 return apply_filters( 'image_widget_option_defaults', $defaults );
258 }
259
260 /**
261 * Render the image html output.
262 *
263 * @param array $instance
264 * @param bool $include_link will only render the link if this is set to true. Otherwise link is ignored.
265 * @return string image html
266 */
267 private function get_image_html( $instance, $include_link = true ) {
268
269 // Backwards compatible image display.
270 if ( $instance['attachment_id'] == 0 && $instance['image'] > 0 ) {
271 $instance['attachment_id'] = $instance['image'];
272 }
273
274 $output = '';
275
276 if ( $include_link && ! empty( $instance['link'] ) ) {
277
278 $attr = array(
279 'href' => $instance['link'],
280 'id' => $instance['linkid'],
281 'target' => $instance['linktarget'],
282 'class' => $this->widget_options['classname'] . '-image-link',
283 'title' => ( ! empty( $instance['linktitle'] ) ) ? $instance['linktitle'] : $instance['title'],
284 'rel' => $instance['rel'],
285 );
286
287 $attr = apply_filters( 'image_widget_link_attributes', $attr, $instance );
288 $attr = array_map( 'esc_attr', $attr );
289
290 $output = '<a';
291
292 foreach ( $attr as $name => $value ) {
293 if ( ! empty( $value ) ) {
294 $output .= sprintf( ' %s="%s"', $name, $value );
295 }
296 }
297 $output .= '>';
298 }
299
300 $size = $this->get_image_size( $instance );
301
302 if ( is_array( $size ) ) {
303 $instance['width'] = $size[0];
304 $instance['height'] = $size[1];
305 } elseif ( ! empty( $instance['attachment_id'] ) ) {
306 //$instance['width'] = $instance['height'] = 0;
307 $image_details = wp_get_attachment_image_src( $instance['attachment_id'], $size );
308 if ( $image_details ) {
309 $instance['imageurl'] = $image_details[0];
310 $instance['width'] = $image_details[1];
311 $instance['height'] = $image_details[2];
312 }
313
314 $image_srcset = function_exists( 'wp_get_attachment_image_srcset' )
315 ? wp_get_attachment_image_srcset( $instance['attachment_id'], $size )
316 : false;
317 if ( $image_srcset ) {
318 $instance['srcset'] = $image_srcset;
319
320 $image_sizes = function_exists( 'wp_get_attachment_image_sizes' )
321 ? wp_get_attachment_image_sizes( $instance['attachment_id'], $size )
322 : false;
323 if ( $image_sizes ) {
324 $instance['sizes'] = $image_sizes;
325 }
326 }
327 }
328
329 $instance['width'] = abs( $instance['width'] );
330 $instance['height'] = abs( $instance['height'] );
331
332 $attr = array();
333
334 if ( ! empty( $instance['alt'] ) ) {
335 $attr['alt'] = $instance['alt'];
336 } elseif ( ! empty( $instance['title'] ) ) {
337 $attr['alt'] = $instance['title'];
338 }
339
340 if ( is_array( $size ) ) {
341 $attr['class'] = 'attachment-' . join( 'x', $size );
342 } else {
343 $attr['class'] = 'attachment-' . $size;
344 }
345
346 $attr['style'] = '';
347 if ( ! empty( $instance['maxwidth'] ) ) {
348 $attr['style'] .= "max-width: {$instance['maxwidth']};";
349 }
350
351 if ( ! empty( $instance['maxheight'] ) ) {
352 $attr['style'] .= "max-height: {$instance['maxheight']};";
353 }
354
355 if ( ! empty( $instance['align'] ) && $instance['align'] != 'none' ) {
356 $attr['class'] .= " align{$instance['align']}";
357 }
358
359 if ( ! empty( $instance['srcset'] ) ) {
360 $attr['srcset'] = $instance['srcset'];
361 }
362
363 if ( ! empty( $instance['sizes'] ) ) {
364 $attr['sizes'] = $instance['sizes'];
365 }
366
367 /**
368 * Allow filtering of the image attributes used on the front-end.
369 *
370 * @param array $attr Image attributes to be filtered.
371 * @param array $instance The current widget instance.
372 */
373 $attr = apply_filters( 'image_widget_image_attributes', $attr, $instance );
374
375 // If there is an imageurl, use it to render the image. Eventually we should kill this and simply rely on attachment_ids.
376 if ( ! empty( $instance['imageurl'] ) ) {
377 // If all we have is an image src url we can still render an image.
378 $attr['src'] = $instance['imageurl'];
379 $attr = array_map( 'esc_attr', $attr );
380 $hwstring = image_hwstring( $instance['width'], $instance['height'] );
381
382 $output .= rtrim( "<img $hwstring" );
383
384 foreach ( $attr as $name => $value ) {
385 $output .= sprintf( ' %s="%s"', $name, $value );
386 }
387
388 $output .= ' />';
389
390 } elseif ( abs( $instance['attachment_id'] ) > 0 ) {
391 $output .= wp_get_attachment_image( $instance['attachment_id'], $size, false, $attr );
392 }
393
394 if ( $include_link && ! empty( $instance['link'] ) ) {
395 $output .= '</a>';
396 }
397
398 return $output;
399 }
400
401 /**
402 * Get all possible image sizes to choose from
403 *
404 * @return array
405 */
406 private function possible_image_sizes() {
407 $registered = get_intermediate_image_sizes();
408 // label other sizes with their image size "ID"
409 $registered = array_combine( $registered, $registered );
410
411 $possible_sizes = array_merge( $registered, array(
412 'full' => __( 'Full Size', 'image-widget' ),
413 'thumbnail' => __( 'Thumbnail', 'image-widget' ),
414 'medium' => __( 'Medium', 'image-widget' ),
415 'large' => __( 'Large', 'image-widget' ),
416 self::CUSTOM_IMAGE_SIZE_SLUG => __( 'Custom', 'image-widget' ),
417 ) );
418
419 /**
420 * Allow filtering the image sizes available for use in the Image Widget dropdown
421 *
422 * @param array $possible_sizes The array of available sizes.
423 */
424 return (array) apply_filters( 'image_size_names_choose', $possible_sizes );
425 }
426
427 /**
428 * Assesses the image size in case it has not been set or in case there is a mismatch.
429 *
430 * @param $instance
431 * @return array|string
432 */
433 private function get_image_size( $instance ) {
434 if ( ! empty( $instance['size'] ) && $instance['size'] != self::CUSTOM_IMAGE_SIZE_SLUG ) {
435 $size = $instance['size'];
436 } elseif ( isset( $instance['width'] ) && is_numeric( $instance['width'] ) && isset( $instance['height'] ) && is_numeric( $instance['height'] ) ) {
437 //$size = array(abs($instance['width']),abs($instance['height']));
438 $size = array( $instance['width'], $instance['height'] );
439 } else {
440 $size = 'full';
441 }
442
443 return $size;
444 }
445
446 /**
447 * Establish the aspect ratio of the image.
448 *
449 * @param $instance
450 * @return float|number
451 */
452 private function get_image_aspect_ratio( $instance ) {
453 if ( ! empty( $instance['aspect_ratio'] ) ) {
454 return abs( $instance['aspect_ratio'] );
455 } else {
456 $attachment_id = ( ! empty( $instance['attachment_id'] ) ) ? $instance['attachment_id'] : $instance['image'];
457 if ( ! empty( $attachment_id ) ) {
458 $image_details = wp_get_attachment_image_src( $attachment_id, 'full' );
459 if ( $image_details ) {
460 return ( $image_details[1] / $image_details[2] );
461 }
462 }
463 }
464 }
465
466 /**
467 * Loads theme files in appropriate hierarchy: 1) child theme,
468 * 2) parent template, 3) plugin resources. will look in the image-widget/
469 * directory in a theme and the views/ directory in the plugin
470 *
471 * @param string $template template file to search for
472 * @return template path
473 */
474
475 public function getTemplateHierarchy( $template ) {
476 // whether or not .php was added
477 $template_slug = rtrim( $template, '.php' );
478 $template = $template_slug . '.php';
479
480 if ( $theme_file = locate_template( array( 'image-widget/' . $template ) ) ) {
481 $file = $theme_file;
482 } else {
483 $file = 'views/' . $template;
484 }
485
486 /**
487 * Allow filtering of currently-retrieved Image Widget template file's path.
488 *
489 * @param string $file The retrieved template file's path.
490 */
491 return apply_filters( 'sp_template_image-widget_' . $template, $file );
492 }
493
494 /**
495 * Display a thank you nag when the plugin has been upgraded.
496 */
497 public function post_upgrade_nag() {
498
499 if (
500 ! current_user_can( 'install_plugins' )
501 || class_exists( 'Tribe__Image__Plus__Main' )
502 ) {
503 return;
504 }
505
506 global $pagenow;
507 $msg = false;
508 switch ( $pagenow ) {
509 case 'plugins.php' :
510 $msg = $this->upgrade_nag_plugins_admin_msg();
511 break;
512 case 'widgets.php' :
513 $msg = $this->upgrade_nag_widget_admin_msg();
514 break;
515 }
516
517 if ( ! $msg ) return;
518
519 echo $msg;
520 ?><script>
521 jQuery(document).ready(function($){
522 // Dismiss our admin notice
523 $( document ).on( 'click', '.image-widget-notice .notice-dismiss', function () {
524 var key = $( this ).closest( '.image-widget-notice' ).data( 'key' );
525 $.ajax( ajaxurl,
526 {
527 type: 'POST',
528 data: {
529 action: 'dismissed_image_widget_notice_handler',
530 key: key
531 }
532 } );
533 } );
534 } );
535 </script><?php
536 }
537
538 /**
539 * AJAX handler to store the state of dismissible notices.
540 */
541 public function ajax_notice_handler() {
542 if ( empty( $_POST['key'] ) ) {
543 return;
544 }
545
546 $key = $this->generate_key( sanitize_text_field( $_POST['key'] ) );
547
548 update_site_option( $key, self::VERSION );
549 }
550
551 /**
552 * Generate version key for admin notice options
553 *
554 * @param string $key
555 * @return string option key
556 */
557 private function generate_key( $key ) {
558 return join( '_', array( self::VERSION_KEY, $key, ) );
559 }
560
561 /**
562 * Upgrade nag: Plugins Admin
563 *
564 * @return string alert message.
565 */
566 private function upgrade_nag_plugins_admin_msg() {
567 $key = 'plugin';
568 $option_key = $this->generate_key( $key );
569
570 if ( get_site_option( $option_key ) == self::VERSION ) {
571 return;
572 }
573
574 $msg = sprintf(
575 __( '<p class="dashicons-before dashicons-format-gallery"><strong>Image Widget Plus</strong> - Add lightbox, slideshow, and random image widgets. <strong><a href="%s" target="_blank">Find out how!</a></strong></p>', 'image-widget' ),
576 'https://evnt.is/19my'
577 );
578
579 return "<div class='notice notice-info is-dismissible image-widget-notice' data-key='$key'>$msg</div>";
580 }
581
582 /**
583 * Upgrade nag: Widget Admin
584 *
585 * @return string alert message.
586 */
587 private function upgrade_nag_widget_admin_msg() {
588 $key = 'widget';
589 $option_key = $this->generate_key( $key );
590
591 if ( get_site_option( $option_key ) == self::VERSION ) {
592 return;
593 }
594
595 $msg = sprintf(
596 __( '<p class="dashicons-before dashicons-star-filled"><strong>Image Widget Plus</strong> - Add lightbox, slideshow, and random image widgets. <strong><a href="%s" target="_blank">Find out how!</a></strong></p>', 'image-widget' ),
597 'https://evnt.is/19mx'
598 );
599
600 return "<div class='notice notice-info is-dismissible image-widget-notice' data-key='$key'>$msg</div>";
601 }
602
603 /**
604 * Display an informational section in the plugin admin ui.
605 *
606 * @param $meta
607 * @param $file
608 * @return array
609 */
610 public function plugin_row_meta( $meta, $file ) {
611 if ( $file == plugin_basename( dirname( __FILE__ ) . '/image-widget.php' ) ) {
612 $meta[] = '<strong><a href="https://evnt.is/19ma" target="_blank">' . esc_html__( 'Image Widget Plus', 'image-widget' ) . '</a></strong>';
613 }
614
615 return $meta;
616 }
617 }
618