PluginProbe ʕ •ᴥ•ʔ
Image Widget / 4.4
Image Widget v4.4
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 9 years ago lib 9 years ago resources 9 years ago views 9 years ago image-widget.php 9 years ago index.php 9 years ago readme.txt 9 years ago
image-widget.php
543 lines
1 <?php
2 /*
3 Plugin Name: Image Widget
4 Plugin URI: http://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>COMING SOON: <a href="http://theeventscalendar.org/products/image-widget-plus/?utm_campaign=in-app&utm_source=docblock&utm_medium=image-widget">Image Widget Plus</a> - Multiple images, slider and more.</strong>
6 Author: Modern Tribe, Inc.
7 Version: 4.4
8 Author URI: http://m.tri.be/iwpdoc
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 /**
25 * Tribe_Image_Widget class
26 **/
27 class Tribe_Image_Widget extends WP_Widget {
28
29 const VERSION = '4.4';
30
31 const CUSTOM_IMAGE_SIZE_SLUG = 'tribe_image_widget_custom';
32
33 const VERSION_KEY = '_image_widget_version';
34
35 /**
36 * Tribe Image Widget constructor
37 *
38 * @author Modern Tribe, Inc.
39 */
40 public function __construct() {
41 load_plugin_textdomain( 'image-widget', false, trailingslashit( basename( dirname( __FILE__ ) ) ) . 'lang/' );
42 $widget_ops = array( 'classname' => 'widget_sp_image', 'description' => __( 'Showcase a single image with a Title, URL, and a Description', 'image-widget' ) );
43 $control_ops = array( 'id_base' => 'widget_sp_image' );
44 parent::__construct( 'widget_sp_image', __( 'Image Widget', 'image-widget' ), $widget_ops, $control_ops );
45
46 if ( $this->use_old_uploader() ) {
47 require_once( 'lib/ImageWidgetDeprecated.php' );
48 new ImageWidgetDeprecated( $this );
49 } else {
50 add_action( 'sidebar_admin_setup', array( $this, 'admin_setup' ) );
51 }
52 add_action( 'admin_head-widgets.php', array( $this, 'admin_head' ) );
53
54 add_action( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
55
56 if ( ! defined( 'I_HAVE_SUPPORTED_THE_IMAGE_WIDGET' ) )
57 add_action( 'admin_notices', array( $this, 'post_upgrade_nag' ) );
58
59 add_action( 'network_admin_notices', array( $this, 'post_upgrade_nag' ) );
60 add_action( 'wp_ajax_dismissed_image_widget_notice_handler', array( $this, 'ajax_notice_handler' ) );
61 }
62
63 /**
64 * Test to see if this version of WordPress supports the new image manager.
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' ) ) return true;
69 return ! function_exists( 'wp_enqueue_media' );
70 }
71
72 /**
73 * Enqueue all the javascript.
74 */
75 public function admin_setup() {
76 wp_enqueue_media();
77 wp_enqueue_script( 'tribe-image-widget', plugins_url( 'resources/js/image-widget.js', __FILE__ ), array( 'jquery', 'media-upload', 'media-views' ), self::VERSION );
78
79 wp_localize_script( 'tribe-image-widget', 'TribeImageWidget', array(
80 'frame_title' => __( 'Select an Image', 'image-widget' ),
81 'button_title' => __( 'Insert Into Widget', 'image-widget' ),
82 ) );
83 }
84
85 /**
86 * Widget frontend output
87 *
88 * @param array $args
89 * @param array $instance
90 * @author Modern Tribe, Inc.
91 */
92 public function widget( $args, $instance ) {
93 extract( $args );
94 $instance = wp_parse_args( (array) $instance, self::get_defaults() );
95 if ( ! empty( $instance['imageurl'] ) || ! empty( $instance['attachment_id'] ) ) {
96
97 $instance['title'] = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'] );
98 $instance['description'] = apply_filters( 'widget_text', $instance['description'], $args, $instance );
99 $instance['link'] = apply_filters( 'image_widget_image_link', esc_url( $instance['link'] ), $args, $instance );
100 $instance['linkid'] = apply_filters( 'image_widget_image_link_id', esc_attr( $instance['linkid'] ), $args, $instance );
101 $instance['linktarget'] = apply_filters( 'image_widget_image_link_target', esc_attr( $instance['linktarget'] ), $args, $instance );
102 $instance['width'] = apply_filters( 'image_widget_image_width', abs( $instance['width'] ), $args, $instance );
103 $instance['height'] = apply_filters( 'image_widget_image_height', abs( $instance['height'] ), $args, $instance );
104 $instance['maxwidth'] = apply_filters( 'image_widget_image_maxwidth', esc_attr( $instance['maxwidth'] ), $args, $instance );
105 $instance['maxheight'] = apply_filters( 'image_widget_image_maxheight', esc_attr( $instance['maxheight'] ), $args, $instance );
106 $instance['align'] = apply_filters( 'image_widget_image_align', esc_attr( $instance['align'] ), $args, $instance );
107 $instance['alt'] = apply_filters( 'image_widget_image_alt', esc_attr( $instance['alt'] ), $args, $instance );
108 $instance['rel'] = apply_filters( 'image_widget_image_rel', esc_attr( $instance['rel'] ), $args, $instance );
109
110 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) ) {
111 $instance['attachment_id'] = ( $instance['attachment_id'] > 0 ) ? $instance['attachment_id'] : $instance['image'];
112 $instance['attachment_id'] = apply_filters( 'image_widget_image_attachment_id', abs( $instance['attachment_id'] ), $args, $instance );
113 $instance['size'] = apply_filters( 'image_widget_image_size', esc_attr( $instance['size'] ), $args, $instance );
114 }
115 $instance['imageurl'] = apply_filters( 'image_widget_image_url', esc_url( $instance['imageurl'] ), $args, $instance );
116
117 // No longer using extracted vars. This is here for backwards compatibility.
118 extract( $instance );
119
120 include( $this->getTemplateHierarchy( 'widget' ) );
121 }
122 }
123
124 /**
125 * Update widget options
126 *
127 * @param object $new_instance Widget Instance
128 * @param object $old_instance Widget Instance
129 * @return object
130 * @author Modern Tribe, Inc.
131 */
132 public function update( $new_instance, $old_instance ) {
133 $instance = $old_instance;
134 $new_instance = wp_parse_args( (array) $new_instance, self::get_defaults() );
135 $instance['title'] = strip_tags( $new_instance['title'] );
136 if ( current_user_can( 'unfiltered_html' ) ) {
137 $instance['description'] = $new_instance['description'];
138 } else {
139 $instance['description'] = wp_filter_post_kses( $new_instance['description'] );
140 }
141 $instance['link'] = $new_instance['link'];
142 $instance['linkid'] = $new_instance['linkid'];
143 $instance['linktarget'] = $new_instance['linktarget'];
144 $instance['width'] = abs( $new_instance['width'] );
145 $instance['height'] = abs( $new_instance['height'] );
146 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) ) {
147 $instance['size'] = $new_instance['size'];
148 }
149 $instance['align'] = $new_instance['align'];
150 $instance['alt'] = $new_instance['alt'];
151 $instance['rel'] = $new_instance['rel'];
152
153 // Reverse compatibility with $image, now called $attachement_id
154 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) && $new_instance['attachment_id'] > 0 ) {
155 $instance['attachment_id'] = abs( $new_instance['attachment_id'] );
156 } elseif ( $new_instance['image'] > 0 ) {
157 $instance['attachment_id'] = $instance['image'] = abs( $new_instance['image'] );
158 if ( class_exists( 'ImageWidgetDeprecated' ) ) {
159 $instance['imageurl'] = ImageWidgetDeprecated::get_image_url( $instance['image'], $instance['width'], $instance['height'] ); // image resizing not working right now
160 }
161 }
162 $instance['imageurl'] = $new_instance['imageurl']; // deprecated
163
164 $instance['aspect_ratio'] = $this->get_image_aspect_ratio( $instance );
165
166 return $instance;
167 }
168
169 /**
170 * Form UI
171 *
172 * @param object $instance Widget Instance
173 * @author Modern Tribe, Inc.
174 */
175 public function form( $instance ) {
176 $instance = wp_parse_args( (array) $instance, self::get_defaults() );
177 if ( $this->use_old_uploader() ) {
178 include( $this->getTemplateHierarchy( 'widget-admin.deprecated' ) );
179 } else {
180 include( $this->getTemplateHierarchy( 'widget-admin' ) );
181 }
182 }
183
184 /**
185 * Admin header css
186 *
187 * @author Modern Tribe, Inc.
188 */
189 public function admin_head() {
190 ?>
191 <style type="text/css">
192 .uploader input.button {
193 width: 100%;
194 height: 34px;
195 line-height: 33px;
196 margin-top: 15px;
197 }
198 .tribe_preview .aligncenter {
199 display: block;
200 margin-left: auto !important;
201 margin-right: auto !important;
202 }
203 .tribe_preview {
204 overflow: hidden;
205 max-height: 300px;
206 }
207 .tribe_preview img {
208 margin: 10px 0;
209 height: auto;
210 }
211 </style>
212 <?php
213 }
214
215 /**
216 * Render an array of default values.
217 *
218 * @return array default values
219 */
220 private static function get_defaults() {
221
222 $defaults = array(
223 'title' => '',
224 'description' => '',
225 'link' => '',
226 'linkid' => '',
227 'linktarget' => '',
228 'width' => 0,
229 'height' => 0,
230 'maxwidth' => '100%',
231 'maxheight' => '',
232 'image' => 0, // reverse compatible - now attachement_id
233 'imageurl' => '', // reverse compatible.
234 'align' => 'none',
235 'alt' => '',
236 'rel' => '',
237 );
238
239 if ( ! defined( 'IMAGE_WIDGET_COMPATIBILITY_TEST' ) ) {
240 $defaults['size'] = self::CUSTOM_IMAGE_SIZE_SLUG;
241 $defaults['attachment_id'] = 0;
242 }
243
244 return $defaults;
245 }
246
247 /**
248 * Render the image html output.
249 *
250 * @param array $instance
251 * @param bool $include_link will only render the link if this is set to true. Otherwise link is ignored.
252 * @return string image html
253 */
254 private function get_image_html( $instance, $include_link = true ) {
255
256 // Backwards compatible image display.
257 if ( $instance['attachment_id'] == 0 && $instance['image'] > 0 ) {
258 $instance['attachment_id'] = $instance['image'];
259 }
260
261 $output = '';
262
263 if ( $include_link && ! empty( $instance['link'] ) ) {
264 $attr = array(
265 'href' => $instance['link'],
266 'id' => $instance['linkid'],
267 'target' => $instance['linktarget'],
268 'class' => $this->widget_options['classname'] . '-image-link',
269 'title' => ( ! empty( $instance['alt'] ) ) ? $instance['alt'] : $instance['title'],
270 'rel' => $instance['rel'],
271 );
272 $attr = apply_filters( 'image_widget_link_attributes', $attr, $instance );
273 $attr = array_map( 'esc_attr', $attr );
274 $output = '<a';
275 foreach ( $attr as $name => $value ) {
276 $output .= sprintf( ' %s="%s"', $name, $value );
277 }
278 $output .= '>';
279 }
280
281 $size = $this->get_image_size( $instance );
282 if ( is_array( $size ) ) {
283 $instance['width'] = $size[0];
284 $instance['height'] = $size[1];
285 } elseif ( ! empty( $instance['attachment_id'] ) ) {
286 //$instance['width'] = $instance['height'] = 0;
287 $image_details = wp_get_attachment_image_src( $instance['attachment_id'], $size );
288 if ( $image_details ) {
289 $instance['imageurl'] = $image_details[0];
290 $instance['width'] = $image_details[1];
291 $instance['height'] = $image_details[2];
292 }
293
294 $image_srcset = wp_get_attachment_image_srcset( $instance['attachment_id'], $size);
295 if ( $image_srcset ) {
296 $instance['srcset'] = $image_srcset;
297 }
298
299 $image_sizes = wp_get_attachment_image_sizes( $instance['attachment_id'], $size );
300 if ( $image_sizes ) {
301 $instance['sizes'] = $image_sizes;
302 }
303 }
304 $instance['width'] = abs( $instance['width'] );
305 $instance['height'] = abs( $instance['height'] );
306
307 $attr = array();
308 $attr['alt'] = ( ! empty( $instance['alt'] ) ) ? $instance['alt'] : $instance['title'];
309 if ( is_array( $size ) ) {
310 $attr['class'] = 'attachment-' . join( 'x', $size );
311 } else {
312 $attr['class'] = 'attachment-' . $size;
313 }
314 $attr['style'] = '';
315 if ( ! empty( $instance['maxwidth'] ) ) {
316 $attr['style'] .= "max-width: {$instance['maxwidth']};";
317 }
318 if ( ! empty( $instance['maxheight'] ) ) {
319 $attr['style'] .= "max-height: {$instance['maxheight']};";
320 }
321 if ( ! empty( $instance['align'] ) && $instance['align'] != 'none' ) {
322 $attr['class'] .= " align{$instance['align']}";
323 }
324 if ( !empty($instance['srcset'] ) ) {
325 $attr['srcset'] = $instance['srcset'];
326 }
327 if ( ! empty($instance['sizes'] ) ) {
328 $attr['sizes'] = $instance['sizes'];
329 }
330 $attr = apply_filters( 'image_widget_image_attributes', $attr, $instance );
331
332 // If there is an imageurl, use it to render the image. Eventually we should kill this and simply rely on attachment_ids.
333 if ( ! empty( $instance['imageurl'] ) ) {
334 // If all we have is an image src url we can still render an image.
335 $attr['src'] = $instance['imageurl'];
336 $attr = array_map( 'esc_attr', $attr );
337 $hwstring = image_hwstring( $instance['width'], $instance['height'] );
338 $output .= rtrim( "<img $hwstring" );
339 foreach ( $attr as $name => $value ) {
340 $output .= sprintf( ' %s="%s"', $name, $value );
341 }
342 $output .= ' />';
343 } elseif ( abs( $instance['attachment_id'] ) > 0 ) {
344 $output .= wp_get_attachment_image( $instance['attachment_id'], $size, false, $attr );
345 }
346
347 if ( $include_link && ! empty( $instance['link'] ) ) {
348 $output .= '</a>';
349 }
350
351 return $output;
352 }
353
354 /**
355 * Get all possible image sizes to choose from
356 *
357 * @return array
358 */
359 private function possible_image_sizes() {
360 $registered = get_intermediate_image_sizes();
361 // label other sizes with their image size "ID"
362 $registered = array_combine( $registered, $registered );
363
364 $possible_sizes = array_merge( $registered, array(
365 'full' => __( 'Full Size', 'image-widget' ),
366 'thumbnail' => __( 'Thumbnail', 'image-widget' ),
367 'medium' => __( 'Medium', 'image-widget' ),
368 'large' => __( 'Large', 'image-widget' ),
369 self::CUSTOM_IMAGE_SIZE_SLUG => __( 'Custom', 'image-widget' ),
370 ) );
371
372 return (array) apply_filters( 'image_size_names_choose', $possible_sizes );
373 }
374
375 /**
376 * Assesses the image size in case it has not been set or in case there is a mismatch.
377 *
378 * @param $instance
379 * @return array|string
380 */
381 private function get_image_size( $instance ) {
382 if ( ! empty( $instance['size'] ) && $instance['size'] != self::CUSTOM_IMAGE_SIZE_SLUG ) {
383 $size = $instance['size'];
384 } elseif ( isset( $instance['width'] ) && is_numeric( $instance['width'] ) && isset( $instance['height'] ) && is_numeric( $instance['height'] ) ) {
385 //$size = array(abs($instance['width']),abs($instance['height']));
386 $size = array( $instance['width'], $instance['height'] );
387 } else {
388 $size = 'full';
389 }
390 return $size;
391 }
392
393 /**
394 * Establish the aspect ratio of the image.
395 *
396 * @param $instance
397 * @return float|number
398 */
399 private function get_image_aspect_ratio( $instance ) {
400 if ( ! empty( $instance['aspect_ratio'] ) ) {
401 return abs( $instance['aspect_ratio'] );
402 } else {
403 $attachment_id = ( ! empty( $instance['attachment_id'] ) ) ? $instance['attachment_id'] : $instance['image'];
404 if ( ! empty( $attachment_id ) ) {
405 $image_details = wp_get_attachment_image_src( $attachment_id, 'full' );
406 if ( $image_details ) {
407 return ( $image_details[1] / $image_details[2] );
408 }
409 }
410 }
411 }
412
413 /**
414 * Loads theme files in appropriate hierarchy: 1) child theme,
415 * 2) parent template, 3) plugin resources. will look in the image-widget/
416 * directory in a theme and the views/ directory in the plugin
417 *
418 * @param string $template template file to search for
419 * @return template path
420 * @author Modern Tribe, Inc. (Matt Wiebe)
421 **/
422
423 public function getTemplateHierarchy( $template ) {
424 // whether or not .php was added
425 $template_slug = rtrim( $template, '.php' );
426 $template = $template_slug . '.php';
427
428 if ( $theme_file = locate_template( array( 'image-widget/' . $template ) ) ) {
429 $file = $theme_file;
430 } else {
431 $file = 'views/' . $template;
432 }
433 return apply_filters( 'sp_template_image-widget_' . $template, $file );
434 }
435
436 /**
437 * Display a thank you nag when the plugin has been upgraded.
438 */
439 public function post_upgrade_nag() {
440 if ( ! current_user_can( 'install_plugins' ) ) return;
441
442 global $pagenow;
443 $msg = false;
444 switch ( $pagenow ) {
445 case 'plugins.php' :
446 $msg = $this->upgrade_nag_plugins_admin_msg();
447 break;
448 case 'widgets.php' :
449 $msg = $this->upgrade_nag_widget_admin_msg();
450 break;
451 }
452
453 if ( !$msg ) return;
454
455 echo $msg;
456 ?><script>
457 jQuery(document).ready(function($){
458 // Dismiss our admin notice
459 $( document ).on( 'click', '.image-widget-notice .notice-dismiss', function () {
460 var key = $( this ).closest( '.image-widget-notice' ).data( 'key' );
461 $.ajax( ajaxurl,
462 {
463 type: 'POST',
464 data: {
465 action: 'dismissed_image_widget_notice_handler',
466 key: key
467 }
468 } );
469 } );
470 } );
471 </script><?php
472 }
473
474 /**
475 * AJAX handler to store the state of dismissible notices.
476 */
477 function ajax_notice_handler() {
478 if ( empty( $_POST['key'] ) ) return;
479 $key = $this->generate_key( sanitize_text_field( $_POST['key'] ) );
480 update_site_option( $key, self::VERSION );
481 }
482
483 /**
484 * Generate version key for admin notice options
485 *
486 * @param string $key
487 * @return string option key
488 */
489 private function generate_key( $key ) {
490 $option_key = join( "_", array(
491 self::VERSION_KEY,
492 $key
493 ) );
494 return $option_key;
495 }
496
497 /**
498 * Upgrade nag: Plugins Admin
499 *
500 * @return string alert message.
501 */
502 private function upgrade_nag_plugins_admin_msg() {
503 $key = "plugin";
504 $option_key = $this->generate_key( $key );
505 if ( get_site_option( $option_key ) == self::VERSION ) return;
506 $msg = sprintf(
507 __( '<p class="dashicons-before dashicons-format-gallery"><strong><a href="%s" target="_blank">Image Widget Plus</a></strong> is coming soon! Add random images, lightbox, and slider - <strong><a href="%s">Sign up now for early access.</a></strong></p>','image-widget' ),
508 'http://m.tri.be/19my',
509 'http://m.tri.be/19my'
510 );
511 return "<div class='notice notice-info is-dismissible image-widget-notice' data-key='$key'>$msg</div>";
512 }
513
514 /**
515 * Upgrade nag: Widget Admin
516 *
517 * @return string alert message.
518 */
519 private function upgrade_nag_widget_admin_msg() {
520 $key = "widget";
521 $option_key = $this->generate_key( $key );
522 if ( get_site_option( $option_key ) == self::VERSION ) return;
523 $msg = sprintf(
524 __( '<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' ),
525 'http://m.tri.be/19mx'
526 );
527 return "<div class='notice notice-info is-dismissible image-widget-notice' data-key='$key'>$msg</div>";
528 }
529
530 /**
531 * Display an informational section in the plugin admin ui.
532 * @param $meta
533 * @param $file
534 *
535 * @return array
536 */
537 public function plugin_row_meta( $meta, $file ) {
538 if ( $file == plugin_basename( dirname( __FILE__ ) . '/image-widget.php' ) ) {
539 $meta[] = '<strong>' . esc_html__( 'Coming Soon:', 'image-widget' ) . '</strong> <a href="http://m.tri.be/19ma" target="_blank">' . esc_html__( 'Image Widget Plus', 'image-widget' ) . '</a>';
540 }
541 return $meta;
542 }
543 }