PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.0
Responsive Lightbox & Gallery v2.0
2.7.8 trunk 1.0.0 1.0.1 1.0.1.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4.0 1.4.0.1 1.4.1 1.4.11 1.4.12 1.4.13 1.4.14 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3.1 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7
responsive-lightbox / includes / class-galleries.php
responsive-lightbox / includes Last commit date
class-frontend.php 8 years ago class-galleries.php 8 years ago class-settings.php 8 years ago class-tour.php 8 years ago class-welcome.php 8 years ago class-widgets.php 8 years ago functions.php 8 years ago
class-galleries.php
3053 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 /**
7 * Responsive Lightbox Galleries class.
8 *
9 * @class Responsive_Lightbox_Galleries
10 */
11 class Responsive_Lightbox_Galleries {
12
13 public $tabs;
14 private $menu_item;
15 public $fields;
16 public $media_item_template;
17 public $tab;
18 public $sizes;
19 public $gallery_args;
20
21 /**
22 * Constructor.
23 *
24 * @param bool $read_only Whether is it read only mode
25 * @return void
26 */
27 public function __construct( $read_only = false ) {
28 // set instance
29 Responsive_Lightbox()->galleries = $this;
30
31 if ( $read_only )
32 return;
33
34 // actions
35 add_action( 'init', array( $this, 'init' ), 11 );
36 add_action( 'admin_init', array( $this, 'init_admin' ) );
37 add_action( 'edit_form_after_title', array( $this, 'after_title_nav_menu' ) );
38 add_action( 'admin_footer', array( $this, 'modal_gallery_template' ) );
39 add_action( 'media_buttons', array( $this, 'add_gallery_button') );
40 add_action( 'add_meta_boxes_rl_gallery', array( $this, 'add_meta_boxes' ) );
41 add_action( 'save_post_rl_gallery', array( $this, 'save_post' ), 10, 3 );
42 add_action( 'manage_rl_gallery_posts_custom_column', array( $this, 'gallery_columns_content' ), 10, 2 );
43 add_action( 'wp_ajax_rl-get-menu-content', array( $this, 'get_menu_content' ) );
44 add_action( 'wp_ajax_rl-get-preview-content', array( $this, 'get_gallery_preview_content' ) );
45 add_action( 'wp_ajax_rl-post-get-galleries', array( $this, 'post_get_galleries' ) );
46 add_action( 'wp_ajax_rl-post-gallery-preview', array( $this, 'post_gallery_preview' ) );
47 add_action( 'wp_ajax_rl-get-gallery-page-content', array( $this, 'get_gallery_page' ) );
48 add_action( '_wp_put_post_revision', array( $this, 'save_revision' ) );
49 add_action( 'shutdown', array( $this, 'shutdown_preview' ) );
50 // add_action( 'wp_ajax_rl-get-query-args', array( $this, 'get_query_args' ) );
51
52 // filters
53 add_filter( 'manage_rl_gallery_posts_columns', array( $this, 'gallery_columns' ) );
54 add_filter( 'admin_post_thumbnail_html', array( $this, 'admin_post_thumbnail_html' ), 10, 2 );
55 add_filter( 'post_thumbnail_html', array( $this, 'post_thumbnail_html' ), 10, 5 );
56 add_filter( 'get_post_metadata', array( $this, 'filter_preview_metadata' ), 10, 4 );
57 add_filter( 'preview_post_link', array( $this, 'preview_post_link' ), 10, 2 );
58
59 if ( ! empty( $_POST['rl_active_tab'] ) )
60 add_filter( 'redirect_post_location', array( $this, 'add_active_tab' ) );
61 }
62
63 /**
64 * Load needed data.
65 *
66 * @return void
67 */
68 public function init() {
69 // register shortcode
70 add_shortcode( 'rl_gallery', array( $this, 'gallery_shortcode' ) );
71
72 // single image template
73 $this->media_item_template = '<li class="rl-gallery-image __IMAGE_STATUS__" data-attachment_id="__IMAGE_ID__"><div class="rl-gallery-inner">__IMAGE__</div><div class="rl-gallery-actions"><a href="#" class="rl-gallery-image-status dashicons dashicons-marker" title="' . __( 'Status', 'responsive-lightbox' ) . '"></a><a href="#" class="rl-gallery-image-edit dashicons dashicons-edit" title="' . __( 'Edit image', 'responsive-lightbox' ) . '"></a><a href="#" class="rl-gallery-image-remove dashicons dashicons-no" title="' . __( 'Remove image', 'responsive-lightbox' ) . '"></a></div></li>';
74
75 $config_menu_items = apply_filters( 'rl_gallery_types', Responsive_Lightbox()->gallery_types );
76 $config_menu_items['default'] = __( 'Global', 'responsive-lightbox' );
77
78 $this->tabs = apply_filters( 'rl_gallery_tabs', array(
79 'images' => array(
80 'label' => __( 'Images', 'responsive-lightbox' ),
81 'description' => __( 'The settings below adjust the contents of the gallery.', 'responsive-lightbox' ),
82 'menu_items' => array(
83 'media' => __( 'Media Library', 'responsive-lightbox' ),
84 'featured' => __( 'Featured Content', 'responsive-lightbox' )
85 )
86 ),
87 'config' => array(
88 'label' => __( 'Config', 'responsive-lightbox' ),
89 'description' => __( 'The settings below adjust the configuration options for the gallery.', 'responsive-lightbox' ),
90 'menu_items' => $config_menu_items
91 ),
92 'design' => array(
93 'label' => __( 'Design', 'responsive-lightbox' ),
94 'description' => __( 'The settings below adjust the gallery design options.', 'responsive-lightbox' )
95 ),
96 'paging' => array(
97 'label' => __( 'Paging', 'responsive-lightbox' ),
98 'description' => __( 'The settings below adjust the gallery pagination options.', 'responsive-lightbox' )
99 ),
100 'lightbox' => array(
101 'label' => __( 'Lightbox', 'responsive-lightbox' ),
102 'description' => __( 'The settings below adjust the lightbox options.', 'responsive-lightbox' ),
103 ),
104 'misc' => array(
105 'label' => __( 'Misc', 'responsive-lightbox' ),
106 'description' => __( 'The settings below adjust miscellaneous options.', 'responsive-lightbox' ),
107 )
108 ) );
109
110 // use sizes as keys and values
111 $this->sizes = $this->get_image_sizes();
112 $sizes = array_combine( array_keys( $this->sizes ), array_keys( $this->sizes ) );
113
114 // add default, custom and full image size
115 $sizes['full'] = __( 'Full size', 'responsive-lightbox' );
116 $sizes['global'] = __( 'Global', 'responsive-lightbox' );
117 $sizes['rl_custom_size'] = __( 'Custom size', 'responsive-lightbox' );
118
119 $positions = array(
120 'none' => __( 'None', 'responsive-lightbox' ),
121 'top' => __( 'Top', 'responsive-lightbox' ),
122 'bottom' => __( 'Bottom', 'responsive-lightbox' )
123 );
124
125 $this->fields = apply_filters( 'rl_gallery_tab_fields', array(
126 'images' => array(
127 'media' => array(
128 'attachments' => array(
129 'title' => '',
130 'type' => 'media_library',
131 'default' => array(
132 'ids' => array(),
133 'exclude' => array()
134 )
135 )
136 ),
137 'featured' => array(
138 'attachments' => array(
139 'title' => '',
140 'type' => 'media_preview',
141 'default' => array(
142 'exclude' => array()
143 )
144 ),
145 'number_of_posts' => array(
146 'title' => __( 'Number of Posts', 'responsive-lightbox' ),
147 'type' => 'number',
148 'description' => __( 'Enter the number of posts.', 'responsive-lightbox' ),
149 'default' => 10,
150 'min' => 0
151 ),
152 'orderby' => array(
153 'title' => __( 'Posts Sorting', 'responsive-lightbox' ),
154 'type' => 'select',
155 'description' => __( 'Select the posts sorting.', 'responsive-lightbox' ),
156 'default' => 'date',
157 'options' => array(
158 'id' => __( 'ID', 'responsive-lightbox' ),
159 'author' => __( 'Author', 'responsive-lightbox' ),
160 'title' => __( 'Title', 'responsive-lightbox' ),
161 'name' => __( 'Slug', 'responsive-lightbox' ),
162 'date' => __( 'Date', 'responsive-lightbox' ),
163 'modified' => __( 'Last modified date', 'responsive-lightbox' ),
164 'parent' => __( 'Parent ID', 'responsive-lightbox' ),
165 'rand' => __( 'Random', 'responsive-lightbox' )
166 )
167 ),
168 'order' => array(
169 'title' => __( 'Posts Order', 'responsive-lightbox' ),
170 'type' => 'radio',
171 'description' => __( 'Select the posts order.', 'responsive-lightbox' ),
172 'default' => 'asc',
173 'options' => array(
174 'asc' => __( 'Ascending', 'responsive-lightbox' ),
175 'desc' => __( 'Descending', 'responsive-lightbox' )
176 )
177 ),
178 'offset' => array(
179 'title' => __( 'Posts Offset', 'responsive-lightbox' ),
180 'type' => 'number',
181 'description' => __( 'Enter the posts offset.', 'responsive-lightbox' ),
182 'default' => 0,
183 'min' => 0
184 ),
185 'image_source' => array(
186 'title' => __( 'Image Source', 'responsive-lightbox' ),
187 'type' => 'radio',
188 'description' => __( 'Select the image source.', 'responsive-lightbox' ),
189 'default' => 'thumbnails',
190 'options' => array(
191 'thumbnails' => __( 'Post Thumbnails', 'responsive-lightbox' ),
192 'attached_images' => __( 'Post Attached Images', 'responsive-lightbox' )
193 )
194 ),
195 'images_per_post' => array(
196 'title' => __( 'Images per Post', 'responsive-lightbox' ),
197 'type' => 'number',
198 'description' => __( 'Enter maximum number of images for a post.', 'responsive-lightbox' ),
199 'default' => 1,
200 'min' => 1
201 ),
202 'post_type' => array(
203 'title' => __( 'Post Type', 'responsive-lightbox' ),
204 'type' => 'multiselect',
205 'description' => __( 'Select the post types to query.', 'responsive-lightbox' ),
206 'options' => array(),
207 'default' => array()
208 ),
209 'post_status' => array(
210 'title' => __( 'Post Status', 'responsive-lightbox' ),
211 'type' => 'multiselect',
212 'description' => __( 'Select the post status.', 'responsive-lightbox' ),
213 'options' => array(),
214 'default' => array()
215 ),
216 'post_format' => array(
217 'title' => __( 'Post Format', 'responsive-lightbox' ),
218 'type' => 'multiselect',
219 'description' => __( 'Select the post format.', 'responsive-lightbox' ),
220 'options' => array(),
221 'default' => array()
222 ),
223 'post_term' => array(
224 'title' => __( 'Post Term', 'responsive-lightbox' ),
225 'type' => 'multiselect',
226 'description' => __( 'Select the post taxonomy terms to query.', 'responsive-lightbox' ),
227 'options' => array(),
228 'default' => array()
229 ),
230 'post_author' => array(
231 'title' => __( 'Post Author', 'responsive-lightbox' ),
232 'type' => 'multiselect',
233 'description' => __( 'Select the post author.', 'responsive-lightbox' ),
234 'options' => array(),
235 'default' => array()
236 ),
237 'page_parent' => array(
238 'title' => __( 'Page Parent', 'responsive-lightbox' ),
239 'type' => 'multiselect',
240 'description' => __( 'Select the post parent.', 'responsive-lightbox' ),
241 'options' => array(),
242 'default' => array()
243 ),
244 'page_template' => array(
245 'title' => __( 'Page Template', 'responsive-lightbox' ),
246 'type' => 'multiselect',
247 'description' => __( 'Select the page template.', 'responsive-lightbox' ),
248 'options' => array(),
249 'default' => array()
250 )
251 )
252 ),
253 'config' => array(),
254 'design' => array(
255 'options' => array(
256 'show_title' => array(
257 'title' => __( 'Thumbnail title', 'responsive-lightbox' ),
258 'type' => 'select',
259 'description' => __( 'Select title for the gallery thumbnails.', 'responsive-lightbox' ),
260 'default' => 'global',
261 'options' => array_merge( array( 'global' => __( 'Global', 'responsive-lightbox' ) ), Responsive_Lightbox()->settings->image_titles )
262 ),
263 'show_caption' => array(
264 'title' => __( 'Thumbnail caption', 'responsive-lightbox' ),
265 'type' => 'select',
266 'description' => __( 'Select caption for the gallery thumbnails.', 'responsive-lightbox' ),
267 'default' => 'global',
268 'options' => array_merge( array( 'global' => __( 'Global', 'responsive-lightbox' ) ), Responsive_Lightbox()->settings->image_titles )
269 ),
270 'show_icon' => array(
271 'title' => __( 'Thumbnail icon', 'responsive-lightbox' ),
272 'type' => 'radio',
273 'description' => __( 'Select icon for the gallery thumbnails.', 'responsive-lightbox' ),
274 'default' => '0',
275 'options' => Responsive_Lightbox()->settings->image_icons
276 ),
277 'hover_effect' => array(
278 'title' => __( 'Hover effect', 'responsive-lightbox' ),
279 'type' => 'select',
280 'description' => __( 'Select thumbnail effect on hover.', 'responsive-lightbox' ),
281 'default' => '0',
282 'options' => array(
283 '0' => __( 'none', 'responsive-lightbox' ),
284 '1' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 1 ),
285 '2' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 2 ),
286 '3' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 3 ),
287 '4' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 4 ),
288 '5' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 5 ),
289 '6' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 6 ),
290 '7' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 7 ),
291 '8' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 8 ),
292 '9' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 9 )
293 )
294 ),
295 'title_color' => array(
296 'title' => __( 'Title Color', 'responsive-lightbox' ),
297 'type' => 'color_picker',
298 'default' => '#ffffff'
299 ),
300 'caption_color' => array(
301 'title' => __( 'Caption Color', 'responsive-lightbox' ),
302 'type' => 'color_picker',
303 'default' => '#cccccc'
304 ),
305 'background_color' => array(
306 'title' => __( 'Background Color', 'responsive-lightbox' ),
307 'type' => 'color_picker',
308 'default' => '#000000'
309 ),
310 'background_opacity' => array(
311 'title' => __( 'Background Opacity', 'responsive-lightbox' ),
312 'type' => 'number',
313 'default' => 80,
314 'step' => 1,
315 'min' => 0,
316 'max' => 100,
317 'append' => '%'
318 ),
319 'border_color' => array(
320 'title' => __( 'Border Color', 'responsive-lightbox' ),
321 'type' => 'color_picker',
322 'default' => '#000000'
323 ),
324 'border_width' => array(
325 'title' => __( 'Border Width', 'responsive-lightbox' ),
326 'type' => 'number',
327 'default' => 0,
328 'step' => 1,
329 'min' => 0,
330 'max' => 100,
331 'append' => 'px'
332 )
333 )
334 ),
335 'paging' => array(
336 'options' => array(
337 'pagination' => array(
338 'title' => __( 'Use pagination', 'responsive-lightbox' ),
339 'type' => 'boolean',
340 'label' => __( 'Enable pagination.', 'responsive-lightbox' ),
341 'default' => false
342 ),
343 'pagination_type' => array(
344 'title' => __( 'Pagination type', 'responsive-lightbox' ),
345 'type' => 'select',
346 'description' => __( 'Select pagination type.', 'responsive-lightbox' ),
347 'default' => 'paged',
348 'options' => array(
349 'paged' => __( 'standard', 'responsive-lightbox' ),
350 'ajax' => __( 'AJAX', 'responsive-lightbox' ),
351 'infinite' => __( 'infinite scroll', 'responsive-lightbox' )
352 )
353 ),
354 'pagination_position' => array(
355 'title' => __( 'Pagination position', 'responsive-lightbox' ),
356 'type' => 'select',
357 'description' => __( 'Select pagination position.', 'responsive-lightbox' ),
358 'default' => 'bottom',
359 'options' => array(
360 'bottom' => __( 'bottom', 'responsive-lightbox' ),
361 'top' => __( 'top', 'responsive-lightbox' ),
362 'both' => __( 'top & bottom', 'responsive-lightbox' )
363 )
364 ),
365 'images_per_page' => array(
366 'title' => __( 'Images per page', 'responsive-lightbox' ),
367 'type' => 'number',
368 'description' => __( 'Number of images per page.', 'responsive-lightbox' ),
369 'default' => get_option( 'posts_per_page', 20 ),
370 'step' => 1,
371 'min' => 0
372 ),
373 'load_more' => array(
374 'title' => __( 'Load More', 'responsive-lightbox' ),
375 'type' => 'radio',
376 'description' => __( 'Select the load more trigger (infinite scroll only).', 'responsive-lightbox' ),
377 'default' => 'automatically',
378 'options' => array(
379 'automatically' => __( 'Automatically', 'responsive-lightbox' ),
380 'manually' => __( 'On click', 'responsive-lightbox' )
381 )
382 )
383 )
384 ),
385 'lightbox' => array(
386 'options' => array(
387 'lightbox_enable' => array(
388 'title' => __( 'Enable Lightbox', 'responsive-lightbox' ),
389 'type' => 'boolean',
390 'label' => __( 'Enable lightbox effect for the gallery.', 'responsive-lightbox' ),
391 'default' => true
392 ),
393 'lightbox_image_size' => array(
394 'title' => __( 'Image Size', 'responsive-lightbox' ),
395 'type' => 'select',
396 'description' => __( 'Select image size for gallery lightbox.', 'responsive-lightbox' ),
397 'default' => 'global',
398 'options' => $sizes
399 ),
400 'lightbox_custom_size' => array(
401 'title' => __( 'Custom size', 'responsive-lightbox' ),
402 'type' => 'multiple',
403 'description' => __( 'Choose the custom image size for gallery lightbox (used if Custom Image size is selected).', 'responsive-lightbox' ),
404 'fields' => array(
405 'lightbox_custom_size_width' => array(
406 'type' => 'number',
407 'append' => __( 'width in px', 'responsive-lightbox' ),
408 'default' => (int) get_option( 'large_size_w' )
409 ),
410 'lightbox_custom_size_height' => array(
411 'type' => 'number',
412 'append' => __( 'height in px', 'responsive-lightbox' ),
413 'default' => (int) get_option( 'large_size_h' )
414 )
415 )
416 ),
417 'lightbox_image_title' => array(
418 'title' => __( 'Image Title', 'responsive-lightbox' ),
419 'type' => 'select',
420 'description' => __( 'Select image title for gallery lightbox.', 'responsive-lightbox' ),
421 'default' => 'global',
422 'options' => array( 'global' => __( 'Global', 'responsive-lightbox' ) ) + Responsive_Lightbox()->settings->image_titles
423 ),
424 'lightbox_image_caption' => array(
425 'title' => __( 'Image Caption', 'responsive-lightbox' ),
426 'type' => 'select',
427 'description' => __( 'Select image caption for gallery lightbox (used if supported by selected lightbox effect).', 'responsive-lightbox' ),
428 'default' => 'global',
429 'options' => array( 'global' => __( 'Global', 'responsive-lightbox' ) ) + Responsive_Lightbox()->settings->image_titles
430 )
431 )
432 ),
433 'misc' => array(
434 'options' => array(
435 'gallery_title_position' => array(
436 'title' => __( 'Title Position', 'responsive-lightbox' ),
437 'type' => 'select',
438 'description' => __( 'Select where to display the title.', 'responsive-lightbox' ),
439 'default' => 'none',
440 'options' => $positions
441 ),
442 'gallery_description_position' => array(
443 'title' => __( 'Description Position', 'responsive-lightbox' ),
444 'type' => 'select',
445 'description' => __( 'Select where to display the description.', 'responsive-lightbox' ),
446 'default' => 'none',
447 'options' => $positions
448 ),
449 'gallery_description' => array(
450 'title' => __( 'Gallery Description', 'responsive-lightbox' ),
451 'type' => 'textarea',
452 'description' => __( 'Enter the gallery description (optional).', 'responsive-lightbox' ),
453 'default' => '',
454 'class' => 'large-text'
455 ),
456 'gallery_custom_class' => array(
457 'title' => __( 'Custom Classes', 'responsive-lightbox' ),
458 'type' => 'class',
459 'description' => __( 'Add custom, space saparated CSS classes (optional).', 'responsive-lightbox' ),
460 'default' => '',
461 'class' => 'large-text'
462 )
463 )
464 )
465 ) );
466 }
467
468 /**
469 * Add a gallery shortcode.
470 *
471 * @param array $args Shortcode arguments
472 * @return function Generated gallery shortcode
473 */
474 public function gallery_shortcode( $args ) {
475 // prepare defaults
476 $defaults = array(
477 'id' => 0
478 );
479
480 // merge defaults with arguments
481 $args = array_merge( $defaults, $args );
482
483 // parse ID
484 $args['id'] = (int) $args['id'];
485
486 // is it gallery?
487 if ( get_post_type( $args['id'] ) !== 'rl_gallery' )
488 return '';
489
490 // get images
491 $images = $this->get_gallery_images( $args['id'], array( 'exclude' => true ) );
492
493 if ( ! $images )
494 return '';
495
496 $attachments = array();
497
498 // build config
499 foreach ( $images as $image ) {
500 if ( ! empty( $image['id'] ) )
501 $attachments[] = $image['id'];
502 }
503
504 // get config data
505 $config = get_post_meta( $args['id'], '_rl_config', true );
506
507 // prepare gallery shortcode parameters
508 $fields = array();
509
510 if ( ! empty( $config['menu_item'] ) ) {
511 // assign data from db
512 $data = $config[$config['menu_item']];
513
514 foreach ( Responsive_Lightbox()->frontend->get_default_gallery_fields() as $field_name => $field_args ) {
515 // replace default values
516 if ( array_key_exists( $field_name, $data ) )
517 $fields[$field_name] = $data[$field_name];
518 }
519
520 // is it default gallery type?
521 if ( $config['menu_item'] === 'default' ) {
522 // set new gallery type
523 $gallery_type = Responsive_Lightbox()->options['settings']['builder_gallery'];
524
525 // assign gallery settings and defaults
526 $gallery_fields = Responsive_Lightbox()->settings->settings[$gallery_type . '_gallery']['fields'];
527 $gallery_defaults = Responsive_Lightbox()->options[$gallery_type . '_gallery'];
528 } else {
529 $gallery_type = $config['menu_item'];
530
531 // assign gallery settings and defaults
532 $gallery_fields = Responsive_Lightbox()->settings->settings[$config['menu_item'] . '_gallery']['fields'];
533 $gallery_defaults = Responsive_Lightbox()->defaults[$config['menu_item'] . '_gallery'];
534 }
535
536 if ( isset( $gallery_fields, $gallery_defaults ) ) {
537 // run through all fields
538 foreach ( $gallery_fields as $field_name => $field_args ) {
539 if ( $field_args['type'] === 'multiple' ) {
540 foreach ( $field_args['fields'] as $subfield_name => $subfield_args ) {
541 // field exists in db?
542 if ( array_key_exists( $subfield_name, $data ) )
543 $fields[$subfield_name] = $data[$subfield_name];
544 else
545 $fields[$subfield_name] = $gallery_defaults[$subfield_name];
546 }
547 } else {
548 // field exists in db?
549 if ( array_key_exists( $field_name, $data ) )
550 $fields[$field_name] = $data[$field_name];
551 else
552 $fields[$field_name] = $gallery_defaults[$field_name];
553 }
554 }
555 }
556
557 // add gallery type
558 $fields['type'] = $gallery_type;
559 }
560
561 $shortcode = '';
562
563 foreach ( $fields as $arg => $value ) {
564 $shortcode .= ' ' . $arg . '="' . (string) $value . '"';
565 }
566
567 // get design data
568 $design = get_post_meta( $args['id'], '_rl_design', true );
569
570 if ( ! empty( $design['menu_item'] ) ) {
571 foreach ( $design[$design['menu_item']] as $arg => $value ) {
572 $shortcode .= ' ' . $arg . '="' . (string) $value . '"';
573 }
574 }
575
576 // get lightbox data
577 $lightbox = get_post_meta( $args['id'], '_rl_lightbox', true );
578
579 if ( ! empty( $lightbox['menu_item'] ) ) {
580 foreach ( $lightbox[$lightbox['menu_item']] as $arg => $value ) {
581 $shortcode .= ' ' . $arg . '="' . (string) $value . '"';
582 }
583 }
584
585 return do_shortcode( '[gallery rl_gallery_id="' . $args['id'] .'" include="' . ( empty( $attachments ) ? '' : implode( ',', $attachments ) ) . '"' . $shortcode . ']' );
586 }
587
588 /**
589 * Add a gallery button.
590 *
591 * @param string $editor_id Editor ID
592 * @return void
593 */
594 public function add_gallery_button( $editor_id ) {
595 if ( get_post_type() === 'rl_gallery' )
596 return;
597
598 wp_enqueue_script( 'responsive-lightbox-admin-post', RESPONSIVE_LIGHTBOX_URL . '/js/admin-post.js', array( 'jquery' ), Responsive_Lightbox()->defaults['version'], false );
599
600 wp_localize_script(
601 'responsive-lightbox-admin-post',
602 'rlArgs',
603 array(
604 'nonce' => wp_create_nonce( 'rl-gallery-post' ),
605 'post_id' => get_the_ID()
606 )
607 );
608
609 wp_enqueue_style( 'responsive-lightbox-admin-post', RESPONSIVE_LIGHTBOX_URL . '/css/admin-post.css', array(), Responsive_Lightbox()->defaults['version'] );
610
611 echo '<button type="button" id="rl-insert-modal-gallery-button" class="button" data-editor="' . $editor_id . '"><span class="wp-media-buttons-icon dashicons dashicons-format-gallery"></span> ' . __( 'Add Gallery', 'responsive-lightbox' ) . '</button>';
612 }
613
614 /**
615 * Modal gallery HTML template.
616 *
617 * @return mixed
618 */
619 public function modal_gallery_template() {
620 global $pagenow;
621
622 // display only for post edit pages
623 if ( ! ( ( $pagenow === 'post.php' || $pagenow === 'post-new.php' ) && get_post_type() !== 'rl_gallery' ) )
624 return;
625
626 echo '
627 <div id="rl-modal-gallery" style="display: none;">
628 <div class="media-modal wp-core-ui">
629 <button type="button" class="media-modal-close"><span class="media-modal-icon"><span class="screen-reader-text">' . __( 'Close', 'responsive-lightbox' ) . '</span></span></button>
630 <div class="media-modal-content">
631 <div class="media-frame mode-select wp-core-ui hide-menu hide-router">
632 <div class="media-frame-title">
633 <h1 class="wrap">' . __( 'Insert Gallery', 'responsive-lightbox' ) . ' <a class="rl-reload-galleries page-title-action" href="#">' . __( 'Reload', 'responsive-lightbox' ). '</a><span class="rl-gallery-reload-spinner spinner"></span></h1>
634 </div>
635 <div class="media-frame-content" data-columns="0">
636 <div class="attachments-browser">
637 <div class="media-toolbar">
638 <div class="media-toolbar-primary search-form">
639 <label for="rl-media-search-input" class="screen-reader-text">' . __( 'Search galleries', 'responsive-lightbox' ) . '</label><input type="search" placeholder="' . esc_attr__( 'Search galleries', 'responsive-lightbox' ) . '" id="rl-media-search-input" class="search">
640 </div>
641 </div>
642 <ul class="attachments rl-galleries-list ui-sortable ui-sortable-disabled">
643 </ul>
644 <div class="media-sidebar visible">
645 <h2>' . __( 'Select A Gallery', 'responsive-lightbox' ) . '</h2>
646 <p>' . __( 'To select a gallery simply click on one of the boxes to the left.', 'responsive-lightbox' ) . '</p>
647 <p>' . __( 'To insert your gallery into the editor, click on the "Insert Gallery" button below.', 'responsive-lightbox' ) . '</p>
648 </div>
649 </div>
650 </div>
651 <div class="media-frame-toolbar">
652 <div class="media-toolbar">
653 <div class="media-toolbar-secondary">
654 <div class="media-selection empty">
655 <div class="selection-info">
656 <span class="rl-gallery-count count">' . sprintf( _n( '%s image', '%s images', 0, 'responsive-lightbox' ), 0 ) . '</span>
657 <a href="" class="button-link rl-edit-gallery-link">' . __( 'Edit gallery', 'responsive-lightbox' ) . '</a>
658 </div>
659 <div class="selection-view">
660 <span class="rl-gallery-images-spinner spinner" style="display: none;"></span>
661 <ul class="attachments rl-attachments-list">
662 </ul>
663 </div>
664 </div>
665 </div>
666 <div class="media-toolbar-primary search-form">
667 <button type="button" class="button media-button button-primary button-large rl-media-button-insert-gallery" disabled="disabled">' . __( 'Insert into post', 'responsive-lightbox') . '</button>
668 <button type="button" class="button media-button button-secondary button-large rl-media-button-cancel-gallery">' . __( 'Cancel', 'responsive-lightbox') . '</button>
669 </div>
670 </div>
671 </div>
672 </div>
673 </div>
674 </div>
675 <div class="media-modal-backdrop"></div>
676 </div>';
677 }
678
679 /**
680 * Render gallery field.
681 *
682 * @param string $field Field name
683 * @param string $tab_id Field tab
684 * @param string $menu_item Field parent
685 * @param array $args Field arguments
686 * @param bool $subfield Is this a subfield
687 * @return string Rendered HTML field
688 */
689 public function render_field( $field, $tab_id, $menu_item, $args, $gallery_id, $subfield = false ) {
690 if ( $subfield ) {
691 $template = '%s%s';
692 $html = '';
693 $subhtml = '';
694 } else {
695 $template = $args['type'] === 'section' ? '<th colspan="2"><h3>%s</h3></th>' : '<th><label for="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '">%s</label></th><td>%s</td>';
696 $html = '<tr class="rl-gallery-field-' . $tab_id . '-' . $menu_item . '-' . $field. ' rl-gallery-field-' . $args['type'] . '" data-field_type="' . $args['type'] . '" data-field_name="' . $field . '">';
697 $subhtml = '';
698 }
699
700 switch ( $args['type'] ) {
701 case 'range':
702 $html .= sprintf(
703 $template,
704 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
705 '<input id="rl_' . $tab_id . '_' . $menu_item . '_' . $field . '" type="range" value="' . $args['value'] . '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']" min="' . ( ! empty( $args['min'] ) ? $args['min'] : 0 ) . '"' . ( ! empty( $args['max'] ) ? ' max="' . $args['max'] . '"' : '' ) . ' step="' . ( ! empty( $args['step'] ) ? $args['step'] : 1 ) . '" oninput="this.form.rl_' . $tab_id . '_' . $menu_item . '_' . $field . '_range.value=this.value" /><output class="rl-gallery-field-output" name="rl_' . $tab_id . '_' . $menu_item . '_' . $field . '_range">' . $args['value'] . '</output>' . ( ! empty( $args['append'] ) ? ' <span>' . esc_html( $args['append'] ) . '</span>' : '' ) . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
706 );
707 break;
708
709 case 'radio':
710 $subhtml = '';
711
712 foreach ( $args['options'] as $key => $label ) {
713 $subhtml .= '<label class="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '" for="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '-' . $key . '"><input id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '-' . $key . '" type="radio" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']" value="' . $key . '" ' . checked( $key, $args['value'], false ) . ' />' . esc_html( $label ) . '</label> ';
714 }
715
716 $html .= sprintf(
717 $template,
718 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
719 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
720 );
721 break;
722
723 case 'number':
724 $html .= sprintf(
725 $template,
726 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
727 '<input id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '" class="small-text" type="number" value="' . $args['value'] . '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']" min="' . ( ! empty( $args['min'] ) ? $args['min'] : 0 ) . '"' . ( ! empty( $args['max'] ) ? ' max="' . $args['max'] . '"' : '' ) . ' step="' . ( ! empty( $args['step'] ) ? $args['step'] : 1 ) . '" />' . ( ! empty( $args['append'] ) ? ' <span>' . esc_html( $args['append'] ) . '</span>' : '' ) . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
728 );
729 break;
730
731 case 'text':
732 $html .= sprintf(
733 $template,
734 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
735 '<input id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '"' . ( ! empty( $args['class'] ) ? ' class="' . $args['class'] . '"' : '' ) . ' type="text" value="' . esc_attr( $args['value'] ) . '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']" />' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
736 );
737 break;
738
739 case 'class':
740 case 'textarea':
741 $html .= sprintf(
742 $template,
743 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
744 '<textarea id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '"' . ( ! empty( $args['class'] ) ? ' class="' . $args['class'] . '"' : '' ) . ' name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']">' . esc_textarea( $args['value'] ) . '</textarea>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
745 );
746 break;
747
748 case 'select':
749 $subhtml = '<select id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']">';
750
751 foreach ( $args['options'] as $key => $label ) {
752 $subhtml .= '
753 <option value="' . $key . '" ' . selected( $args['value'], $key, false ) . '>' . $label . '</option>';
754 }
755
756 $html .= sprintf(
757 $template,
758 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
759 $subhtml . '</select>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
760 );
761 break;
762
763 case 'multiselect':
764 $subhtml = '<select multiple="multiple" class="select2" id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '" data-empty="' . ( (int) empty( $args['value'] ) ) . '" data-type="' . $field . '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . '][]">';
765
766 if ( $field === 'post_term' ) {
767 foreach ( $args['options'] as $taxanomy => $data ) {
768 $subhtml .= '<optgroup label="' . esc_attr( $data['label'] ) . '">';
769
770 foreach ( $data['terms'] as $term_id => $name ) {
771 $subhtml .= '<option value="' . $term_id . '" ' . selected( in_array( $term_id, $args['value'], false ), true, false ) . '>' . esc_html( $name ) . '</option>';
772 }
773
774 $subhtml .= '</optgroup>';
775 }
776 } else {
777 foreach ( $args['options'] as $key => $label ) {
778 $subhtml .= '
779 <option value="' . $key . '" ' . selected( in_array( $key, $args['value'], false ), true, false ) . '>' . $label . '</option>';
780 }
781 }
782
783 $html .= sprintf(
784 $template,
785 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
786 $subhtml . '</select>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
787 );
788 break;
789
790 case 'boolean':
791 $html .= sprintf(
792 $template,
793 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
794 '<label class="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '" for="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '"><input id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '" type="checkbox" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']" value="true" ' . checked( $args['value'], true, false ) . ' />' . $args['label'] . '</label>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
795 );
796 break;
797
798 case 'multiple':
799 $subhtml = '';
800
801 foreach ( $args['fields'] as $sub_field => $sub_args ) {
802 $subhtml .= $this->render_field( $sub_field, $tab_id, $menu_item, $sub_args, $gallery_id, true ) . '<br />';
803 }
804
805 $html .= sprintf(
806 $template,
807 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
808 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
809 );
810 break;
811
812 case 'color_picker':
813 $html .= sprintf(
814 $template,
815 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
816 '<input id="rl-' . $tab_id . '-' . $menu_item . '-' . $field. '" class="color-picker" type="text" value="' . $args['value'] . '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']" data-default-color="' . $args['default'] . '" />' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
817 );
818 break;
819
820 case 'media_library':
821 $data = get_post_meta( $gallery_id, '_rl_images', true );
822
823 // get images
824 if ( ( ! empty( $data['menu_item'] ) && $data['menu_item'] === 'media' ) || ! ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-menu-content' ) )
825 $images = $this->get_gallery_images( $gallery_id );
826 else
827 $images = array();
828
829 // get media item template
830 $media_item_template = $this->media_item_template;
831
832 $html .= '
833 <td colspan="2" class="rl-colspan">
834 <input type="hidden" class="rl-gallery-ids" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field. '][ids]" value="' . ( ! empty( $args['value']['ids'] ) ? implode( ',', $args['value']['ids'] ) : '' ) . '">
835 <a href="#" class="rl-gallery-select button button-secondary">' . __( 'Select images', 'responsive-lightbox' ) . '</a>
836 <div class="rl-gallery-content">
837 <ul class="rl-gallery-images rl-gallery-images-media">';
838
839 if ( ! empty( $images ) ) {
840 foreach ( $images as $image ) {
841 if ( $image['id'] === 0 )
842 $excluded_item = $image['url'];
843 else
844 $excluded_item = $image['id'];
845
846 $image_html = $this->get_gallery_image( $image, 'thumbnail' );
847
848 // replace ID and URL of an image
849 $html .= str_replace( '__IMAGE__', '<input type="hidden" class="rl-gallery-exclude" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field. '][exclude][]" value="' . ( in_array( $excluded_item, $args['value']['exclude'], true ) ? $excluded_item : '' ) . '">' . $image_html, str_replace( '__IMAGE_ID__', $image['id'], str_replace( '__IMAGE_STATUS__', in_array( $excluded_item, $args['value']['exclude'], true ) ? 'rl-status-inactive' : 'rl-status-active', $media_item_template ) ) );
850 }
851 }
852
853 $html .= '
854 </ul>
855 </div>
856 </td>';
857 break;
858
859 case 'media_preview':
860 $this->menu_item = $menu_item;
861
862 // get images
863 $images = $this->get_gallery_images( $gallery_id );
864
865 // get media item template
866 $media_item_template = $this->media_item_template;
867
868 $html .= '
869 <td colspan="2" class="rl-colspan">
870 <div class="rl-gallery-preview-inside">
871 <a href="#" class="rl-gallery-update-preview button button-secondary">' . __( 'Update preview', 'responsive-lightbox' ) . '</a><span class="spinner" style="display: none;"></span>
872 </div>
873 <div class="rl-gallery-content">
874 <ul class="rl-gallery-images rl-gallery-images-featured">';
875
876 if ( ! empty( $images ) ) {
877 foreach ( $images as $image ) {
878 if ( empty( $image['id'] ) ) {
879 $excluded_item = $image['url'];
880 $image['id'] = 0;
881 } else {
882 $excluded_item = $image['id'];
883 }
884
885 $image_html = $this->get_gallery_image( $image, 'thumbnail' );
886
887 // replace ID and URL of an image
888 $html .= str_replace( '__IMAGE__', '<input type="hidden" class="rl-gallery-exclude" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field. '][exclude][]" value="' . ( in_array( $excluded_item, $args['value']['exclude'], true ) ? $excluded_item : '' ) . '">' . $image_html, str_replace( '__IMAGE_ID__', $image['id'], str_replace( '__IMAGE_STATUS__', in_array( $excluded_item, $args['value']['exclude'], true ) ? 'rl-status-inactive' : 'rl-status-active', $media_item_template ) ) );
889 }
890 }
891
892 $html .= '
893 </ul>
894 </div>
895 </td>';
896 break;
897
898 default:
899 $html .= sprintf(
900 $template,
901 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
902 apply_filters( 'rl_render_gallery_field_' . $args['type'], $subhtml, $field, $tab_id, $menu_item, $args, $subfield ) . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
903 );
904 }
905
906 if ( ! $subfield )
907 $html .= '</tr>';
908
909 return apply_filters( 'rl_render_gallery_field', $html, $field, $tab_id, $menu_item, $args, $subfield );
910 }
911
912 /**
913 * Sanitize field based on type. Internal use only.
914 *
915 * @param string $field Field name
916 * @param mixed $value Field value
917 * @param array $args Field arguments
918 * @return mixed Sanitized value
919 */
920 public function sanitize_field( $field, $value, $args ) {
921 switch ( $args['type'] ) {
922 case 'radio':
923 case 'select':
924 $value = array_key_exists( $value, $args['options'] ) ? $value : $args['default'];
925 break;
926
927 case 'multiselect':
928 if ( is_array( $value ) ) {
929 // is it post term field?
930 if ( $field === 'post_term' ) {
931 $terms = array();
932
933 foreach ( $args['options'] as $data ) {
934 $terms += $data['terms'];
935 }
936
937 $args['options'] = $terms;
938 }
939
940 $values = array();
941
942 foreach ( $value as $subvalue ) {
943 if ( array_key_exists( $subvalue, $args['options'] ) )
944 $values[] = $subvalue;
945 }
946
947 $value = $values;
948 } else
949 $value = $args['default'];
950 break;
951
952 case 'boolean':
953 $value = $value === 'true';
954 break;
955
956 case 'range':
957 case 'number':
958 $value = (int) $value;
959
960 // is value lower than?
961 if ( isset( $args['min'] ) && $value < $args['min'] )
962 $value = $args['min'];
963
964 // is value greater than?
965 if ( isset( $args['max'] ) && $value > $args['max'] )
966 $value = $args['max'];
967 break;
968
969 case 'class':
970 $value = trim( $value );
971
972 // more than 1 class?
973 if ( strpos( $value, ' ' ) !== false ) {
974 // get unique valid HTML classes
975 $value = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $value ) ) ) );
976
977 if ( ! empty( $value ) )
978 $value = implode( ' ', $value );
979 else
980 $value = '';
981 // single class
982 } else
983 $value = sanitize_html_class( $value );
984 break;
985
986 case 'text':
987 $value = trim( sanitize_text_field( $value ) );
988 break;
989
990 case 'textarea':
991 $value = trim( sanitize_textarea_field( $value ) );
992 break;
993
994 case 'color_picker':
995 if ( preg_match( '/^#[a-f0-9]{6}$/i', $value ) !== 1 )
996 $value = $args['default'];
997 break;
998
999 case 'media_library':
1000 if ( is_array( $value ) ) {
1001 $data = $args['default'];
1002
1003 // check IDs
1004 if ( array_key_exists( 'ids', $value ) ) {
1005 $ids = (string) trim( $value['ids'] );
1006
1007 if ( $ids !== '' )
1008 // get unique and non empty attachment IDs only
1009 $data['ids'] = $this->check_attachments( array_unique( array_filter( array_map( 'intval', explode( ',', $ids ) ) ) ) );
1010 else
1011 $data['ids'] = array();
1012 }
1013
1014 // check excluded items
1015 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
1016 $ids = $strings = array();
1017
1018 foreach ( $value['exclude'] as $exclude_item ) {
1019 $item = trim( $exclude_item );
1020
1021 if ( is_numeric( $item ) )
1022 $ids[] = (int) $item;
1023 elseif ( $item !== '' )
1024 $strings[] = $item;
1025 }
1026
1027 if ( ! empty( $ids ) ) {
1028 // get unique and non empty attachment IDs only
1029 $ids = $this->check_attachments( array_unique( array_filter( $ids ) ) );
1030 }
1031
1032 $data['exclude'] = $ids + $strings;
1033 }
1034
1035 $value = $data;
1036 } else
1037 $value = $args['default'];
1038 break;
1039
1040 case 'media_preview':
1041 if ( is_array( $value ) ) {
1042 $data = $args['default'];
1043
1044 // check excluded items
1045 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
1046 $ids = $strings = array();
1047
1048 foreach ( $value['exclude'] as $exclude_item ) {
1049 $item = trim( $exclude_item );
1050
1051 if ( is_numeric( $item ) )
1052 $ids[] = (int) $item;
1053 elseif ( $item !== '' )
1054 $strings[] = $item;
1055 }
1056
1057 if ( ! empty( $ids ) ) {
1058 // get unique and non empty attachment IDs only
1059 $ids = $this->check_attachments( array_unique( array_filter( $ids ) ) );
1060 }
1061
1062 $data['exclude'] = $ids + $strings;
1063 }
1064
1065 $value = $data;
1066 } else
1067 $value = $args['default'];
1068 }
1069
1070 return apply_filters( 'rl_sanitize_gallery_field', $value, $args );
1071 }
1072
1073 /**
1074 * Sanitize set of fields.
1075 *
1076 * @param array $items Fields
1077 * @param array $data POST data
1078 * @param string $tab_id Gallery tab
1079 * @param string $menu_item Gallery menu item
1080 * @return array Sanitize fields
1081 */
1082 public function sanitize_fields( $items, $data, $tab_id, $menu_item ) {
1083 $safedata = array();
1084
1085 foreach ( $items as $field => $item ) {
1086 // skip this field
1087 if ( isset( $item['save'] ) && ! $item['save'] )
1088 continue;
1089
1090 // available field?
1091 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$field] ) )
1092 $safedata[$tab_id][$menu_item][$field] = $this->sanitize_field( $field, $data[$tab_id][$menu_item][$field], $item );
1093 // boolean field?
1094 elseif ( $item['type'] === 'boolean' )
1095 $safedata[$tab_id][$menu_item][$field] = false;
1096 // multiple fields?
1097 elseif ( $item['type'] === 'multiple' ) {
1098 foreach ( $item['fields'] as $subfield => $subitem ) {
1099 // available subfield?
1100 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$subfield] ) )
1101 $safedata[$tab_id][$menu_item][$subfield] = $this->sanitize_field( $subfield, $data[$tab_id][$menu_item][$subfield], $subitem );
1102 // boolean subfield?
1103 elseif ( $subitem['type'] === 'boolean' )
1104 $safedata[$tab_id][$menu_item][$subfield] = false;
1105 // any other case
1106 else
1107 $safedata[$tab_id][$menu_item][$subfield] = $subitem['default'];
1108 }
1109 // any other case
1110 } else
1111 $safedata[$tab_id][$menu_item][$field] = $item['default'];
1112 }
1113
1114 return $safedata;
1115 }
1116
1117 /**
1118 * Add menu tabs after the post title.
1119 *
1120 * @param object $post Post object
1121 * @return mixed
1122 */
1123 public function after_title_nav_menu( $post ) {
1124 if ( $post->post_type !== 'rl_gallery' )
1125 return;
1126
1127 global $wp_meta_boxes;
1128
1129 $active_tab = ! empty( $_GET['rl_active_tab'] ) && array_key_exists( $_GET['rl_active_tab'], $this->tabs ) ? $_GET['rl_active_tab'] : 'images';
1130
1131 // this will be moved to #postbox-container-2 using js to avoid mobile devices problem
1132 echo '
1133 <h2 class="nav-tab-wrapper">';
1134
1135 foreach ( $this->tabs as $key => $data ) {
1136 echo '
1137 <a id="rl-gallery-tab-' . $key . '" class="rl-gallery-tab nav-tab' . ( $key === $active_tab ? ' nav-tab-active' : '' ) . '" href="#' . $key . '">' . $data['label'] . '</a>';
1138 }
1139
1140 echo '
1141 </h2>';
1142
1143 do_meta_boxes( $post->post_type, 'after_title', $post );
1144
1145 unset( $wp_meta_boxes[$post->post_type]['after_title'] );
1146 }
1147
1148 /**
1149 * Add class to hide metabox.
1150 *
1151 * @param array $classes Classes
1152 * @return array Classes
1153 */
1154 public function hide_metabox( $classes ) {
1155 $classes[] = 'rl-metabox-content';
1156 $classes[] = 'rl-hide-metabox';
1157
1158 return $classes;
1159 }
1160
1161 /**
1162 * Add class to display the metabox.
1163 *
1164 * @param array $classes Classes
1165 * @return array Classes
1166 */
1167 function display_metabox( $classes ) {
1168 $classes[] = 'rl-metabox-content';
1169 $classes[] = 'rl-display-metabox';
1170
1171 return $classes;
1172 }
1173
1174 /**
1175 * Add active tab to post redirect destination URL.
1176 *
1177 * @param string $location Destination URL
1178 * @return string Detination URL with extra arg
1179 */
1180 function add_active_tab( $location ) {
1181 return add_query_arg( 'rl_active_tab', ! empty( $_POST['rl_active_tab'] ) && array_key_exists( $_POST['rl_active_tab'], $this->tabs ) ? $_POST['rl_active_tab'] : 'images', $location );
1182 }
1183
1184 /**
1185 * Add metaboxes.
1186 *
1187 * @return void
1188 */
1189 public function add_meta_boxes() {
1190 $active_tab = ! empty( $_GET['rl_active_tab'] ) && array_key_exists( $_GET['rl_active_tab'], $this->tabs ) ? $_GET['rl_active_tab'] : 'images';
1191
1192 // normal metaboxes
1193 foreach ( $this->tabs as $key => $args ) {
1194 if ( $key === 'images' )
1195 $new_args = $args + array( 'tab_id' => $key, 'active_tab' => $active_tab );
1196 else
1197 $new_args = $args + array( 'tab_id' => $key );
1198
1199 // handle metabox class
1200 if ( $active_tab === $key )
1201 add_filter( 'postbox_classes_rl_gallery_responsive-gallery-' . $key, array( $this, 'display_metabox' ) );
1202 else
1203 add_filter( 'postbox_classes_rl_gallery_responsive-gallery-' . $key, array( $this, 'hide_metabox' ) );
1204
1205 add_meta_box( 'responsive-gallery-' . $key, sprintf( __( 'Gallery %s', 'responsive-lightbox' ), $args['label'] ), array( $this, 'add_metabox' ), 'rl_gallery', 'after_title', 'high', $new_args );
1206 }
1207
1208 // side metaboxes
1209 add_meta_box( 'responsive-gallery-shortcode', __( 'Gallery Code', 'responsive-lightbox' ), array( $this, 'shortcode_metabox' ), 'rl_gallery', 'side', 'core' );
1210 }
1211
1212 /**
1213 * Add single metabox.
1214 *
1215 * @param type $post
1216 * @param array $callback_args
1217 * @return mixed
1218 */
1219 public function add_metabox( $post, $callback_args ) {
1220 $html = $callback_args['args']['tab_id'] === 'images' ? '<input type="hidden" name="rl_active_tab" value="' . $callback_args['args']['active_tab'] . '" />' : '';
1221
1222 // default menu item
1223 $menu_item = 'options';
1224
1225 // get tab data
1226 $data = get_post_meta( $post->ID, '_rl_' . $callback_args['args']['tab_id'], true );
1227
1228 if ( ! is_array( $data ) )
1229 $data = array();
1230
1231 // maybe add description
1232 $html .= ! empty( $callback_args['args']['description'] ) ? '<p class="rl-gallery-tab-description">' . esc_html( $callback_args['args']['description'] ) . '</p>' : '';
1233
1234 // maybe add menu
1235 if ( ! empty( $callback_args['args']['menu_items'] ) ) {
1236 // get selected menu item
1237 $menu_item = ! empty( $data['menu_item'] ) && in_array( $data['menu_item'], array_keys( $callback_args['args']['menu_items'] ) ) ? $data['menu_item'] : key( $callback_args['args']['menu_items'] );
1238
1239 $html .= '
1240 <div class="rl-gallery-tab-menu rl-gallery-tab-menu-' . $callback_args['args']['tab_id'] . '">';
1241
1242 foreach ( $callback_args['args']['menu_items'] as $menu_key => $menu_label ) {
1243 $html .= '
1244 <label><input type="radio" class="rl-gallery-tab-menu-item" name="rl_gallery[' . $callback_args['args']['tab_id'] . '][menu_item]" value="' . $menu_key . '" ' . checked( $menu_item, $menu_key, false ) . ' />' . esc_html( $menu_label ) . ( $callback_args['args']['tab_id'] === 'config' && $menu_key === 'default' ? ' (' . $this->tabs['config']['menu_items'][Responsive_Lightbox()->options['settings']['builder_gallery']] . ')' : '' ) . '</label>';
1245 }
1246
1247 $html .= '
1248 <span class="spinner" style="display: none;"></span>
1249 </div>';
1250 }
1251
1252 $html .= '
1253 <div class="rl-gallery-tab-content rl-gallery-tab-content-' . $callback_args['args']['tab_id'] . '">';
1254
1255 $html .= ! empty( $callback_args['args']['callback'] ) && is_callable( $callback_args['args']['callback'] ) ? call_user_func( $callback_args['args']['callback'], $callback_args['args']['tab_id'], $data, $menu_item, $post->ID ) : $this->get_metabox_content( $callback_args['args']['tab_id'], $data, $menu_item, $post->ID );
1256
1257 $html .= '
1258 </div>';
1259
1260 echo $html;
1261 }
1262
1263 /**
1264 * Get single metabox content.
1265 *
1266 * @param string $tab_id
1267 * @param array $data
1268 * @param string $menu_item
1269 * @param int $gallery_id Gallery ID
1270 * @return string
1271 */
1272 public function get_metabox_content( $tab_id, $data, $menu_item, $gallery_id = 0 ) {
1273 $html = '
1274 <div class="rl-gallery-tab-inside rl-gallery-tab-inside-' . $tab_id . '-' . $menu_item . '">
1275 <table class="form-table">';
1276
1277 switch ( $tab_id ) {
1278 case 'config':
1279 // get default gallery fields
1280 $default_gallery = Responsive_Lightbox()->frontend->get_default_gallery_fields();
1281
1282 // assign settings and defaults
1283 $settings = Responsive_Lightbox()->settings->settings;
1284 $defaults = Responsive_Lightbox()->defaults;
1285
1286 if ( ! array_key_exists( 'default_gallery', $settings ) )
1287 $settings['default_gallery']['fields'] = $default_gallery;
1288
1289 // assign default values
1290 foreach ( $default_gallery as $field => $field_args ) {
1291 $defaults['default_gallery'][$field] = $field_args['default'];
1292 }
1293
1294 // valid gallery?
1295 if ( array_key_exists( $menu_item . '_gallery', $settings ) && array_key_exists( $menu_item . '_gallery', $defaults ) ) {
1296 if ( $menu_item === 'default' )
1297 $fields = $settings['default_gallery']['fields'];
1298 else {
1299 $fields = Responsive_Lightbox()->frontend->get_unique_fields( $settings['default_gallery']['fields'], $settings[$menu_item . '_gallery']['fields'] );
1300
1301 // add default gallery default values
1302 foreach ( $default_gallery as $field => $field_args ) {
1303 $defaults[$menu_item . '_gallery'][$field] = $field_args['default'];
1304 }
1305 }
1306
1307 foreach ( $fields as $field => $args ) {
1308 if ( $args['type'] === 'multiple' ) {
1309 $new_args = $args;
1310
1311 foreach ( $args['fields'] as $subfield => $subargs ) {
1312 $new_args['fields'][$subfield] = $subargs + array(
1313 'value' => isset( $data[$menu_item], $data[$menu_item][$subfield] ) ? $data[$menu_item][$subfield] : $defaults[$menu_item . '_gallery'][$subfield],
1314 'default' => $defaults[$menu_item . '_gallery'][$subfield]
1315 );
1316 }
1317 } else {
1318 $new_args = $args + array(
1319 'value' => isset( $data[$menu_item], $data[$menu_item][$field] ) ? $data[$menu_item][$field] : $defaults[$menu_item . '_gallery'][$field],
1320 'default' => $defaults[$menu_item . '_gallery'][$field]
1321 );
1322 }
1323
1324 $html .= $this->render_field( $field, $tab_id, $menu_item, $new_args, $gallery_id );
1325 }
1326 // just in case ajax would fail
1327 } else
1328 $html .= '<p>' . __( 'No data', 'responsive-lightbox' ) . '</p>';
1329 break;
1330
1331 default:
1332 foreach ( $this->fields[$tab_id][$menu_item] as $field => $args ) {
1333 // was this field stored in a database?
1334 if ( isset( $args['save'] ) && ! $args['save'] )
1335 $new_args = $args;
1336 elseif ( $args['type'] === 'multiple' ) {
1337 $new_args = $args;
1338
1339 foreach ( $args['fields'] as $subfield => $subargs ) {
1340 $new_args['fields'][$subfield] = $subargs + array( 'value' => isset( $data[$menu_item], $data[$menu_item][$subfield] ) ? $data[$menu_item][$subfield] : $subargs['default'] );
1341 }
1342 } else
1343 $new_args = $args + array( 'value' => isset( $data[$menu_item], $data[$menu_item][$field] ) ? $data[$menu_item][$field] : $args['default'] );
1344
1345 // media preview?
1346 // if ( $tab_id === 'images' && $menu_item === 'featured' && $field === 'attachments' && $args['type'] === 'media_preview' )
1347 // $new_args['subfields'] = $data['featured'];
1348
1349 $html .= $this->render_field( $field, $tab_id, $menu_item, $new_args, $gallery_id );
1350 }
1351 }
1352
1353 $html .= '
1354 </table>
1355 </div>';
1356
1357 return apply_filters( 'rl_gallery_tab_content', $html, $tab_id, $data, $menu_item );
1358 }
1359
1360 /**
1361 * Get gallery images.
1362 *
1363 * @param int $gallery_id
1364 * @param array $args
1365 * @return array
1366 */
1367 public function get_gallery_images( $gallery_id = 0, $args = array() ) {
1368 global $pagenow;
1369
1370 $images = array();
1371 $excluded = array();
1372
1373 // get args
1374 $defaults = array(
1375 'exclude' => false,
1376 'posts_per_page' => -1,
1377 'images_per_page' => 0,
1378 'page' => 1,
1379 'nopaging' => true,
1380 'image_size' => 'large',
1381 'thumbnail_size' => 'thumbnail',
1382 'pagination_type' => 'paged',
1383 'pagination_position' => 'bottom'
1384 );
1385
1386 $args = wp_parse_args( apply_filters( 'rl_get_gallery_images_args', $args, $gallery_id ), $defaults );
1387
1388 // sanitize args
1389 $args['exclude'] = (bool) ! empty( $args['exclude'] );
1390 $args['posts_per_page'] = ! empty( $args['posts_per_page'] ) ? (int) $args['posts_per_page'] : -1;
1391 $args['nopaging'] = (bool) ! empty( $args['nopaging'] );
1392
1393 $paging = get_post_meta( $gallery_id, '_rl_paging', true );
1394
1395 if ( isset( $paging['menu_item'] ) ) {
1396 $pagination = $paging[$paging['menu_item']];
1397
1398 if ( $pagination['pagination'] ) {
1399 $args['nopaging'] = false;
1400 $args['images_per_page'] = $pagination['images_per_page'];
1401 $args['pagination_type'] = $pagination['pagination_type'];
1402
1403 // infinite type?
1404 if ( $args['pagination_type'] === 'infinite' )
1405 $args['pagination_position'] = 'bottom';
1406 else
1407 $args['pagination_position'] = $pagination['pagination_position'];
1408 } else
1409 $args['nopaging'] = true;
1410 }
1411
1412 // is it preview?
1413 if ( ( in_array( $pagenow, array( 'post.php', 'post-new.php' ), true ) && $gallery_id ) || ( isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-preview-content' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['action'] ) && $_POST['action'] === 'rl-post-gallery-preview' ) ) {
1414 $args['images_per_page'] = 0;
1415 }
1416
1417 if ( isset( $_GET['rl_page'] ) )
1418 $args['page'] = (int) $_GET['rl_page'];
1419 else
1420 $args['page'] = (int) $args['page'];
1421
1422 if ( get_post_type( $gallery_id ) === 'rl_gallery' ) {
1423 $data = get_post_meta( $gallery_id, '_rl_images', true );
1424
1425 // already saved gallery?
1426 if ( ! empty( $data ) ) {
1427 $menu_item = ! empty( $this->menu_item ) ? $this->menu_item : $data['menu_item'];
1428
1429 if ( empty( $data[$menu_item] ) )
1430 $data[$menu_item] = array();
1431
1432 switch ( $menu_item ) {
1433 case 'media':
1434 // get attachment ids
1435 $attachments = ! empty( $data[$menu_item]['attachments']['ids'] ) ? array_map( 'absint', $data[$menu_item]['attachments']['ids'] ) : array();
1436
1437 if ( $attachments ) {
1438 if ( $args['exclude'] )
1439 $excluded = ! empty( $data[$menu_item]['attachments']['exclude'] ) ? $data[$menu_item]['attachments']['exclude'] : array();
1440
1441 foreach ( $attachments as $attachment_id ) {
1442 // get attachment image data
1443 if ( ! in_array( $attachment_id, $excluded ) )
1444 $images[] = $this->get_gallery_image_src( $attachment_id, $args['image_size'], $args['thumbnail_size'] );
1445 }
1446 }
1447 break;
1448
1449 case 'featured':
1450 // get attachment ids
1451 $attachments = $this->gallery_query( array_merge( $data[$menu_item], $args ) );
1452
1453 if ( $attachments ) {
1454 if ( $args['exclude'] )
1455 $excluded = ! empty( $data[$menu_item]['attachments']['exclude'] ) ? $data[$menu_item]['attachments']['exclude'] : array();
1456
1457 foreach ( $attachments as $attachment_id ) {
1458 // get attachment image data
1459 if ( ! in_array( $attachment_id, $excluded ) )
1460 $images[] = $this->get_gallery_image_src( $attachment_id, $args['image_size'], $args['thumbnail_size'] );
1461 }
1462 }
1463 }
1464 }
1465 }
1466
1467 $images = apply_filters( 'rl_get_gallery_images_array', $images, $gallery_id, $args );
1468
1469 // save images count
1470 $images_count = count( $images );
1471
1472 if ( metadata_exists( 'post', $gallery_id, '_rl_images_count' ) ) {
1473 $images_count_prev = get_post_meta( $gallery_id, '_rl_images_count', true );
1474
1475 update_post_meta( $gallery_id, '_rl_images_count', $images_count, $images_count_prev );
1476 } else
1477 add_post_meta( $gallery_id, '_rl_images_count', $images_count );
1478
1479 if ( $images && ! $args['nopaging'] && $args['images_per_page'] > 0 ) {
1480 // get part of images
1481 $images = array_slice( $images, ( $args['page'] - 1 ) * $args['images_per_page'], $args['images_per_page'], true );
1482
1483 // pass gallery args
1484 $this->gallery_args = $args;
1485 $this->gallery_args['total'] = (int) ceil( $images_count / $args['images_per_page'] );
1486
1487 // pagination position
1488 if ( $args['pagination_position'] === 'top' )
1489 add_action( 'rl_before_gallery', array( $this, 'do_pagination' ), 10, 2 );
1490 elseif ( $args['pagination_position'] === 'bottom' )
1491 add_action( 'rl_after_gallery', array( $this, 'do_pagination' ), 10, 2 );
1492 else {
1493 add_action( 'rl_before_gallery', array( $this, 'do_pagination' ), 10, 2 );
1494 add_action( 'rl_after_gallery', array( $this, 'do_pagination' ), 10, 2 );
1495 }
1496 }
1497
1498 return apply_filters( 'rl_get_gallery_images', array_values( $images ), $gallery_id, $args );
1499 }
1500
1501 /**
1502 *
1503 */
1504 public function do_pagination( $args, $gallery_id ) {
1505 global $wp;
1506
1507 // get current action
1508 $current_action = current_action();
1509
1510 if ( $current_action === 'rl_before_gallery' )
1511 $class = ' rl-pagination-top';
1512 elseif ( $current_action === 'rl_after_gallery' )
1513 $class = ' rl-pagination-bottom';
1514 else
1515 $class = '';
1516
1517 echo
1518 '<div class="rl-pagination' . $class . '"' . ( $args['pagination_type'] === 'infinite' ? ' data-button="' . $args['load_more'] . '"' : '' ) .'>' .
1519 paginate_links(
1520 array(
1521 'format' => '?rl_page=%#%',
1522 'base' => add_query_arg( array( 'rl_gallery_no' => Responsive_Lightbox()->frontend->gallery_no, 'rl_page' => '%#%' ), $args['pagination_type'] !== 'paged' ? get_permalink( $gallery_id ) : home_url( $wp->request ) ),
1523 'total' => $this->gallery_args['total'],
1524 'current' => $this->gallery_args['page'],
1525 'show_all' => false,
1526 'end_size' => 1,
1527 'mid_size' => 2,
1528 'prev_next' => true,
1529 'prev_text' => __( '&laquo; Previous', 'responsive-lightbox' ),
1530 'next_text' => __( 'Next &raquo;', 'responsive-lightbox' ),
1531 'type' => 'plain',
1532 // 'add_args' => array( 'rl_gallery_no' => Responsive_Lightbox()->frontend->gallery_no ),
1533 'add_args' => '',
1534 'add_fragment' => '',
1535 'before_page_number' => '',
1536 'after_page_number' => ''
1537 )
1538 ) .
1539 '</div>' . ( $args['pagination_type'] === 'infinite' && $args['load_more'] === 'manually' ? '<div class="rl-gallery-button"><button class="rl-button rl-load-more">' . esc_html__( 'Load more', 'responsive-lightbox' ) . '</button></div>' : '' );
1540 }
1541
1542 /**
1543 * Get gallery attachments.
1544 *
1545 * @return string Encoded JSON with HTML content
1546 */
1547 public function get_gallery_page( $args ) {
1548 if ( isset( $_POST['gallery_id'], $_POST['page'], $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'rl_nonce' ) ) {
1549 $_GET['rl_page'] = (int) $_POST['page'];
1550
1551 echo $this->gallery_shortcode( array( 'id' => (int) $_POST['gallery_id'] ) );
1552 }
1553
1554 exit;
1555 }
1556
1557 /**
1558 * Get gallery attachments.
1559 *
1560 * @return string Encoded JSON with HTML content
1561 */
1562 public function post_gallery_preview() {
1563 if ( ! isset( $_POST['post_id'], $_POST['gallery_id'], $_POST['nonce'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) || ! current_user_can( 'edit_post', (int) $_POST['post_id'] ) )
1564 wp_send_json_error();
1565
1566 // parse gallery ID
1567 $gallery_id = (int) $_POST['gallery_id'];
1568
1569 // get gallery data
1570 $data = get_post_meta( $gallery_id, '_rl_images', true );
1571
1572 // prepare data
1573 $attachments = $exclude = array();
1574 $html = '';
1575
1576 $images = $this->get_gallery_images( $gallery_id, array( 'exclude' => true ) );
1577
1578 // count attachments
1579 $images_count = absint( get_post_meta( $gallery_id, '_rl_images_count', true ) );
1580
1581 if ( ! empty( $images ) ) {
1582 foreach ( $images as $image ) {
1583 $html .= '
1584 <li role="checkbox" aria-label="" aria-checked="false" data-id="' . $image['id'] . '" class="attachment save-ready rl-status-active' . '">
1585 <div class="attachment-preview js--select-attachment type-image landscape">
1586 <div class="thumbnail">
1587 <div class="centered">
1588 <img src="' . $image['thumbnail_url'] . '" draggable="false" alt="" />
1589 </div>
1590 </div>
1591 </div>
1592 </li>';
1593 }
1594 }
1595
1596 // send attachments content
1597 wp_send_json_success(
1598 array(
1599 'attachments' => $html,
1600 'count' => sprintf( _n( '%s image', '%s images', $images_count, 'responsive-lightbox' ), $images_count ),
1601 'edit_url' => current_user_can( 'edit_post', $gallery_id ) ? admin_url( 'post.php?post=' . $gallery_id . '&action=edit' ): ''
1602 )
1603 );
1604 }
1605
1606 /**
1607 * Get all galleries.
1608 *
1609 * @return mixed JSON encoded HTML content
1610 */
1611 public function post_get_galleries() {
1612 if ( ! isset( $_POST['post_id'], $_POST['search'], $_POST['nonce'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) || ! current_user_can( 'edit_post', $post_id = (int) $_POST['post_id'] ) )
1613 wp_send_json_error();
1614
1615 $args = array(
1616 'post_type' => 'rl_gallery',
1617 'post_status' => 'publish',
1618 'nopaging' => true,
1619 'posts_per_page' => -1,
1620 'orderby' => 'title',
1621 'order' => 'ASC',
1622 'suppress_filters' => false,
1623 'no_found_rows' => true,
1624 'cache_results' => false
1625 );
1626
1627 $search = wp_unslash( trim( $_POST['search'] ) );
1628
1629 if ( $search !== '' )
1630 $args['s'] = $search;
1631
1632 // get galleries
1633 $query = new WP_Query( $args );
1634
1635 $html = '';
1636
1637 if ( ! empty( $query->posts ) ) {
1638 foreach ( $query->posts as $gallery ) {
1639 // get title
1640 $title = $gallery->post_title !== '' ? $gallery->post_title : __( '(no title)', 'responsive-gallery' );
1641
1642 $html .= '
1643 <li role="checkbox" aria-label="' . esc_attr( $title ) . '" aria-checked="false" data-id="' . $gallery->ID . '" class="attachment save-ready">
1644 <div class="attachment-preview js--select-attachment type-image landscape">
1645 <div class="thumbnail">
1646 <div class="centered">
1647 ' . $this->get_featured_image( $gallery->ID ) . '
1648 </div>
1649 <div class="filename">
1650 <div>' . esc_html( $title ) . '</div>
1651 </div>
1652 </div>
1653 </div>
1654 <button type="button" class="button-link check"><span class="media-modal-icon"></span><span class="screen-reader-text">' . __( 'Deselect', 'responsive-lightbox' ) . '</span></button>
1655 </li>';
1656 }
1657 }
1658
1659 // send galleries content
1660 wp_send_json_success( $html );
1661 }
1662
1663 /**
1664 * Get gallery content based on request.
1665 *
1666 * @return string Encoded JSON with HTML content
1667 */
1668 public function get_menu_content() {
1669 if ( ! isset( $_POST['post_id'], $_POST['tab'], $_POST['menu_item'], $_POST['nonce'] ) || ! check_ajax_referer( 'rl-gallery', 'nonce', false ) || ! current_user_can( 'edit_post', $post_id = (int) $_POST['post_id'] ) || ! array_key_exists( $_POST['tab'], $this->tabs ) )
1670 wp_send_json_error();
1671
1672 // get selected menu item
1673 $menu_item = ! empty( $_POST['menu_item'] ) && in_array( $_POST['menu_item'], array_keys( $this->tabs[$_POST['tab']]['menu_items'] ) ) ? esc_attr( $_POST['menu_item'] ) : key( $this->tabs[$_POST['tab']]['menu_items'] );
1674
1675 // get tab content
1676 wp_send_json_success( $this->get_metabox_content( $_POST['tab'], get_post_meta( $post_id, '_rl_' . $_POST['tab'], true ), $menu_item, $post_id ) );
1677 }
1678
1679 /**
1680 * Get gallery preview content based on request.
1681 *
1682 * @return string Encoded JSON with HTML content
1683 */
1684 public function get_gallery_preview_content() {
1685 if ( ! isset( $_POST['post_id'], $_POST['menu_item'], $_POST['nonce'] ) || ! check_ajax_referer( 'rl-gallery', 'nonce', false ) || ! current_user_can( 'edit_post', $post_id = (int) $_POST['post_id'] ) || ! current_user_can( 'upload_files' ) )
1686 wp_send_json_error();
1687
1688 // get query args
1689 $args = ! empty( $_POST['query'] ) ? wp_unslash( $_POST['query'] ) : array();
1690
1691 // set images menu item
1692 $menu_item = $this->menu_item = ! empty( $_POST['menu_item'] ) ? esc_attr( $_POST['menu_item'] ) : 'media';
1693
1694 // get images
1695 $images = $this->get_gallery_images( $post_id, $args );
1696
1697 // parse excluded images
1698 $excluded = ! empty( $_POST['excluded'] ) ? esc_attr( $_POST['excluded'] ) : array();
1699
1700 // get excluded images
1701 if ( $excluded ) {
1702 $excluded = array_unique( array_filter( array_map( 'esc_attr', explode( ',', $excluded ) ) ) );
1703 }
1704
1705 // get media item template
1706 $media_item_template = $this->media_item_template;
1707
1708 // build html
1709 $html = '';
1710
1711 if ( ! empty( $images ) ) {
1712 foreach ( $images as $image ) {
1713 // replace ID and URL of an image
1714 $html .= str_replace( '__IMAGE__', '<img src="' . $image['thumbnail_url'] . '" width="' . $image['thumbnail_width'] . '" height="' . $image['thumbnail_height'] . '" class="attachment-thumbnail size-thumbnail" alt="" sizes="(max-width: 150px) 100vw, 150px" />', str_replace( '__IMAGE_ID__', $image['id'], str_replace( '__IMAGE_STATUS__', in_array( $image['id'], $excluded, true ) ? 'rl-status-inactive' : 'rl-status-active', $media_item_template ) ) );
1715 }
1716 }
1717
1718 // send JSON encoded HTML
1719 wp_send_json_success( $html );
1720 }
1721
1722 /**
1723 * Get gallery image.
1724 * Based on wp_get_attachment_image() function.
1725 *
1726 * @param array $image
1727 * @param string $size
1728 * @param array attr
1729 * @return array
1730 */
1731 public function get_gallery_image( $image = array(), $size = 'thumbnail', $attr = '' ) {
1732 $html = '';
1733
1734 $image = $this->get_gallery_image_src( $image, $size );
1735
1736 if ( ! empty( $image['url'] ) || ! empty( $image['id'] ) ) {
1737 $size_class = $size;
1738
1739 if ( is_array( $size_class ) )
1740 $size_class = join( 'x', $size_class );
1741
1742 // set parameters
1743 $width = $image['width'];
1744 $height = $image['height'];
1745
1746 $default_attr = array(
1747 'src' => $image['url'],
1748 'class' => 'attachment-' . $size_class . ' size-' . $size_class . ( $height > $width ? ' format-portrait' : ' format-landscape' ),
1749 'alt' => $image['alt']
1750 );
1751
1752 $attr = wp_parse_args( $attr, $default_attr );
1753 $attr = apply_filters( 'rl_get_gallery_image_attributes', $attr, $image, $size );
1754 $attr = array_map( 'esc_attr', $attr );
1755
1756 $html = rtrim( '<img ' . image_hwstring( $width, $height ) );
1757
1758 foreach ( $attr as $name => $value ) {
1759 $html .= ' ' . $name . '="' . $value . '"';
1760 }
1761
1762 $html .= ' />';
1763 }
1764
1765 return apply_filters( 'rl_get_gallery_image', $html, $image, $size );
1766 }
1767
1768 /**
1769 * Get attachment image.
1770 *
1771 * @param int|string|array attachment_id, image url or array of image data
1772 * @param string $image_size
1773 * @param string $thumbnail_size
1774 * @return array
1775 */
1776 public function get_gallery_image_src( $image, $image_size = 'large', $thumbnail_size = 'thumbnail' ) {
1777 $imagedata = array();
1778
1779 // attachment id
1780 if ( is_int( $image ) ) {
1781
1782 $image_src = wp_get_attachment_image_src( $image, $image_size, false );
1783
1784 if ( $image && wp_attachment_is_image( $image ) ) {
1785 if ( $thumbnail_size !== $image_size )
1786 $thumbnail_src = wp_get_attachment_image_src( $image, $thumbnail_size, false );
1787 else
1788 $thumbnail_src = $image_src;
1789
1790 $imagedata = array(
1791 'id' => $image,
1792 'link' => '',
1793 'title' => '',
1794 'caption' => '',
1795 'alt' => '',
1796 'url' => $image_src[0],
1797 'width' => $image_src[1],
1798 'height' => $image_src[2],
1799 'thumbnail_url' => $thumbnail_src[0],
1800 'thumbnail_width' => $thumbnail_src[1],
1801 'thumbnail_height' => $thumbnail_src[2]
1802 );
1803 }
1804
1805 // image url
1806 } elseif ( is_string( $image ) ) {
1807
1808 $imagedata['url'] = $image;
1809
1810 @list( $imagedata['width'], $imagedata['height'] ) = getimagesize( $imagedata['url'] );
1811
1812 $imagedata = array(
1813 'id' => 0,
1814 'link' => '',
1815 'title' => '',
1816 'caption' => '',
1817 'alt' => '',
1818 'url' => $imagedata['url'],
1819 'width' => $imagedata['width'],
1820 'height' => $imagedata['height'],
1821 'thumbnail_url' => $imagedata['url'],
1822 'thumbnail_width' => $imagedata['width'],
1823 'thumbnail_height' => $imagedata['height']
1824 );
1825
1826 } elseif ( is_array( $image ) ) {
1827 // set width and height from url, if not available
1828 if ( empty( $image['width'] ) || empty( $image['height'] ) ) {
1829 @list( $image['width'], $image['height'] ) = getimagesize( $image['url'] );
1830 }
1831
1832 // set thumbnail data, if not available
1833 if ( empty( $image['thumbnail_url'] ) ) {
1834 $image['thumbnail_url'] = $image['url'];
1835 $image['thumbnail_width'] = $image['width'];
1836 $image['thumbnail_height'] = $image['height'];
1837 } else {
1838 // set thumbnail width and height from url, if not available
1839 if ( empty( $image['thumbnail_width'] ) || empty( $image['thumbnail_height'] ) ) {
1840 @list( $image['thumbnail_width'], $image['thumbnail_height'] ) = getimagesize( $image['thumbnail_url'] );
1841 }
1842 }
1843
1844 /* adjust thumbnail size ?
1845 $image_size_data = $this->get_image_size( $image_size );
1846 $thumbnail_size_data = $this->get_image_size( $thumbnail_size );
1847
1848 if ( $thumbnail_size_data && $image['thumbnail_width'] < $thumbnail_size_data['width'] && $image['thumbnail_height'] < $thumbnail_size_data['height'] ) {
1849 $image['thumbnail_url'] = $image['url'];
1850 $image['thumbnail_width'] = $image['width'];
1851 $image['thumbnail_height'] = $image['height'];
1852 }
1853 */
1854
1855 $imagedata = array(
1856 'id' => ! empty( $image['id'] ) ? (int) $image['id'] : 0,
1857 'link' => ! empty( $image['link'] ) ? esc_url( $image['link'] ) : '',
1858 'title' => ! empty( $image['title'] ) ? esc_html( $image['title'] ) : '',
1859 'caption' => ! empty( $image['caption'] ) ? esc_html( $image['caption'] ) : '',
1860 'alt' => ! empty( $image['alt'] ) ? esc_html( $image['alt'] ) : '',
1861 'url' => ! empty( $image['url'] ) ? esc_url( $image['url'] ) : '',
1862 'width' => ! empty( $image['width'] ) ? (int) $image['width'] : 0,
1863 'height' => ! empty( $image['height'] ) ? (int) $image['height'] : 0,
1864 'thumbnail_url' => ! empty( $image['thumbnail_url'] ) ? esc_url( $image['thumbnail_url'] ) : '',
1865 'thumbnail_width' => ! empty( $image['thumbnail_width'] ) ? (int) $image['thumbnail_width'] : 0,
1866 'thumbnail_height' => ! empty( $image['thumbnail_height'] ) ? (int) $image['thumbnail_height'] : 0,
1867 );
1868 }
1869
1870 // print_r( $imagedata );
1871
1872 return apply_filters( 'rl_get_gallery_image_src', $imagedata, $image, $image_size, $thumbnail_size );
1873 }
1874
1875 /**
1876 * Get gallery featured image.
1877 *
1878 * @param int $gallery_id
1879 * @param $size array
1880 * @param attr array
1881 * @return array
1882 */
1883 public function get_featured_image( $gallery_id, $size = 'thumbnail', $attr = '' ) {
1884 $html = '';
1885 $image = $this->get_featured_image_src( $gallery_id );
1886
1887 if ( $image ) {
1888 $html = $this->get_gallery_image( $image, $size, $attr );
1889 }
1890
1891 return apply_filters( 'rl_get_featured_image', $html, $gallery_id, $size );
1892 }
1893
1894 /**
1895 * Get gallery featured image data.
1896 *
1897 * @param int $gallery_id
1898 * @return array
1899 */
1900 public function get_featured_image_src( $gallery_id ) {
1901 // get featured image data
1902 $featured_image_type = get_post_meta( $gallery_id, '_rl_featured_image_type', true );
1903 $featured_image = get_post_meta( $gallery_id, '_rl_featured_image', true );
1904
1905 switch ( $featured_image_type ) {
1906 case 'url':
1907 $image = esc_url( $featured_image );
1908 break;
1909
1910 case 'id':
1911 $image = (int) $featured_image;
1912 break;
1913
1914 case 'image':
1915 default:
1916 // get gallery images
1917 $images = $this->get_gallery_images( $gallery_id, array( 'exclude' => true ) );
1918
1919 // set image data
1920 if ( $images )
1921 $image = reset( $images );
1922 else
1923 $image = 0;
1924 }
1925
1926 // return only the first image
1927 return apply_filters( 'rl_get_featured_image_src', $image, $gallery_id, $featured_image_type, $featured_image );
1928 }
1929
1930 /**
1931 * Get featured gallery attachments.
1932 *
1933 * @param array $args Query arguments
1934 * @return array Attachment IDs
1935 */
1936 public function gallery_query( $args ) {
1937 $attachments = array();
1938
1939 // get fields
1940 $fields = $this->fields['images']['featured'];
1941
1942 // force these settings
1943 $args['fields'] = 'ids';
1944 $args['tax_query'] = array();
1945 $args['meta_query'] = array();
1946 $args['author__in'] = array();
1947 $args['post_parent__in'] = array();
1948
1949 // get image source
1950 $args['image_source'] = isset( $args['image_source'] ) && array_key_exists( $args['image_source'], $fields['image_source']['options'] ) ? $args['image_source'] : $fields['image_source']['default'];
1951 // get images per post
1952 $args['images_per_post'] = isset( $args['images_per_post'] ) ? absint( $args['images_per_post'] ) : $fields['images_per_post']['default'];
1953
1954 $args['number_of_posts'] = isset( $args['number_of_posts'] ) ? (int) $args['number_of_posts'] : $fields['number_of_posts']['default'];
1955
1956 // get all posts?
1957 if ( $args['number_of_posts'] <= 0 )
1958 $args['number_of_posts'] = -1;
1959
1960 // convert to query arg
1961 $args['posts_per_page'] = $args['number_of_posts'];
1962
1963 $args['order'] = isset( $args['order'] ) && array_key_exists( $args['order'], $fields['order']['options'] ) ? $args['order'] : $fields['order']['default'];
1964 $args['orderby'] = isset( $args['orderby'] ) && array_key_exists( $args['orderby'], $fields['orderby']['options'] ) ? $args['orderby'] : $fields['orderby']['default'];
1965 $args['offset'] = isset( $args['offset'] ) ? absint( $args['offset'] ) : 0;
1966
1967 $tax_queries = array(
1968 'post_format' => array(),
1969 'post_term' => array()
1970 );
1971
1972 $meta_queries = array(
1973 'page_template' => array(),
1974 'image_source' => array()
1975 );
1976
1977 // post type
1978 if ( ! empty( $args['post_type'] ) ) {
1979 // assign post types
1980 $post_types = $args['post_type'];
1981
1982 // clear post types
1983 $args['post_type'] = array();
1984
1985 foreach ( $post_types as $post_type ) {
1986 if ( array_key_exists( $post_type, $fields['post_type']['options'] ) )
1987 $args['post_type'][] = $post_type;
1988 }
1989 } else
1990 $args['post_type'] = 'any';
1991
1992 // post status
1993 if ( ! empty( $args['post_status'] ) ) {
1994 // assign post statuses
1995 $post_statuses = $args['post_status'];
1996
1997 // clear post statuses
1998 $args['post_status'] = array();
1999
2000 foreach ( $post_statuses as $post_status ) {
2001 if ( array_key_exists( $post_status, $fields['post_status']['options'] ) )
2002 $args['post_status'][] = $post_status;
2003 }
2004 }
2005
2006 // post format
2007 if ( ! empty( $args['post_format'] ) ) {
2008 // assign post formats
2009 $post_formats = $args['post_format'];
2010
2011 foreach ( $post_formats as $post_format ) {
2012 if ( array_key_exists( $post_format, $fields['post_format']['options'] ) ) {
2013 // standard format?
2014 if ( $post_format === 'standard' ) {
2015 $tax_queries['post_format'][] = array(
2016 'relation' => 'OR',
2017 array(
2018 'taxonomy' => 'post_format',
2019 'field' => 'slug',
2020 'terms' => array( 'post-format-standard' )
2021 ),
2022 array(
2023 'taxonomy' => 'post_format',
2024 'field' => 'slug',
2025 'operator' => 'NOT EXISTS'
2026 )
2027 );
2028 } else {
2029 $tax_queries['post_format'][] = array(
2030 'taxonomy' => 'post_format',
2031 'field' => 'slug',
2032 'terms' => array( 'post-format-' . $post_format )
2033 );
2034 }
2035 }
2036 }
2037
2038 unset( $args['post_format'] );
2039 }
2040
2041 // page template
2042 if ( ! empty( $args['page_template'] ) ) {
2043 foreach ( $args['page_template'] as $page_template ) {
2044 if ( array_key_exists( $page_template, $fields['page_template']['options'] ) ) {
2045 if ( $page_template === 'default' ) {
2046 $meta_queries['page_template'][] = array(
2047 'relation' => 'OR',
2048 array(
2049 'key' => '_wp_page_template',
2050 'value' => 'default'
2051 ),
2052 array(
2053 'key' => '_wp_page_template',
2054 'value' => ''
2055 ),
2056 array(
2057 'key' => '_wp_page_template',
2058 'compare' => 'NOT EXISTS'
2059 )
2060 );
2061 } else {
2062 $meta_queries['page_template'][] = array(
2063 'key' => '_wp_page_template',
2064 'value' => $page_template
2065 );
2066 }
2067 }
2068 }
2069 }
2070
2071 // post author
2072 if ( ! empty( $args['post_author'] ) ) {
2073 foreach ( $args['post_author'] as $post_author ) {
2074 if ( array_key_exists( $post_author, $fields['post_author']['options'] ) )
2075 $args['author__in'][] = $post_author;
2076 }
2077 }
2078
2079 // page parent
2080 if ( ! empty( $args['page_parent'] ) ) {
2081 foreach ( $args['page_parent'] as $page_parent ) {
2082 if ( array_key_exists( $page_parent, $fields['page_parent']['options'] ) )
2083 $args['post_parent__in'][] = $page_parent;
2084 }
2085 }
2086
2087 // post term
2088 if ( ! empty( $args['post_term'] ) ) {
2089 foreach ( $args['post_term'] as $post_term ) {
2090 if ( array_key_exists( $post_term, $fields['post_term']['options'] ) ) {
2091 $term = get_term( $post_term );
2092
2093 $tax_queries['post_term'][] = array(
2094 'taxonomy' => $term->taxonomy,
2095 'field' => 'term_id',
2096 'terms' => (int) $post_term
2097 );
2098 }
2099 }
2100 }
2101
2102 switch ( $args['image_source'] ) {
2103 case 'thumbnails':
2104 $meta_queries['image_source'][] = array(
2105 'relation' => 'OR',
2106 array(
2107 'key' => '_thumbnail_id',
2108 'compare' => 'EXISTS'
2109 )
2110 );
2111 }
2112
2113 // any tax queries?
2114 if ( ! empty( $tax_queries['post_term'] ) || ! empty( $tax_queries['post_format'] ) ) {
2115 $args['tax_query'] = array( 'relation' => 'AND' );
2116
2117 if ( ! empty( $tax_queries['post_term'] ) )
2118 $args['tax_query'][] = array( 'relation' => 'OR' ) + $tax_queries['post_term'];
2119
2120 if ( ! empty( $tax_queries['post_format'] ) )
2121 $args['tax_query'][] = array( 'relation' => 'OR' ) + $tax_queries['post_format'];
2122 }
2123
2124 // any tax queries?
2125 if ( ! empty( $meta_queries['page_template'] ) || ! empty( $meta_queries['image_source'] ) ) {
2126 $args['meta_query'] = array( 'relation' => 'AND' );
2127
2128 if ( ! empty( $meta_queries['page_template'] ) )
2129 $args['meta_query'][] = array( 'relation' => 'OR', $meta_queries['page_template'] );
2130
2131 if ( ! empty( $meta_queries['image_source'] ) )
2132 $args['meta_query'][] = array( 'relation' => 'OR', $meta_queries['image_source'] );
2133 }
2134
2135 // get posts
2136 $query = new WP_Query( apply_filters( 'rl_gallery_query_args', $args ) );
2137
2138 // get attachments
2139 if ( $query->have_posts() )
2140 $attachments = $this->get_gallery_query_attachments( $query->posts, $args );
2141
2142 return $attachments;
2143 }
2144
2145 /**
2146 * Get query attachments.
2147 *
2148 * @param array $posts Post ids, array or objects
2149 * @param array $args Additional arguments
2150 * @return array
2151 */
2152 public function get_gallery_query_attachments( $posts, $args ) {
2153 $attachments = array();
2154
2155 // any posts?
2156 if ( ! empty( $posts ) ) {
2157 switch ( $args['image_source'] ) {
2158 case 'thumbnails':
2159 foreach ( $posts as $post_id ) {
2160 $attachment_id = (int) get_post_thumbnail_id( $post_id );
2161
2162 if ( ! empty( $attachment_id ) ) {
2163 $attachments[] = $attachment_id;
2164 }
2165 }
2166
2167 array_unique( $attachments );
2168 break;
2169
2170 case 'attached_images':
2171 foreach ( $posts as $post_id ) {
2172 // get attached images, do not use get_attached_media here!
2173 $attachment_ids = (array) get_children(
2174 array(
2175 'post_parent' => $post_id,
2176 'post_status' => 'inherit',
2177 'post_type' => 'attachment',
2178 'post_mime_type' => 'image',
2179 'posts_per_page' => $args['images_per_post'],
2180 'order' => 'ASC',
2181 'orderby' => 'menu_order',
2182 'nopaging' => false,
2183 'page' => 1,
2184 'fields' => 'ids'
2185 )
2186 );
2187
2188 if ( $attachment_ids ) {
2189 foreach ( $attachment_ids as $attachment_id ) {
2190 if ( ! empty( $attachment_id ) ) {
2191 $attachments[] = $attachment_id;
2192 }
2193 }
2194 }
2195 }
2196
2197 array_unique( $attachments );
2198 }
2199 }
2200
2201 return apply_filters( 'rl_get_gallery_query_attachments', $attachments, $posts, $args );
2202 }
2203
2204 /**
2205 * Get query arguments based on type.
2206 *
2207 * @return string Encoded JSON with values
2208 */
2209 public function get_query_args() {
2210 // if ( isset( $_GET['type'], $_GET['nonce'], $_GET['search'], $_GET['page'] ) && check_ajax_referer( 'rl-gallery', 'nonce', false ) ) {
2211 if ( isset( $_POST['type'], $_POST['post_id'], $_POST['nonce'] ) && check_ajax_referer( 'rl-gallery', 'nonce', false ) ) {
2212 $data = $this->prepare_query_args( $_POST['type'] );
2213 $html = '';
2214
2215 if ( ! empty( $data ) ) {
2216 $images = get_post_meta( (int) $_POST['post_id'], '_rl_images', true );
2217
2218 if ( isset( $images['featured'], $images['featured'][$_POST['type']] ) ) {
2219 $selected = $images['featured'][$_POST['type']];
2220 } else
2221 $selected = array();
2222
2223 if ( $_POST['type'] === 'post_term' ) {
2224 foreach ( $data as $taxanomy => $group ) {
2225 $html .= '<optgroup label="' . esc_attr( $group['label'] ) . '">';
2226
2227 foreach ( $group['terms'] as $term_id => $name ) {
2228 $html .= '<option value="' . $term_id . '" ' . selected( in_array( $term_id, $selected, false ), true, false ) . '>' . esc_html( $name ) . '</option>';
2229 }
2230
2231 $html .= '</optgroup>';
2232 }
2233 } else {
2234 foreach ( $data as $key => $label ) {
2235 $html .= '<option value="' . $key . '" ' . selected( in_array( $key, $selected, false ), true, false ) . '>' . $label . '</option>';
2236 }
2237 }
2238 }
2239
2240 wp_send_json_success( array( 'html' => $html ) );
2241 } else
2242 wp_send_json_error();
2243
2244 exit;
2245 }
2246
2247 /**
2248 * Load featured content query args.
2249 *
2250 * @return void
2251 */
2252 public function init_admin() {
2253 global $pagenow;
2254
2255 // prepare query arguments if needed
2256 if ( in_array( $pagenow, array( 'post.php', 'post-new.php', 'edit.php', 'admin-ajax.php' ), true ) ) {
2257 foreach ( array( 'post_type', 'post_status', 'post_format', 'post_term', 'post_author', 'page_parent', 'page_template' ) as $option ) {
2258 $this->fields['images']['featured'][$option]['options'] = $this->prepare_query_args( $option );
2259 }
2260 }
2261
2262 // add default thumbnail image if needed
2263 if ( Responsive_Lightbox()->options['builder']['gallery_builder'] && $pagenow === 'edit.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === 'rl_gallery' )
2264 $this->maybe_generate_thumbnail();
2265 }
2266
2267 /**
2268 * Generate post thumbnail replacement.
2269 */
2270 public function maybe_generate_thumbnail() {
2271 // get attachment
2272 $thumbnail_id = get_posts(
2273 array(
2274 'name' => 'responsive-lightbox-thumbnail',
2275 'post_type' => 'attachment',
2276 'post_status' => 'inherit',
2277 'numberposts' => 1,
2278 'fields' => 'ids'
2279 )
2280 );
2281
2282 // no attachment?
2283 if ( empty( $thumbnail_id ) ) {
2284 // get upload directory data
2285 $wp_upload_dir = wp_upload_dir();
2286
2287 // get file path
2288 $filepath = str_replace( '\\', '/', RESPONSIVE_LIGHTBOX_PATH . 'images/responsive-lightbox-thumbnail.png' );
2289
2290 // get file name
2291 $filename = basename( $filepath );
2292
2293 // new filepath in upload dir
2294 $new_filepath = $wp_upload_dir['path'] . '/' . $filename;
2295
2296 // copty file to upload dir
2297 copy( $filepath, $new_filepath );
2298
2299 // get type of file
2300 $filetype = wp_check_filetype( $filename );
2301
2302 // insert attachment
2303 $thumbnail_id = wp_insert_attachment(
2304 array(
2305 'guid' => $wp_upload_dir['url'] . '/' . $filename,
2306 'post_mime_type' => $filetype['type'],
2307 'post_title' => preg_replace( '/\.[^.]+$/', '', $filename ),
2308 'post_content' => '',
2309 'post_parent' => 0,
2310 'post_status' => 'inherit'
2311 ),
2312 $new_filepath,
2313 0
2314 );
2315
2316 // success?
2317 if ( $thumbnail_id ) {
2318 // make sure that this file is included
2319 require_once( ABSPATH . 'wp-admin/includes/image.php' );
2320
2321 // update database with generated metadata for the attachment
2322 wp_update_attachment_metadata( $thumbnail_id, wp_generate_attachment_metadata( $thumbnail_id, $new_filepath ) );
2323 }
2324 } else
2325 $thumbnail_id = $thumbnail_id[0];
2326
2327 return (int) $thumbnail_id;
2328 }
2329
2330 /**
2331 * Prepare values option list.
2332 *
2333 * @param string $type Value type
2334 * @param string $selected Selected value
2335 * @return string Generated HTML
2336 */
2337 public function prepare_query_args( $type = '' ) {
2338 $html = '';
2339
2340 switch( $type ) {
2341 case 'post_type':
2342 $data = $this->get_post_types();
2343 break;
2344
2345 case 'post_status':
2346 $data = $this->get_post_statuses();
2347 break;
2348
2349 case 'post_format':
2350 $data = $this->get_post_formats();
2351 break;
2352
2353 case 'post_term':
2354 $taxonomies = $this->get_taxonomies();
2355 $new_terms = array();
2356
2357 if ( ! empty( $taxonomies ) ) {
2358 foreach ( $taxonomies as $tax_id => $label ) {
2359 $terms = get_terms(
2360 array(
2361 'taxonomy' => $tax_id,
2362 'orderby' => 'name',
2363 'order' => 'ASC',
2364 'hide_empty' => false,
2365 'fields' => 'id=>name'
2366 )
2367 );
2368
2369 if ( ! empty( $terms ) )
2370 $new_terms[$tax_id] = array(
2371 'label' => $label,
2372 'terms' => $terms
2373 );
2374 }
2375 }
2376
2377 $data = $new_terms;
2378 break;
2379
2380 case 'post_author':
2381 $data = $this->get_users();
2382 break;
2383
2384 case 'page_parent':
2385 $parents = array();
2386 $hierarchical = get_post_types(
2387 array(
2388 'public' => true,
2389 'hierarchical' => true
2390 ),
2391 'objects',
2392 'and'
2393 );
2394
2395 if ( ! empty( $hierarchical ) ) {
2396 foreach ( $hierarchical as $post_type => $object ) {
2397 // get top level hierarchical posts
2398 $query = new WP_Query(
2399 array(
2400 'post_type' => $post_type,
2401 'post_status' => 'publish',
2402 'nopaging' => true,
2403 'posts_per_page' => -1,
2404 'orderby' => 'title',
2405 'order' => 'ASC',
2406 'suppress_filters' => false,
2407 'no_found_rows' => true,
2408 'cache_results' => false,
2409 'post_parent' => 0
2410 )
2411 );
2412
2413 if ( ! empty( $query->posts ) ) {
2414 foreach ( $query->posts as $post ) {
2415 $parents[$post->ID] = trim( $post->post_title ) === '' ? __( 'Untitled' ) : $post->post_title;
2416 }
2417 }
2418 }
2419 }
2420
2421 $data = $parents;
2422 break;
2423
2424 case 'page_template':
2425 $data = $this->get_page_templates();
2426 break;
2427
2428 default:
2429 $data = array();
2430 }
2431
2432 return apply_filters( 'rl_galleries_prepare_query_args', $data, $type );
2433 }
2434
2435 /**
2436 * Get public post types.
2437 *
2438 * @return array Post types
2439 */
2440 public function get_post_types() {
2441 $post_types = get_post_types(
2442 array(
2443 'public' => true
2444 ),
2445 'objects',
2446 'and'
2447 );
2448
2449 $data = array();
2450
2451 if ( ! empty( $post_types ) ) {
2452 foreach ( $post_types as $post_type => $cpt ) {
2453 // skip gallery and attachment post types
2454 if ( $post_type === 'rl_gallery' || $post_type === 'attachment' )
2455 continue;
2456
2457 $data[$post_type] = $cpt->labels->singular_name;
2458 }
2459 }
2460
2461 asort( $data );
2462
2463 return $data;
2464 }
2465
2466 /**
2467 * Get post statuses.
2468 *
2469 * @return array Post statuses
2470 */
2471 public function get_post_statuses() {
2472 $post_statuses = get_post_stati();
2473
2474 asort( $post_statuses );
2475
2476 // remove inherit post status
2477 if ( isset( $post_statuses['inherit'] ) )
2478 unset( $post_statuses['inherit'] );
2479
2480 return $post_statuses;
2481 }
2482
2483 /**
2484 * Get post formats.
2485 *
2486 * @return array Post formats
2487 */
2488 public function get_post_formats() {
2489 $post_formats = array(
2490 'aside' => __( 'Aside' ),
2491 'audio' => __( 'Audio' ),
2492 'chat' => __( 'Chat' ),
2493 'gallery' => __( 'Gallery' ),
2494 'link' => __( 'Link' ),
2495 'photo' => __( 'Photo' ),
2496 'quote' => __( 'Quote' ),
2497 'standard' => __( 'Standard' ),
2498 'status' => __( 'Status' ),
2499 'video' => __( 'Video' )
2500 );
2501
2502 asort( $post_formats );
2503
2504 return $post_formats;
2505 }
2506
2507 /**
2508 * Get
2509 */
2510 public function get_taxonomies() {
2511 $taxonomies = get_taxonomies(
2512 array(
2513 'public' => true
2514 ),
2515 'objects',
2516 'and'
2517 );
2518
2519 // remove post format
2520 if ( array_key_exists( 'post_format', $taxonomies ) )
2521 unset( $taxonomies['post_format'] );
2522
2523 $data = array();
2524
2525 if ( ! empty( $taxonomies ) ) {
2526 foreach ( $taxonomies as $tax_id => $taxonomy ) {
2527 $data[$tax_id] = $taxonomy->labels->singular_name;
2528 }
2529 }
2530
2531 asort( $data );
2532
2533 return $data;
2534 }
2535
2536 /**
2537 * Get users.
2538 *
2539 * @return array Users
2540 */
2541 public function get_users() {
2542 $users = get_users(
2543 array(
2544 'fields' => array( 'ID', 'user_login' )
2545 )
2546 );
2547
2548 $data = array();
2549
2550 if ( ! empty( $users ) ) {
2551 foreach ( $users as $user ) {
2552 $data[(int) $user->ID] = $user->user_login;
2553 }
2554 }
2555
2556 asort( $data );
2557
2558 return $data;
2559 }
2560
2561 /**
2562 * Get page templates.
2563 *
2564 * @return array Page templates
2565 */
2566 public function get_page_templates() {
2567 $data = array();
2568 $page_templates = wp_get_theme()->get_page_templates();
2569
2570 if ( ! empty( $page_templates ) ) {
2571 $page_templates = array_flip( $page_templates );
2572
2573 asort( $page_templates );
2574 }
2575
2576 $data = array_merge( array( 'default' => apply_filters( 'default_page_template_title', __( 'Default Template' ) ) ), $page_templates );
2577
2578 return $data;
2579 }
2580
2581 /**
2582 * Save gallery metadata.
2583 *
2584 * @param int $post_id Post ID
2585 * @param object $post Post object
2586 * @param bool $update Whether this is an existing post being updated or not
2587 * @return void
2588 */
2589 public function save_post( $post_id, $post, $update ) {
2590 if ( wp_is_post_revision( $post_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! $update || in_array( $post->post_status, array( 'trash', 'auto-draft' ), true ) || ( isset( $_GET['action'] ) && $_GET['action'] === 'untrash' ) || empty( $_POST['rl_gallery'] ) )
2591 return;
2592
2593 $this->save_gallery( wp_unslash( $_POST ), $post_id );
2594 }
2595
2596 /**
2597 * Save gallery preview metadata.
2598 *
2599 * @param array $data Gallery data
2600 * @param int $post_id Post ID
2601 * @param bool $preview Whether is it preview
2602 * @return void
2603 */
2604 public function save_gallery( $post_data, $post_id, $preview = false ) {
2605 $data = $post_data['rl_gallery'];
2606
2607 // prepare sanitized data
2608 $safedata = array();
2609
2610 // sanitize all fields
2611 foreach ( $this->fields as $tab_id => $menu_items ) {
2612 switch ( $tab_id ) {
2613 case 'config':
2614 // add menu item
2615 $menu_item = isset( $data[$tab_id], $data[$tab_id]['menu_item'] ) && array_key_exists( $data[$tab_id]['menu_item'], $this->tabs[$tab_id]['menu_items'] ) ? $data[$tab_id]['menu_item'] : reset( $this->tabs[$tab_id]['menu_items'] );
2616
2617 // get default gallery fields
2618 $default_gallery_fields = Responsive_Lightbox()->frontend->get_default_gallery_fields();
2619
2620 // prepare fields
2621 if ( $menu_item === 'default' )
2622 $items = $default_gallery_fields;
2623 else {
2624 // assign settings and defaults
2625 $fields = Responsive_Lightbox()->settings->settings[$menu_item . '_gallery']['fields'];
2626 $defaults = Responsive_Lightbox()->defaults[$menu_item . '_gallery'];
2627
2628 // make a copy
2629 $fields_copy = $fields;
2630
2631 foreach ( $fields_copy as $field_id => $field ) {
2632 if ( $field['type'] === 'multiple' ) {
2633 foreach ( $field['fields'] as $subfield_id => $subfield ) {
2634 $fields[$field_id]['fields'][$subfield_id]['default'] = $defaults[$subfield_id];
2635 }
2636 } else
2637 $fields[$field_id]['default'] = $defaults[$field_id];
2638 }
2639
2640 $items = Responsive_Lightbox()->frontend->get_unique_fields( $default_gallery_fields, $fields );
2641 }
2642
2643 // sanitize fields
2644 $safedata = $this->sanitize_fields( $items, $data, $tab_id, $menu_item );
2645
2646 // add menu item
2647 $safedata[$tab_id]['menu_item'] = $menu_item;
2648 break;
2649
2650 default:
2651 // add menu item
2652 $menu_item = isset( $data[$tab_id], $data[$tab_id]['menu_item'] ) && array_key_exists( $data[$tab_id]['menu_item'], $this->tabs[$tab_id]['menu_items'] ) ? $data[$tab_id]['menu_item'] : 'options';
2653
2654 // prepare fields
2655 $items = $menu_items[$menu_item];
2656
2657 // sanitize fields
2658 $safedata = $this->sanitize_fields( $items, $data, $tab_id, $menu_item );
2659
2660 // add menu item
2661 $safedata[$tab_id]['menu_item'] = $menu_item;
2662 }
2663
2664 $safedata[$tab_id] = apply_filters( 'rl_gallery_tab_metadata', $safedata[$tab_id], $tab_id );
2665
2666 // preview?
2667 if ( $preview )
2668 update_metadata( 'post', $post_id, '_rl_' . $tab_id, $safedata[$tab_id] );
2669 else
2670 update_post_meta( $post_id, '_rl_' . $tab_id, $safedata[$tab_id] );
2671 }
2672
2673 $featured_image_type = ! empty( $post_data['rl_gallery_featured_image'] ) && in_array( $post_data['rl_gallery_featured_image'], array( 'id', 'url', 'image' ), true ) ? $post_data['rl_gallery_featured_image'] : 'id';
2674
2675 switch ( $featured_image_type ) {
2676 case 'url':
2677 $thumbnail_id = $this->maybe_generate_thumbnail();
2678
2679 $featured_image = isset( $post_data['_rl_thumbnail_url'] ) ? esc_url( $post_data['_rl_thumbnail_url'] ) : '';
2680 break;
2681
2682 case 'image':
2683 $thumbnail_id = $this->maybe_generate_thumbnail();
2684
2685 $featured_image = '';
2686 break;
2687
2688 case 'id':
2689 default:
2690 $featured_image = $thumbnail_id = isset( $post_data['_thumbnail_id'] ) ? (int) $post_data['_thumbnail_id'] : 0;
2691 }
2692
2693 // preview?
2694 if ( $preview ) {
2695 update_metadata( 'post', $post_id, '_rl_featured_image_type', $featured_image_type );
2696 update_metadata( 'post', $post_id, '_rl_featured_image', $featured_image );
2697 update_metadata( 'post', $post_id, '_thumbnail_id', $thumbnail_id );
2698 } else {
2699 // update featured image
2700 update_post_meta( $post_id, '_rl_featured_image_type', $featured_image_type );
2701 update_post_meta( $post_id, '_rl_featured_image', $featured_image );
2702 update_post_meta( $post_id, '_thumbnail_id', $thumbnail_id );
2703 }
2704
2705 // update post excerpt
2706 if ( isset( $safedata['misc']['options']['gallery_description'] ) ) {
2707
2708 remove_action( 'save_post_rl_gallery', array( $this, 'save_post' ), 10, 3 );
2709
2710 $postdata = array(
2711 'ID' => $post_id,
2712 'post_excerpt' => wp_kses_post( $safedata['misc']['options']['gallery_description'] ),
2713 );
2714
2715 wp_update_post( $postdata );
2716
2717 add_action( 'save_post_rl_gallery', array( $this, 'save_post' ), 10, 3 );
2718 }
2719 }
2720
2721 /**
2722 * Check attachments IDs.
2723 *
2724 * @param array $attachments Attachment ID's
2725 * @return array Existing image attachment ID's
2726 */
2727 public function check_attachments( $attachments ) {
2728 if ( empty( $attachments ) || ! is_array( $attachments ) )
2729 return array();
2730
2731 $copy = array_map( 'intval', $attachments );
2732
2733 // check attachments
2734 foreach ( $attachments as $key => $attachment_id ) {
2735 // is it an image?
2736 if ( ! wp_attachment_is_image( $attachment_id ) )
2737 unset( $copy[$key] );
2738 }
2739
2740 return $copy;
2741 }
2742
2743 /**
2744 * Display shortcode metabox.
2745 *
2746 * @param object $post Post object
2747 * @return void
2748 */
2749 public function shortcode_metabox( $post ) {
2750 echo '
2751 <p>' . __( 'You can place this gallery anywhere into your posts, pages, custom post types or widgets by using the shortcode below', 'responsive-lightbox' ) . ':</p>
2752 <code class="rl-shortcode">[rl_gallery id=&quot;' . $post->ID . '&quot;]</code>
2753 <p>' . __( 'You can also place this gallery into your template files by using the template tag below', 'responsive-lightbox' ) . ':</p>
2754 <code class="rl-shortcode">if ( function_exists( \'rl_gallery\' ) ) { rl_gallery( \'' . $post->ID . '\' ); }</code>';
2755 }
2756
2757 /**
2758 * Add new event listing columns.
2759 */
2760 public function gallery_columns( $columns ) {
2761 // find title position
2762 $offset = array_search( 'title', array_keys( $columns ) );
2763
2764 // put image column before title
2765 $columns = array_merge(
2766 array_slice( $columns, 0, $offset ),
2767 array(
2768 'image' => __( 'Gallery', 'responsive-lightbox' )
2769 ),
2770 array_slice( $columns, $offset )
2771 );
2772
2773 // put new columns after title
2774 $columns = array_merge(
2775 array_slice( $columns, 0, $offset + 2 ),
2776 array(
2777 'shortcode' => __( 'Shortcode', 'responsive-lightbox' ),
2778 'type' => __( 'Type', 'responsive-lightbox' ),
2779 'source' => __( 'Source', 'responsive-lightbox' )
2780 ),
2781 array_slice( $columns, $offset + 2 )
2782 );
2783
2784 return $columns;
2785 }
2786
2787 /**
2788 * Add new gallery listing columns content.
2789 *
2790 * @return void
2791 */
2792 public function gallery_columns_content( $column_name, $post_id ) {
2793 global $pagenow;
2794
2795 if ( $pagenow === 'edit.php' ) {
2796 switch ( $column_name ) {
2797 case 'image':
2798 // get image data, based on gallery source type
2799 $image = $this->get_featured_image( $post_id, array( 60, 60 ) );
2800 $images_count = absint( get_post_meta( $post_id, '_rl_images_count', true ) );
2801
2802 // display count
2803 if ( ! empty( $image ) )
2804 echo '<span class="media-icon image-icon">' . $image . '</span><span>' . sprintf( _n( '%s image', '%s images', $images_count, 'responsive-lightbox' ), $images_count ) . '</span>';
2805 else
2806 echo '<span class="media-icon image-icon">' . wp_get_attachment_image( 0, array( 60, 60 ), true, array( 'alt' => '' ) ) . '</span>';
2807 break;
2808
2809 case 'shortcode':
2810 echo '<code>[rl_gallery id="' . $post_id . '"]</code>';
2811 break;
2812
2813 case 'type':
2814 $config = get_post_meta( $post_id, '_rl_config', true );
2815
2816 if ( ! empty( $config['menu_item'] ) && array_key_exists( $config['menu_item'], $this->tabs['config']['menu_items'] ) ) {
2817 echo $this->tabs['config']['menu_items'][$config['menu_item']];
2818
2819 if ( $config['menu_item'] === 'default' )
2820 echo ' (' . $this->tabs['config']['menu_items'][Responsive_Lightbox()->options['settings']['builder_gallery']] . ')';
2821 } else
2822 echo '-';
2823 break;
2824
2825 case 'source':
2826 $images = get_post_meta( $post_id, '_rl_images', true );
2827
2828 if ( ! empty( $images['menu_item'] ) && array_key_exists( $images['menu_item'], $this->tabs['images']['menu_items'] ) )
2829 echo $this->tabs['images']['menu_items'][$images['menu_item']];
2830 else
2831 echo '-';
2832 break;
2833 }
2834 }
2835 }
2836
2837 /**
2838 * Get size information for all currently-registered image sizes.
2839 *
2840 * @global $_wp_additional_image_sizes
2841 * @uses get_intermediate_image_sizes()
2842 * @return array $sizes Data for all currently-registered image sizes.
2843 */
2844 public function get_image_sizes() {
2845 global $_wp_additional_image_sizes;
2846
2847 $sizes = array();
2848
2849 foreach ( get_intermediate_image_sizes() as $_size ) {
2850 if ( in_array( $_size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
2851 $sizes[$_size]['width'] = get_option( "{$_size}_size_w" );
2852 $sizes[$_size]['height'] = get_option( "{$_size}_size_h" );
2853 $sizes[$_size]['crop'] = (bool) get_option( "{$_size}_crop" );
2854 } elseif ( isset( $_wp_additional_image_sizes[$_size] ) ) {
2855 $sizes[$_size] = array(
2856 'width' => $_wp_additional_image_sizes[$_size]['width'],
2857 'height' => $_wp_additional_image_sizes[$_size]['height'],
2858 'crop' => $_wp_additional_image_sizes[$_size]['crop'],
2859 );
2860 }
2861 }
2862
2863 return $sizes;
2864 }
2865
2866 /**
2867 * Get size information for a specific image size.
2868 *
2869 * @uses get_image_sizes()
2870 * @param string $size The image size for which to retrieve data.
2871 * @return bool|array $size Size data about an image size or false if the size doesn't exist.
2872 */
2873 public function get_image_size( $size ) {
2874 if ( isset( $this->sizes[$size] ) )
2875 return $this->sizes[$size];
2876 else
2877 return false;
2878 }
2879
2880 /**
2881 * Filter the admin post thumbnail HTML markup
2882 *
2883 * @param mixed $content
2884 * @param int $post_id
2885 * @return mixed
2886 */
2887 public function admin_post_thumbnail_html( $content, $post_id ) {
2888 if ( get_post_type( $post_id ) === 'rl_gallery' ) {
2889 $value = get_post_meta( $post_id, '_rl_featured_image', true );
2890 $type = get_post_meta( $post_id, '_rl_featured_image_type', true );
2891 $type = ! empty( $type ) && in_array( $type, array( 'image', 'id', 'url' ) ) ? $type : 'image';
2892
2893 if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) && $this->maybe_generate_thumbnail() === (int) get_post_meta( $post_id, '_thumbnail_id', true ) ) {
2894 remove_filter( 'admin_post_thumbnail_html', array( $this, 'admin_post_thumbnail_html' ), 10 );
2895
2896 $content = _wp_post_thumbnail_html( 0, $post_id );
2897 }
2898
2899 $content = '
2900 <div class="rl-gallery-featured-image-options">
2901 <p class="howto">' . __( 'Select gallery featured image source:', 'responsive-lightbox' ) . '</p>
2902 <label for="rl-gallery-featured-image"><input id="rl-gallery-featured-image" type="radio" name="rl_gallery_featured_image" value="image" ' . checked( $type, 'image', false ) . ' />' . __( 'First gallery image', 'responsive-lightbox' ) . '</label><br />
2903 <label for="rl-gallery-featured-id"><input id="rl-gallery-featured-id" type="radio" name="rl_gallery_featured_image" value="id" ' . checked( $type, 'id', false ) . ' />' . __( 'Media Library', 'responsive-lightbox' ) . '</label><br />
2904 <label for="rl-gallery-featured-url"><input id="rl-gallery-featured-url" type="radio" name="rl_gallery_featured_image" value="url" ' . checked( $type, 'url', false ) . ' />' . __( 'Custom URL', 'responsive-lightbox' ) . '</label>
2905 </div>
2906 <div class="rl-gallery-featured-image-select">
2907 <div class="rl-gallery-featured-image-select-id"' . ( $type === 'id' ? '' : ' style="display: none;"') . '>' . $content . '</div>
2908 <div class="rl-gallery-featured-image-select-url"' . ( $type === 'url' ? '' : ' style="display: none;"') . '>
2909 <p><input id="_rl_thumbnail_url" class="large-text" name="_rl_thumbnail_url" value="' . ( $type === 'url' ? esc_url( $value ) : '' ) . '" type="text" /></p>
2910 <p class="howto">' . __( 'Custom featured image URL', 'responsive-lightbox' ) . '</p>
2911 </div>
2912 <div class="rl-gallery-featured-image-select-image"' . ( $type === 'image' ? '' : ' style="display: none;"') . '><p class="howto">' . __( 'Dynamically generated first gallery image', 'responsive-lightbox' ) . '</p></div>
2913 </div>
2914 ';
2915 }
2916
2917 return $content;
2918 }
2919
2920 /**
2921 * Modify the resulting HTML so that the feature image is set as a background property.
2922 *
2923 * @param string $html the HTML image tag.
2924 * @param integer $post_id the post whose featured image is to be printed.
2925 * @param string $post_thumbnail_id the post thumbnail ID.
2926 * @param array|string $size the size of the featured image.
2927 * @param array $attr additional attributes.
2928 * @return string the HTML image tag, with a CSS background property set (when required).
2929 */
2930 public function post_thumbnail_html( $html, $post_id = 0, $post_thumbnail_id = '', $size = false, $attr = array() ) {
2931 if ( get_post_type( $post_id ) === 'rl_gallery' ) {
2932 // break if featured image type is media library
2933 $image_type = get_post_meta( $post_id, '_rl_featured_image_type', true );
2934
2935 if ( ! $image_type || $image_type == 'id' )
2936 return $html;
2937
2938 $image_src = $this->get_gallery_image_src( $this->get_featured_image_src( $post_id ) );
2939 $image_url = $image_src['url'];
2940
2941 // add featured image as background in style tag.
2942 $quote = '"';
2943 $style = "style=${quote}background:url( $image_url ) no-repeat center center;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size: cover;${quote}";
2944
2945 $html = str_replace( 'src=', $style . ' src=', $html );
2946
2947 // fix the alt tag (if possible).
2948 $alt = $image_src['alt'];
2949
2950 if ( isset( $attr['alt'] ) )
2951 $alt = $attr['alt'];
2952
2953 if ( $alt ) {
2954 $html = str_replace( '/(alt=\'[^\']+\'\|alt="[^"]+")/', '', $html );
2955 $html = str_replace( 'src=', ' alt="' . esc_attr( $alt ) . '" src=', $html );
2956 }
2957 }
2958
2959 return $html;
2960 }
2961
2962 /**
2963 * Save the revision meta data.
2964 *
2965 * @param int $revision_id
2966 * @return void
2967 */
2968 public function save_revision( $revision_id ) {
2969 // get revision
2970 $revision = get_post( $revision_id );
2971
2972 // get gallery ID
2973 $post_id = $revision->post_parent;
2974
2975 // is it rl gallery?
2976 if ( get_post_type( $post_id ) !== 'rl_gallery' )
2977 return;
2978
2979 $this->revision_id = $revision_id;
2980
2981 // save revisioned meta data
2982 $this->save_gallery( wp_unslash( $_POST ), $revision_id, true );
2983 }
2984
2985 /**
2986 * Update preview link.
2987 *
2988 * @param string $link Preview link
2989 * @param object $post Post object
2990 * @return string
2991 */
2992 public function preview_post_link( $link, $post ) {
2993 // add rl gallery revision ID
2994 if ( $post->post_type === 'rl_gallery' && property_exists( $this, 'revision_id' ) && ! is_null( $this->revision_id ) )
2995 return add_query_arg( 'rl_gallery_revision_id', $this->revision_id, $link );
2996
2997 return $link;
2998 }
2999
3000 /**
3001 * Delete gallery revision at shutdown.
3002 *
3003 * @return void
3004 */
3005 public function shutdown_preview() {
3006 // is it a frontend preview?
3007 if ( is_preview() && isset( $_GET['rl_gallery_revision_id'] ) ) {
3008 global $post;
3009
3010 // cast revision ID
3011 $revision_id = (int) $_GET['rl_gallery_revision_id'];
3012
3013 // is it a valid revision?
3014 if ( get_post_type( $post->ID ) === 'rl_gallery' && wp_is_post_revision( $revision_id ) === $post->ID )
3015 wp_delete_post_revision( $revision_id );
3016 }
3017 }
3018
3019 /**
3020 * Filter gallery meta data.
3021 *
3022 * @param mixed $value Meta value to filter
3023 * @param int $object_id Object ID
3024 * @param string $meta_key Meta key to filter a value for
3025 * @param bool $single Whether to return a single value
3026 * @return mixed
3027 */
3028 public function filter_preview_metadata( $value, $object_id, $meta_key, $single ) {
3029 if ( get_post_type( $object_id ) !== 'rl_gallery' )
3030 return $value;
3031
3032 // get current post
3033 $post = get_post();
3034
3035 // prepare keys
3036 $keys = array( '_rl_featured_image_type', '_rl_featured_image', '_thumbnail_id' );
3037
3038 foreach ( array_keys( $this->tabs ) as $key ) {
3039 $keys[] = '_rl_' . $key;
3040 }
3041
3042 if ( empty( $post ) || (int) $post->ID !== (int) $object_id || ! in_array( $meta_key, $keys, true ) || $post->post_type === 'revision' )
3043 return $value;
3044
3045 // grab the autosave.
3046 $preview = wp_get_post_autosave( $post->ID );
3047
3048 if ( ! is_object( $preview ) )
3049 return $value;
3050
3051 return array( get_post_meta( $preview->ID, $meta_key, $single ) );
3052 }
3053 }