PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.3.3
Responsive Lightbox & Gallery v2.3.3
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
providers 4 years ago class-fast-image.php 8 years ago class-folders-walker.php 7 years ago class-folders.php 4 years ago class-frontend.php 4 years ago class-galleries.php 4 years ago class-multilang.php 4 years ago class-remote-library-api.php 4 years ago class-remote-library.php 4 years ago class-settings.php 4 years ago class-tour.php 4 years ago class-welcome.php 4 years ago class-widgets.php 4 years ago functions.php 4 years ago
class-galleries.php
4267 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 public $fields;
15 public $tab;
16 public $sizes;
17 public $gallery_args;
18 public $current_page = 1;
19 private $menu_item;
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( 'customize_controls_print_footer_scripts', array( $this, 'modal_gallery_template' ) );
40 add_action( 'media_buttons', array( $this, 'add_gallery_button' ) );
41 add_action( 'add_meta_boxes_rl_gallery', array( $this, 'add_meta_boxes' ) );
42 add_action( 'save_post_rl_gallery', array( $this, 'save_post' ), 10, 3 );
43 add_action( 'manage_rl_gallery_posts_custom_column', array( $this, 'gallery_columns_content' ), 10, 2 );
44 add_action( 'admin_action_duplicate_gallery', array( $this, 'duplicate_gallery' ) );
45 add_action( 'wp_ajax_rl-get-menu-content', array( $this, 'get_menu_content' ) );
46 add_action( 'wp_ajax_rl-get-preview-content', array( $this, 'get_gallery_preview_content' ) );
47 add_action( 'wp_ajax_rl-post-get-galleries', array( $this, 'post_get_galleries' ) );
48 add_action( 'wp_ajax_rl-post-gallery-preview', array( $this, 'post_gallery_preview' ) );
49 add_action( 'wp_ajax_rl-get-gallery-page-content', array( $this, 'get_gallery_page' ) );
50 add_action( 'wp_ajax_nopriv_rl-get-gallery-page-content', array( $this, 'get_gallery_page' ) );
51 add_action( '_wp_put_post_revision', array( $this, 'save_revision' ) );
52 add_action( 'shutdown', array( $this, 'shutdown_preview' ) );
53
54 // filters
55 add_filter( 'manage_rl_gallery_posts_columns', array( $this, 'gallery_columns' ) );
56 add_filter( 'admin_post_thumbnail_html', array( $this, 'admin_post_thumbnail_html' ), 10, 2 );
57 add_filter( 'post_thumbnail_html', array( $this, 'post_thumbnail_html' ), 10, 5 );
58 add_filter( 'preview_post_link', array( $this, 'preview_post_link' ) );
59 add_filter( 'post_row_actions', array( $this, 'post_row_actions_duplicate' ), 10, 2 );
60
61 if ( ! empty( $_POST['rl_active_tab'] ) )
62 add_filter( 'redirect_post_location', array( $this, 'add_active_tab' ) );
63 }
64
65 /**
66 * Get default gallery single image template.
67 *
68 * @param array $args Template arguments
69 * @return string Rendered template
70 */
71 public function get_media_item_template( $args = array() ) {
72 $args = array_merge(
73 array(
74 'draggable' => false,
75 'editable' => false,
76 'removable' => false,
77 'changable' => false
78 ),
79 $args
80 );
81
82 return '
83 <li class="rl-gallery-image __IMAGE_STATUS__" data-attachment_id="__IMAGE_ID__"' . ( $args['draggable'] ? ' style="cursor: move;"' : '' ) . '>
84 <div class="rl-gallery-inner">__IMAGE__</div>
85 <div class="rl-gallery-actions">' .
86 ( $args['changeable'] ? '<a href="#" class="rl-gallery-image-status dashicons dashicons-marker" title="' . __( 'Status', 'responsive-lightbox' ) . '"></a>' : '' ) .
87 ( $args['editable'] ? '<a href="#" class="rl-gallery-image-edit dashicons dashicons-edit" title="' . __( 'Edit image', 'responsive-lightbox' ) . '"></a>' : '' ) .
88 ( $args['removable'] ? '<a href="#" class="rl-gallery-image-remove dashicons dashicons-no" title="' . __( 'Remove image', 'responsive-lightbox' ) . '"></a>' : '' ) . '
89 </div>
90 </li>';
91 }
92
93 /**
94 * Load needed data.
95 *
96 * @return void
97 */
98 public function init() {
99 // register shortcode
100 add_shortcode( 'rl_gallery', array( $this, 'gallery_shortcode' ) );
101
102 // get main instance
103 $rl = Responsive_Lightbox();
104
105 $config_menu_items = apply_filters( 'rl_gallery_types', $rl->gallery_types );
106 $config_menu_items['default'] = __( 'Global', 'responsive-lightbox' );
107
108 // set tabs
109 $this->tabs = apply_filters(
110 'rl_gallery_tabs',
111 array(
112 'images' => array(
113 'label' => __( 'Images', 'responsive-lightbox' ),
114 'description' => __( 'The settings below adjust the contents of the gallery.', 'responsive-lightbox' ),
115 'menu_items' => array(
116 'media' => __( 'Media Library', 'responsive-lightbox' ),
117 'featured' => __( 'Featured Content', 'responsive-lightbox' )
118 )
119 ),
120 'config' => array(
121 'label' => __( 'Config', 'responsive-lightbox' ),
122 'description' => __( 'The settings below adjust the configuration options for the gallery.', 'responsive-lightbox' ),
123 'menu_items' => $config_menu_items
124 ),
125 'design' => array(
126 'label' => __( 'Design', 'responsive-lightbox' ),
127 'description' => __( 'The settings below adjust the gallery design options.', 'responsive-lightbox' )
128 ),
129 'paging' => array(
130 'label' => __( 'Paging', 'responsive-lightbox' ),
131 'description' => __( 'The settings below adjust the gallery pagination options.', 'responsive-lightbox' )
132 ),
133 'lightbox' => array(
134 'label' => __( 'Lightbox', 'responsive-lightbox' ),
135 'description' => __( 'The settings below adjust the lightbox options.', 'responsive-lightbox' ),
136 ),
137 'misc' => array(
138 'label' => __( 'Misc', 'responsive-lightbox' ),
139 'description' => __( 'The settings below adjust miscellaneous options.', 'responsive-lightbox' ),
140 )
141 )
142 );
143
144 // add folders if active
145 $this->tabs['images']['menu_items']['folders'] = __( 'Media Folders', 'responsive-lightbox' );
146
147 // add remote library if active
148 $this->tabs['images']['menu_items']['remote_library'] = __( 'Remote Library', 'responsive-lightbox' );
149
150 // use sizes as keys and values
151 $this->sizes = $this->get_image_sizes();
152 $sizes = array_combine( array_keys( $this->sizes ), array_keys( $this->sizes ) );
153
154 // add default, custom and full image size
155 $sizes['full'] = __( 'Full size', 'responsive-lightbox' );
156 $sizes['global'] = __( 'Global', 'responsive-lightbox' );
157 $sizes['rl_custom_size'] = __( 'Custom size', 'responsive-lightbox' );
158
159 // positions
160 $positions = array(
161 'none' => __( 'None', 'responsive-lightbox' ),
162 'top' => __( 'Top', 'responsive-lightbox' ),
163 'bottom' => __( 'Bottom', 'responsive-lightbox' )
164 );
165
166 // merge titles
167 $merged_titles = array( 'global' => __( 'Global', 'responsive-lightbox' ) ) + $rl->settings->image_titles;
168
169 // set fields
170 $this->fields = apply_filters(
171 'rl_gallery_tab_fields',
172 array(
173 'images' => array(
174 'media' => array(
175 'attachments' => array(
176 'title' => '',
177 'type' => 'media_library',
178 'default' => array(
179 'ids' => array(),
180 'exclude' => array()
181 ),
182 'preview' => array(
183 'pagination' => true,
184 'draggable' => true,
185 'editable' => true,
186 'removable' => true,
187 'changeable' => true
188 )
189 )
190 ),
191 'featured' => array(
192 'attachments' => array(
193 'title' => '',
194 'type' => 'media_preview',
195 'default' => array(
196 'exclude' => array()
197 ),
198 'preview' => array(
199 'pagination' => true,
200 'draggable' => false,
201 'editable' => true,
202 'removable' => false,
203 'changeable' => false
204 )
205 ),
206 'number_of_posts' => array(
207 'title' => __( 'Number of Posts', 'responsive-lightbox' ),
208 'type' => 'number',
209 'description' => __( 'Enter the number of posts.', 'responsive-lightbox' ),
210 'default' => 10,
211 'min' => 0
212 ),
213 'orderby' => array(
214 'title' => __( 'Posts Sorting', 'responsive-lightbox' ),
215 'type' => 'select',
216 'description' => __( 'Select the posts sorting.', 'responsive-lightbox' ),
217 'default' => 'date',
218 'options' => array(
219 'id' => __( 'ID', 'responsive-lightbox' ),
220 'author' => __( 'Author', 'responsive-lightbox' ),
221 'title' => __( 'Title', 'responsive-lightbox' ),
222 'name' => __( 'Slug', 'responsive-lightbox' ),
223 'date' => __( 'Date', 'responsive-lightbox' ),
224 'modified' => __( 'Last modified date', 'responsive-lightbox' ),
225 'parent' => __( 'Parent ID', 'responsive-lightbox' ),
226 'rand' => __( 'Random', 'responsive-lightbox' )
227 )
228 ),
229 'order' => array(
230 'title' => __( 'Posts Order', 'responsive-lightbox' ),
231 'type' => 'radio',
232 'description' => __( 'Select the posts order.', 'responsive-lightbox' ),
233 'default' => 'asc',
234 'options' => array(
235 'asc' => __( 'Ascending', 'responsive-lightbox' ),
236 'desc' => __( 'Descending', 'responsive-lightbox' )
237 )
238 ),
239 'offset' => array(
240 'title' => __( 'Posts Offset', 'responsive-lightbox' ),
241 'type' => 'number',
242 'description' => __( 'Enter the posts offset.', 'responsive-lightbox' ),
243 'default' => 0,
244 'min' => 0
245 ),
246 'image_source' => array(
247 'title' => __( 'Image Source', 'responsive-lightbox' ),
248 'type' => 'radio',
249 'description' => __( 'Select the image source.', 'responsive-lightbox' ),
250 'default' => 'thumbnails',
251 'options' => array(
252 'thumbnails' => __( 'Post Thumbnails', 'responsive-lightbox' ),
253 'attached_images' => __( 'Post Attached Images', 'responsive-lightbox' )
254 )
255 ),
256 'images_per_post' => array(
257 'title' => __( 'Images per Post', 'responsive-lightbox' ),
258 'type' => 'number',
259 'description' => __( 'Enter maximum number of images for a post.', 'responsive-lightbox' ),
260 'default' => 1,
261 'min' => 1
262 ),
263 'post_type' => array(
264 'title' => __( 'Post Type', 'responsive-lightbox' ),
265 'type' => 'multiselect',
266 'description' => __( 'Select the post types to query.', 'responsive-lightbox' ),
267 'options' => array(),
268 'default' => array()
269 ),
270 'post_status' => array(
271 'title' => __( 'Post Status', 'responsive-lightbox' ),
272 'type' => 'multiselect',
273 'description' => __( 'Select the post status.', 'responsive-lightbox' ),
274 'options' => array(),
275 'default' => array()
276 ),
277 'post_format' => array(
278 'title' => __( 'Post Format', 'responsive-lightbox' ),
279 'type' => 'multiselect',
280 'description' => __( 'Select the post format.', 'responsive-lightbox' ),
281 'options' => array(),
282 'default' => array()
283 ),
284 'post_term' => array(
285 'title' => __( 'Post Term', 'responsive-lightbox' ),
286 'type' => 'multiselect',
287 'description' => __( 'Select the post taxonomy terms to query.', 'responsive-lightbox' ),
288 'options' => array(),
289 'default' => array()
290 ),
291 'post_author' => array(
292 'title' => __( 'Post Author', 'responsive-lightbox' ),
293 'type' => 'multiselect',
294 'description' => __( 'Select the post author.', 'responsive-lightbox' ),
295 'options' => array(),
296 'default' => array()
297 ),
298 'page_parent' => array(
299 'title' => __( 'Page Parent', 'responsive-lightbox' ),
300 'type' => 'multiselect',
301 'description' => __( 'Select the post parent.', 'responsive-lightbox' ),
302 'options' => array(),
303 'default' => array()
304 ),
305 'page_template' => array(
306 'title' => __( 'Page Template', 'responsive-lightbox' ),
307 'type' => 'multiselect',
308 'description' => __( 'Select the page template.', 'responsive-lightbox' ),
309 'options' => array(),
310 'default' => array()
311 )
312 ),
313 'folders' => array(
314 'attachments' => array(
315 'title' => '',
316 'type' => 'media_preview',
317 'default' => array(
318 'exclude' => array()
319 ),
320 'preview' => array(
321 'pagination' => true,
322 'draggable' => false,
323 'editable' => true,
324 'removable' => false,
325 'changeable' => false
326 )
327 ),
328 'folder' => array(
329 'title' => __( 'Media Folder', 'responsive-lightbox' ),
330 'type' => 'taxonomy',
331 'description' => __( 'Select media folder.', 'responsive-lightbox' ),
332 'default' => array(
333 'id' => 0,
334 'children' => false
335 ),
336 'include_children' => true,
337 'taxonomy' => $rl->options['folders']['media_taxonomy']
338 )
339 ),
340 'remote_library' => array(
341 'attachments' => array(
342 'title' => '',
343 'type' => 'media_preview',
344 'default' => array(
345 'exclude' => array()
346 ),
347 'preview' => array(
348 'pagination' => true,
349 'draggable' => false,
350 'editable' => false,
351 'removable' => false,
352 'changeable' => false
353 )
354 ),
355 'media_search' => array(
356 'title' => __( 'Search string', 'responsive-lightbox' ),
357 'type' => 'text',
358 'description' => __( 'Enter the search phrase.', 'responsive-lightbox' ),
359 'default' => ''
360 ),
361 'media_provider' => array(
362 'title' => __( 'Media Providers', 'responsive-lightbox' ),
363 'type' => 'select',
364 'description' => __( 'Select which remote library should be used.', 'responsive-lightbox' ),
365 'default' => 'all',
366 'options' => array(
367 'all' => __( 'All Media Providers', 'responsive-lightbox' )
368 )
369 ),
370 'response_data' => array(
371 'title' => '',
372 'type' => 'hidden',
373 'description' => '',
374 'default' => '',
375 'callback' => array( $rl->remote_library, 'remote_library_response_data' )
376 )
377 )
378 ),
379 'config' => array(),
380 'design' => array(
381 'options' => array(
382 'show_title' => array(
383 'title' => __( 'Thumbnail title', 'responsive-lightbox' ),
384 'type' => 'select',
385 'description' => __( 'Select title for the gallery thumbnails.', 'responsive-lightbox' ),
386 'default' => 'global',
387 'options' => $merged_titles
388 ),
389 'show_caption' => array(
390 'title' => __( 'Thumbnail caption', 'responsive-lightbox' ),
391 'type' => 'select',
392 'description' => __( 'Select caption for the gallery thumbnails.', 'responsive-lightbox' ),
393 'default' => 'global',
394 'options' => $merged_titles
395 ),
396 'show_icon' => array(
397 'title' => __( 'Thumbnail icon', 'responsive-lightbox' ),
398 'type' => 'radio',
399 'description' => __( 'Select icon for the gallery thumbnails.', 'responsive-lightbox' ),
400 'default' => '0',
401 'options' => array(
402 '0' => __( 'none', 'responsive-lightbox' ),
403 '1' => '',
404 '2' => '',
405 '3' => '',
406 '4' => '',
407 '5' => '',
408 '6' => '',
409 '7' => '',
410 '8' => '',
411 '9' => '',
412 '10' => ''
413 )
414 ),
415 'hover_effect' => array(
416 'title' => __( 'Hover effect', 'responsive-lightbox' ),
417 'type' => 'select',
418 'description' => __( 'Select thumbnail effect on hover.', 'responsive-lightbox' ),
419 'default' => '0',
420 'options' => array(
421 '0' => __( 'none', 'responsive-lightbox' ),
422 '1' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 1 ),
423 '2' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 2 ),
424 '3' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 3 ),
425 '4' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 4 ),
426 '5' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 5 ),
427 '6' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 6 ),
428 '7' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 7 ),
429 '8' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 8 ),
430 '9' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 9 )
431 )
432 ),
433 'title_color' => array(
434 'title' => __( 'Title Color', 'responsive-lightbox' ),
435 'type' => 'color_picker',
436 'default' => '#ffffff'
437 ),
438 'caption_color' => array(
439 'title' => __( 'Caption Color', 'responsive-lightbox' ),
440 'type' => 'color_picker',
441 'default' => '#cccccc'
442 ),
443 'background_color' => array(
444 'title' => __( 'Background Color', 'responsive-lightbox' ),
445 'type' => 'color_picker',
446 'default' => '#000000'
447 ),
448 'background_opacity' => array(
449 'title' => __( 'Background Opacity', 'responsive-lightbox' ),
450 'type' => 'number',
451 'default' => 80,
452 'step' => 1,
453 'min' => 0,
454 'max' => 100,
455 'append' => '%'
456 ),
457 'border_color' => array(
458 'title' => __( 'Border Color', 'responsive-lightbox' ),
459 'type' => 'color_picker',
460 'default' => '#000000'
461 ),
462 'border_width' => array(
463 'title' => __( 'Border Width', 'responsive-lightbox' ),
464 'type' => 'number',
465 'default' => 0,
466 'step' => 1,
467 'min' => 0,
468 'max' => 100,
469 'append' => 'px'
470 )
471 )
472 ),
473 'paging' => array(
474 'options' => array(
475 'pagination' => array(
476 'title' => __( 'Use pagination', 'responsive-lightbox' ),
477 'type' => 'boolean',
478 'label' => __( 'Enable pagination.', 'responsive-lightbox' ),
479 'default' => false
480 ),
481 'pagination_type' => array(
482 'title' => __( 'Pagination type', 'responsive-lightbox' ),
483 'type' => 'select',
484 'description' => __( 'Select pagination type.', 'responsive-lightbox' ),
485 'default' => 'paged',
486 'options' => array(
487 'paged' => __( 'standard', 'responsive-lightbox' ),
488 'ajax' => __( 'AJAX', 'responsive-lightbox' ),
489 'infinite' => __( 'infinite scroll', 'responsive-lightbox' )
490 )
491 ),
492 'pagination_position' => array(
493 'title' => __( 'Pagination position', 'responsive-lightbox' ),
494 'type' => 'select',
495 'description' => __( 'Select pagination position.', 'responsive-lightbox' ),
496 'default' => 'bottom',
497 'options' => array(
498 'bottom' => __( 'bottom', 'responsive-lightbox' ),
499 'top' => __( 'top', 'responsive-lightbox' ),
500 'both' => __( 'top & bottom', 'responsive-lightbox' )
501 )
502 ),
503 'images_per_page' => array(
504 'title' => __( 'Images per page', 'responsive-lightbox' ),
505 'type' => 'number',
506 'description' => __( 'Number of images per page.', 'responsive-lightbox' ),
507 'default' => get_option( 'posts_per_page', 20 ),
508 'step' => 1,
509 'min' => 0
510 ),
511 'load_more' => array(
512 'title' => __( 'Load More', 'responsive-lightbox' ),
513 'type' => 'radio',
514 'description' => __( 'Select the load more trigger (infinite scroll only).', 'responsive-lightbox' ),
515 'default' => 'automatically',
516 'options' => array(
517 'automatically' => __( 'Automatically', 'responsive-lightbox' ),
518 'manually' => __( 'On click', 'responsive-lightbox' )
519 )
520 )
521 )
522 ),
523 'lightbox' => array(
524 'options' => array(
525 'lightbox_enable' => array(
526 'title' => __( 'Enable Lightbox', 'responsive-lightbox' ),
527 'type' => 'boolean',
528 'label' => __( 'Enable lightbox effect for the gallery.', 'responsive-lightbox' ),
529 'default' => true
530 ),
531 'lightbox_image_size' => array(
532 'title' => __( 'Image Size', 'responsive-lightbox' ),
533 'type' => 'select',
534 'description' => __( 'Select image size for gallery lightbox.', 'responsive-lightbox' ),
535 'default' => 'global',
536 'options' => $sizes
537 ),
538 'lightbox_custom_size' => array(
539 'title' => __( 'Custom size', 'responsive-lightbox' ),
540 'type' => 'multiple',
541 'description' => __( 'Choose the custom image size for gallery lightbox (used if Custom Image size is selected).', 'responsive-lightbox' ),
542 'fields' => array(
543 'lightbox_custom_size_width' => array(
544 'type' => 'number',
545 'append' => __( 'width in px', 'responsive-lightbox' ),
546 'default' => (int) get_option( 'large_size_w' )
547 ),
548 'lightbox_custom_size_height' => array(
549 'type' => 'number',
550 'append' => __( 'height in px', 'responsive-lightbox' ),
551 'default' => (int) get_option( 'large_size_h' )
552 )
553 )
554 ),
555 'lightbox_image_title' => array(
556 'title' => __( 'Image Title', 'responsive-lightbox' ),
557 'type' => 'select',
558 'description' => __( 'Select image title for gallery lightbox.', 'responsive-lightbox' ),
559 'default' => 'global',
560 'options' => $merged_titles
561 ),
562 'lightbox_image_caption' => array(
563 'title' => __( 'Image Caption', 'responsive-lightbox' ),
564 'type' => 'select',
565 'description' => __( 'Select image caption for gallery lightbox (used if supported by selected lightbox effect).', 'responsive-lightbox' ),
566 'default' => 'global',
567 'options' => $merged_titles
568 )
569 )
570 ),
571 'misc' => array(
572 'options' => array(
573 'gallery_title_position' => array(
574 'title' => __( 'Title Position', 'responsive-lightbox' ),
575 'type' => 'select',
576 'description' => __( 'Select where to display the title.', 'responsive-lightbox' ),
577 'default' => 'none',
578 'options' => $positions
579 ),
580 'gallery_description_position' => array(
581 'title' => __( 'Description Position', 'responsive-lightbox' ),
582 'type' => 'select',
583 'description' => __( 'Select where to display the description.', 'responsive-lightbox' ),
584 'default' => 'none',
585 'options' => $positions
586 ),
587 'gallery_description' => array(
588 'title' => __( 'Gallery Description', 'responsive-lightbox' ),
589 'type' => 'textarea',
590 'description' => __( 'Enter the gallery description (optional).', 'responsive-lightbox' ),
591 'default' => '',
592 'class' => 'large-text'
593 ),
594 'gallery_custom_class' => array(
595 'title' => __( 'Custom Classes', 'responsive-lightbox' ),
596 'type' => 'class',
597 'description' => __( 'Add custom, space saparated CSS classes (optional).', 'responsive-lightbox' ),
598 'default' => '',
599 'class' => 'large-text'
600 )
601 )
602 )
603 )
604 );
605
606 // is remote library active?
607 if ( $rl->options['remote_library']['active'] ) {
608 // get providers
609 $providers = $rl->remote_library->get_providers();
610 $active_providers = $rl->remote_library->get_active_providers();
611
612 // update active providers
613 foreach ( $active_providers as $provider ) {
614 $this->fields['images']['remote_library']['media_provider']['options'][$provider] = $providers[$provider]['name'];
615 }
616 }
617 }
618
619 /**
620 * Duplicate gallery action in admin.
621 *
622 * @return void
623 */
624 public function duplicate_gallery() {
625 if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) ) || ! isset( $_REQUEST['action'] ) || ! isset( $_REQUEST['rl_gallery_nonce'] ) || ( isset( $_REQUEST['rl_gallery_nonce'] ) && ! wp_verify_nonce( esc_attr( $_REQUEST['rl_gallery_nonce'] ), 'responsive-lightbox-duplicate-gallery' ) ) )
626 wp_die( __( 'No gallery to duplicate has been supplied!', 'responsive-lightbox' ) );
627
628 // get the original post
629 $post_id = ( isset( $_GET['post'] ) ? (int) $_GET['post'] : (int) $_POST['post'] );
630
631 if ( empty( $post_id ) )
632 wp_die( __( 'No gallery to duplicate has been supplied!', 'responsive-lightbox' ) );
633
634 if ( ! current_user_can( 'edit_post', $post_id ) )
635 wp_die( __( 'You do not have permission to copy this gallery.', 'responsive-lightbox' ) );
636
637 $post = get_post( $post_id );
638
639 // copy the post and insert it
640 if ( isset( $post ) && $post != null ) {
641 $new_id = $this->create_gallery_duplicate( $post );
642
643 // redirect to the post list screen
644 wp_redirect( admin_url( 'edit.php?post_type=' . $post->post_type ) );
645 exit;
646 } else
647 wp_die( esc_attr( __( 'Copy creation failed, could not find original gallery:', 'responsive-lightbox' ) ) . ' ' . htmlspecialchars( $post_id ) );
648 }
649
650 /**
651 * Add duplicate link to gallery listing.
652 *
653 * @param array $actions Link actions
654 * @param object $post Post object
655 * @return array
656 */
657 public function post_row_actions_duplicate( $actions, $post ) {
658 global $pagenow;
659
660 if ( $post->post_type !== 'rl_gallery' )
661 return $actions;
662
663 if ( ! current_user_can( 'edit_post', $post->ID ) )
664 return $actions;
665
666 // duplicate link
667 $actions['duplicate_gallery'] = '<a class="duplicate-gallery" title="' . esc_attr__( 'Duplicate this item', 'responsive-lightbox' ) . '" href="' . wp_nonce_url( admin_url( $pagenow . '?post=' . $post->ID . '&action=duplicate_gallery' ), 'responsive-lightbox-duplicate-gallery', 'rl_gallery_nonce' ) . '">' . __( 'Duplicate', 'responsive-lightbox' ) . '</a>';
668
669 return $actions;
670 }
671
672 /**
673 * Create a gallery duplicate.
674 *
675 * @param $post object Post object
676 * @return void|int
677 */
678 public function create_gallery_duplicate( $post ) {
679 // skip revisions
680 if ( $post->post_type == 'revision' )
681 return;
682
683 $new_post = apply_filters(
684 'rl_duplicate_gallery_args',
685 array(
686 'menu_order' => $post->menu_order,
687 'comment_status' => $post->comment_status,
688 'ping_status' => $post->ping_status,
689 'post_author' => $post->post_author,
690 'post_content' => $post->post_content,
691 'post_excerpt' => $post->post_excerpt,
692 'post_mime_type' => $post->post_mime_type,
693 'post_parent' => $post->post_parent,
694 'post_password' => $post->post_password,
695 'post_status' => $post->post_status,
696 'post_title' => $post->post_title,
697 'post_type' => $post->post_type,
698 'post_date' => current_time( 'mysql' ),
699 'post_date_gmt' => get_gmt_from_date( current_time( 'mysql' ) )
700 ),
701 $post
702 );
703
704 $new_post_id = wp_insert_post( $new_post );
705
706 // if the copy is published or scheduled, we have to set a proper slug
707 if ( $new_post['status'] == 'publish' || $new_post['status'] == 'future' ) {
708 $post_name = wp_unique_post_slug( $post->post_name, $new_post_id, $new_post['status'], $post->post_type, $new_post['post_parent'] );
709
710 $new_post = array();
711 $new_post['ID'] = $new_post_id;
712 $new_post['post_name'] = $post_name;
713
714 // update the post into the database
715 wp_update_post( $new_post );
716 }
717
718 // create metadata for the duplicated gallery
719 $this->create_gallery_duplicate_metadata( $new_post_id, $post );
720
721 // copy taxonomies
722 $this->duplicate_gallery_taxonomies( $new_post_id, $post );
723
724 // action hook for developers
725 do_action( 'rl_after_duplicate_gallery', $new_post_id, $post );
726
727 return $new_post_id;
728 }
729
730 /**
731 * Create a gallery duplicate metadata.
732 *
733 * @param int $new_post_id Post ID
734 * @param object $post Post object
735 * @return void
736 */
737 public function create_gallery_duplicate_metadata( $new_post_id, $post ) {
738 if ( empty( $post ) || $post == null )
739 return;
740
741 // meta keys to be copied
742 $meta_keys = apply_filters( 'rl_duplicate_gallery_meta_keys', get_post_custom_keys( $post->ID ) );
743
744 if ( empty( $meta_keys ) )
745 return;
746
747 foreach ( $meta_keys as $meta_key ) {
748 // meta values to be copied
749 $meta_values = apply_filters( 'rl_duplicate_gallery_meta_values', get_post_custom_values( $meta_key, $post->ID ) );
750
751 foreach ( $meta_values as $meta_value ) {
752 $meta_value = maybe_unserialize( $meta_value );
753
754 // add metadata to duplicated post
755 add_post_meta( $new_post_id, $meta_key, $meta_value );
756 }
757 }
758 }
759
760 /**
761 * Copy the taxonomies of a gallery to another gallery.
762 *
763 * @param int $new_post_id Post ID
764 * @param object $post Post object
765 * @return void
766 */
767 function duplicate_gallery_taxonomies( $new_post_id, $post ) {
768 global $wpdb;
769
770 if ( isset( $wpdb->terms ) ) {
771 // clear default category
772 wp_set_object_terms( $new_post_id, null, 'category' );
773
774 // get gallery taxonomies
775 $gallery_taxonomies = get_object_taxonomies( $post->post_type );
776
777 if ( ! empty( $gallery_taxonomies ) ) {
778 foreach ( $gallery_taxonomies as $taxonomy ) {
779 $terms = array();
780
781 // get taxonomy terms
782 $post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'orderby' => 'term_order' ) );
783
784 if ( ! empty( $post_terms ) ) {
785 foreach ( $post_terms as $term ) {
786 $terms[] = $term->slug;
787 }
788 }
789
790 // copy taxonomy terms
791 wp_set_object_terms( $new_post_id, $terms, $taxonomy );
792 }
793 }
794 }
795 }
796
797 /**
798 * Add a gallery shortcode.
799 *
800 * @param array $args Shortcode arguments
801 * @return string Generated gallery shortcode
802 */
803 public function gallery_shortcode( $args ) {
804 // enable only for frontend previews
805 if ( ! is_admin() && is_preview() )
806 add_filter( 'get_post_metadata', array( $this, 'filter_preview_metadata' ), 10, 4 );
807
808 // prepare defaults
809 $defaults = array(
810 'id' => 0
811 );
812
813 // merge defaults with arguments
814 $args = array_merge( $defaults, $args );
815
816 // parse ID
817 $args['id'] = (int) $args['id'];
818
819 // is it gallery?
820 if ( get_post_type( $args['id'] ) !== 'rl_gallery' )
821 return '';
822
823 // get images
824 $images = $this->get_gallery_images( $args['id'], array( 'exclude' => true ) );
825
826 if ( ! $images )
827 return '';
828
829 $attachments = array();
830
831 // build config
832 foreach ( $images as $image ) {
833 if ( ! empty( $image['id'] ) )
834 $attachments[] = $image['id'];
835 }
836
837 // get config data
838 $config = get_post_meta( $args['id'], '_rl_config', true );
839
840 // prepare gallery shortcode parameters
841 $fields = array();
842
843 // get main instance
844 $rl = Responsive_Lightbox();
845
846 // valid menu item?
847 if ( ! empty( $config['menu_item'] ) ) {
848 // assign data from db
849 $data = $config[$config['menu_item']];
850
851 foreach ( $rl->frontend->get_default_gallery_fields() as $field_name => $field_args ) {
852 // replace default values
853 if ( array_key_exists( $field_name, $data ) )
854 $fields[$field_name] = $data[$field_name];
855 }
856
857 // is it default gallery type?
858 if ( $config['menu_item'] === 'default' ) {
859 // set new gallery type
860 $gallery_type = $rl->options['settings']['builder_gallery'];
861
862 // assign gallery settings
863 if ( array_key_exists( $gallery_type . '_gallery', $rl->settings->settings ) )
864 $gallery_fields = $rl->settings->settings[$gallery_type . '_gallery']['fields'];
865
866 // assign gallery defaults
867 if ( array_key_exists( $gallery_type . '_gallery', $rl->options ) )
868 $gallery_defaults = $rl->options[$gallery_type . '_gallery'];
869 } else {
870 $gallery_type = $config['menu_item'];
871
872 // assign gallery settings
873 if ( array_key_exists( $config['menu_item'] . '_gallery', $rl->settings->settings ) )
874 $gallery_fields = $rl->settings->settings[$config['menu_item'] . '_gallery']['fields'];
875
876 // assign gallery defaults
877 if ( array_key_exists( $config['menu_item'] . '_gallery', $rl->defaults ) )
878 $gallery_defaults = $rl->defaults[$config['menu_item'] . '_gallery'];
879 }
880
881 if ( isset( $gallery_fields, $gallery_defaults ) ) {
882 // run through all fields
883 foreach ( $gallery_fields as $field_name => $field_args ) {
884 if ( $field_args['type'] === 'multiple' ) {
885 foreach ( $field_args['fields'] as $subfield_name => $subfield_args ) {
886 // field exists in db?
887 if ( array_key_exists( $subfield_name, $data ) )
888 $fields[$subfield_name] = $data[$subfield_name];
889 else
890 $fields[$subfield_name] = $gallery_defaults[$subfield_name];
891 }
892 } else {
893 // field exists in db?
894 if ( array_key_exists( $field_name, $data ) )
895 $fields[$field_name] = $data[$field_name];
896 else
897 $fields[$field_name] = $gallery_defaults[$field_name];
898 }
899 }
900 }
901
902 // add gallery type
903 $fields['type'] = $gallery_type;
904 }
905
906 $shortcode = '';
907
908 foreach ( $fields as $arg => $value ) {
909 if ( is_array( $value ) )
910 $shortcode .= ' ' . $arg . '="' . (string) implode( ',', $value ) . '"';
911 else
912 $shortcode .= ' ' . $arg . '="' . (string) $value . '"';
913 }
914
915 // get design data
916 $design = get_post_meta( $args['id'], '_rl_design', true );
917
918 if ( ! empty( $design['menu_item'] ) ) {
919 foreach ( $design[$design['menu_item']] as $arg => $value ) {
920 $shortcode .= ' ' . $arg . '="' . (string) $value . '"';
921 }
922 }
923
924 // get lightbox data
925 $lightbox = get_post_meta( $args['id'], '_rl_lightbox', true );
926
927 if ( ! empty( $lightbox['menu_item'] ) ) {
928 foreach ( $lightbox[$lightbox['menu_item']] as $arg => $value ) {
929 $shortcode .= ' ' . $arg . '="' . (string) $value . '"';
930 }
931 }
932
933 return do_shortcode( '[gallery rl_gallery_id="' . $args['id'] .'" include="' . ( empty( $attachments ) ? '' : implode( ',', $attachments ) ) . '"' . $shortcode . ']' );
934 }
935
936 /**
937 * Add a gallery button.
938 *
939 * @param string $editor_id Editor ID
940 * @return void
941 */
942 public function add_gallery_button( $editor_id ) {
943 if ( get_post_type() === 'rl_gallery' )
944 return;
945
946 $this->enqueue_gallery_scripts_styles();
947
948 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>';
949 }
950
951 /**
952 * Enqueue scripts and styles needed for gallery modal.
953 *
954 * @return void
955 */
956 public function enqueue_gallery_scripts_styles() {
957 global $pagenow;
958
959 // count how many times function was executed
960 static $run = 0;
961
962 // allow this only once
963 if ( $run > 0 )
964 return;
965
966 $run++;
967
968 // assign main instance
969 $rl = Responsive_Lightbox();
970
971 wp_enqueue_script( 'responsive-lightbox-admin-gallery', RESPONSIVE_LIGHTBOX_URL . '/js/admin-gallery.js', array( 'jquery', 'underscore' ), $rl->defaults['version'], false );
972
973 wp_localize_script(
974 'responsive-lightbox-admin-gallery',
975 'rlArgsGallery',
976 array(
977 'nonce' => wp_create_nonce( 'rl-gallery-post' ),
978 'post_id' => get_the_ID(),
979 'page' => esc_url( $pagenow )
980 )
981 );
982
983 wp_enqueue_style( 'responsive-lightbox-admin-gallery', RESPONSIVE_LIGHTBOX_URL . '/css/admin-gallery.css', array(), $rl->defaults['version'] );
984 }
985
986 /**
987 * Modal gallery HTML template.
988 *
989 * @return void
990 */
991 public function modal_gallery_template() {
992 global $wp_version;
993 global $pagenow;
994
995 // display only for post edit pages
996 if ( ! ( ( ( $pagenow === 'post.php' || $pagenow === 'post-new.php' ) && get_post_type() !== 'rl_gallery' ) || ( version_compare( $wp_version, '5.8', '>=' ) && ( $pagenow === 'widgets.php' || $pagenow === 'customize.php' ) ) ) )
997 return;
998
999 // get main instance
1000 $rl = Responsive_Lightbox();
1001
1002 // builder categories?
1003 if ( $rl->options['builder']['categories'] ) {
1004 $terms = get_terms(
1005 array(
1006 'taxonomy' => 'rl_category',
1007 'orderby' => 'name',
1008 'order' => 'ASC',
1009 'hide_empty' => false,
1010 'fields' => 'id=>name'
1011 )
1012 );
1013
1014 // get categories dropdown
1015 $categories = wp_dropdown_categories(
1016 array(
1017 'orderby' => 'name',
1018 'order' => 'asc',
1019 'show_option_none' => empty( $terms ) ? __( 'All categories', 'responsive-lightbox' ) : '',
1020 'show_option_all' => __( 'All categories', 'responsive-lightbox' ),
1021 'show_count' => false,
1022 'hide_empty' => false,
1023 'option_none_value' => 0,
1024 'hierarchical' => true,
1025 'selected' => 0,
1026 'taxonomy' => 'rl_category',
1027 'hide_if_empty' => false,
1028 'echo' => false,
1029 'id' => 'rl-media-attachment-categories',
1030 'class' => 'attachment-filters',
1031 'name' => ''
1032 )
1033 );
1034 }
1035
1036 echo '
1037 <div id="rl-modal-gallery" style="display: none;">
1038 <div class="media-modal wp-core-ui">
1039 <button type="button" class="media-modal-close"><span class="media-modal-icon"><span class="screen-reader-text">' . __( 'Close', 'responsive-lightbox' ) . '</span></span></button>
1040 <div class="media-modal-content">
1041 <div class="media-frame mode-select wp-core-ui hide-menu hide-router">
1042 <div class="media-frame-title">
1043 <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>
1044 </div>
1045 <div class="media-frame-content" data-columns="0">
1046 <div class="attachments-browser">
1047 <div class="uploader-inline rl-no-galleries" style="display: none;">
1048 <div class="uploader-inline-content has-upload-message">
1049 <h2 class="upload-message">' . esc_html( 'No items found.', 'responsive-lightbox' ) . '</h2>
1050 <div class="upload-ui">
1051 <h2 class="upload-instructions">' . esc_html( 'No galleries? Create them first or try another search phrase.', 'responsive-lightbox' ) . '</h2>
1052 </div>
1053 </div>
1054 </div>
1055 <div class="media-toolbar">' . ( $rl->options['builder']['categories'] ? '
1056 <div class="media-toolbar-secondary"><label for="rl-media-attachment-categories" class="screen-reader-text">' . esc_html__( 'Filter by category', 'responsive-lightbox' ) . '</label>' . $categories . '</div>' : '' ) . '
1057 <div class="media-toolbar-primary search-form">
1058 <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">
1059 </div>
1060 </div>
1061 <ul class="attachments rl-galleries-list ui-sortable ui-sortable-disabled">
1062 </ul>
1063 <div class="media-sidebar visible">
1064 <h2>' . __( 'Select A Gallery', 'responsive-lightbox' ) . '</h2>
1065 <p>' . __( 'To select a gallery simply click on one of the boxes to the left.', 'responsive-lightbox' ) . '</p>
1066 <p>' . __( 'To insert your gallery into the editor, click on the "Insert Gallery" button below.', 'responsive-lightbox' ) . '</p>
1067 </div>
1068 </div>
1069 </div>
1070 <div class="media-frame-toolbar">
1071 <div class="media-toolbar">
1072 <div class="media-toolbar-secondary">
1073 <div class="media-selection empty">
1074 <div class="selection-info">
1075 <span class="rl-gallery-count count">' . sprintf( _n( '%s image', '%s images', 0, 'responsive-lightbox' ), 0 ) . '</span>
1076 <a href="" class="button-link rl-edit-gallery-link">' . __( 'Edit gallery', 'responsive-lightbox' ) . '</a>
1077 </div>
1078 <div class="selection-view">
1079 <span class="rl-gallery-images-spinner spinner" style="display: none;"></span>
1080 <ul class="attachments rl-attachments-list">
1081 </ul>
1082 </div>
1083 </div>
1084 </div>
1085 <div class="media-toolbar-primary search-form">
1086 <button style="display: none;" type="button" class="button media-button button-primary button-large rl-media-button-insert-gallery" disabled="disabled">' . __( 'Insert gallery into post', 'responsive-lightbox') . '</button>
1087 <button style="display: none;" type="button" class="button media-button button-primary button-large rl-media-button-select-gallery" disabled="disabled">' . __( 'Select gallery', 'responsive-lightbox') . '</button>
1088 <button type="button" class="button media-button button-secondary button-large rl-media-button-cancel-gallery">' . __( 'Cancel', 'responsive-lightbox') . '</button>
1089 </div>
1090 </div>
1091 </div>
1092 </div>
1093 </div>
1094 </div>
1095 <div class="media-modal-backdrop"></div>
1096 </div>';
1097 }
1098
1099 /**
1100 * Render gallery field.
1101 *
1102 * @param string $field Field name
1103 * @param string $tab_id Field tab
1104 * @param string $menu_item Field parent
1105 * @param array $args Field arguments
1106 * @param bool $subfield Is this a subfield
1107 * @return string Rendered HTML field
1108 */
1109 public function render_field( $field, $tab_id, $menu_item, $args, $gallery_id, $subfield = false ) {
1110 if ( $subfield ) {
1111 $template = '%s%s';
1112 $html = '';
1113 $subhtml = '';
1114 } else {
1115 $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>';
1116 $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 . '">';
1117 $subhtml = '';
1118 }
1119
1120 switch ( $args['type'] ) {
1121 case 'range':
1122 $html .= sprintf(
1123 $template,
1124 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1125 '<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>' : '' )
1126 );
1127 break;
1128
1129 case 'radio':
1130 $subhtml = '';
1131
1132 foreach ( $args['options'] as $key => $label ) {
1133 $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> ';
1134 }
1135
1136 $html .= sprintf(
1137 $template,
1138 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1139 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
1140 );
1141 break;
1142
1143 case 'number':
1144 $html .= sprintf(
1145 $template,
1146 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1147 '<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>' : '' )
1148 );
1149 break;
1150
1151 case 'text':
1152 $html .= sprintf(
1153 $template,
1154 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1155 '<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>' : '' )
1156 );
1157 break;
1158
1159 case 'class':
1160 case 'textarea':
1161 $html .= sprintf(
1162 $template,
1163 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1164 '<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>' : '' )
1165 );
1166 break;
1167
1168 case 'select':
1169 $subhtml = '<select id="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . ']">';
1170
1171 foreach ( $args['options'] as $key => $label ) {
1172 $subhtml .= '
1173 <option value="' . $key . '" ' . selected( $args['value'], $key, false ) . '>' . $label . '</option>';
1174 }
1175
1176 $html .= sprintf(
1177 $template,
1178 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1179 $subhtml . '</select>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
1180 );
1181 break;
1182
1183 case 'taxonomy':
1184 if ( taxonomy_exists( $args['taxonomy'] ) ) {
1185 $subhtml = wp_dropdown_categories(
1186 array(
1187 'orderby' => 'name',
1188 'order' => 'asc',
1189 'show_option_none' => __( 'Root Folder', 'responsive-lightbox' ),
1190 'show_option_all' => false,
1191 'show_count' => false,
1192 'hide_empty' => false,
1193 'option_none_value' => 0,
1194 'hierarchical' => true,
1195 'selected' => $args['value']['id'],
1196 'taxonomy' => $args['taxonomy'],
1197 'hide_if_empty' => false,
1198 'echo' => false,
1199 'id' => 'rl-' . $tab_id . '-' . $menu_item . '-' . $field,
1200 'name' => 'rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . '][id]'
1201 )
1202 );
1203 } else
1204 $subhtml = '<select id="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . '][]" ><option value="0">' . esc_html__( 'Root Folder', 'responsive-lightbox' ) . '</option></select> ';
1205
1206 if ( isset( $args['include_children'] ) && $args['include_children'] ) {
1207 $subhtml .= '<label class="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '-include-children" for="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '-include-children"><input id="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '-include-children" type="checkbox" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . '][children]" value="true" ' . checked( $args['value']['children'], true, false ) . ' />' . esc_html__( 'Include children.', 'responsive-lightbox' ) . '</label>';
1208 }
1209
1210 $html .= sprintf(
1211 $template,
1212 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1213 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
1214 );
1215 break;
1216
1217 case 'multiselect':
1218 $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 . '][]">';
1219
1220 if ( $field === 'post_term' ) {
1221 foreach ( $args['options'] as $taxanomy => $data ) {
1222 $subhtml .= '<optgroup label="' . esc_attr( $data['label'] ) . '">';
1223
1224 foreach ( $data['terms'] as $term_id => $name ) {
1225 $subhtml .= '<option value="' . $term_id . '" ' . selected( in_array( $term_id, $args['value'], false ), true, false ) . '>' . esc_html( $name ) . '</option>';
1226 }
1227
1228 $subhtml .= '</optgroup>';
1229 }
1230 } else {
1231 foreach ( $args['options'] as $key => $label ) {
1232 $subhtml .= '
1233 <option value="' . $key . '" ' . selected( in_array( $key, $args['value'], false ), true, false ) . '>' . $label . '</option>';
1234 }
1235 }
1236
1237 $html .= sprintf(
1238 $template,
1239 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1240 $subhtml . '</select>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
1241 );
1242 break;
1243
1244 case 'boolean':
1245 $html .= sprintf(
1246 $template,
1247 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1248 '<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>' : '' )
1249 );
1250 break;
1251
1252 case 'checkbox':
1253 $subhtml = '';
1254
1255 foreach ( $args['options'] as $key => $label ) {
1256 $subhtml .= '<label class="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '-' . $key . '" for="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '-' . $key . '"><input id="rl-' . $tab_id . '-' . $menu_item . '-' . $field . '-' . $key . '" type="checkbox" name="rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . '][' . $key . ']" value="true" ' . checked( in_array( $key, $args['value'], true ), true, false ) . ' />' . $label . '</label><br />';
1257 }
1258
1259 $html .= sprintf(
1260 $template,
1261 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1262 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
1263 );
1264 break;
1265
1266 case 'multiple':
1267 $subhtml = '';
1268
1269 foreach ( $args['fields'] as $sub_field => $sub_args ) {
1270 $subhtml .= $this->render_field( $sub_field, $tab_id, $menu_item, $sub_args, $gallery_id, true ) . '<br />';
1271 }
1272
1273 $html .= sprintf(
1274 $template,
1275 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1276 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . $args['description'] . '</p>' : '' )
1277 );
1278 break;
1279
1280 case 'color_picker':
1281 $html .= sprintf(
1282 $template,
1283 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1284 '<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>' : '' )
1285 );
1286 break;
1287
1288 case 'media_library':
1289 $data = get_post_meta( $gallery_id, '_rl_images', true );
1290
1291 // get images
1292 if ( ( ! empty( $data['menu_item'] ) && $data['menu_item'] === 'media' ) || ! ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-menu-content' ) )
1293 $images = $this->get_gallery_images( $gallery_id );
1294 else
1295 $images = array();
1296
1297 // get media item template
1298 $media_item_template = $this->get_media_item_template( $args['preview'] );
1299
1300 $html .= '
1301 <td colspan="2" class="rl-colspan">
1302 <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'] ) : '' ) . '">
1303 <a href="#" class="rl-gallery-select button button-secondary">' . __( 'Select images', 'responsive-lightbox' ) . '</a>
1304 <div class="rl-gallery-content">
1305 <ul class="rl-gallery-images rl-gallery-images-media">';
1306
1307 if ( ! empty( $images ) ) {
1308 foreach ( $images as $image ) {
1309 if ( $image['id'] === 0 )
1310 $excluded_item = $image['url'];
1311 else
1312 $excluded_item = $image['id'];
1313
1314 $image_html = $image['thumbnail_link'];
1315
1316 // replace ID and URL of an image
1317 $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 ) ) );
1318 }
1319 }
1320
1321 $html .= '
1322 </ul>
1323 </div>
1324 </td>';
1325 break;
1326
1327 case 'media_preview':
1328 $this->menu_item = $menu_item;
1329
1330 // get images
1331 $images = $this->get_gallery_images( $gallery_id );
1332
1333 // get media item template
1334 $media_item_template = $this->get_media_item_template( $args['preview'] );
1335
1336 $html .= '
1337 <td colspan="2" class="rl-colspan">
1338 <div class="rl-gallery-preview-inside">
1339 <a href="#" class="rl-gallery-update-preview button button-secondary">' . __( 'Update preview', 'responsive-lightbox' ) . '</a><span class="spinner" style="display: none;"></span>
1340 </div>
1341 <div class="rl-gallery-content">
1342 <ul class="rl-gallery-images rl-gallery-images-' . $menu_item . '">';
1343
1344 if ( ! empty( $images ) ) {
1345 foreach ( $images as $image ) {
1346 if ( empty( $image['id'] ) ) {
1347 $excluded_item = $image['url'];
1348 $image['id'] = 0;
1349 } else
1350 $excluded_item = $image['id'];
1351
1352 $image_html = $image['thumbnail_link'];
1353
1354 // replace ID and URL of an image
1355 $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 ) ) );
1356 }
1357 }
1358
1359 $html .= '
1360 </ul>
1361 </div>';
1362
1363 if ( ! empty( $args['preview'] ) && isset( $args['preview']['pagination'] )&& $args['preview']['pagination'] )
1364 $html .= $this->get_preview_pagination( $this->current_page );
1365
1366 $html .= '
1367 </td>';
1368 break;
1369
1370 case 'hidden':
1371 // prepare args
1372 $args['tab_id'] = $tab_id;
1373 $args['menu_item'] = $menu_item;
1374 $args['field'] = $field;
1375
1376 $html .= sprintf(
1377 $template,
1378 '',
1379 call_user_func( $args['callback'], $args )
1380 );
1381 break;
1382
1383 default:
1384 $html .= sprintf(
1385 $template,
1386 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1387 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>' : '' )
1388 );
1389 }
1390
1391 if ( ! $subfield )
1392 $html .= '</tr>';
1393
1394 return apply_filters( 'rl_render_gallery_field', $html, $field, $tab_id, $menu_item, $args, $subfield );
1395 }
1396
1397 /**
1398 * Get preview pagination.
1399 *
1400 * @param int $current_page Page number
1401 * @return string Generated HTML
1402 */
1403 public function get_preview_pagination( $current_page ) {
1404 $items = '';
1405 $page_links = array();
1406 $total_pages = $current_page + 1;
1407 $current = $current_page;
1408 $disable_first = $disable_last = $disable_prev = $disable_next = false;
1409 $current_url = 'preview_page';
1410
1411 if ( $current == 1 ) {
1412 $disable_first = true;
1413 $disable_prev = true;
1414 } elseif ( $current == 2 )
1415 $disable_first = true;
1416
1417 if ( $current == $total_pages ) {
1418 $disable_last = true;
1419 $disable_next = true;
1420 }
1421
1422 if ( $current == $total_pages - 1 )
1423 $disable_last = true;
1424
1425 if ( $disable_first )
1426 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
1427 else {
1428 $page_links[] = sprintf(
1429 '<a class="first-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1430 $current_url,
1431 __( 'First page', 'responsive-lightbox' ),
1432 '&laquo;'
1433 );
1434 }
1435
1436 if ( $disable_prev )
1437 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
1438 else {
1439 $page_links[] = sprintf(
1440 '<a class="prev-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1441 $current_url . '/' . max( 1, $current - 1 ),
1442 __( 'Previous page', 'responsive-lightbox' ),
1443 '&lsaquo;'
1444 );
1445 }
1446
1447 $html_current_page = sprintf(
1448 '%s<input disabled="disabled" class="current-page" id="current-page-selector" type="text" name="paged" value="%s" size="%d" aria-describedby="table-paging" /><span class="tablenav-paging-text">',
1449 '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page', 'responsive-lightbox' ) . '</label>',
1450 $current,
1451 strlen( $total_pages )
1452 );
1453
1454 $html_total_pages = sprintf( '<span class="total-pages">%s</span>', number_format_i18n( $total_pages ) );
1455 // $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . '</span></span>';
1456 $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s', 'paging' ), $html_current_page, $html_total_pages ) . '</span></span>';
1457
1458 if ( $disable_next )
1459 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
1460 else {
1461 $page_links[] = sprintf(
1462 '<a class="next-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1463 $current_url . '/' . min( $total_pages, $current + 1 ),
1464 __( 'Next page', 'responsive-lightbox' ),
1465 '&rsaquo;'
1466 );
1467 }
1468
1469 if ( $disable_last )
1470 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
1471 else {
1472 $page_links[] = sprintf(
1473 '<a class="last-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1474 $current_url . '/' . $total_pages,
1475 __( 'Last page', 'responsive-lightbox' ),
1476 '&raquo;'
1477 );
1478 }
1479
1480 if ( $total_pages )
1481 $page_class = $total_pages < 2 ? ' one-page' : '';
1482 else
1483 $page_class = ' no-pages';
1484
1485 return '<div class="rl-gallery-preview-pagination tablenav"><div class="tablenav-pages' . $page_class . '">' . $items . '<span class="pagination-links">' . join( "\n", $page_links ) . '</span></div>';
1486 }
1487
1488 /**
1489 * Sanitize field based on type. Internal use only.
1490 *
1491 * @param string $field Field name
1492 * @param mixed $value Field value
1493 * @param array $args Field arguments
1494 * @return mixed Sanitized value
1495 */
1496 public function sanitize_field( $field, $value, $args ) {
1497 switch ( $args['type'] ) {
1498 case 'radio':
1499 case 'select':
1500 $value = array_key_exists( $value, $args['options'] ) ? $value : $args['default'];
1501 break;
1502
1503 case 'taxonomy':
1504 if ( is_array( $value ) ) {
1505 if ( isset( $value['id'] ) )
1506 $value['id'] = (int) $value['id'];
1507 else
1508 $value['id'] = 0;
1509
1510 $value['children'] = isset( $value['children'] );
1511 } else
1512 $value = $args['default'];
1513
1514 // get term
1515 $term = get_term( $value['id'], $args['taxonomy'] );
1516
1517 // valid term?
1518 if ( is_a( $term, 'WP_Term' ) )
1519 $value['id'] = $term->term_id;
1520 else
1521 $value['id'] = 0;
1522 break;
1523
1524 case 'multiselect':
1525 if ( is_array( $value ) ) {
1526 // is it post term field?
1527 if ( $field === 'post_term' ) {
1528 $terms = array();
1529
1530 foreach ( $args['options'] as $data ) {
1531 $terms += $data['terms'];
1532 }
1533
1534 $args['options'] = $terms;
1535 }
1536
1537 $values = array();
1538
1539 foreach ( $value as $subvalue ) {
1540 if ( array_key_exists( $subvalue, $args['options'] ) )
1541 $values[] = $subvalue;
1542 }
1543
1544 $value = $values;
1545 } else
1546 $value = $args['default'];
1547 break;
1548
1549 case 'checkbox':
1550 if ( is_array( $value ) && ! empty( $value ) ) {
1551 $sort = array();
1552
1553 foreach ( $value as $sort_key => $bool ) {
1554 if ( array_key_exists( $sort_key, $args['options'] ) )
1555 $sort[] = $sort_key;
1556 }
1557
1558 $value = $sort;
1559 } else
1560 $value = array();
1561 break;
1562
1563 case 'boolean':
1564 $value = $value === 'true';
1565 break;
1566
1567 case 'range':
1568 case 'number':
1569 $value = (int) $value;
1570
1571 // is value lower than?
1572 if ( isset( $args['min'] ) && $value < $args['min'] )
1573 $value = $args['min'];
1574
1575 // is value greater than?
1576 if ( isset( $args['max'] ) && $value > $args['max'] )
1577 $value = $args['max'];
1578 break;
1579
1580 case 'class':
1581 $value = trim( $value );
1582
1583 // more than 1 class?
1584 if ( strpos( $value, ' ' ) !== false ) {
1585 // get unique valid HTML classes
1586 $value = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $value ) ) ) );
1587
1588 if ( ! empty( $value ) )
1589 $value = implode( ' ', $value );
1590 else
1591 $value = '';
1592 // single class
1593 } else
1594 $value = sanitize_html_class( $value );
1595 break;
1596
1597 case 'text':
1598 $value = trim( sanitize_text_field( $value ) );
1599 break;
1600
1601 case 'textarea':
1602 global $wp_version;
1603
1604 // WP 4.7+
1605 if ( version_compare( $wp_version, '4.7', '>=' ) )
1606 $value = trim( sanitize_textarea_field( $value ) );
1607 // _sanitize_text_fields
1608 else {
1609 $value = wp_check_invalid_utf8( $value );
1610
1611 if ( strpos( $value, '<' ) !== false ) {
1612 $value = wp_pre_kses_less_than( $value );
1613
1614 // this will strip extra whitespace for us.
1615 $value = wp_strip_all_tags( $value, false );
1616
1617 // use html entities in a special case to make sure no later newline stripping stage could lead to a functional tag
1618 $value = str_replace( "<\n", "&lt;\n", $value );
1619 }
1620
1621 $value = trim( $value );
1622 $found = false;
1623
1624 while ( preg_match('/%[a-f0-9]{2}/i', $value, $match ) ) {
1625 $value = str_replace( $match[0], '', $value );
1626 $found = true;
1627 }
1628
1629 // strip out the whitespace that may now exist after removing the octets.
1630 if ( $found )
1631 $value = trim( preg_replace( '/ +/', ' ', $value ) );
1632 }
1633 break;
1634
1635 case 'color_picker':
1636 if ( preg_match( '/^#[a-f0-9]{6}$/i', $value ) !== 1 )
1637 $value = $args['default'];
1638 break;
1639
1640 case 'media_library':
1641 if ( is_array( $value ) ) {
1642 $data = $args['default'];
1643
1644 // check IDs
1645 if ( array_key_exists( 'ids', $value ) ) {
1646 $ids = (string) trim( $value['ids'] );
1647
1648 if ( $ids !== '' )
1649 // get unique and non empty attachment IDs only
1650 $data['ids'] = $this->check_attachments( array_unique( array_filter( array_map( 'intval', explode( ',', $ids ) ) ) ) );
1651 else
1652 $data['ids'] = array();
1653 }
1654
1655 // check excluded items
1656 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
1657 $ids = $strings = array();
1658
1659 foreach ( $value['exclude'] as $exclude_item ) {
1660 $item = trim( $exclude_item );
1661
1662 if ( is_numeric( $item ) )
1663 $ids[] = (int) $item;
1664 elseif ( $item !== '' )
1665 $strings[] = $item;
1666 }
1667
1668 if ( ! empty( $ids ) ) {
1669 // get unique and non empty attachment IDs only
1670 $ids = $this->check_attachments( array_unique( array_filter( $ids ) ) );
1671 }
1672
1673 $data['exclude'] = $ids + $strings;
1674 }
1675
1676 $value = $data;
1677 } else
1678 $value = $args['default'];
1679 break;
1680
1681 case 'media_preview':
1682 if ( is_array( $value ) ) {
1683 $data = $args['default'];
1684
1685 // check excluded items
1686 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
1687 $ids = $strings = array();
1688
1689 foreach ( $value['exclude'] as $exclude_item ) {
1690 $item = trim( $exclude_item );
1691
1692 if ( is_numeric( $item ) )
1693 $ids[] = (int) $item;
1694 elseif ( $item !== '' )
1695 $strings[] = $item;
1696 }
1697
1698 if ( ! empty( $ids ) ) {
1699 // get unique and non empty attachment IDs only
1700 $ids = $this->check_attachments( array_unique( array_filter( $ids ) ) );
1701 }
1702
1703 $data['exclude'] = $ids + $strings;
1704 }
1705
1706 $value = $data;
1707 } else
1708 $value = $args['default'];
1709 }
1710
1711 return apply_filters( 'rl_sanitize_gallery_field', $value, $args );
1712 }
1713
1714 /**
1715 * Sanitize set of fields.
1716 *
1717 * @param array $items Fields
1718 * @param array $data POST data
1719 * @param string $tab_id Gallery tab
1720 * @param string $menu_item Gallery menu item
1721 * @return array Sanitize fields
1722 */
1723 public function sanitize_fields( $items, $data, $tab_id, $menu_item ) {
1724 $safedata = array();
1725
1726 foreach ( $items as $field => $item ) {
1727 // skip this field
1728 if ( isset( $item['save'] ) && ! $item['save'] )
1729 continue;
1730
1731 // available field?
1732 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$field] ) )
1733 $safedata[$tab_id][$menu_item][$field] = $this->sanitize_field( $field, $data[$tab_id][$menu_item][$field], $item );
1734 // boolean field?
1735 elseif ( $item['type'] === 'boolean' )
1736 $safedata[$tab_id][$menu_item][$field] = false;
1737 // multiple fields?
1738 elseif ( $item['type'] === 'multiple' ) {
1739 foreach ( $item['fields'] as $subfield => $subitem ) {
1740 // available subfield?
1741 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$subfield] ) )
1742 $safedata[$tab_id][$menu_item][$subfield] = $this->sanitize_field( $subfield, $data[$tab_id][$menu_item][$subfield], $subitem );
1743 // boolean subfield?
1744 elseif ( $subitem['type'] === 'boolean' )
1745 $safedata[$tab_id][$menu_item][$subfield] = false;
1746 // any other case
1747 else
1748 $safedata[$tab_id][$menu_item][$subfield] = $subitem['default'];
1749 }
1750 // any other case
1751 } else
1752 $safedata[$tab_id][$menu_item][$field] = $item['default'];
1753 }
1754
1755 return $safedata;
1756 }
1757
1758 /**
1759 * Add menu tabs after the post title.
1760 *
1761 * @param object $post Post object
1762 * @return void
1763 */
1764 public function after_title_nav_menu( $post ) {
1765 if ( $post->post_type !== 'rl_gallery' )
1766 return;
1767
1768 global $wp_meta_boxes;
1769
1770 $active_tab = ! empty( $_GET['rl_active_tab'] ) && array_key_exists( $_GET['rl_active_tab'], $this->tabs ) ? $_GET['rl_active_tab'] : 'images';
1771
1772 // this will be moved to #postbox-container-2 using js to avoid mobile devices problem
1773 echo '
1774 <h2 class="nav-tab-wrapper">';
1775
1776 foreach ( $this->tabs as $key => $data ) {
1777 echo '
1778 <a id="rl-gallery-tab-' . $key . '" class="rl-gallery-tab nav-tab' . ( $key === $active_tab ? ' nav-tab-active' : '' ) . '" href="#' . $key . '">' . $data['label'] . '</a>';
1779 }
1780
1781 echo '
1782 </h2>';
1783
1784 do_meta_boxes( $post->post_type, 'after_title', $post );
1785
1786 unset( $wp_meta_boxes[$post->post_type]['after_title'] );
1787 }
1788
1789 /**
1790 * Add class to hide metabox.
1791 *
1792 * @param array $classes Classes
1793 * @return array Classes
1794 */
1795 public function hide_metabox( $classes ) {
1796 $classes[] = 'rl-metabox-content';
1797 $classes[] = 'rl-hide-metabox';
1798
1799 return $classes;
1800 }
1801
1802 /**
1803 * Add class to display the metabox.
1804 *
1805 * @param array $classes Classes
1806 * @return array Classes
1807 */
1808 function display_metabox( $classes ) {
1809 $classes[] = 'rl-metabox-content';
1810 $classes[] = 'rl-display-metabox';
1811
1812 return $classes;
1813 }
1814
1815 /**
1816 * Add active tab to post redirect destination URL.
1817 *
1818 * @param string $location Destination URL
1819 * @return string Detination URL with extra arg
1820 */
1821 function add_active_tab( $location ) {
1822 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 );
1823 }
1824
1825 /**
1826 * Add metaboxes.
1827 *
1828 * @return void
1829 */
1830 public function add_meta_boxes() {
1831 $active_tab = ! empty( $_GET['rl_active_tab'] ) && array_key_exists( $_GET['rl_active_tab'], $this->tabs ) ? $_GET['rl_active_tab'] : 'images';
1832
1833 // normal metaboxes
1834 foreach ( $this->tabs as $key => $args ) {
1835 if ( $key === 'images' )
1836 $new_args = $args + array( 'tab_id' => $key, 'active_tab' => $active_tab );
1837 else
1838 $new_args = $args + array( 'tab_id' => $key );
1839
1840 // handle metabox class
1841 if ( $active_tab === $key )
1842 add_filter( 'postbox_classes_rl_gallery_responsive-gallery-' . $key, array( $this, 'display_metabox' ) );
1843 else
1844 add_filter( 'postbox_classes_rl_gallery_responsive-gallery-' . $key, array( $this, 'hide_metabox' ) );
1845
1846 add_meta_box( 'responsive-gallery-' . $key, sprintf( __( 'Gallery %s', 'responsive-lightbox' ), $args['label'] ), array( $this, 'add_metabox' ), 'rl_gallery', 'after_title', 'high', $new_args );
1847 }
1848
1849 // side metaboxes
1850 add_meta_box( 'responsive-gallery-shortcode', __( 'Gallery Code', 'responsive-lightbox' ), array( $this, 'shortcode_metabox' ), 'rl_gallery', 'side', 'core' );
1851 }
1852
1853 /**
1854 * Add single metabox.
1855 *
1856 * @param type $post Post object
1857 * @param array $callback_args Arguments
1858 * @return void
1859 */
1860 public function add_metabox( $post, $callback_args ) {
1861 $html = $callback_args['args']['tab_id'] === 'images' ? '<input type="hidden" name="rl_active_tab" value="' . $callback_args['args']['active_tab'] . '" />' : '';
1862
1863 // default menu item
1864 $menu_item = 'options';
1865
1866 // get tab data
1867 $data = get_post_meta( $post->ID, '_rl_' . $callback_args['args']['tab_id'], true );
1868
1869 if ( ! is_array( $data ) )
1870 $data = array();
1871
1872 // maybe add description
1873 $html .= ! empty( $callback_args['args']['description'] ) ? '<p class="rl-gallery-tab-description">' . esc_html( $callback_args['args']['description'] ) . '</p>' : '';
1874
1875 // assign main instance
1876 $rl = Responsive_Lightbox();
1877
1878 // maybe add menu
1879 if ( ! empty( $callback_args['args']['menu_items'] ) ) {
1880 // get selected menu item
1881 $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'] );
1882
1883 $html .= '
1884 <div class="rl-gallery-tab-menu rl-gallery-tab-menu-' . $callback_args['args']['tab_id'] . '">';
1885
1886 foreach ( $callback_args['args']['menu_items'] as $menu_key => $menu_label ) {
1887 // disable select for remote library if needed
1888 if ( $menu_key === 'remote_library' && ! $rl->options['remote_library']['active'] ) {
1889 $title = ' title="' . __( 'Remote Library is disabled. Enable it in the settings.', 'responsive-lightbox' ) . '"';
1890 $disabled = ' disabled="disabled"';
1891 // disable select for media folders if needed
1892 } elseif ( $menu_key === 'folders' && ! $rl->options['folders']['active'] ) {
1893 $title = ' title="' . __( 'Media Folders are disabled. Enable it in the settings.', 'responsive-lightbox' ) . '"';
1894 $disabled = ' disabled="disabled"';
1895 // other menu items
1896 } else {
1897 $title = '';
1898 $disabled = '';
1899 }
1900
1901 $html .= '
1902 <label' . $title . '><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 ) . $disabled . ' />' . esc_html( $menu_label ) . ( $callback_args['args']['tab_id'] === 'config' && $menu_key === 'default' ? ' (' . $this->tabs['config']['menu_items'][$rl->options['settings']['builder_gallery']] . ')' : '' ) . '</label>';
1903 }
1904
1905 $html .= '
1906 <span class="spinner" style="display: none;"></span>
1907 </div>';
1908 }
1909
1910 $content = '';
1911
1912 // disable gallery images content for remote library or media folders if needed
1913 if ( $callback_args['args']['tab_id'] === 'images' && ( ( $menu_item === 'remote_library' && ! $rl->options['remote_library']['active'] ) || ( $menu_item === 'folders' && ! $rl->options['folders']['active'] ) ) )
1914 $content = ' rl-loading-content';
1915
1916 $html .= '
1917 <div class="rl-gallery-tab-content rl-gallery-tab-content-' . $callback_args['args']['tab_id'] . $content . '">';
1918
1919 $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 );
1920
1921 $html .= '
1922 </div>';
1923
1924 echo $html;
1925 }
1926
1927 /**
1928 * Get single metabox content.
1929 *
1930 * @param string $tab_id Tab ID
1931 * @param array $data Metabox data
1932 * @param string $menu_item Specified menu item
1933 * @param int $gallery_id Gallery ID
1934 * @return string
1935 */
1936 public function get_metabox_content( $tab_id, $data, $menu_item, $gallery_id = 0 ) {
1937 $html = '
1938 <div class="rl-gallery-tab-inside rl-gallery-tab-inside-' . $tab_id . '-' . $menu_item . '">
1939 <table class="form-table">';
1940
1941 switch ( $tab_id ) {
1942 case 'config':
1943 // assign main instance
1944 $rl = Responsive_Lightbox();
1945
1946 // get default gallery fields
1947 $default_gallery = $rl->frontend->get_default_gallery_fields();
1948
1949 // assign settings and defaults
1950 $settings = $rl->settings->settings;
1951 $defaults = $rl->defaults;
1952
1953 if ( ! array_key_exists( 'default_gallery', $settings ) )
1954 $settings['default_gallery']['fields'] = $default_gallery;
1955
1956 // assign default values
1957 foreach ( $default_gallery as $field => $field_args ) {
1958 $defaults['default_gallery'][$field] = $field_args['default'];
1959 }
1960
1961 // valid gallery?
1962 if ( array_key_exists( $menu_item . '_gallery', $settings ) && array_key_exists( $menu_item . '_gallery', $defaults ) ) {
1963 if ( $menu_item === 'default' )
1964 $fields = $settings['default_gallery']['fields'];
1965 else {
1966 $fields = $rl->frontend->get_unique_fields( $settings['default_gallery']['fields'], $settings[$menu_item . '_gallery']['fields'] );
1967
1968 // add default gallery default values
1969 foreach ( $default_gallery as $field => $field_args ) {
1970 $defaults[$menu_item . '_gallery'][$field] = $field_args['default'];
1971 }
1972 }
1973
1974 foreach ( $fields as $field => $args ) {
1975 if ( $args['type'] === 'multiple' ) {
1976 $new_args = $args;
1977
1978 foreach ( $args['fields'] as $subfield => $subargs ) {
1979 $new_args['fields'][$subfield] = $subargs + array(
1980 'value' => isset( $data[$menu_item], $data[$menu_item][$subfield] ) ? $data[$menu_item][$subfield] : $defaults[$menu_item . '_gallery'][$subfield],
1981 'default' => $defaults[$menu_item . '_gallery'][$subfield]
1982 );
1983 }
1984 } else {
1985 $new_args = $args + array(
1986 'value' => isset( $data[$menu_item], $data[$menu_item][$field] ) ? $data[$menu_item][$field] : $defaults[$menu_item . '_gallery'][$field],
1987 'default' => $defaults[$menu_item . '_gallery'][$field]
1988 );
1989 }
1990
1991 $html .= $this->render_field( $field, $tab_id, $menu_item, $new_args, $gallery_id );
1992 }
1993 // just in case ajax would fail
1994 } else
1995 $html .= '<p>' . __( 'No data', 'responsive-lightbox' ) . '</p>';
1996 break;
1997
1998 default:
1999 foreach ( $this->fields[$tab_id][$menu_item] as $field => $args ) {
2000 // was this field stored in a database?
2001 if ( isset( $args['save'] ) && ! $args['save'] )
2002 $new_args = $args;
2003 elseif ( $args['type'] === 'multiple' ) {
2004 $new_args = $args;
2005
2006 foreach ( $args['fields'] as $subfield => $subargs ) {
2007 $new_args['fields'][$subfield] = $subargs + array( 'value' => isset( $data[$menu_item], $data[$menu_item][$subfield] ) ? $data[$menu_item][$subfield] : $subargs['default'] );
2008 }
2009 } else
2010 $new_args = $args + array( 'value' => isset( $data[$menu_item], $data[$menu_item][$field] ) ? $data[$menu_item][$field] : $args['default'] );
2011
2012 // media preview?
2013 // if ( $tab_id === 'images' && $menu_item === 'featured' && $field === 'attachments' && $args['type'] === 'media_preview' )
2014 // $new_args['subfields'] = $data['featured'];
2015
2016 $html .= $this->render_field( $field, $tab_id, $menu_item, $new_args, $gallery_id );
2017 }
2018 }
2019
2020 $html .= '
2021 </table>
2022 </div>';
2023
2024 return apply_filters( 'rl_gallery_tab_content', $html, $tab_id, $data, $menu_item );
2025 }
2026
2027 /**
2028 * Get gallery images.
2029 *
2030 * @param int $gallery_id Gallery ID
2031 * @param array $args Gallery arguments
2032 * @return array
2033 */
2034 public function get_gallery_images( $gallery_id = 0, $args = array() ) {
2035 $images = array();
2036 $excluded = array();
2037
2038 // assign main instance
2039 $rl = Responsive_Lightbox();
2040
2041 // get args
2042 $defaults = array(
2043 'exclude' => false,
2044 'posts_per_page' => -1,
2045 'images_per_page' => 0,
2046 'page' => 1,
2047 'nopaging' => true,
2048 'image_size' => 'large',
2049 'thumbnail_size' => 'thumbnail',
2050 'pagination_type' => 'paged',
2051 'pagination_position' => 'bottom',
2052 'orderby' => 'menu_order',
2053 'order' => 'asc',
2054 'preview' => is_admin(),
2055 'preview_type' => 'update',
2056 'preview_page' => 1,
2057 'preview_per_page' => 20,
2058 'taxonomy' => $rl->options['folders']['media_taxonomy'],
2059 'folder' => array(
2060 'id' => 0,
2061 'children' => null // do not change!
2062 )
2063 );
2064
2065 // parse arguments
2066 $args = wp_parse_args( apply_filters( 'rl_get_gallery_images_args', $args, $gallery_id ), $defaults );
2067
2068 // sanitize args
2069 $args['exclude'] = (bool) ! empty( $args['exclude'] );
2070 $args['posts_per_page'] = ! empty( $args['posts_per_page'] ) ? (int) $args['posts_per_page'] : -1;
2071 $args['nopaging'] = (bool) ! empty( $args['nopaging'] );
2072
2073 // is it rl_gallery?
2074 if ( $valid_gallery_type = ( get_post_type( $gallery_id ) === 'rl_gallery' ) ) {
2075 $paging = get_post_meta( $gallery_id, '_rl_paging', true );
2076
2077 if ( isset( $paging['menu_item'] ) ) {
2078 $pagination = $paging[$paging['menu_item']];
2079
2080 if ( $pagination['pagination'] ) {
2081 $args['nopaging'] = false;
2082 $args['images_per_page'] = $pagination['images_per_page'];
2083 $args['pagination_type'] = $pagination['pagination_type'];
2084
2085 // infinite type?
2086 if ( $args['pagination_type'] === 'infinite' )
2087 $args['pagination_position'] = 'bottom';
2088 else
2089 $args['pagination_position'] = $pagination['pagination_position'];
2090 } else
2091 $args['nopaging'] = true;
2092 }
2093 }
2094
2095 global $pagenow;
2096
2097 // is it preview?
2098 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' || $_POST['action'] === 'rl-get-menu-content' ) ) )
2099 $args['images_per_page'] = 0;
2100
2101 if ( isset( $_GET['rl_page'] ) )
2102 $args['page'] = (int) $_GET['rl_page'];
2103 else
2104 $args['page'] = (int) $args['page'];
2105
2106 // is it rl_gallery?
2107 if ( $valid_gallery_type ) {
2108 // get config metadata
2109 $config_meta = get_post_meta( $gallery_id, '_rl_config', true );
2110
2111 // config order
2112 if ( isset( $config_meta['menu_item'] ) ) {
2113 $config = $config_meta[$config_meta['menu_item']];
2114
2115 $args['orderby'] = $config['orderby'];
2116 $args['order'] = $config['order'];
2117 }
2118
2119 // get images metadata
2120 $data = get_post_meta( $gallery_id, '_rl_images', true );
2121
2122 // array?
2123 if ( ! is_array( $data ) )
2124 $data = array();
2125
2126 // get menu item
2127 if ( ! empty( $this->menu_item ) )
2128 $menu_item = $this->menu_item;
2129 elseif ( array_key_exists( 'menu_item', $data ) )
2130 $menu_item = $data['menu_item'];
2131 else
2132 $menu_item = 'media';
2133
2134 // valid data?
2135 if ( ! array_key_exists( $menu_item, $data ) )
2136 $data[$menu_item] = array();
2137
2138 if ( $args['preview'] && $this->fields['images'][$menu_item]['attachments']['preview']['pagination'] ) {
2139 if ( isset( $args['preview_page'] ) )
2140 $args['preview_page'] = (int) $args['preview_page'];
2141 else
2142 $args['preview_page'] = 1;
2143
2144 $args['preview_per_page'] = (int) $args['preview_per_page'];
2145 }
2146
2147 switch ( $menu_item ) {
2148 case 'media':
2149 // get attachment ids
2150 $attachments = ! empty( $data[$menu_item]['attachments']['ids'] ) ? array_map( 'absint', $data[$menu_item]['attachments']['ids'] ) : array();
2151
2152 // filter attachments
2153 $attachments = apply_filters( 'rl_get_gallery_images_attachments', $attachments );
2154
2155 if ( $attachments ) {
2156 if ( $args['exclude'] )
2157 $excluded = ! empty( $data[$menu_item]['attachments']['exclude'] ) ? $data[$menu_item]['attachments']['exclude'] : array();
2158
2159 foreach ( $attachments as $attachment_id ) {
2160 // real attachment?
2161 if ( ! wp_attachment_is_image( $attachment_id ) )
2162 continue;
2163
2164 // get attachment image data
2165 if ( ! in_array( $attachment_id, $excluded ) )
2166 $images[] = $this->get_gallery_image_src( $attachment_id, $args['image_size'], $args['thumbnail_size'] );
2167 }
2168 }
2169 break;
2170
2171 case 'featured':
2172 // only for featured frontend galleries
2173 if ( ! is_admin() ) {
2174 // prepare featured fields
2175 $this->fields['images']['featured'] = $this->prepare_featured_fields( $this->fields['images']['featured'] );
2176 }
2177
2178 // copy arguments
2179 $query_args = $args;
2180
2181 // prevent duplicating images order (config tab) with posts order (images tab), query will handle empty strings
2182 if ( array_key_exists( 'post_orderby', $args ) )
2183 $query_args['orderby'] = $args['post_orderby'];
2184 elseif ( array_key_exists( 'orderby', $data[$menu_item] ) )
2185 $query_args['orderby'] = $data[$menu_item]['orderby'];
2186 else
2187 $query_args['orderby'] = '';
2188
2189 if ( array_key_exists( 'post_order', $args ) )
2190 $query_args['order'] = $args['post_order'];
2191 elseif ( array_key_exists( 'order', $data[$menu_item] ) )
2192 $query_args['order'] = $data[$menu_item]['order'];
2193 else
2194 $query_args['order'] = '';
2195
2196 // get attachment ids
2197 $attachments = $this->gallery_query( array_merge( $data[$menu_item], $query_args ) );
2198
2199 // filter attachments
2200 $attachments = apply_filters( 'rl_get_gallery_images_attachments', $attachments );
2201
2202 if ( $attachments ) {
2203 if ( $args['exclude'] )
2204 $excluded = ! empty( $data[$menu_item]['attachments']['exclude'] ) ? $data[$menu_item]['attachments']['exclude'] : array();
2205
2206 foreach ( $attachments as $attachment_id ) {
2207 // get attachment image data
2208 if ( ! in_array( $attachment_id, $excluded ) )
2209 $images[] = $this->get_gallery_image_src( $attachment_id, $args['image_size'], $args['thumbnail_size'] );
2210 }
2211 }
2212 break;
2213
2214 case 'folders':
2215 if ( ! array_key_exists( 'folder', $data[$menu_item] ) )
2216 $data[$menu_item]['folder'] = $defaults['folder'];
2217
2218 // AJAX requests
2219 if ( is_string( $args['folder']['id'] ) )
2220 $args['folder']['id'] = (int) $args['folder']['id'];
2221
2222 // not empty folder term ID?
2223 if ( ! empty( $args['folder']['id'] ) ) {
2224 // get term
2225 $term = get_term( $args['folder']['id'], $args['taxonomy'] );
2226
2227 // valid term?
2228 if ( is_a( $term, 'WP_Term' ) )
2229 $folder_id = (int) $term->term_id;
2230 else
2231 $folder_id = (int) $data[$menu_item]['folder']['id'];
2232 } else {
2233 if ( isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-preview-content' )
2234 $folder_id = $args['folder']['id'];
2235 else
2236 $folder_id = (int) $data[$menu_item]['folder']['id'];
2237 }
2238
2239 if ( $folder_id >= 0 ) {
2240 $include_children = false;
2241
2242 // null means folder was not changed
2243 if ( $args['folder']['children'] === null ) {
2244 if ( array_key_exists( 'children', $data[$menu_item]['folder'] ) && $data[$menu_item]['folder']['children'] === true )
2245 $include_children = true;
2246 // overwritten by args
2247 } else {
2248 if ( is_string( $args['folder']['children'] ) ) {
2249 if ( $args['folder']['children'] === 'true' )
2250 $include_children = true;
2251 } elseif ( is_bool( $args['folder']['children'] ) ) {
2252 if ( $args['folder']['children'] )
2253 $include_children = true;
2254 }
2255 }
2256
2257 if ( $folder_id === 0 ) {
2258 if ( $include_children ) {
2259 $all_folders = get_terms(
2260 array(
2261 'taxonomy' => $args['taxonomy'],
2262 'hide_empty' => false,
2263 'fields' => 'ids',
2264 'hierarchical' => false,
2265 'number' => 0
2266 )
2267 );
2268
2269 $tax_query = array(
2270 array(
2271 'relation' => 'OR',
2272 array(
2273 'taxonomy' => $args['taxonomy'],
2274 'field' => 'term_id',
2275 'terms' => ( ! is_wp_error( $all_folders ) ) ? $all_folders : $folder_id,
2276 'include_children' => $include_children,
2277 'operator' => 'IN'
2278 ),
2279 array(
2280 'taxonomy' => $args['taxonomy'],
2281 'field' => 'term_id',
2282 'terms' => $folder_id,
2283 'include_children' => $include_children,
2284 'operator' => 'NOT EXISTS'
2285 )
2286 )
2287 );
2288 } else {
2289 $tax_query = array(
2290 array(
2291 'taxonomy' => $args['taxonomy'],
2292 'field' => 'term_id',
2293 'terms' => $folder_id,
2294 'include_children' => $include_children,
2295 'operator' => 'NOT EXISTS'
2296 )
2297 );
2298 }
2299 } else {
2300 $tax_query = array(
2301 array(
2302 'taxonomy' => $args['taxonomy'],
2303 'field' => 'term_id',
2304 'terms' => $folder_id,
2305 'include_children' => $include_children,
2306 'operator' => 'IN'
2307 )
2308 );
2309 }
2310
2311 // prepare query arguments
2312 $wp_query_args = array(
2313 'post_type' => 'attachment',
2314 'post_status' => 'inherit',
2315 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
2316 'nopaging' => true,
2317 'posts_per_page' => -1,
2318 'fields' => 'ids',
2319 'tax_query' => $tax_query
2320 );
2321
2322 // is it preview?
2323 if ( $args['preview'] ) {
2324 $wp_query_args['posts_per_page'] = $args['preview_per_page'];
2325 $wp_query_args['offset'] = ( $args['preview_page'] - 1 ) * $args['preview_per_page'];
2326 $wp_query_args['nopaging'] = false;
2327 }
2328
2329 // run query
2330 $query = new WP_Query( apply_filters( 'rl_folders_query_args', $wp_query_args ) );
2331
2332 // get attachment IDs
2333 $attachments = $query->get_posts();
2334
2335 // valid attachments?
2336 if ( ! is_wp_error( $attachments ) ) {
2337 // cast IDs to int
2338 $attachments = array_map( 'intval', $attachments );
2339
2340 // make sure to skip duplicates
2341 $attachments = array_unique( $attachments );
2342
2343 // filter attachments
2344 $attachments = apply_filters( 'rl_get_gallery_images_attachments', $attachments );
2345
2346 if ( $args['exclude'] )
2347 $excluded = ! empty( $data[$menu_item]['attachments']['exclude'] ) ? $data[$menu_item]['attachments']['exclude'] : array();
2348
2349 foreach ( $attachments as $attachment_id ) {
2350 // get attachment image data
2351 if ( ! in_array( $attachment_id, $excluded ) )
2352 $images[] = $this->get_gallery_image_src( $attachment_id, $args['image_size'], $args['thumbnail_size'] );
2353 }
2354 }
2355 }
2356 break;
2357
2358 case 'remote_library':
2359 // is remote library active?
2360 if ( ! $rl->options['remote_library']['active'] )
2361 break;
2362
2363 // check for
2364 if ( ! isset( $args['media_search'] ) )
2365 $args['media_search'] = isset( $data[$menu_item]['media_search'] ) ? $data[$menu_item]['media_search'] : '';
2366
2367 if ( ! isset( $args['media_provider'] ) )
2368 $args['media_provider'] = isset( $data[$menu_item]['media_provider'] ) ? $data[$menu_item]['media_provider'] : 'all';
2369
2370 $images = $rl->remote_library->get_remote_library_images( $args );
2371 break;
2372 }
2373 }
2374
2375 // config sort order
2376 switch ( $args['orderby'] ) {
2377 case 'id':
2378 $sort = array();
2379
2380 foreach ( $images as $key => $image ) {
2381 // set sorting value
2382 $sort[$key] = $image['id'];
2383 }
2384
2385 // sort
2386 array_multisort( $sort, $args['order'] === 'asc' ? SORT_ASC : SORT_DESC, SORT_NUMERIC, $images );
2387 break;
2388
2389 case 'title':
2390 $sort = array();
2391
2392 if ( $valid_gallery_type ) {
2393 // get lightbox data
2394 $lightbox_meta = get_post_meta( $gallery_id, '_rl_lightbox', true );
2395
2396 // valid data?
2397 if ( isset( $lightbox_meta['menu_item'] ) )
2398 $title_arg = $lightbox_meta[$lightbox_meta['menu_item']]['lightbox_image_title'];
2399 else
2400 $title_arg = $rl->options['settings']['gallery_image_title'];
2401 } else
2402 $title_arg = $rl->options['settings']['gallery_image_title'];
2403
2404 $images_copy = $images;
2405
2406 foreach ( $images_copy as $key => $image ) {
2407 if ( $title_arg === 'global' )
2408 $images[$key]['title'] = $rl->frontend->get_attachment_title( $image['id'], $rl->options['settings']['gallery_image_title'] );
2409 elseif ( $title_arg === 'default' )
2410 $images[$key]['title'] = '';
2411 else
2412 $images[$key]['title'] = $rl->frontend->get_attachment_title( $image['id'], $title_arg );
2413
2414 // set sorting value
2415 $sort[$key] = function_exists( 'mb_strtolower' ) ? mb_strtolower( $images[$key]['title'] ) : strtolower( $images[$key]['title'] );
2416 }
2417
2418 // sort
2419 array_multisort( $sort, $args['order'] === 'asc' ? SORT_ASC : SORT_DESC, SORT_STRING, $images );
2420 break;
2421
2422 case 'post_date':
2423 $sort = array();
2424
2425 foreach ( $images as $key => $image ) {
2426 // set sorting value
2427 $sort[$key] = $image['date'];
2428 }
2429
2430 // sort
2431 array_multisort( $sort, $args['order'] === 'asc' ? SORT_ASC : SORT_DESC, $images );
2432 break;
2433
2434 case 'menu_order':
2435 // do nothing
2436 break;
2437
2438 case 'rand':
2439 shuffle( $images );
2440 break;
2441 }
2442
2443 $images = apply_filters( 'rl_get_gallery_images_array', $images, $gallery_id, $args );
2444
2445 // save images count
2446 $images_count = count( $images );
2447
2448 if ( metadata_exists( 'post', $gallery_id, '_rl_images_count' ) ) {
2449 $images_count_prev = get_post_meta( $gallery_id, '_rl_images_count', true );
2450
2451 update_post_meta( $gallery_id, '_rl_images_count', $images_count, $images_count_prev );
2452 } else
2453 add_post_meta( $gallery_id, '_rl_images_count', $images_count );
2454
2455 if ( $images && ! $args['nopaging'] && $args['images_per_page'] > 0 ) {
2456 // get part of images
2457 $images = array_slice( $images, ( $args['page'] - 1 ) * $args['images_per_page'], $args['images_per_page'], true );
2458
2459 // pass gallery args
2460 $this->gallery_args = $args;
2461 $this->gallery_args['total'] = (int) ceil( $images_count / $args['images_per_page'] );
2462
2463 // pagination position
2464 if ( $args['pagination_position'] === 'top' )
2465 add_action( 'rl_before_gallery', array( $this, 'do_pagination' ), 10, 2 );
2466 elseif ( $args['pagination_position'] === 'bottom' )
2467 add_action( 'rl_after_gallery', array( $this, 'do_pagination' ), 10, 2 );
2468 else {
2469 add_action( 'rl_before_gallery', array( $this, 'do_pagination' ), 10, 2 );
2470 add_action( 'rl_after_gallery', array( $this, 'do_pagination' ), 10, 2 );
2471 }
2472 }
2473
2474 return apply_filters( 'rl_get_gallery_images', array_values( $images ), $gallery_id, $args );
2475 }
2476
2477 /**
2478 * Create gallery pagination.
2479 *
2480 * @param array $args Arguments
2481 * @param int $gallery_id Arguments
2482 * @return string Rendered HTML
2483 */
2484 public function do_pagination( $args, $gallery_id ) {
2485 global $wp;
2486
2487 // get current action
2488 $current_action = current_action();
2489
2490 if ( $current_action === 'rl_before_gallery' )
2491 $class = ' rl-pagination-top';
2492 elseif ( $current_action === 'rl_after_gallery' )
2493 $class = ' rl-pagination-bottom';
2494 else
2495 $class = '';
2496
2497 echo
2498 '<div class="rl-pagination' . $class . '"' . ( $args['pagination_type'] === 'infinite' ? ' data-button="' . $args['load_more'] . '"' : '' ) .'>' .
2499 paginate_links(
2500 array(
2501 'format' => '?rl_page=%#%',
2502 '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 ) ),
2503 'total' => $this->gallery_args['total'],
2504 'current' => $this->gallery_args['page'],
2505 'show_all' => false,
2506 'end_size' => 1,
2507 'mid_size' => 2,
2508 'prev_next' => true,
2509 'prev_text' => __( '&laquo; Previous', 'responsive-lightbox' ),
2510 'next_text' => __( 'Next &raquo;', 'responsive-lightbox' ),
2511 'type' => 'plain',
2512 'add_args' => '',
2513 'add_fragment' => '',
2514 'before_page_number' => '',
2515 'after_page_number' => ''
2516 )
2517 ) .
2518 '</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>' : '' );
2519 }
2520
2521 /**
2522 * Get gallery page.
2523 *
2524 * @param array $args Arguments
2525 * @return void
2526 */
2527 public function get_gallery_page( $args ) {
2528 if ( isset( $_POST['gallery_id'], $_POST['page'], $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'rl_nonce' ) ) {
2529 $_GET['rl_page'] = (int) $_POST['page'];
2530
2531 echo $this->gallery_shortcode( array( 'id' => (int) $_POST['gallery_id'] ) );
2532 }
2533
2534 exit;
2535 }
2536
2537 /**
2538 * Generate gallery preview.
2539 *
2540 * @return void
2541 */
2542 public function post_gallery_preview() {
2543 // check data
2544 if ( ! isset( $_POST['post_id'], $_POST['gallery_id'], $_POST['nonce'], $_POST['page'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) )
2545 wp_send_json_error();
2546
2547 // check page
2548 if ( ! in_array( $_POST['page'], [ 'widgets.php', 'customize.php', 'post.php', 'post-new.php' ], true ) )
2549 wp_send_json_error();
2550
2551 // check edit_post capability
2552 if ( ( $_POST['page'] === 'post.php' || $_POST['page'] === 'post-new.php' ) && ! current_user_can( 'edit_post', (int) $_POST['post_id'] ) )
2553 wp_send_json_error();
2554
2555 // check edit_theme_options capability
2556 if ( ( $_POST['page'] === 'widgets.php' || $_POST['page'] === 'customize.php' ) && ! current_user_can( 'edit_theme_options' ) )
2557 wp_send_json_error();
2558
2559 // parse gallery ID
2560 $gallery_id = (int) $_POST['gallery_id'];
2561
2562 // get gallery data
2563 $data = get_post_meta( $gallery_id, '_rl_images', true );
2564
2565 // prepare data
2566 $attachments = $exclude = array();
2567 $html = '';
2568
2569 $images = $this->get_gallery_images( $gallery_id, array( 'exclude' => true ) );
2570
2571 // count attachments
2572 $images_count = (int) get_post_meta( $gallery_id, '_rl_images_count', true );
2573
2574 if ( ! empty( $images ) ) {
2575 foreach ( $images as $image ) {
2576 $html .= '
2577 <li role="checkbox" aria-label="" aria-checked="false" data-id="' . $image['id'] . '" class="attachment save-ready rl-status-active' . '">
2578 <div class="attachment-preview js--select-attachment type-image landscape">
2579 <div class="thumbnail">
2580 <div class="centered">
2581 <img src="' . $image['thumbnail_url'] . '" draggable="false" alt="" />
2582 </div>
2583 </div>
2584 </div>
2585 </li>';
2586 }
2587 }
2588
2589 // send attachments content
2590 wp_send_json_success(
2591 array(
2592 'attachments' => $html,
2593 'count' => sprintf( _n( '%s image', '%s images', $images_count, 'responsive-lightbox' ), $images_count ),
2594 'edit_url' => current_user_can( 'edit_post', $gallery_id ) ? admin_url( 'post.php?post=' . $gallery_id . '&action=edit' ): ''
2595 )
2596 );
2597 }
2598
2599 /**
2600 * Get all galleries.
2601 *
2602 * @return void
2603 */
2604 public function post_get_galleries() {
2605 // check data
2606 if ( ! isset( $_POST['post_id'], $_POST['search'], $_POST['nonce'], $_POST['page'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) )
2607 wp_send_json_error();
2608
2609 // check page
2610 if ( ! in_array( $_POST['page'], [ 'widgets.php', 'customize.php', 'post.php', 'post-new.php' ], true ) )
2611 wp_send_json_error();
2612
2613 // check edit_post capability
2614 if ( ( $_POST['page'] === 'post.php' || $_POST['page'] === 'post-new.php' ) && ! current_user_can( 'edit_post', (int) $_POST['post_id'] ) )
2615 wp_send_json_error();
2616
2617 // check edit_theme_options capability
2618 if ( ( $_POST['page'] === 'widgets.php' || $_POST['page'] === 'customize.php' ) && ! current_user_can( 'edit_theme_options' ) )
2619 wp_send_json_error();
2620
2621 $args = array(
2622 'post_type' => 'rl_gallery',
2623 'post_status' => 'publish',
2624 'nopaging' => true,
2625 'posts_per_page' => -1,
2626 'orderby' => 'title',
2627 'order' => 'ASC',
2628 'suppress_filters' => false,
2629 'no_found_rows' => true,
2630 'cache_results' => false
2631 );
2632
2633 // specific category?
2634 if ( ! empty( $_POST['category'] ) ) {
2635 $args['tax_query'] = array(
2636 array(
2637 'taxonomy' => 'rl_category',
2638 'field' => 'term_id',
2639 'operator' => 'IN',
2640 'include_children' => false,
2641 'terms' => (int) $_POST['category']
2642 )
2643 );
2644 }
2645
2646 $search = wp_unslash( trim( $_POST['search'] ) );
2647
2648 if ( $search !== '' )
2649 $args['s'] = $search;
2650
2651 // get galleries
2652 $query = new WP_Query( $args );
2653
2654 $html = '';
2655
2656 if ( ! empty( $query->posts ) ) {
2657 foreach ( $query->posts as $gallery ) {
2658 $featured = $this->get_featured_image_src( $gallery->ID );
2659
2660 if ( is_array( $featured ) && array_key_exists( 'url', $featured ) )
2661 $featured = $featured['url'];
2662 else
2663 $featured = '';
2664
2665 // get title
2666 $title = $gallery->post_title !== '' ? $gallery->post_title : __( '(no title)', 'responsive-gallery' );
2667
2668 $html .= '
2669 <li role="checkbox" aria-label="' . esc_attr( $title ) . '" aria-checked="false" data-id="' . $gallery->ID . '" class="attachment save-ready">
2670 <div class="attachment-preview js--select-attachment type-image landscape">
2671 <div class="thumbnail">
2672 <div class="centered" data-full-src="' . $featured . '">
2673 ' . $this->get_featured_image( $gallery->ID ) . '
2674 </div>
2675 <div class="filename">
2676 <div>' . esc_html( $title ) . '</div>
2677 </div>
2678 </div>
2679 </div>
2680 <button type="button" class="button-link check"><span class="media-modal-icon"></span><span class="screen-reader-text">' . __( 'Deselect', 'responsive-lightbox' ) . '</span></button>
2681 </li>';
2682 }
2683 }
2684
2685 // send galleries content
2686 wp_send_json_success( $html );
2687 }
2688
2689 /**
2690 * Get gallery content based on request.
2691 *
2692 * @return void
2693 */
2694 public function get_menu_content() {
2695 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 ) )
2696 wp_send_json_error();
2697
2698 // get selected menu item
2699 $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'] );
2700
2701 // get tab content
2702 wp_send_json_success( $this->get_metabox_content( $_POST['tab'], get_post_meta( $post_id, '_rl_' . $_POST['tab'], true ), $menu_item, $post_id ) );
2703 }
2704
2705 /**
2706 * Get gallery preview content based on request.
2707 *
2708 * @return void
2709 */
2710 public function get_gallery_preview_content() {
2711 // initial checks
2712 if ( ! isset( $_POST['post_id'], $_POST['menu_item'], $_POST['nonce'], $_POST['preview_type'] ) || ! check_ajax_referer( 'rl-gallery', 'nonce', false ) )
2713 wp_send_json_error();
2714
2715 // cast gallery ID
2716 $post_id = (int) $_POST['post_id'];
2717
2718 // check user privileges
2719 if ( ! current_user_can( 'edit_post', $post_id ) || ! current_user_can( 'upload_files' ) )
2720 wp_send_json_error();
2721
2722 // get query args
2723 $args = ! empty( $_POST['query'] ) ? wp_unslash( $_POST['query'] ) : array();
2724
2725 // check orderby
2726 if ( array_key_exists( 'orderby', $args ) ) {
2727 $args['post_orderby'] = $args['orderby'];
2728
2729 unset( $args['orderby'] );
2730 }
2731
2732 // check order
2733 if ( array_key_exists( 'order', $args ) ) {
2734 $args['post_order'] = $args['order'];
2735
2736 unset( $args['order'] );
2737 }
2738
2739 // check preview type
2740 if ( ! in_array( $_POST['preview_type'], array( 'page', 'update' ), true ) )
2741 $args['preview_type'] = 'page';
2742 else
2743 $args['preview_type'] = $_POST['preview_type'];
2744
2745 // check for POST menu item
2746 $menu_item = ! empty( $_POST['menu_item'] ) && is_string( $_POST['menu_item'] ) ? esc_attr( $_POST['menu_item'] ) : '';
2747
2748 // set images menu item
2749 $menu_item = $this->menu_item = ! empty( $menu_item ) && array_key_exists( $menu_item, $this->tabs['images']['menu_items'] ) ? $menu_item : 'media';
2750
2751 if ( $this->fields['images'][$menu_item]['attachments']['preview']['pagination'] ) {
2752 if ( isset( $args['preview_page'] ) )
2753 $args['preview_page'] = (int) $args['preview_page'];
2754 else
2755 $args['preview_page'] = 1;
2756 }
2757
2758 // get images
2759 $images = $this->get_gallery_images( $post_id, $args );
2760
2761 // prepare JSON array
2762 $data = array();
2763
2764 if ( $menu_item === 'remote_library' ) {
2765 // get main instance
2766 $rl = Responsive_Lightbox();
2767
2768 $response_data = array();
2769
2770 // single provider?
2771 if ( $args['media_provider'] !== 'all' ) {
2772 // get provider
2773 $provider = $rl->providers[$args['media_provider']];
2774
2775 // add response data arguments if needed
2776 if ( ! empty( $provider['response_args'] ) ) {
2777 $response = $provider['instance']->get_response_data();
2778
2779 foreach ( $provider['response_args'] as $arg ) {
2780 if ( array_key_exists( $arg, $response ) )
2781 $response_data[$provider['slug']][$arg] = base64_encode( json_encode( $response[$arg] ) );
2782 }
2783 }
2784 } else {
2785 // get active providers
2786 $providers = $this->get_active_providers();
2787
2788 if ( ! empty( $providers ) ) {
2789 foreach ( $providers as $provider ) {
2790 // get provider
2791 $provider = $rl->providers[$provider];
2792
2793 // add response data arguments if needed
2794 if ( ! empty( $provider['response_args'] ) ) {
2795 $response = $provider['instance']->get_response_data();
2796
2797 foreach ( $provider['response_args'] as $arg ) {
2798 if ( array_key_exists( $arg, $response ) )
2799 $response_data[$provider['slug']][$arg] = base64_encode( json_encode( $response[$arg] ) );
2800 }
2801 }
2802 }
2803 }
2804 }
2805
2806 $data['data'] = $response_data;
2807 }
2808
2809 // parse excluded images
2810 $excluded = ! empty( $_POST['excluded'] ) ? $_POST['excluded'] : array();
2811
2812 // get excluded images
2813 if ( $excluded )
2814 $excluded = array_unique( array_filter( array_map( 'intval', $excluded ) ) );
2815
2816 // get media item template
2817 $media_item_template = $this->get_media_item_template( $this->fields['images'][$menu_item]['attachments']['preview'] );
2818
2819 // build html
2820 $html = '';
2821
2822 // any images?
2823 if ( ! empty( $images ) ) {
2824 foreach ( $images as $image ) {
2825 $image_html = $image['thumbnail_link'];
2826
2827 // replace ID and URL of an image
2828 $html .= str_replace( '__IMAGE__', '<input type="hidden" class="rl-gallery-exclude" name="rl_gallery[images][' . $menu_item . '][attachments][exclude][]" value="' . ( in_array( $image['id'], $excluded, true ) ? $image['id'] : '' ) . '" />' . $image_html, 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 ) ) );
2829 }
2830 }
2831
2832 $data['images'] = $html;
2833
2834 if ( $this->fields['images'][$menu_item]['attachments']['preview']['pagination'] )
2835 $data['pagination'] = $this->get_preview_pagination( $args['preview_page'] );
2836
2837 // send JSON
2838 wp_send_json_success( $data );
2839 }
2840
2841 /**
2842 * Get gallery image link.
2843 *
2844 * @param array $image Image data
2845 * @param mixed $size Image size
2846 * @param array $attr Image attributes
2847 * @return string
2848 */
2849 public function get_gallery_image_link( $image, $size = 'thumbnail', $attr = array() ) {
2850 $link = '';
2851
2852 if ( $size === 'thumbnail' ) {
2853 $url = $image['thumbnail_url'];
2854 $width = $image['thumbnail_width'];
2855 $height = $image['thumbnail_height'];
2856 } else {
2857 $url = $image['url'];
2858 $width = $image['width'];
2859 $height = $image['height'];
2860 }
2861
2862 if ( ! empty( $image['url'] ) ) {
2863 $size_class = $size;
2864
2865 if ( is_array( $size_class ) )
2866 $size_class = join( 'x', $size_class );
2867
2868 // combine attributes
2869 $attr = wp_parse_args(
2870 $attr,
2871 array(
2872 'src' => $url,
2873 'class' => 'attachment-' . $size_class . ' size-' . $size_class . ' format-' . ( $height > $width ? 'portrait' : 'landscape' ),
2874 'alt' => $image['alt']
2875 )
2876 );
2877
2878 // apply filters if any
2879 $attr = apply_filters( 'rl_get_gallery_image_attributes', $attr, $image, $size );
2880
2881 // escape every attribute
2882 $attr = array_map( 'esc_attr', $attr );
2883
2884 // start link output
2885 $link = rtrim( '<img ' . image_hwstring( $width, $height ) );
2886
2887 // add attributes
2888 foreach ( $attr as $name => $value ) {
2889 $link .= ' ' . $name . '="' . $value . '"';
2890 }
2891
2892 // end link output
2893 $link .= ' />';
2894 }
2895
2896 return apply_filters( 'rl_get_gallery_image_link', $link, $image, $size );
2897 }
2898
2899 /**
2900 * Get attachment image source.
2901 *
2902 * @param int|string|array $image Attachment ID, image URL or array of image data
2903 * @param string $image_size Image size
2904 * @param string $thumbnail_size Thumbnail size
2905 * @return array
2906 */
2907 public function get_gallery_image_src( $image, $image_size = 'large', $thumbnail_size = 'thumbnail' ) {
2908 $imagedata = array();
2909 $diff_sizes = $thumbnail_size !== $image_size;
2910
2911 // attachment ID?
2912 if ( is_int( $image ) ) {
2913 $image_src = wp_get_attachment_image_src( $image, $image_size, false );
2914
2915 if ( $image && wp_attachment_is_image( $image ) ) {
2916 if ( $diff_sizes )
2917 $thumbnail_src = wp_get_attachment_image_src( $image, $thumbnail_size, false );
2918 else
2919 $thumbnail_src = $image_src;
2920
2921 $imagedata = array(
2922 'id' => $image,
2923 'title' => get_the_title( $image ),
2924 'date' => get_the_date( 'Y-m-d H:i:s', $image ),
2925 'caption' => '',
2926 'alt' => '',
2927 'url' => $image_src[0],
2928 'width' => $image_src[1],
2929 'height' => $image_src[2],
2930 'thumbnail_url' => $thumbnail_src[0],
2931 'thumbnail_width' => $thumbnail_src[1],
2932 'thumbnail_height' => $thumbnail_src[2]
2933 );
2934 }
2935 // image url
2936 } elseif ( is_string( $image ) ) {
2937 $imagedata['url'] = $image;
2938
2939 @list( $imagedata['width'], $imagedata['height'] ) = rl_get_image_size_by_url( $imagedata['url'] );
2940
2941 $imagedata = array(
2942 'id' => 0,
2943 'title' => '',
2944 'caption' => '',
2945 'alt' => '',
2946 'url' => $imagedata['url'],
2947 'width' => $imagedata['width'],
2948 'height' => $imagedata['height'],
2949 'thumbnail_url' => $imagedata['url'],
2950 'thumbnail_width' => $imagedata['width'],
2951 'thumbnail_height' => $imagedata['height']
2952 );
2953 } elseif ( is_array( $image ) ) {
2954 // set width and height from url, if not available
2955 if ( empty( $image['width'] ) || empty( $image['height'] ) )
2956 @list( $image['width'], $image['height'] ) = rl_get_image_size_by_url( $image['url'] );
2957
2958 // set thumbnail data, if not available
2959 if ( empty( $image['thumbnail_url'] ) ) {
2960 $image['thumbnail_url'] = $image['url'];
2961 $image['thumbnail_width'] = $image['width'];
2962 $image['thumbnail_height'] = $image['height'];
2963 } else {
2964 // set thumbnail width and height from url, if not available
2965 if ( empty( $image['thumbnail_width'] ) || empty( $image['thumbnail_height'] ) )
2966 @list( $image['thumbnail_width'], $image['thumbnail_height'] ) = rl_get_image_size_by_url( $image['thumbnail_url'] );
2967 }
2968
2969 $imagedata = array(
2970 'id' => ! empty( $image['id'] ) ? (int) $image['id'] : 0,
2971 'link' => ! empty( $image['link'] ) ? esc_url( $image['link'] ) : '',
2972 'thumbnail_link' => ! empty( $image['thumbnail_link'] ) ? esc_url( $image['thumbnail_link'] ) : '',
2973 'title' => ! empty( $image['title'] ) ? esc_html( $image['title'] ) : '',
2974 'caption' => ! empty( $image['caption'] ) ? esc_html( $image['caption'] ) : '',
2975 'alt' => ! empty( $image['alt'] ) ? esc_html( $image['alt'] ) : '',
2976 'url' => ! empty( $image['url'] ) ? esc_url( $image['url'] ) : '',
2977 'width' => ! empty( $image['width'] ) ? (int) $image['width'] : 0,
2978 'height' => ! empty( $image['height'] ) ? (int) $image['height'] : 0,
2979 'thumbnail_url' => ! empty( $image['thumbnail_url'] ) ? esc_url( $image['thumbnail_url'] ) : '',
2980 'thumbnail_width' => ! empty( $image['thumbnail_width'] ) ? (int) $image['thumbnail_width'] : 0,
2981 'thumbnail_height' => ! empty( $image['thumbnail_height'] ) ? (int) $image['thumbnail_height'] : 0,
2982 );
2983 }
2984
2985 // link does not exist?
2986 if ( empty( $imagedata['link'] ) )
2987 $imagedata['link'] = $this->get_gallery_image_link( $imagedata, $image_size );
2988
2989 // thumbnail link does not exist?
2990 if ( empty( $imagedata['thumbnail_link'] ) ) {
2991 if ( $diff_sizes )
2992 $imagedata['thumbnail_link'] = $this->get_gallery_image_link( $imagedata, $thumbnail_size );
2993 else
2994 $imagedata['thumbnail_link'] = $imagedata['link'];
2995 }
2996
2997 return apply_filters( 'rl_get_gallery_image_src', $imagedata, $image, $image_size, $thumbnail_size );
2998 }
2999
3000 /**
3001 * Get gallery featured image.
3002 *
3003 * @param int $gallery_id Gallery ID
3004 * @param array $size Image size
3005 * @param array $attr Image attributes
3006 * @return string
3007 */
3008 public function get_featured_image( $gallery_id, $size = 'thumbnail', $attr = array() ) {
3009 $image = $this->get_featured_image_src( $gallery_id );
3010 $html = '';
3011
3012 if ( $image )
3013 $html = $this->get_gallery_image_link( $this->get_gallery_image_src( $image, 'large', $size ), $size, $attr );
3014
3015 return apply_filters( 'rl_get_featured_image', $html, $gallery_id, $size );
3016 }
3017
3018 /**
3019 * Get gallery featured image data.
3020 *
3021 * @param int $gallery_id Gallery ID
3022 * @return array
3023 */
3024 public function get_featured_image_src( $gallery_id ) {
3025 // get featured image data
3026 $featured_image_type = get_post_meta( $gallery_id, '_rl_featured_image_type', true );
3027 $featured_image = get_post_meta( $gallery_id, '_rl_featured_image', true );
3028
3029 switch ( $featured_image_type ) {
3030 // custom url
3031 case 'url':
3032 $image = esc_url( $featured_image );
3033 break;
3034
3035 // attachment id
3036 case 'id':
3037 $featured_image = (int) $featured_image;
3038 $image = wp_attachment_is_image( $featured_image ) ? $featured_image : $this->maybe_generate_thumbnail();
3039 break;
3040
3041 // first image
3042 case 'image':
3043 default:
3044 // get gallery images
3045 $images = $this->get_gallery_images( $gallery_id, array( 'exclude' => true ) );
3046
3047 // set image data
3048 if ( $images )
3049 $image = reset( $images );
3050 else
3051 $image = 0;
3052 }
3053
3054 // return only the first image
3055 return apply_filters( 'rl_get_featured_image_src', $image, $gallery_id, $featured_image_type, $featured_image );
3056 }
3057
3058 /**
3059 * Get featured gallery attachments.
3060 *
3061 * @param array $args Query arguments
3062 * @return array Attachment IDs
3063 */
3064 public function gallery_query( $args ) {
3065 $attachments = array();
3066
3067 // get fields
3068 $fields = $this->fields['images']['featured'];
3069
3070 // force these settings
3071 $args['fields'] = 'ids';
3072 $args['tax_query'] = array();
3073 $args['meta_query'] = array();
3074 $args['author__in'] = array();
3075 $args['post_parent__in'] = array();
3076
3077 // get image source
3078 $args['image_source'] = isset( $args['image_source'] ) && array_key_exists( $args['image_source'], $fields['image_source']['options'] ) ? $args['image_source'] : $fields['image_source']['default'];
3079 // get images per post
3080 $args['images_per_post'] = isset( $args['images_per_post'] ) ? absint( $args['images_per_post'] ) : $fields['images_per_post']['default'];
3081
3082 $args['number_of_posts'] = isset( $args['number_of_posts'] ) ? (int) $args['number_of_posts'] : $fields['number_of_posts']['default'];
3083
3084 // get all posts?
3085 if ( $args['number_of_posts'] <= 0 )
3086 $args['number_of_posts'] = -1;
3087
3088 // convert to query arg
3089 $args['posts_per_page'] = $args['number_of_posts'];
3090
3091 $args['order'] = isset( $args['order'] ) && array_key_exists( $args['order'], $fields['order']['options'] ) ? $args['order'] : $fields['order']['default'];
3092 $args['orderby'] = isset( $args['orderby'] ) && array_key_exists( $args['orderby'], $fields['orderby']['options'] ) ? $args['orderby'] : $fields['orderby']['default'];
3093 $args['offset'] = isset( $args['offset'] ) ? absint( $args['offset'] ) : 0;
3094
3095 $tax_queries = array(
3096 'post_format' => array(),
3097 'post_term' => array()
3098 );
3099
3100 $meta_queries = array(
3101 'page_template' => array(),
3102 'image_source' => array()
3103 );
3104
3105 // post type
3106 if ( ! empty( $args['post_type'] ) ) {
3107 // assign post types
3108 $post_types = $args['post_type'];
3109
3110 // clear post types
3111 $args['post_type'] = array();
3112
3113 foreach ( $post_types as $post_type ) {
3114 if ( array_key_exists( $post_type, $fields['post_type']['options'] ) )
3115 $args['post_type'][] = $post_type;
3116 }
3117 } else
3118 $args['post_type'] = $this->get_post_types( true );
3119
3120 // post status
3121 if ( ! empty( $args['post_status'] ) ) {
3122 // assign post statuses
3123 $post_statuses = $args['post_status'];
3124
3125 // clear post statuses
3126 $args['post_status'] = array();
3127
3128 foreach ( $post_statuses as $post_status ) {
3129 if ( array_key_exists( $post_status, $fields['post_status']['options'] ) )
3130 $args['post_status'][] = $post_status;
3131 }
3132 }
3133
3134 // post format
3135 if ( ! empty( $args['post_format'] ) ) {
3136 // assign post formats
3137 $post_formats = $args['post_format'];
3138
3139 foreach ( $post_formats as $post_format ) {
3140 if ( array_key_exists( $post_format, $fields['post_format']['options'] ) ) {
3141 // standard format?
3142 if ( $post_format === 'standard' ) {
3143 $tax_queries['post_format'][] = array(
3144 'relation' => 'OR',
3145 array(
3146 'taxonomy' => 'post_format',
3147 'field' => 'slug',
3148 'terms' => array( 'post-format-standard' )
3149 ),
3150 array(
3151 'taxonomy' => 'post_format',
3152 'field' => 'slug',
3153 'operator' => 'NOT EXISTS'
3154 )
3155 );
3156 } else {
3157 $tax_queries['post_format'][] = array(
3158 'taxonomy' => 'post_format',
3159 'field' => 'slug',
3160 'terms' => array( 'post-format-' . $post_format )
3161 );
3162 }
3163 }
3164 }
3165
3166 unset( $args['post_format'] );
3167 }
3168
3169 // page template
3170 if ( ! empty( $args['page_template'] ) ) {
3171 foreach ( $args['page_template'] as $page_template ) {
3172 if ( array_key_exists( $page_template, $fields['page_template']['options'] ) ) {
3173 if ( $page_template === 'default' ) {
3174 $meta_queries['page_template'][] = array(
3175 'relation' => 'OR',
3176 array(
3177 'key' => '_wp_page_template',
3178 'value' => 'default'
3179 ),
3180 array(
3181 'key' => '_wp_page_template',
3182 'value' => ''
3183 ),
3184 array(
3185 'key' => '_wp_page_template',
3186 'compare' => 'NOT EXISTS'
3187 )
3188 );
3189 } else {
3190 $meta_queries['page_template'][] = array(
3191 'key' => '_wp_page_template',
3192 'value' => $page_template
3193 );
3194 }
3195 }
3196 }
3197 }
3198
3199 // post author
3200 if ( ! empty( $args['post_author'] ) ) {
3201 foreach ( $args['post_author'] as $post_author ) {
3202 if ( array_key_exists( $post_author, $fields['post_author']['options'] ) )
3203 $args['author__in'][] = $post_author;
3204 }
3205 }
3206
3207 // page parent
3208 if ( ! empty( $args['page_parent'] ) ) {
3209 foreach ( $args['page_parent'] as $page_parent ) {
3210 if ( array_key_exists( $page_parent, $fields['page_parent']['options'] ) )
3211 $args['post_parent__in'][] = $page_parent;
3212 }
3213 }
3214
3215 // post term
3216 if ( ! empty( $args['post_term'] ) ) {
3217 $terms = array();
3218
3219 // get all terms
3220 if ( ! empty( $fields['post_term']['options'] ) ) {
3221 foreach ( $fields['post_term']['options'] as $tax => $data ) {
3222 $terms = array_merge( $terms, array_map( 'intval', array_keys( $data['terms'] ) ) );
3223 }
3224 }
3225
3226 foreach ( $args['post_term'] as $post_term ) {
3227 if ( in_array( $post_term, $terms ) ) {
3228 $term = get_term( $post_term );
3229
3230 $tax_queries['post_term'][] = array(
3231 'taxonomy' => $term->taxonomy,
3232 'field' => 'term_id',
3233 'terms' => (int) $post_term
3234 );
3235 }
3236 }
3237 }
3238
3239 switch ( $args['image_source'] ) {
3240 case 'thumbnails':
3241 $meta_queries['image_source'][] = array(
3242 'relation' => 'OR',
3243 array(
3244 'key' => '_thumbnail_id',
3245 'compare' => 'EXISTS'
3246 )
3247 );
3248 }
3249
3250 // any tax queries?
3251 if ( ! empty( $tax_queries['post_term'] ) || ! empty( $tax_queries['post_format'] ) ) {
3252 $args['tax_query'] = array( 'relation' => 'AND' );
3253
3254 if ( ! empty( $tax_queries['post_term'] ) )
3255 $args['tax_query'][] = array( 'relation' => 'OR' ) + $tax_queries['post_term'];
3256
3257 if ( ! empty( $tax_queries['post_format'] ) )
3258 $args['tax_query'][] = array( 'relation' => 'OR' ) + $tax_queries['post_format'];
3259 }
3260
3261 // any tax queries?
3262 if ( ! empty( $meta_queries['page_template'] ) || ! empty( $meta_queries['image_source'] ) ) {
3263 $args['meta_query'] = array( 'relation' => 'AND' );
3264
3265 if ( ! empty( $meta_queries['page_template'] ) )
3266 $args['meta_query'][] = array( 'relation' => 'OR', $meta_queries['page_template'] );
3267
3268 if ( ! empty( $meta_queries['image_source'] ) )
3269 $args['meta_query'][] = array( 'relation' => 'OR', $meta_queries['image_source'] );
3270 }
3271
3272 // get posts
3273 $query = new WP_Query( apply_filters( 'rl_gallery_query_args', $args ) );
3274
3275 // get attachments
3276 if ( $query->have_posts() )
3277 $attachments = $this->get_gallery_query_attachments( $query->posts, $args );
3278
3279 return $attachments;
3280 }
3281
3282 /**
3283 * Get query attachments.
3284 *
3285 * @param array $posts Post ids, array or objects
3286 * @param array $args Additional arguments
3287 * @return array
3288 */
3289 public function get_gallery_query_attachments( $posts, $args ) {
3290 $attachments = array();
3291
3292 // any posts?
3293 if ( ! empty( $posts ) ) {
3294 switch ( $args['image_source'] ) {
3295 case 'thumbnails':
3296 $nop = count( $posts ) - 1;
3297
3298 foreach ( $posts as $number => $post_id ) {
3299 $attachment_id = (int) get_post_thumbnail_id( $post_id );
3300
3301 if ( ! empty( $attachment_id ) )
3302 $attachments[] = $attachment_id;
3303
3304 if ( $args['preview'] ) {
3305 $attachments = array_unique( $attachments );
3306 $noa = count( $attachments );
3307
3308 if ( ( $noa >= ( $args['preview_per_page'] * $args['preview_page'] ) ) || $nop === $number ) {
3309 $attachments = array_slice( $attachments, ( $args['preview_page'] - 1 ) * $args['preview_per_page'], $args['preview_per_page'], false );
3310
3311 break;
3312 }
3313 }
3314 }
3315 break;
3316
3317 case 'attached_images':
3318 $nop = count( $posts ) - 1;
3319
3320 foreach ( $posts as $number => $post_id ) {
3321 // get attached images, do not use get_attached_media here!
3322 $attachment_ids = (array) get_children(
3323 array(
3324 'post_parent' => $post_id,
3325 'post_status' => 'inherit',
3326 'post_type' => 'attachment',
3327 'post_mime_type' => 'image',
3328 'posts_per_page' => $args['images_per_post'],
3329 'order' => 'ASC',
3330 'orderby' => 'menu_order',
3331 'nopaging' => false,
3332 'page' => 1,
3333 'fields' => 'ids'
3334 )
3335 );
3336
3337 if ( $attachment_ids ) {
3338 foreach ( $attachment_ids as $attachment_id ) {
3339 if ( ! empty( $attachment_id ) ) {
3340 $attachments[] = $attachment_id;
3341 }
3342 }
3343 }
3344
3345 if ( $args['preview'] ) {
3346 $attachments = array_unique( $attachments );
3347 $noa = count( $attachments );
3348
3349 if ( ( $noa >= ( $args['preview_per_page'] * $args['preview_page'] ) ) || $nop === $number ) {
3350 $attachments = array_slice( $attachments, ( $args['preview_page'] - 1 ) * $args['preview_per_page'], $args['preview_per_page'], false );
3351
3352 break;
3353 }
3354 }
3355 }
3356 }
3357 }
3358
3359 return apply_filters( 'rl_get_gallery_query_attachments', array_unique( $attachments ), $posts, $args );
3360 }
3361
3362 /**
3363 * Load featured content query args.
3364 *
3365 * @return void
3366 */
3367 public function init_admin() {
3368 global $pagenow;
3369
3370 // prepare query arguments if needed
3371 if ( ( $pagenow === 'post.php' && ( ( isset( $_GET['post'] ) && get_post_type( $_GET['post'] ) === 'rl_gallery' ) || ( isset( $_POST['post_ID'] ) && get_post_type( $_POST['post_ID'] ) === 'rl_gallery' ) ) ) || ( in_array( $pagenow, array( 'edit.php', 'post-new.php'), true ) && isset( $_GET['post_type'] ) && $_GET['post_type'] === 'rl_gallery' ) || ( $pagenow === 'admin-ajax.php' && isset( $_POST['action'] ) && in_array( $_POST['action'], array( 'rl-get-preview-content', 'rl-post-gallery-preview', 'rl-get-menu-content' ), true ) ) )
3372 $this->fields['images']['featured'] = $this->prepare_featured_fields( $this->fields['images']['featured'] );
3373
3374 // add default thumbnail image if needed
3375 if ( Responsive_Lightbox()->options['builder']['gallery_builder'] && $pagenow === 'edit.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === 'rl_gallery' )
3376 $this->maybe_generate_thumbnail();
3377 }
3378
3379 /**
3380 * Generate post thumbnail replacement.
3381 *
3382 * @return int Thumbnail ID
3383 */
3384 public function maybe_generate_thumbnail() {
3385 // get old attachment
3386 $thumbnail_id = get_posts(
3387 array(
3388 'name' => 'responsive-lightbox-thumbnail',
3389 'post_type' => 'attachment',
3390 'post_status' => 'inherit',
3391 'numberposts' => 1,
3392 'fields' => 'ids'
3393 )
3394 );
3395
3396 // no attachment?
3397 if ( empty( $thumbnail_id ) ) {
3398 // get new attachment
3399 $thumbnail_id = get_posts(
3400 array(
3401 'name' => 'responsive-lightbox-thumbnail',
3402 'post_type' => 'attachment',
3403 'post_status' => 'pending',
3404 'numberposts' => 1,
3405 'fields' => 'ids'
3406 )
3407 );
3408
3409 // no attachment?
3410 if ( empty( $thumbnail_id ) ) {
3411 // get upload directory data
3412 $wp_upload_dir = wp_upload_dir();
3413
3414 // get file path
3415 $filepath = str_replace( '\\', '/', RESPONSIVE_LIGHTBOX_PATH . 'images/responsive-lightbox-thumbnail.png' );
3416
3417 // get file name
3418 $filename = basename( $filepath );
3419
3420 // new filepath in upload dir
3421 $new_filepath = $wp_upload_dir['path'] . '/' . $filename;
3422
3423 // copty file to upload dir
3424 copy( $filepath, $new_filepath );
3425
3426 // get type of file
3427 $filetype = wp_check_filetype( $filename );
3428
3429 // force pending status for the attachment
3430 add_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
3431
3432 // insert attachment
3433 $thumbnail_id = wp_insert_attachment(
3434 array(
3435 'guid' => $wp_upload_dir['url'] . '/' . $filename,
3436 'post_mime_type' => $filetype['type'],
3437 'post_title' => preg_replace( '/\.[^.]+$/', '', $filename ),
3438 'post_content' => '',
3439 'post_parent' => 0,
3440 'post_status' => 'inherit'
3441 ),
3442 $new_filepath,
3443 0
3444 );
3445
3446 remove_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
3447
3448 // success?
3449 if ( $thumbnail_id ) {
3450 // make sure that this file is included
3451 require_once( ABSPATH . 'wp-admin/includes/image.php' );
3452
3453 // update database with generated metadata for the attachment
3454 wp_update_attachment_metadata( $thumbnail_id, wp_generate_attachment_metadata( $thumbnail_id, $new_filepath ) );
3455 }
3456 } else
3457 $thumbnail_id = $thumbnail_id[0];
3458 } else {
3459 // force pending status for the attachment
3460 add_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
3461
3462 $thumbnail_id = wp_update_post(
3463 array(
3464 'ID' => $thumbnail_id[0],
3465 'post_status' => 'pending'
3466 )
3467 );
3468
3469 remove_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
3470 }
3471
3472 return (int) $thumbnail_id;
3473 }
3474
3475 /**
3476 * Change status of new attachment thumbnail replacement.
3477 *
3478 * @param array $data Post data
3479 * @return array
3480 */
3481 function set_attachment_post_status( $data ) {
3482 $data['post_status'] = 'pending';
3483
3484 return $data;
3485 }
3486
3487 /**
3488 * Prepare featured content fields.
3489 *
3490 * @param array $fields
3491 * @return array
3492 */
3493 public function prepare_featured_fields( $fields ) {
3494 foreach ( array( 'post_type', 'post_status', 'post_format', 'post_term', 'post_author', 'page_parent', 'page_template' ) as $option ) {
3495 $fields[$option]['options'] = $this->prepare_query_args( $option );
3496 }
3497
3498 return $fields;
3499 }
3500
3501 /**
3502 * Prepare values option list.
3503 *
3504 * @param string $type Value type
3505 * @return string Generated HTML
3506 */
3507 public function prepare_query_args( $type = '' ) {
3508 $html = '';
3509
3510 switch( $type ) {
3511 case 'post_type':
3512 $data = $this->get_post_types();
3513 break;
3514
3515 case 'post_status':
3516 $data = $this->get_post_statuses();
3517 break;
3518
3519 case 'post_format':
3520 $data = $this->get_post_formats();
3521 break;
3522
3523 case 'post_term':
3524 $taxonomies = $this->get_taxonomies();
3525 $new_terms = array();
3526
3527 if ( ! empty( $taxonomies ) ) {
3528 foreach ( $taxonomies as $tax_id => $label ) {
3529 $terms = get_terms(
3530 array(
3531 'taxonomy' => $tax_id,
3532 'orderby' => 'name',
3533 'order' => 'ASC',
3534 'hide_empty' => false,
3535 'fields' => 'id=>name'
3536 )
3537 );
3538
3539 if ( ! empty( $terms ) )
3540 $new_terms[$tax_id] = array(
3541 'label' => $label,
3542 'terms' => $terms
3543 );
3544 }
3545 }
3546
3547 $data = $new_terms;
3548 break;
3549
3550 case 'post_author':
3551 $data = $this->get_users();
3552 break;
3553
3554 case 'page_parent':
3555 $parents = array();
3556 $hierarchical = get_post_types(
3557 array(
3558 'public' => true,
3559 'hierarchical' => true
3560 ),
3561 'objects',
3562 'and'
3563 );
3564
3565 if ( ! empty( $hierarchical ) ) {
3566 foreach ( $hierarchical as $post_type => $object ) {
3567 // get top level hierarchical posts
3568 $query = new WP_Query(
3569 array(
3570 'post_type' => $post_type,
3571 'post_status' => 'publish',
3572 'nopaging' => true,
3573 'posts_per_page' => -1,
3574 'orderby' => 'title',
3575 'order' => 'ASC',
3576 'suppress_filters' => false,
3577 'no_found_rows' => true,
3578 'cache_results' => false,
3579 'post_parent' => 0
3580 )
3581 );
3582
3583 if ( ! empty( $query->posts ) ) {
3584 foreach ( $query->posts as $post ) {
3585 $parents[$post->ID] = trim( $post->post_title ) === '' ? __( 'Untitled' ) : $post->post_title;
3586 }
3587 }
3588 }
3589 }
3590
3591 $data = $parents;
3592 break;
3593
3594 case 'page_template':
3595 $data = $this->get_page_templates();
3596 break;
3597
3598 default:
3599 $data = array();
3600 }
3601
3602 return apply_filters( 'rl_galleries_prepare_query_args', $data, $type );
3603 }
3604
3605 /**
3606 * Get public post types.
3607 *
3608 * @param bool $simple Which data should be returned
3609 * @param bool $skip Which post types should be skipped
3610 * @return array Post types
3611 */
3612 public function get_post_types( $simple = false, $skip = array( 'attachment', 'rl_gallery' ) ) {
3613 $post_types = get_post_types(
3614 array(
3615 'public' => true
3616 ),
3617 'objects',
3618 'and'
3619 );
3620
3621 $data = array();
3622
3623 if ( ! empty( $post_types ) ) {
3624 foreach ( $post_types as $post_type => $cpt ) {
3625 // skip unwanted post types
3626 if ( in_array( $post_type, $skip, true ) )
3627 continue;
3628
3629 if ( $simple )
3630 $data[] = $post_type;
3631 else
3632 $data[$post_type] = $cpt->labels->singular_name;
3633 }
3634 }
3635
3636 if ( ! $simple )
3637 asort( $data );
3638
3639 return $data;
3640 }
3641
3642 /**
3643 * Get post statuses.
3644 *
3645 * @return array Post statuses
3646 */
3647 public function get_post_statuses() {
3648 $post_statuses = get_post_stati();
3649
3650 asort( $post_statuses );
3651
3652 // remove inherit post status
3653 if ( isset( $post_statuses['inherit'] ) )
3654 unset( $post_statuses['inherit'] );
3655
3656 return $post_statuses;
3657 }
3658
3659 /**
3660 * Get post formats.
3661 *
3662 * @return array Post formats
3663 */
3664 public function get_post_formats() {
3665 $post_formats = array(
3666 'aside' => __( 'Aside' ),
3667 'audio' => __( 'Audio' ),
3668 'chat' => __( 'Chat' ),
3669 'gallery' => __( 'Gallery' ),
3670 'link' => __( 'Link' ),
3671 'photo' => __( 'Photo' ),
3672 'quote' => __( 'Quote' ),
3673 'standard' => __( 'Standard' ),
3674 'status' => __( 'Status' ),
3675 'video' => __( 'Video' )
3676 );
3677
3678 asort( $post_formats );
3679
3680 return $post_formats;
3681 }
3682
3683 /**
3684 * Get taxonomies.
3685 *
3686 * @return array Taxonomies
3687 */
3688 public function get_taxonomies() {
3689 $taxonomies = get_taxonomies(
3690 array(
3691 'public' => true
3692 ),
3693 'objects',
3694 'and'
3695 );
3696
3697 // remove post format
3698 if ( array_key_exists( 'post_format', $taxonomies ) )
3699 unset( $taxonomies['post_format'] );
3700
3701 // get main instance
3702 $rl = Responsive_Lightbox();
3703
3704 // remove gallery categories
3705 if ( $rl->options['builder']['categories'] && array_key_exists( 'rl_category', $taxonomies ) )
3706 unset( $taxonomies['rl_category'] );
3707
3708 // remove gallery tags
3709 if ( $rl->options['builder']['tags'] && array_key_exists( 'rl_tag', $taxonomies ) )
3710 unset( $taxonomies['rl_tag'] );
3711
3712 if ( $rl->options['folders']['active'] ) {
3713 // remove media folders categories
3714 unset( $taxonomies['rl_media_folder'] );
3715
3716 // remove custom media folders categories
3717 if ( $rl->options['folders']['media_taxonomy'] !== 'rl_media_folder' )
3718 unset( $taxonomies[$rl->options['folders']['media_taxonomy']] );
3719
3720 // remove media folders tags
3721 if ( $rl->options['folders']['media_tags'] )
3722 unset( $taxonomies['rl_media_tag'] );
3723 }
3724
3725 $data = array();
3726
3727 if ( ! empty( $taxonomies ) ) {
3728 foreach ( $taxonomies as $tax_id => $taxonomy ) {
3729 $data[$tax_id] = $taxonomy->labels->singular_name;
3730 }
3731 }
3732
3733 // sort taxonomies
3734 asort( $data );
3735
3736 return $data;
3737 }
3738
3739 /**
3740 * Get users.
3741 *
3742 * @return array Users
3743 */
3744 public function get_users() {
3745 $users = get_users(
3746 array(
3747 'fields' => array( 'ID', 'user_login' )
3748 )
3749 );
3750
3751 $data = array();
3752
3753 if ( ! empty( $users ) ) {
3754 foreach ( $users as $user ) {
3755 $data[(int) $user->ID] = $user->user_login;
3756 }
3757 }
3758
3759 asort( $data );
3760
3761 return $data;
3762 }
3763
3764 /**
3765 * Get page templates.
3766 *
3767 * @return array Page templates
3768 */
3769 public function get_page_templates() {
3770 $data = array();
3771 $page_templates = wp_get_theme()->get_page_templates();
3772
3773 if ( ! empty( $page_templates ) )
3774 asort( $page_templates );
3775
3776 $data = array_merge( array( 'default' => apply_filters( 'default_page_template_title', __( 'Default Template' ) ) ), $page_templates );
3777
3778 return $data;
3779 }
3780
3781 /**
3782 * Save gallery metadata.
3783 *
3784 * @param int $post_id Post ID
3785 * @param object $post Post object
3786 * @param bool $update Whether this is an existing post being updated or not
3787 * @return void
3788 */
3789 public function save_post( $post_id, $post, $update ) {
3790 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'] ) )
3791 return;
3792
3793 $this->save_gallery( wp_unslash( $_POST ), $post_id );
3794 }
3795
3796 /**
3797 * Save gallery preview metadata.
3798 *
3799 * @param array $post_data Gallery data
3800 * @param int $post_id Post ID
3801 * @param bool $preview Whether is it preview
3802 * @return void
3803 */
3804 public function save_gallery( $post_data, $post_id, $preview = false ) {
3805 $data = $post_data['rl_gallery'];
3806
3807 // prepare sanitized data
3808 $safedata = array();
3809
3810 // sanitize all fields
3811 foreach ( $this->fields as $tab_id => $menu_items ) {
3812 switch ( $tab_id ) {
3813 case 'config':
3814 // add menu item
3815 $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'] );
3816
3817 // get default gallery fields
3818 $default_gallery_fields = Responsive_Lightbox()->frontend->get_default_gallery_fields();
3819
3820 // prepare fields
3821 if ( $menu_item === 'default' )
3822 $items = $default_gallery_fields;
3823 else {
3824 // assign settings and defaults
3825 $fields = Responsive_Lightbox()->settings->settings[$menu_item . '_gallery']['fields'];
3826 $defaults = Responsive_Lightbox()->defaults[$menu_item . '_gallery'];
3827
3828 // make a copy
3829 $fields_copy = $fields;
3830
3831 foreach ( $fields_copy as $field_id => $field ) {
3832 if ( $field['type'] === 'multiple' ) {
3833 foreach ( $field['fields'] as $subfield_id => $subfield ) {
3834 $fields[$field_id]['fields'][$subfield_id]['default'] = $defaults[$subfield_id];
3835 }
3836 } else
3837 $fields[$field_id]['default'] = $defaults[$field_id];
3838 }
3839
3840 $items = Responsive_Lightbox()->frontend->get_unique_fields( $default_gallery_fields, $fields );
3841 }
3842
3843 // sanitize fields
3844 $safedata = $this->sanitize_fields( $items, $data, $tab_id, $menu_item );
3845
3846 // add menu item
3847 $safedata[$tab_id]['menu_item'] = $menu_item;
3848 break;
3849
3850 default:
3851 // add menu item
3852 $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';
3853
3854 // prepare fields
3855 $items = $menu_items[$menu_item];
3856
3857 // sanitize fields
3858 $safedata = $this->sanitize_fields( $items, $data, $tab_id, $menu_item );
3859
3860 // add menu item
3861 $safedata[$tab_id]['menu_item'] = $menu_item;
3862 }
3863
3864 $safedata[$tab_id] = apply_filters( 'rl_gallery_tab_metadata', $safedata[$tab_id], $tab_id );
3865
3866 // preview?
3867 if ( $preview )
3868 update_metadata( 'post', $post_id, '_rl_' . $tab_id, $safedata[$tab_id] );
3869 else
3870 update_post_meta( $post_id, '_rl_' . $tab_id, $safedata[$tab_id] );
3871 }
3872
3873 $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';
3874
3875 switch ( $featured_image_type ) {
3876 // custom url
3877 case 'url':
3878 $thumbnail_id = $this->maybe_generate_thumbnail();
3879 $featured_image = isset( $post_data['_rl_thumbnail_url'] ) ? esc_url( $post_data['_rl_thumbnail_url'] ) : '';
3880 break;
3881
3882 // first image
3883 case 'image':
3884 $thumbnail_id = $this->maybe_generate_thumbnail();
3885 $featured_image = '';
3886 break;
3887
3888 // attachment id
3889 case 'id':
3890 default:
3891 $featured_image = $thumbnail_id = isset( $post_data['_thumbnail_id'] ) ? (int) $post_data['_thumbnail_id'] : 0;
3892 }
3893
3894 // preview?
3895 if ( $preview ) {
3896 update_metadata( 'post', $post_id, '_rl_featured_image_type', $featured_image_type );
3897 update_metadata( 'post', $post_id, '_rl_featured_image', $featured_image );
3898 update_metadata( 'post', $post_id, '_thumbnail_id', $thumbnail_id );
3899 } else {
3900 // update featured image
3901 update_post_meta( $post_id, '_rl_featured_image_type', $featured_image_type );
3902 update_post_meta( $post_id, '_rl_featured_image', $featured_image );
3903 update_post_meta( $post_id, '_thumbnail_id', $thumbnail_id );
3904 }
3905
3906 // update post excerpt
3907 if ( isset( $safedata['misc']['options']['gallery_description'] ) ) {
3908 remove_action( 'save_post_rl_gallery', array( $this, 'save_post' ), 10, 3 );
3909
3910 $postdata = array(
3911 'ID' => $post_id,
3912 'post_excerpt' => wp_kses_post( $safedata['misc']['options']['gallery_description'] ),
3913 );
3914
3915 wp_update_post( $postdata );
3916
3917 add_action( 'save_post_rl_gallery', array( $this, 'save_post' ), 10, 3 );
3918 }
3919 }
3920
3921 /**
3922 * Check attachments IDs.
3923 *
3924 * @param array $attachments Attachment ID's
3925 * @return array Existing image attachment ID's
3926 */
3927 public function check_attachments( $attachments ) {
3928 if ( empty( $attachments ) || ! is_array( $attachments ) )
3929 return array();
3930
3931 $copy = array_map( 'intval', $attachments );
3932
3933 // check attachments
3934 foreach ( $attachments as $key => $attachment_id ) {
3935 // is it an image?
3936 if ( ! wp_attachment_is_image( $attachment_id ) )
3937 unset( $copy[$key] );
3938 }
3939
3940 return $copy;
3941 }
3942
3943 /**
3944 * Display shortcode metabox.
3945 *
3946 * @param object $post Post object
3947 * @return void
3948 */
3949 public function shortcode_metabox( $post ) {
3950 echo '
3951 <p>' . __( 'You can place this gallery anywhere into your posts, pages, custom post types or widgets by using the shortcode below', 'responsive-lightbox' ) . ':</p>
3952 <code class="rl-shortcode">[rl_gallery id=&quot;' . $post->ID . '&quot;]</code>
3953 <p>' . __( 'You can also place this gallery into your template files by using the template tag below', 'responsive-lightbox' ) . ':</p>
3954 <code class="rl-shortcode">if ( function_exists( \'rl_gallery\' ) ) { rl_gallery( \'' . $post->ID . '\' ); }</code>';
3955 }
3956
3957 /**
3958 * Add new gallery listing columns.
3959 *
3960 * @param array $columns
3961 * @return array
3962 */
3963 public function gallery_columns( $columns ) {
3964 // find title position
3965 $offset = array_search( 'title', array_keys( $columns ) );
3966
3967 // put image column before title
3968 $columns = array_merge(
3969 array_slice( $columns, 0, $offset ),
3970 array(
3971 'image' => __( 'Gallery', 'responsive-lightbox' )
3972 ),
3973 array_slice( $columns, $offset )
3974 );
3975
3976 // put new columns after title
3977 $columns = array_merge(
3978 array_slice( $columns, 0, $offset + 2 ),
3979 array(
3980 'shortcode' => __( 'Shortcode', 'responsive-lightbox' ),
3981 'type' => __( 'Type', 'responsive-lightbox' ),
3982 'source' => __( 'Source', 'responsive-lightbox' )
3983 ),
3984 array_slice( $columns, $offset + 2 )
3985 );
3986
3987 return $columns;
3988 }
3989
3990 /**
3991 * Add new gallery listing columns content.
3992 *
3993 * @param string $column_name Column name
3994 * @param int $post_id Post ID
3995 * @return void
3996 */
3997 public function gallery_columns_content( $column_name, $post_id ) {
3998 global $pagenow;
3999
4000 if ( $pagenow === 'edit.php' ) {
4001 switch ( $column_name ) {
4002 case 'image':
4003 // get image data, based on gallery source type
4004 $image = $this->get_featured_image( $post_id, 'thumbnail' );
4005 $images_count = (int) get_post_meta( $post_id, '_rl_images_count', true );
4006
4007 // display count
4008 if ( ! empty( $image ) )
4009 echo '<span class="media-icon image-icon">' . $image . '</span><span>' . sprintf( _n( '%s image', '%s images', $images_count, 'responsive-lightbox' ), $images_count ) . '</span>';
4010 else
4011 echo '<span class="media-icon image-icon">' . wp_get_attachment_image( 0, array( 60, 60 ), true, array( 'alt' => '' ) ) . '</span>';
4012 break;
4013
4014 case 'shortcode':
4015 echo '<code>[rl_gallery id="' . $post_id . '"]</code>';
4016 break;
4017
4018 case 'type':
4019 $config = get_post_meta( $post_id, '_rl_config', true );
4020
4021 if ( ! empty( $config['menu_item'] ) && array_key_exists( $config['menu_item'], $this->tabs['config']['menu_items'] ) ) {
4022 echo $this->tabs['config']['menu_items'][$config['menu_item']];
4023
4024 if ( $config['menu_item'] === 'default' )
4025 echo ' (' . $this->tabs['config']['menu_items'][Responsive_Lightbox()->options['settings']['builder_gallery']] . ')';
4026 } else
4027 echo '-';
4028 break;
4029
4030 case 'source':
4031 $images = get_post_meta( $post_id, '_rl_images', true );
4032
4033 if ( ! empty( $images['menu_item'] ) && array_key_exists( $images['menu_item'], $this->tabs['images']['menu_items'] ) )
4034 echo $this->tabs['images']['menu_items'][$images['menu_item']];
4035 else
4036 echo '-';
4037 break;
4038 }
4039 }
4040 }
4041
4042 /**
4043 * Get size information for all currently-registered image sizes.
4044 *
4045 * @global $_wp_additional_image_sizes
4046 * @uses get_intermediate_image_sizes()
4047 * @return array $sizes Data for all currently-registered image sizes.
4048 */
4049 public function get_image_sizes() {
4050 global $_wp_additional_image_sizes;
4051
4052 $sizes = array();
4053
4054 foreach ( get_intermediate_image_sizes() as $_size ) {
4055 if ( in_array( $_size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
4056 $sizes[$_size]['width'] = get_option( "{$_size}_size_w" );
4057 $sizes[$_size]['height'] = get_option( "{$_size}_size_h" );
4058 $sizes[$_size]['crop'] = (bool) get_option( "{$_size}_crop" );
4059 } elseif ( isset( $_wp_additional_image_sizes[$_size] ) ) {
4060 $sizes[$_size] = array(
4061 'width' => $_wp_additional_image_sizes[$_size]['width'],
4062 'height' => $_wp_additional_image_sizes[$_size]['height'],
4063 'crop' => $_wp_additional_image_sizes[$_size]['crop'],
4064 );
4065 }
4066 }
4067
4068 return $sizes;
4069 }
4070
4071 /**
4072 * Get size information for a specific image size.
4073 *
4074 * @uses get_image_sizes()
4075 * @param string $size The image size for which to retrieve data.
4076 * @return bool|array $size Size data about an image size or false if the size doesn't exist.
4077 */
4078 public function get_image_size( $size ) {
4079 if ( isset( $this->sizes[$size] ) )
4080 return $this->sizes[$size];
4081 else
4082 return false;
4083 }
4084
4085 /**
4086 * Filter the admin post thumbnail HTML markup
4087 *
4088 * @param mixed $content HTML
4089 * @param int $post_id Post ID
4090 * @return string
4091 */
4092 public function admin_post_thumbnail_html( $content, $post_id ) {
4093 if ( get_post_type( $post_id ) === 'rl_gallery' ) {
4094 $value = get_post_meta( $post_id, '_rl_featured_image', true );
4095 $type = get_post_meta( $post_id, '_rl_featured_image_type', true );
4096 $type = ! empty( $type ) && in_array( $type, array( 'image', 'id', 'url' ) ) ? $type : 'image';
4097
4098 if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) && $this->maybe_generate_thumbnail() === (int) get_post_meta( $post_id, '_thumbnail_id', true ) ) {
4099 remove_filter( 'admin_post_thumbnail_html', array( $this, 'admin_post_thumbnail_html' ), 10 );
4100
4101 $content = _wp_post_thumbnail_html( 0, $post_id );
4102 }
4103
4104 $content = '
4105 <div class="rl-gallery-featured-image-options">
4106 <p class="howto">' . __( 'Select gallery featured image source:', 'responsive-lightbox' ) . '</p>
4107 <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 />
4108 <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 />
4109 <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>
4110 </div>
4111 <div class="rl-gallery-featured-image-select">
4112 <div class="rl-gallery-featured-image-select-id"' . ( $type === 'id' ? '' : ' style="display: none;"') . '>' . $content . '</div>
4113 <div class="rl-gallery-featured-image-select-url"' . ( $type === 'url' ? '' : ' style="display: none;"') . '>
4114 <p><input id="_rl_thumbnail_url" class="large-text" name="_rl_thumbnail_url" value="' . ( $type === 'url' ? esc_url( $value ) : '' ) . '" type="text" /></p>
4115 <p class="howto">' . __( 'Custom featured image URL', 'responsive-lightbox' ) . '</p>
4116 </div>
4117 <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>
4118 </div>
4119 ';
4120 }
4121
4122 return $content;
4123 }
4124
4125 /**
4126 * Modify the resulting HTML so that the feature image is set as a background property.
4127 *
4128 * @param string $html The HTML image tag.
4129 * @param integer $post_id The post whose featured image is to be printed.
4130 * @param string $post_thumbnail_id The post thumbnail ID.
4131 * @param array|string $size The size of the featured image.
4132 * @param array $attr Additional attributes.
4133 * @return string The HTML image tag, with a CSS background property set (when required).
4134 */
4135 public function post_thumbnail_html( $html, $post_id = 0, $post_thumbnail_id = '', $size = false, $attr = array() ) {
4136 if ( get_post_type( $post_id ) === 'rl_gallery' ) {
4137 // break if featured image type is media library
4138 $image_type = get_post_meta( $post_id, '_rl_featured_image_type', true );
4139
4140 if ( ! $image_type || $image_type == 'id' )
4141 return $html;
4142
4143 $image_src = $this->get_gallery_image_src( $this->get_featured_image_src( $post_id ) );
4144 $image_url = $image_src['url'];
4145
4146 // add featured image as background in style tag.
4147 $quote = '"';
4148 $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}";
4149
4150 $html = str_replace( 'src=', $style . ' src=', $html );
4151
4152 // fix the alt tag (if possible).
4153 $alt = $image_src['alt'];
4154
4155 if ( isset( $attr['alt'] ) )
4156 $alt = $attr['alt'];
4157
4158 if ( $alt ) {
4159 $html = str_replace( '/(alt=\'[^\']+\'\|alt="[^"]+")/', '', $html );
4160 $html = str_replace( 'src=', ' alt="' . esc_attr( $alt ) . '" src=', $html );
4161 }
4162 }
4163
4164 return $html;
4165 }
4166
4167 /**
4168 * Save the revision meta data.
4169 *
4170 * @param int $revision_id
4171 * @return void
4172 */
4173 public function save_revision( $revision_id ) {
4174 // get revision
4175 $revision = get_post( $revision_id );
4176
4177 // get gallery ID
4178 $post_id = $revision->post_parent;
4179
4180 // is it rl gallery?
4181 if ( get_post_type( $post_id ) !== 'rl_gallery' )
4182 return;
4183
4184 $this->revision_id = $revision_id;
4185
4186 // save revisioned meta data
4187 $this->save_gallery( wp_unslash( $_POST ), $revision_id, true );
4188 }
4189
4190 /**
4191 * Update preview link.
4192 *
4193 * @param string $link Preview link
4194 * @return string
4195 */
4196 public function preview_post_link( $link ) {
4197 // add rl gallery revision ID
4198 if ( property_exists( $this, 'revision_id' ) && ! is_null( $this->revision_id ) ) {
4199 $post_id = wp_get_post_parent_id( $this->revision_id );
4200
4201 // is it valid rl_gallery post?
4202 if ( $post_id && get_post_type( $post_id ) === 'rl_gallery' )
4203 return add_query_arg( 'rl_gallery_revision_id', $this->revision_id, $link );
4204 }
4205
4206 return $link;
4207 }
4208
4209 /**
4210 * Delete gallery revision at shutdown.
4211 *
4212 * @return void
4213 */
4214 public function shutdown_preview() {
4215 // is it a frontend preview?
4216 if ( is_preview() && isset( $_GET['rl_gallery_revision_id'] ) ) {
4217 global $post;
4218
4219 // cast revision ID
4220 $revision_id = (int) $_GET['rl_gallery_revision_id'];
4221
4222 // is it a valid revision?
4223 if ( get_post_type( $post->ID ) === 'rl_gallery' && wp_is_post_revision( $revision_id ) === (int) $post->ID )
4224 wp_delete_post_revision( $revision_id );
4225 }
4226 }
4227
4228 /**
4229 * Filter gallery meta data needed for frontend gallery preview.
4230 *
4231 * @param mixed $value Meta value to filter
4232 * @param int $object_id Object ID
4233 * @param string $meta_key Meta key to filter a value for
4234 * @param bool $single Whether to return a single value
4235 * @return mixed
4236 */
4237 public function filter_preview_metadata( $value, $object_id, $meta_key, $single ) {
4238 // ignore other post types
4239 if ( get_post_type( $object_id ) !== 'rl_gallery' )
4240 return $value;
4241
4242 // get current post
4243 $post = get_post();
4244
4245 // prepare keys
4246 $keys = array( '_rl_featured_image_type', '_rl_featured_image', '_rl_images_count', '_thumbnail_id' );
4247
4248 // add other metakeys
4249 foreach ( array_keys( $this->tabs ) as $key ) {
4250 $keys[] = '_rl_' . $key;
4251 }
4252
4253 // restrict only to specified data
4254 if ( empty( $post ) || (int) $post->ID !== (int) $object_id || ! in_array( $meta_key, $keys, true ) || $post->post_type === 'revision' )
4255 return $value;
4256
4257 // grab the last autosave
4258 $preview = wp_get_post_autosave( $post->ID );
4259
4260 // invalid revision?
4261 if ( ! is_object( $preview ) )
4262 return $value;
4263
4264 // finally replace metadata
4265 return array( get_post_meta( $preview->ID, $meta_key, $single ) );
4266 }
4267 }