/modules/widgets/gallery.php

  1. <?php 
  2.  
  3. /** 
  4. Plugin Name: Gallery 
  5. Description: Gallery widget 
  6. Author: Automattic, Inc. 
  7. Version: 1.0 
  8. Author URI: http://automattic.com 
  9. */ 
  10.  
  11. class Jetpack_Gallery_Widget extends WP_Widget { 
  12. const THUMB_SIZE = 45; 
  13. const DEFAULT_WIDTH = 265; 
  14.  
  15. protected $_instance_width ; 
  16.  
  17. public function __construct() { 
  18. $widget_ops = array( 
  19. 'classname' => 'widget-gallery',  
  20. 'description' => __( 'Display a photo gallery or slideshow', 'jetpack' ) 
  21. ); 
  22. $control_ops = array( 'width' => 250 ); 
  23.  
  24. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); 
  25.  
  26. parent::__construct( 
  27. 'gallery',  
  28. /** This filter is documented in modules/widgets/facebook-likebox.php */ 
  29. apply_filters( 'jetpack_widget_name', __( 'Gallery', 'jetpack' ) ),  
  30. $widget_ops,  
  31. $control_ops 
  32. ); 
  33.  
  34. /** 
  35. * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget. 
  36. * @param array $instance The settings for the particular instance of the widget. 
  37. */ 
  38. public function widget( $args, $instance ) { 
  39. $instance = wp_parse_args( (array) $instance, $this->defaults() ); 
  40.  
  41. $this->enqueue_frontend_scripts(); 
  42.  
  43. extract( $args ); 
  44.  
  45. $instance['attachments'] = $this->get_attachments( $instance ); 
  46.  
  47. $classes = array(); 
  48.  
  49. $classes[] = 'widget-gallery-' . $instance['type']; 
  50.  
  51. // Due to a bug in the carousel plugin, carousels will be triggered for all tiled galleries that exist on a page 
  52. // with other tiled galleries, regardless of whether or not the widget was set to Carousel mode. The onClick selector 
  53. // is simply too broad, since it was not written with widgets in mind. This special class prevents that behavior, via 
  54. // an override handler in gallery.js 
  55. if( 'carousel' != $instance['link'] && 'slideshow' != $instance['type'] ) 
  56. $classes[] = 'no-carousel'; 
  57. else 
  58. $classes[] = 'carousel'; 
  59.  
  60. $classes = implode( ' ', $classes ); 
  61.  
  62. if ( 'carousel' == $instance['link'] ) { 
  63. require_once plugin_dir_path( realpath( dirname( __FILE__ ) . '/../carousel/jetpack-carousel.php' ) ) . 'jetpack-carousel.php'; 
  64.  
  65. if ( class_exists( 'Jetpack_Carousel' ) ) { 
  66. // Create new carousel so we can use the enqueue_assets() method. Not ideal, but there is a decent amount 
  67. // of logic in that method that shouldn't be duplicated. 
  68. $carousel = new Jetpack_Carousel(); 
  69.  
  70. // First parameter is $output, which comes from filters, and causes bypass of the asset enqueuing. Passing null is correct. 
  71. $carousel->enqueue_assets( null ); 
  72.  
  73. echo $before_widget . "\n"; 
  74.  
  75. /** This filter is documented in core/src/wp-includes/default-widgets.php */ 
  76. $title = apply_filters( 'widget_title', $instance['title'] ); 
  77.  
  78. if ( $title ) 
  79. echo $before_title . esc_html( $title ) . $after_title . "\n"; 
  80.  
  81. echo '<div class="' . esc_attr( $classes ) . '">' . "\n"; 
  82.  
  83. $method = $instance['type'] . '_widget'; 
  84.  
  85. /** 
  86. * Allow the width of a gallery to be altered by themes or other code. 
  87. * 
  88. * @module widgets 
  89. * 
  90. * @since 2.5.0 
  91. * 
  92. * @param int self::DEFAULT_WIDTH Default gallery width. Default is 265. 
  93. * @param string $args Display arguments including before_title, after_title, before_widget, and after_widget. 
  94. * @param array $instance The settings for the particular instance of the widget. 
  95. */ 
  96. $this->_instance_width = apply_filters( 'gallery_widget_content_width', self::DEFAULT_WIDTH, $args, $instance ); 
  97.  
  98. // Register a filter to modify the tiled_gallery_content_width, so Jetpack_Tiled_Gallery 
  99. // can appropriately size the tiles. 
  100. add_filter( 'tiled_gallery_content_width', array( $this, 'tiled_gallery_content_width' ) ); 
  101.  
  102. if ( method_exists( $this, $method ) ) 
  103. echo $this->$method( $args, $instance ); 
  104.  
  105. // Remove the stored $_instance_width, as it is no longer needed 
  106. $this->_instance_width = null; 
  107.  
  108. // Remove the filter, so any Jetpack_Tiled_Gallery in a post is not affected 
  109. remove_filter( 'tiled_gallery_content_width', array( $this, 'tiled_gallery_content_width' ) ); 
  110.  
  111. echo "\n" . '</div>'; // .widget-gallery-$type 
  112.  
  113. echo "\n" . $after_widget; 
  114.  
  115. /** 
  116. * Fetch the images attached to the gallery Widget 
  117. * 
  118. * @param array $instance The Widget instance for which you'd like attachments 
  119. * @return array Array of attachment objects for the Widget in $instance 
  120. */ 
  121. public function get_attachments( $instance ) { 
  122. $ids = explode( ', ', $instance['ids'] ); 
  123.  
  124. if ( isset( $instance['random'] ) && 'on' == $instance['random'] ) { 
  125. shuffle( $ids ); 
  126.  
  127. $attachments_query = new WP_Query( array( 
  128. 'post__in' => $ids,  
  129. 'post_status' => 'inherit',  
  130. 'post_type' => 'attachment',  
  131. 'post_mime_type' => 'image',  
  132. 'posts_per_page' => -1,  
  133. 'orderby' => 'post__in',  
  134. ) ); 
  135.  
  136. $attachments = $attachments_query->get_posts(); 
  137.  
  138. wp_reset_postdata(); 
  139.  
  140. return $attachments; 
  141.  
  142. /** 
  143. * Generate HTML for a rectangular, tiled Widget 
  144. * 
  145. * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget. 
  146. * @param array $instance The Widget instance to generate HTML for 
  147. * @return string String of HTML representing a rectangular gallery 
  148. */ 
  149. public function rectangular_widget( $args, $instance ) { 
  150. if ( ! class_exists( 'Jetpack_Tiled_Gallery' ) 
  151. && ! class_exists( 'Jetpack_Tiled_Gallery_Layout_Rectangular') ) { 
  152. return; 
  153.  
  154. $widget_tiled_gallery = new Jetpack_Tiled_Gallery(); 
  155. $widget_tiled_gallery->default_scripts_and_styles(); 
  156.  
  157. $layout = new Jetpack_Tiled_Gallery_Layout_Rectangular( $instance['attachments'], $instance['link'], false, 3 ); 
  158. return $layout->HTML(); 
  159.  
  160. /** 
  161. * Generate HTML for a square (grid style) Widget 
  162. * 
  163. * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget. 
  164. * @param array $instance The Widget instance to generate HTML for 
  165. * @return string String of HTML representing a square gallery 
  166. */ 
  167. public function square_widget( $args, $instance ) { 
  168. if ( ! class_exists( 'Jetpack_Tiled_Gallery' ) 
  169. && ! class_exists( 'Jetpack_Tiled_Gallery_Layout_Square') ) { 
  170. return; 
  171.  
  172. $widget_tiled_gallery = new Jetpack_Tiled_Gallery(); 
  173. $widget_tiled_gallery->default_scripts_and_styles(); 
  174.  
  175. $layout = new Jetpack_Tiled_Gallery_Layout_Square( $instance['attachments'], $instance['link'], false, 3 ); 
  176. return $layout->HTML(); 
  177.  
  178. /** 
  179. * Generate HTML for a circular (grid style) Widget 
  180. * 
  181. * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget. 
  182. * @param array $instance The Widget instance to generate HTML for 
  183. * @return string String of HTML representing a circular gallery 
  184. */ 
  185. public function circle_widget( $args, $instance ) { 
  186. if ( ! class_exists( 'Jetpack_Tiled_Gallery' ) 
  187. && ! class_exists( 'Jetpack_Tiled_Gallery_Layout_Circle') ) { 
  188. return; 
  189.  
  190. $widget_tiled_gallery = new Jetpack_Tiled_Gallery(); 
  191. $widget_tiled_gallery->default_scripts_and_styles(); 
  192.  
  193. $layout = new Jetpack_Tiled_Gallery_Layout_Circle( $instance['attachments'], $instance['link'], false, 3 ); 
  194. return $layout->HTML(); 
  195.  
  196. /** 
  197. * Generate HTML for a slideshow Widget 
  198. * 
  199. * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget. 
  200. * @param array $instance The Widget instance to generate HTML for 
  201. * @return string String of HTML representing a slideshow gallery 
  202. */ 
  203. public function slideshow_widget( $args, $instance ) { 
  204. global $content_width; 
  205.  
  206. require_once plugin_dir_path( realpath( dirname( __FILE__ ) . '/../shortcodes/slideshow.php' ) ) . 'slideshow.php'; 
  207.  
  208. if ( ! class_exists( 'Jetpack_Slideshow_Shortcode' ) ) 
  209. return; 
  210.  
  211. if ( count( $instance['attachments'] ) < 1 ) 
  212. return; 
  213.  
  214. $slideshow = new Jetpack_Slideshow_Shortcode(); 
  215.  
  216. $slideshow->enqueue_scripts(); 
  217.  
  218. $gallery_instance = "widget-" . $args['widget_id']; 
  219.  
  220. $gallery = array(); 
  221.  
  222. foreach ( $instance['attachments'] as $attachment ) { 
  223. $attachment_image_src = wp_get_attachment_image_src( $attachment->ID, 'full' ); 
  224. $attachment_image_src = $attachment_image_src[0]; // [url, width, height] 
  225.  
  226. $caption = wptexturize( strip_tags( $attachment->post_excerpt ) ); 
  227.  
  228. $gallery[] = (object) array( 
  229. 'src' => (string) esc_url_raw( $attachment_image_src ),  
  230. 'id' => (string) $attachment->ID,  
  231. 'caption' => (string) $caption,  
  232. ); 
  233.  
  234. $max_width = intval( get_option( 'large_size_w' ) ); 
  235. $max_height = 175; 
  236.  
  237. if ( intval( $content_width ) > 0 ) 
  238. $max_width = min( intval( $content_width ), $max_width ); 
  239.  
  240. $color = Jetpack_Options::get_option( 'slideshow_background_color', 'black' ); 
  241. $autostart = isset( $attr['autostart'] ) ? $attr['autostart'] : true; 
  242.  
  243. $js_attr = array( 
  244. 'gallery' => $gallery,  
  245. 'selector' => $gallery_instance,  
  246. 'width' => $max_width,  
  247. 'height' => $max_height,  
  248. 'trans' => 'fade',  
  249. 'color' => $color,  
  250. 'autostart' => $autostart,  
  251. ); 
  252.  
  253. $html = $slideshow->slideshow_js( $js_attr ); 
  254.  
  255. return $html; 
  256.  
  257. /** 
  258. * tiled_gallery_content_width filter 
  259. * 
  260. * Used to adjust the content width of Jetpack_Tiled_Gallery's in sidebars 
  261. * 
  262. * $this->_instance_width is filtered in widget() and this filter is added then removed in widget() 
  263. * 
  264. * @param int $width int The original width value 
  265. * @return int The filtered width 
  266. */ 
  267. public function tiled_gallery_content_width( $width ) { 
  268. return $this->_instance_width; 
  269.  
  270. public function form( $instance ) { 
  271. $defaults = $this->defaults(); 
  272. $allowed_values = $this->allowed_values(); 
  273.  
  274. $instance = wp_parse_args( (array) $instance, $defaults ); 
  275.  
  276. include dirname( __FILE__ ) . '/gallery/templates/form.php'; 
  277.  
  278. public function update( $new_instance, $old_instance ) { 
  279. $instance = $this->sanitize( $new_instance ); 
  280.  
  281. return $instance; 
  282.  
  283. /** 
  284. * Sanitize the $instance's values to the set of allowed values. If a value is not acceptable,  
  285. * it is set to its default. 
  286. * 
  287. * Helps keep things nice and secure by whitelisting only allowed values 
  288. * 
  289. * @param array $instance The Widget instance to sanitize values for 
  290. * @return array $instance The Widget instance with values sanitized 
  291. */ 
  292. public function sanitize( $instance ) { 
  293. $allowed_values = $this->allowed_values(); 
  294. $defaults = $this->defaults(); 
  295.  
  296. foreach ( $instance as $key => $value ) { 
  297. $value = trim( $value ); 
  298.  
  299. if ( isset( $allowed_values[ $key ] ) && $allowed_values[ $key ] && ! array_key_exists( $value, $allowed_values[ $key ] ) ) { 
  300. $instance[ $key ] = $defaults[ $key ]; 
  301. } else { 
  302. $instance[ $key ] = sanitize_text_field( $value ); 
  303.  
  304. return $instance; 
  305.  
  306. /** 
  307. * Return a multi-dimensional array of allowed values (and their labels) for all widget form 
  308. * elements 
  309. * 
  310. * To allow all values on an input, omit it from the returned array 
  311. * 
  312. * @return array Array of allowed values for each option 
  313. */ 
  314. public function allowed_values() { 
  315. $max_columns = 5; 
  316.  
  317. // Create an associative array of allowed column values. This just automates the generation of 
  318. // column <option>s, from 1 to $max_columns 
  319. $allowed_columns = array_combine( range( 1, $max_columns ), range( 1, $max_columns ) ); 
  320.  
  321. return array( 
  322. 'type' => array( 
  323. 'rectangular' => __( 'Tiles', 'jetpack' ),  
  324. 'square' => __( 'Square Tiles', 'jetpack' ),  
  325. 'circle' => __( 'Circles', 'jetpack' ),  
  326. 'slideshow' => __( 'Slideshow', 'jetpack' ),  
  327. ),  
  328. 'columns' => $allowed_columns,  
  329. 'link' => array( 
  330. 'carousel' => __( 'Carousel', 'jetpack' ),  
  331. 'post' => __( 'Attachment Page', 'jetpack' ),  
  332. 'file' => __( 'Media File', 'jetpack' ),  
  333. ); 
  334.  
  335. /** 
  336. * Return an associative array of default values 
  337. * 
  338. * These values are used in new widgets as well as when sanitizing input. If a given value is not allowed,  
  339. * as defined in allowed_values(), that input is set to the default value defined here. 
  340. * 
  341. * @return array Array of default values for the Widget's options 
  342. */ 
  343. public function defaults() { 
  344. return array( 
  345. 'title' => '',  
  346. 'type' => 'rectangular',  
  347. 'ids' => '',  
  348. 'columns' => 3,  
  349. 'link' => 'carousel' 
  350. ); 
  351.  
  352. public function enqueue_frontend_scripts() { 
  353. wp_register_script( 'gallery-widget', plugins_url( '/gallery/js/gallery.js', __FILE__ ) ); 
  354.  
  355. wp_enqueue_script( 'gallery-widget' ); 
  356.  
  357. public function enqueue_admin_scripts() { 
  358. global $pagenow; 
  359.  
  360. if ( 'widgets.php' == $pagenow || 'customize.php' == $pagenow ) { 
  361. wp_enqueue_media(); 
  362.  
  363. wp_enqueue_script( 'gallery-widget-admin', plugins_url( '/gallery/js/admin.js', __FILE__ ), array( 
  364. 'media-models',  
  365. 'media-views' 
  366. ),  
  367. '20150501' 
  368. ); 
  369.  
  370. $js_settings = array( 
  371. 'thumbSize' => self::THUMB_SIZE 
  372. ); 
  373.  
  374. wp_localize_script( 'gallery-widget-admin', '_wpGalleryWidgetAdminSettings', $js_settings ); 
  375. if( is_rtl() ) { 
  376. wp_enqueue_style( 'gallery-widget-admin', plugins_url( '/gallery/css/rtl/admin-rtl.css', __FILE__ ) ); 
  377. } else { 
  378. wp_enqueue_style( 'gallery-widget-admin', plugins_url( '/gallery/css/admin.css', __FILE__ ) ); 
  379.  
  380. add_action( 'widgets_init', 'jetpack_gallery_widget_init' ); 
  381.  
  382. function jetpack_gallery_widget_init() { 
  383. if ( ! method_exists( 'Jetpack', 'is_module_active' ) || Jetpack::is_module_active( 'tiled-gallery' ) ) 
  384. register_widget( 'Jetpack_Gallery_Widget' ); 
.