PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.7.0
Responsive Lightbox & Gallery v2.7.0
2.7.8 trunk 1.0.0 1.0.1 1.0.1.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4.0 1.4.0.1 1.4.1 1.4.11 1.4.12 1.4.13 1.4.14 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3.1 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7
responsive-lightbox / includes / class-galleries.php
responsive-lightbox / includes Last commit date
providers 5 months ago settings 5 months ago class-fast-image.php 2 years ago class-folders.php 5 months ago class-frontend.php 5 months ago class-galleries.php 5 months ago class-multilang.php 2 years ago class-remote-library-api.php 5 months ago class-remote-library.php 5 months ago class-settings-api.php 5 months ago class-settings-data.php 5 months ago class-settings-pages.php 5 months ago class-settings.php 5 months ago class-tour.php 5 months ago class-welcome.php 2 years ago class-widgets.php 2 years ago functions.php 3 years ago
class-galleries.php
5473 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 $fields;
14 private $tabs;
15 private $sizes;
16 private $gallery_args;
17 private $menu_item;
18 private $revision_id;
19 private $allowed_select_html = [
20 'select' => [
21 'name' => true,
22 'id' => true,
23 'class' => true,
24 'required' => true,
25 'tabindex' => true,
26 'aria-describedby' => true
27 ],
28 'option' => [
29 'value' => true,
30 'class' => true,
31 'selected' => true
32 ]
33 ];
34
35
36 /**
37 * Class constructor.
38 *
39 * @param bool $read_only Whether is it read only mode
40 * @return void
41 */
42 public function __construct( $read_only = false ) {
43 // set instance
44 Responsive_Lightbox()->galleries = $this;
45
46 if ( $read_only )
47 return;
48
49 // actions
50 add_action( 'init', array( $this, 'init' ), 11 );
51 add_action( 'admin_init', array( $this, 'init_admin' ) );
52 add_action( 'current_screen', array( $this, 'clear_metaboxes' ) );
53 add_action( 'edit_form_after_title', array( $this, 'after_title_nav_menu' ) );
54 add_action( 'admin_footer', array( $this, 'modal_gallery_template' ) );
55 add_action( 'customize_controls_print_footer_scripts', array( $this, 'modal_gallery_template' ) );
56 add_action( 'media_buttons', array( $this, 'add_gallery_button' ) );
57 add_action( 'add_meta_boxes_rl_gallery', array( $this, 'add_meta_boxes' ) );
58 add_action( 'save_post_rl_gallery', array( $this, 'save_post' ), 10, 3 );
59 add_action( 'manage_rl_gallery_posts_custom_column', array( $this, 'gallery_columns_content' ), 10, 2 );
60 add_action( 'admin_action_duplicate_gallery', array( $this, 'duplicate_gallery' ) );
61 add_action( 'wp_ajax_rl-get-menu-content', array( $this, 'get_menu_content' ) );
62 add_action( 'wp_ajax_rl-get-preview-content', array( $this, 'get_gallery_preview_content' ) );
63 add_action( 'wp_ajax_rl-post-get-galleries', array( $this, 'post_get_galleries' ) );
64 add_action( 'wp_ajax_rl-post-gallery-preview', array( $this, 'post_gallery_preview' ) );
65 add_action( 'wp_ajax_rl-get-gallery-page-content', array( $this, 'get_gallery_page' ) );
66 add_action( 'wp_ajax_nopriv_rl-get-gallery-page-content', array( $this, 'get_gallery_page' ) );
67 add_action( '_wp_put_post_revision', array( $this, 'save_revision' ) );
68 add_action( 'delete_attachment', array( $this, 'delete_attachment' ) );
69 add_action( 'shutdown', array( $this, 'shutdown_preview' ) );
70 add_action( 'wp_loaded', array( $this, 'maybe_change_lightbox' ), 1 );
71
72 // filters
73 add_filter( 'manage_rl_gallery_posts_columns', array( $this, 'gallery_columns' ) );
74 add_filter( 'admin_post_thumbnail_html', array( $this, 'admin_post_thumbnail_html' ), 10, 3 );
75 add_filter( 'post_thumbnail_html', array( $this, 'post_thumbnail_html' ), 10, 5 );
76 add_filter( 'preview_post_link', array( $this, 'preview_post_link' ) );
77 add_filter( 'post_row_actions', array( $this, 'post_row_actions_duplicate' ), 10, 2 );
78
79 if ( ! empty( $_POST['rl_active_tab'] ) )
80 add_filter( 'redirect_post_location', array( $this, 'add_active_tab' ) );
81 }
82
83 /**
84 * Get class data.
85 *
86 * @param string $attr
87 * @return mixed
88 */
89 public function get_data( $attr ) {
90 return property_exists( $this, $attr ) ? $this->{$attr} : null;
91 }
92
93 /**
94 * Get default gallery single image template.
95 *
96 * @param array $args Template arguments
97 * @return string
98 */
99 public function get_media_item_template( $args = [] ) {
100 $args = array_merge(
101 array(
102 'draggable' => false,
103 'editable' => false,
104 'removable' => false,
105 'changeable' => false
106 ),
107 $args
108 );
109
110 return '
111 <li class="rl-gallery-image__MEDIA_STATUS__" data-attachment_id="__MEDIA_ID__" data-type="__MEDIA_TYPE__"' . ( $args['draggable'] ? ' style="cursor: move;"' : '' ) . '>
112 <div class="rl-gallery-inner">
113 <div class="centered">
114 __MEDIA_DATA__
115 </div>
116 </div>
117 <div class="rl-gallery-actions">' .
118 ( $args['changeable'] ? '<a href="#" class="rl-gallery-image-status dashicons dashicons-marker" title="' . esc_attr__( 'Status', 'responsive-lightbox' ) . '"></a>' : '' ) .
119 ( $args['editable'] ? '<a href="#" class="rl-gallery-image-edit dashicons dashicons-edit" title="' . esc_attr__( 'Edit image', 'responsive-lightbox' ) . '"></a>' : '' ) .
120 ( $args['removable'] ? '<a href="#" class="rl-gallery-image-remove dashicons dashicons-no" title="' . esc_attr__( 'Remove image', 'responsive-lightbox' ) . '"></a>' : '' ) . '
121 </div>
122 </li>';
123 }
124
125 /**
126 * Get default gallery embed template.
127 *
128 * @param bool $js
129 * @return string
130 */
131 public function get_media_embed_template( $js = false ) {
132 $html = '';
133
134 if ( $js )
135 $html .= '<div data-id="__EMBED_ID__" style="display: none;">';
136
137 $html .= '
138 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][url]" data-type="url" value="__EMBED_URL__">
139 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][width]" data-type="width" value="__EMBED_WIDTH__">
140 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][height]" data-type="height" value="__EMBED_HEIGHT__">
141 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][thumbnail_url]" data-type="thumbnail_url" value="__EMBED_THUMBNAIL_URL__">
142 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][thumbnail_width]" data-type="thumbnail_width" value="__EMBED_THUMBNAIL_WIDTH__">
143 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][thumbnail_height]" data-type="thumbnail_height" value="__EMBED_THUMBNAIL_HEIGHT__">
144 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][title]" data-type="title" value="__EMBED_TITLE__">
145 <textarea class="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][caption]" data-type="caption">__EMBED_DESCRIPTION__</textarea>
146 <input type="hidden" name="rl_gallery[images][media][attachments][embed][__EMBED_ID__][date]" data-type="date" value="__EMBED_DATE__">';
147
148 if ( $js )
149 $html .= '</div>';
150
151 return $html;
152 }
153
154 /**
155 * Get default gallery exclude input template.
156 *
157 * @param string $tab_id
158 * @param string $menu_item
159 * @param string $field_name
160 * @param mixed $excluded_value
161 * @return string
162 */
163 public function get_media_exclude_input_template( $tab_id = '', $menu_item = '', $field_name = '', $excluded_value = '' ) {
164 $template = '<input type="hidden" class="rl-gallery-exclude" name="rl_gallery[__MEDIA_TAB_ID__][__MEDIA_MENU_ITEM__][__MEDIA_FIELD_NAME__][exclude][]" value="__MEDIA_FIELD_VALUE__" />';
165
166 if ( $tab_id === '' && $menu_item === '' && $field_name === '' && $excluded_value === '' )
167 return str_replace( '__MEDIA_FIELD_VALUE__', '', $template );
168
169 return str_replace(
170 [
171 '__MEDIA_TAB_ID__',
172 '__MEDIA_MENU_ITEM__',
173 '__MEDIA_FIELD_NAME__',
174 '__MEDIA_FIELD_VALUE__'
175 ],
176 [
177 esc_attr( $tab_id ),
178 esc_attr( $menu_item ),
179 esc_attr( $field_name ),
180 empty( $excluded_value ) ? '' : esc_attr( $excluded_value )
181 ],
182 $template
183 );
184 }
185
186 /**
187 * Load needed data.
188 *
189 * @return void
190 */
191 public function init() {
192 // register shortcode
193 add_shortcode( 'rl_gallery', array( $this, 'gallery_shortcode' ) );
194
195 // get main instance
196 $rl = Responsive_Lightbox();
197
198 // set lightbox script for infinite scroll pages
199 if ( isset( $_GET['rl_gallery_no'], $_GET['rl_page'], $_GET['rl_lightbox_script'] ) )
200 $rl->set_lightbox_script( sanitize_key( $_GET['rl_lightbox_script'] ) );
201
202 $config_menu_items = apply_filters( 'rl_gallery_types', $rl->get_data( 'gallery_types' ) );
203 $config_menu_items['default'] = __( 'Global', 'responsive-lightbox' );
204
205 // set tabs
206 $this->tabs = apply_filters(
207 'rl_gallery_tabs',
208 array(
209 'images' => array(
210 'label' => __( 'Images', 'responsive-lightbox' ),
211 'description' => __( 'The settings below adjust the contents of the gallery.', 'responsive-lightbox' ),
212 'menu_items' => array(
213 'media' => __( 'Media Library', 'responsive-lightbox' ),
214 'featured' => __( 'Featured Content', 'responsive-lightbox' )
215 )
216 ),
217 'config' => array(
218 'label' => __( 'Config', 'responsive-lightbox' ),
219 'description' => __( 'The settings below adjust the configuration options for the gallery.', 'responsive-lightbox' ),
220 'menu_items' => $config_menu_items
221 ),
222 'design' => array(
223 'label' => __( 'Design', 'responsive-lightbox' ),
224 'description' => __( 'The settings below adjust the gallery design options.', 'responsive-lightbox' )
225 ),
226 'paging' => array(
227 'label' => __( 'Paging', 'responsive-lightbox' ),
228 'description' => __( 'The settings below adjust the gallery pagination options.', 'responsive-lightbox' )
229 ),
230 'lightbox' => array(
231 'label' => __( 'Lightbox', 'responsive-lightbox' ),
232 'description' => __( 'The settings below adjust the lightbox options.', 'responsive-lightbox' ),
233 ),
234 'misc' => array(
235 'label' => __( 'Misc', 'responsive-lightbox' ),
236 'description' => __( 'The settings below adjust miscellaneous options.', 'responsive-lightbox' ),
237 )
238 )
239 );
240
241 // add folders if active
242 if ( $rl->options['folders']['active'] )
243 $this->tabs['images']['menu_items']['folders'] = __( 'Media Folder', 'responsive-lightbox' );
244
245 // add remote library if active
246 $this->tabs['images']['menu_items']['remote_library'] = __( 'Remote Library', 'responsive-lightbox' );
247
248 // use sizes as keys and values
249 $this->sizes = $this->get_image_sizes();
250 $sizes = array_combine( array_keys( $this->sizes ), array_keys( $this->sizes ) );
251
252 // add default, custom and full image size
253 $sizes['full'] = __( 'Full size', 'responsive-lightbox' );
254 $sizes['global'] = __( 'Global', 'responsive-lightbox' );
255 $sizes['rl_custom_size'] = __( 'Custom size', 'responsive-lightbox' );
256
257 // positions
258 $positions = array(
259 'none' => __( 'None', 'responsive-lightbox' ),
260 'top' => __( 'Top', 'responsive-lightbox' ),
261 'bottom' => __( 'Bottom', 'responsive-lightbox' )
262 );
263
264 // merge titles
265 $merged_titles = array( 'global' => __( 'Global', 'responsive-lightbox' ) ) + $rl->settings->get_data( 'image_titles' );
266
267 // set fields
268 $this->fields = apply_filters(
269 'rl_gallery_tab_fields',
270 array(
271 'images' => array(
272 'media' => array(
273 'attachments' => array(
274 'title' => '',
275 'type' => 'media_library',
276 'default' => array(
277 'ids' => [],
278 'exclude' => [],
279 'embed' => []
280 ),
281 'preview' => array(
282 'pagination' => true,
283 'draggable' => true,
284 'editable' => true,
285 'removable' => true,
286 'changeable' => true
287 )
288 )
289 ),
290 'featured' => array(
291 'attachments' => array(
292 'title' => '',
293 'type' => 'media_preview',
294 'default' => array(
295 'exclude' => []
296 ),
297 'preview' => array(
298 'pagination' => true,
299 'draggable' => false,
300 'editable' => true,
301 'removable' => false,
302 'changeable' => false
303 )
304 ),
305 'number_of_posts' => array(
306 'title' => __( 'Number of Posts', 'responsive-lightbox' ),
307 'type' => 'number',
308 'description' => __( 'Enter the number of posts.', 'responsive-lightbox' ),
309 'default' => 10,
310 'min' => 0
311 ),
312 'orderby' => array(
313 'title' => __( 'Posts Sorting', 'responsive-lightbox' ),
314 'type' => 'select',
315 'description' => __( 'Select the posts sorting.', 'responsive-lightbox' ),
316 'default' => 'date',
317 'options' => array(
318 'id' => __( 'ID', 'responsive-lightbox' ),
319 'author' => __( 'Author', 'responsive-lightbox' ),
320 'title' => __( 'Title', 'responsive-lightbox' ),
321 'name' => __( 'Slug', 'responsive-lightbox' ),
322 'date' => __( 'Date', 'responsive-lightbox' ),
323 'modified' => __( 'Last modified date', 'responsive-lightbox' ),
324 'parent' => __( 'Parent ID', 'responsive-lightbox' ),
325 'rand' => __( 'Random', 'responsive-lightbox' )
326 )
327 ),
328 'order' => array(
329 'title' => __( 'Posts Order', 'responsive-lightbox' ),
330 'type' => 'radio',
331 'description' => __( 'Select the posts order.', 'responsive-lightbox' ),
332 'default' => 'asc',
333 'options' => array(
334 'asc' => __( 'Ascending', 'responsive-lightbox' ),
335 'desc' => __( 'Descending', 'responsive-lightbox' )
336 )
337 ),
338 'offset' => array(
339 'title' => __( 'Posts Offset', 'responsive-lightbox' ),
340 'type' => 'number',
341 'description' => __( 'Enter the posts offset.', 'responsive-lightbox' ),
342 'default' => 0,
343 'min' => 0
344 ),
345 'image_source' => array(
346 'title' => __( 'Image Source', 'responsive-lightbox' ),
347 'type' => 'radio',
348 'description' => __( 'Select the image source.', 'responsive-lightbox' ),
349 'default' => 'thumbnails',
350 'options' => array(
351 'thumbnails' => __( 'Post Thumbnails', 'responsive-lightbox' ),
352 'attached_images' => __( 'Post Attached Images', 'responsive-lightbox' )
353 )
354 ),
355 'images_per_post' => array(
356 'title' => __( 'Images per Post', 'responsive-lightbox' ),
357 'type' => 'number',
358 'description' => __( 'Enter maximum number of images for a post.', 'responsive-lightbox' ),
359 'default' => 1,
360 'min' => 1
361 ),
362 'post_type' => array(
363 'title' => __( 'Post Type', 'responsive-lightbox' ),
364 'type' => 'multiselect',
365 'description' => __( 'Select the post types to query.', 'responsive-lightbox' ),
366 'options' => [],
367 'default' => []
368 ),
369 'post_status' => array(
370 'title' => __( 'Post Status', 'responsive-lightbox' ),
371 'type' => 'multiselect',
372 'description' => __( 'Select the post status.', 'responsive-lightbox' ),
373 'options' => [],
374 'default' => []
375 ),
376 'post_format' => array(
377 'title' => __( 'Post Format', 'responsive-lightbox' ),
378 'type' => 'multiselect',
379 'description' => __( 'Select the post format.', 'responsive-lightbox' ),
380 'options' => [],
381 'default' => []
382 ),
383 'post_term' => array(
384 'title' => __( 'Post Term', 'responsive-lightbox' ),
385 'type' => 'multiselect',
386 'description' => __( 'Select the post taxonomy terms to query.', 'responsive-lightbox' ),
387 'options' => [],
388 'default' => []
389 ),
390 'post_author' => array(
391 'title' => __( 'Post Author', 'responsive-lightbox' ),
392 'type' => 'multiselect',
393 'description' => __( 'Select the post author.', 'responsive-lightbox' ),
394 'options' => [],
395 'default' => []
396 ),
397 'page_parent' => array(
398 'title' => __( 'Page Parent', 'responsive-lightbox' ),
399 'type' => 'multiselect',
400 'description' => __( 'Select the post parent.', 'responsive-lightbox' ),
401 'options' => [],
402 'default' => []
403 ),
404 'page_template' => array(
405 'title' => __( 'Page Template', 'responsive-lightbox' ),
406 'type' => 'multiselect',
407 'description' => __( 'Select the page template.', 'responsive-lightbox' ),
408 'options' => [],
409 'default' => []
410 )
411 ),
412 'folders' => array(
413 'attachments' => array(
414 'title' => '',
415 'type' => 'media_preview',
416 'default' => array(
417 'exclude' => []
418 ),
419 'preview' => array(
420 'pagination' => true,
421 'draggable' => false,
422 'editable' => true,
423 'removable' => false,
424 'changeable' => false
425 )
426 ),
427 'folder' => array(
428 'title' => __( 'Media Folder', 'responsive-lightbox' ),
429 'type' => 'taxonomy',
430 'description' => __( 'Select media folder.', 'responsive-lightbox' ),
431 'default' => array(
432 'id' => 0,
433 'children' => false
434 ),
435 'include_children' => true,
436 'taxonomy' => $rl->folders->get_active_taxonomy()
437 )
438 ),
439 'remote_library' => array(
440 'attachments' => array(
441 'title' => '',
442 'type' => 'media_preview',
443 'default' => array(
444 'exclude' => []
445 ),
446 'preview' => array(
447 'pagination' => true,
448 'draggable' => false,
449 'editable' => false,
450 'removable' => false,
451 'changeable' => false
452 )
453 ),
454 'media_search' => array(
455 'title' => __( 'Search String', 'responsive-lightbox' ),
456 'type' => 'text',
457 'description' => __( 'Enter the search phrase.', 'responsive-lightbox' ),
458 'default' => ''
459 ),
460 'media_provider' => array(
461 'title' => __( 'Media Provider', 'responsive-lightbox' ),
462 'type' => 'select',
463 'description' => __( 'Select which remote library should be used.', 'responsive-lightbox' ),
464 'default' => 'all',
465 'options' => array(
466 'all' => __( 'All Media Providers', 'responsive-lightbox' )
467 )
468 ),
469 'response_data' => array(
470 'title' => '',
471 'type' => 'hidden',
472 'description' => '',
473 'default' => '',
474 'callback' => array( $rl->remote_library, 'remote_library_response_data' )
475 )
476 )
477 ),
478 'config' => [],
479 'design' => array(
480 'options' => array(
481 'design_show_title' => array(
482 'title' => __( 'Thumbnail Title', 'responsive-lightbox' ),
483 'type' => 'select',
484 'description' => __( 'Select title for the gallery thumbnails.', 'responsive-lightbox' ),
485 'default' => 'global',
486 'options' => $merged_titles
487 ),
488 'design_show_caption' => array(
489 'title' => __( 'Thumbnail Caption', 'responsive-lightbox' ),
490 'type' => 'select',
491 'description' => __( 'Select caption for the gallery thumbnails.', 'responsive-lightbox' ),
492 'default' => 'global',
493 'options' => $merged_titles
494 ),
495 'show_icon' => array(
496 'title' => __( 'Thumbnail Icon', 'responsive-lightbox' ),
497 'type' => 'radio',
498 'description' => __( 'Select icon for the gallery thumbnails.', 'responsive-lightbox' ),
499 'default' => '0',
500 'options' => array(
501 '0' => __( 'none', 'responsive-lightbox' ),
502 '1' => '',
503 '2' => '',
504 '3' => '',
505 '4' => '',
506 '5' => '',
507 '6' => '',
508 '7' => '',
509 '8' => '',
510 '9' => '',
511 '10' => ''
512 )
513 ),
514 'hover_effect' => array(
515 'title' => __( 'Hover Effect', 'responsive-lightbox' ),
516 'type' => 'select',
517 'description' => __( 'Select thumbnail effect on hover.', 'responsive-lightbox' ),
518 'default' => '0',
519 'options' => array(
520 '0' => __( 'none', 'responsive-lightbox' ),
521 '1' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 1 ),
522 '2' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 2 ),
523 '3' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 3 ),
524 '4' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 4 ),
525 '5' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 5 ),
526 '6' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 6 ),
527 '7' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 7 ),
528 '8' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 8 ),
529 '9' => sprintf( __( 'Effect %s', 'responsive-lightbox' ), 9 )
530 )
531 ),
532 'caption_font_size' => array(
533 'title' => __( 'Caption Font Size', 'responsive-lightbox' ),
534 'type' => 'number',
535 'default' => 13,
536 'step' => 1,
537 'min' => 10,
538 'max' => 20,
539 'append' => 'px'
540 ),
541 'caption_padding' => array(
542 'title' => __( 'Caption Padding', 'responsive-lightbox' ),
543 'type' => 'number',
544 'default' => 20,
545 'step' => 1,
546 'min' => 5,
547 'max' => 30,
548 'append' => 'px'
549 ),
550 'title_color' => array(
551 'title' => __( 'Title Color', 'responsive-lightbox' ),
552 'type' => 'color_picker',
553 'default' => '#ffffff'
554 ),
555 'caption_color' => array(
556 'title' => __( 'Caption Color', 'responsive-lightbox' ),
557 'type' => 'color_picker',
558 'default' => '#cccccc'
559 ),
560 'background_color' => array(
561 'title' => __( 'Background Color', 'responsive-lightbox' ),
562 'type' => 'color_picker',
563 'default' => '#000000'
564 ),
565 'background_opacity' => array(
566 'title' => __( 'Background Opacity', 'responsive-lightbox' ),
567 'type' => 'number',
568 'default' => 80,
569 'step' => 1,
570 'min' => 0,
571 'max' => 100,
572 'append' => '%'
573 ),
574 'border_color' => array(
575 'title' => __( 'Border Color', 'responsive-lightbox' ),
576 'type' => 'color_picker',
577 'default' => '#000000'
578 ),
579 'border_width' => array(
580 'title' => __( 'Border Width', 'responsive-lightbox' ),
581 'type' => 'number',
582 'default' => 0,
583 'step' => 1,
584 'min' => 0,
585 'max' => 100,
586 'append' => 'px'
587 )
588 )
589 ),
590 'paging' => array(
591 'options' => array(
592 'pagination' => array(
593 'title' => __( 'Use Pagination', 'responsive-lightbox' ),
594 'type' => 'boolean',
595 'label' => __( 'Enable pagination.', 'responsive-lightbox' ),
596 'default' => false
597 ),
598 'pagination_type' => array(
599 'title' => __( 'Pagination Type', 'responsive-lightbox' ),
600 'type' => 'select',
601 'description' => __( 'Select pagination type.', 'responsive-lightbox' ),
602 'default' => 'paged',
603 'options' => array(
604 'paged' => __( 'standard', 'responsive-lightbox' ),
605 'ajax' => __( 'AJAX', 'responsive-lightbox' ),
606 'infinite' => __( 'infinite scroll', 'responsive-lightbox' )
607 )
608 ),
609 'pagination_position' => array(
610 'title' => __( 'Pagination Position', 'responsive-lightbox' ),
611 'type' => 'select',
612 'description' => __( 'Select pagination position.', 'responsive-lightbox' ),
613 'default' => 'bottom',
614 'options' => array(
615 'bottom' => __( 'bottom', 'responsive-lightbox' ),
616 'top' => __( 'top', 'responsive-lightbox' ),
617 'both' => __( 'top & bottom', 'responsive-lightbox' )
618 )
619 ),
620 'images_per_page' => array(
621 'title' => __( 'Images Per Page', 'responsive-lightbox' ),
622 'type' => 'number',
623 'description' => __( 'Number of images per page.', 'responsive-lightbox' ),
624 'default' => get_option( 'posts_per_page', 20 ),
625 'step' => 1,
626 'min' => 0
627 ),
628 'load_more' => array(
629 'title' => __( 'Load More', 'responsive-lightbox' ),
630 'type' => 'radio',
631 'description' => __( 'Select the load more trigger (infinite scroll only).', 'responsive-lightbox' ),
632 'default' => 'automatically',
633 'options' => array(
634 'automatically' => __( 'Automatically', 'responsive-lightbox' ),
635 'manually' => __( 'On click', 'responsive-lightbox' )
636 )
637 )
638 )
639 ),
640 'lightbox' => array(
641 'options' => array(
642 'lightbox_enable' => array(
643 'title' => __( 'Enable Lightbox', 'responsive-lightbox' ),
644 'type' => 'boolean',
645 'label' => __( 'Enable lightbox effect for the gallery.', 'responsive-lightbox' ),
646 'default' => true
647 ),
648 'lightbox_image_size' => array(
649 'title' => __( 'Image Size', 'responsive-lightbox' ),
650 'type' => 'select',
651 'description' => __( 'Select image size for gallery lightbox.', 'responsive-lightbox' ),
652 'default' => 'global',
653 'options' => $sizes
654 ),
655 'lightbox_custom_size' => array(
656 'title' => __( 'Custom Size', 'responsive-lightbox' ),
657 'type' => 'multiple',
658 'description' => __( 'Choose the custom image size for gallery lightbox (used if Custom Image size is selected).', 'responsive-lightbox' ),
659 'fields' => array(
660 'lightbox_custom_size_width' => array(
661 'type' => 'number',
662 'append' => __( 'width in px', 'responsive-lightbox' ),
663 'default' => (int) get_option( 'large_size_w' )
664 ),
665 'lightbox_custom_size_height' => array(
666 'type' => 'number',
667 'append' => __( 'height in px', 'responsive-lightbox' ),
668 'default' => (int) get_option( 'large_size_h' )
669 )
670 )
671 ),
672 'lightbox_image_title' => array(
673 'title' => __( 'Image Title', 'responsive-lightbox' ),
674 'type' => 'select',
675 'description' => __( 'Select image title for gallery lightbox.', 'responsive-lightbox' ),
676 'default' => 'global',
677 'options' => $merged_titles
678 ),
679 'lightbox_image_caption' => array(
680 'title' => __( 'Image Caption', 'responsive-lightbox' ),
681 'type' => 'select',
682 'description' => __( 'Select image caption for gallery lightbox (used if supported by selected lightbox effect).', 'responsive-lightbox' ),
683 'default' => 'global',
684 'options' => $merged_titles
685 )
686 )
687 ),
688 'misc' => array(
689 'options' => array(
690 'gallery_title_position' => array(
691 'title' => __( 'Title Position', 'responsive-lightbox' ),
692 'type' => 'select',
693 'description' => __( 'Select where to display the title.', 'responsive-lightbox' ),
694 'default' => 'none',
695 'options' => $positions
696 ),
697 'gallery_description_position' => array(
698 'title' => __( 'Description Position', 'responsive-lightbox' ),
699 'type' => 'select',
700 'description' => __( 'Select where to display the description.', 'responsive-lightbox' ),
701 'default' => 'none',
702 'options' => $positions
703 ),
704 'gallery_description' => array(
705 'title' => __( 'Gallery Description', 'responsive-lightbox' ),
706 'type' => 'textarea',
707 'description' => __( 'Enter the gallery description (optional).', 'responsive-lightbox' ),
708 'default' => '',
709 'class' => 'large-text'
710 ),
711 'gallery_custom_class' => array(
712 'title' => __( 'Custom Classes', 'responsive-lightbox' ),
713 'type' => 'class',
714 'description' => __( 'Add custom, space saparated CSS classes (optional).', 'responsive-lightbox' ),
715 'default' => '',
716 'class' => 'large-text'
717 )
718 )
719 )
720 )
721 );
722
723 if ( ! $rl->options['folders']['active'] )
724 unset( $this->fields['images']['folders'] );
725
726 // is remote library active?
727 if ( $rl->options['remote_library']['active'] ) {
728 // get providers
729 $providers = $rl->remote_library->get_providers();
730 $active_providers = $rl->remote_library->get_active_providers();
731
732 // update active providers
733 foreach ( $active_providers as $provider ) {
734 $this->fields['images']['remote_library']['media_provider']['options'][$provider] = $providers[$provider]['name'];
735 }
736 }
737 }
738
739 /**
740 * Duplicate gallery action in admin.
741 *
742 * @return void
743 */
744 public function duplicate_gallery() {
745 if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) ) || ! isset( $_REQUEST['action'] ) || ! isset( $_REQUEST['rl_gallery_nonce'] ) || ( isset( $_REQUEST['rl_gallery_nonce'] ) && ! wp_verify_nonce( $_REQUEST['rl_gallery_nonce'], 'responsive-lightbox-duplicate-gallery' ) ) )
746 wp_die( esc_html__( 'No gallery to duplicate has been supplied!', 'responsive-lightbox' ) );
747
748 // get the original post
749 $post_id = isset( $_GET['post'] ) ? (int) $_GET['post'] : ( isset( $_POST['post'] ) ? (int) $_POST['post'] : 0 );
750
751 if ( empty( $post_id ) )
752 wp_die( esc_html__( 'No gallery to duplicate has been supplied!', 'responsive-lightbox' ) );
753
754 if ( ! current_user_can( 'edit_post', $post_id ) )
755 wp_die( esc_html__( 'You do not have permission to copy this gallery.', 'responsive-lightbox' ) );
756
757 $post = get_post( $post_id );
758
759 // copy the post and insert it
760 if ( isset( $post ) && $post !== null ) {
761 $this->create_gallery_duplicate( $post );
762
763 // redirect to the post list screen
764 wp_redirect( admin_url( 'edit.php?post_type=' . $post->post_type ) );
765 exit;
766 } else
767 wp_die( esc_html__( 'Copy creation failed, could not find original gallery:', 'responsive-lightbox' ) . ' ' . (int) $post_id );
768 }
769
770 /**
771 * Add duplicate link to gallery listing.
772 *
773 * @global string $pagenow
774 *
775 * @param array $actions Link actions
776 * @param object $post Post object
777 * @return array
778 */
779 public function post_row_actions_duplicate( $actions, $post ) {
780 global $pagenow;
781
782 if ( $post->post_type !== 'rl_gallery' )
783 return $actions;
784
785 if ( ! current_user_can( 'edit_post', $post->ID ) )
786 return $actions;
787
788 // duplicate link
789 $actions['duplicate_gallery'] = '<a class="duplicate-gallery" title="' . esc_attr__( 'Duplicate this item', 'responsive-lightbox' ) . '" href="' . esc_url( wp_nonce_url( admin_url( $pagenow . '?post=' . $post->ID . '&action=duplicate_gallery' ), 'responsive-lightbox-duplicate-gallery', 'rl_gallery_nonce' ) ) . '">' . esc_html__( 'Duplicate', 'responsive-lightbox' ) . '</a>';
790
791 return $actions;
792 }
793
794 /**
795 * Create a gallery duplicate.
796 *
797 * @param $post object Post object
798 * @return void|int
799 */
800 public function create_gallery_duplicate( $post ) {
801 // skip revisions
802 if ( $post->post_type === 'revision' )
803 return;
804
805 $new_post = apply_filters(
806 'rl_duplicate_gallery_args',
807 [
808 'menu_order' => $post->menu_order,
809 'comment_status' => $post->comment_status,
810 'ping_status' => $post->ping_status,
811 'post_author' => $post->post_author,
812 'post_content' => $post->post_content,
813 'post_excerpt' => $post->post_excerpt,
814 'post_mime_type' => $post->post_mime_type,
815 'post_parent' => $post->post_parent,
816 'post_password' => $post->post_password,
817 'post_status' => $post->post_status,
818 'post_title' => $post->post_title,
819 'post_type' => $post->post_type,
820 'post_date' => current_time( 'mysql' ),
821 'post_date_gmt' => get_gmt_from_date( current_time( 'mysql' ) )
822 ],
823 $post
824 );
825
826 $new_post_id = wp_insert_post( $new_post );
827
828 // if the copy is published or scheduled, we have to set a proper slug
829 if ( $new_post['post_status'] === 'publish' || $new_post['post_status'] === 'future' ) {
830 $post_name = wp_unique_post_slug( $post->post_name, $new_post_id, $new_post['post_status'], $post->post_type, $new_post['post_parent'] );
831
832 $new_post = [];
833 $new_post['ID'] = $new_post_id;
834 $new_post['post_name'] = $post_name;
835
836 // update the post into the database
837 wp_update_post( $new_post );
838 }
839
840 // create metadata for the duplicated gallery
841 $this->create_gallery_duplicate_metadata( $new_post_id, $post );
842
843 // copy taxonomies
844 $this->duplicate_gallery_taxonomies( $new_post_id, $post );
845
846 // action hook for developers
847 do_action( 'rl_after_duplicate_gallery', $new_post_id, $post );
848
849 return $new_post_id;
850 }
851
852 /**
853 * Create a gallery duplicate metadata.
854 *
855 * @param int $new_post_id Post ID
856 * @param object $post Post object
857 * @return void
858 */
859 public function create_gallery_duplicate_metadata( $new_post_id, $post ) {
860 if ( empty( $post ) || $post == null )
861 return;
862
863 // meta keys to be copied
864 $meta_keys = apply_filters( 'rl_duplicate_gallery_meta_keys', get_post_custom_keys( $post->ID ) );
865
866 if ( empty( $meta_keys ) )
867 return;
868
869 foreach ( $meta_keys as $meta_key ) {
870 // meta values to be copied
871 $meta_values = apply_filters( 'rl_duplicate_gallery_meta_values', get_post_custom_values( $meta_key, $post->ID ) );
872
873 foreach ( $meta_values as $meta_value ) {
874 $meta_value = maybe_unserialize( $meta_value );
875
876 // add metadata to duplicated post
877 add_post_meta( $new_post_id, $meta_key, $meta_value );
878 }
879 }
880 }
881
882 /**
883 * Copy the taxonomies of a gallery to another gallery.
884 *
885 * @global object $wpdb
886 *
887 * @param int $new_post_id Post ID
888 * @param object $post Post object
889 * @return void
890 */
891 function duplicate_gallery_taxonomies( $new_post_id, $post ) {
892 global $wpdb;
893
894 if ( isset( $wpdb->terms ) ) {
895 // clear default category
896 wp_set_object_terms( $new_post_id, null, 'category' );
897
898 // get gallery taxonomies
899 $gallery_taxonomies = get_object_taxonomies( $post->post_type );
900
901 if ( ! empty( $gallery_taxonomies ) ) {
902 foreach ( $gallery_taxonomies as $taxonomy ) {
903 $terms = [];
904
905 // get taxonomy terms
906 $post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'orderby' => 'term_order' ) );
907
908 if ( ! empty( $post_terms ) ) {
909 foreach ( $post_terms as $term ) {
910 $terms[] = $term->slug;
911 }
912 }
913
914 // copy taxonomy terms
915 wp_set_object_terms( $new_post_id, $terms, $taxonomy );
916 }
917 }
918 }
919 }
920
921 /**
922 * Add a gallery shortcode.
923 *
924 * @param array $args Shortcode arguments
925 * @return string
926 */
927 public function gallery_shortcode( $args ) {
928 // enable only for frontend previews
929 if ( ! is_admin() && is_preview() )
930 add_filter( 'get_post_metadata', array( $this, 'filter_preview_metadata' ), 10, 4 );
931
932 // prepare defaults
933 $defaults = [ 'id' => 0 ];
934
935 // merge defaults with arguments
936 $args = array_merge( $defaults, $args );
937
938 // parse id
939 $args['id'] = (int) $args['id'];
940
941 // is it gallery?
942 if ( get_post_type( $args['id'] ) !== 'rl_gallery' )
943 return '';
944
945 // private gallery?
946 if ( get_post_status( $args['id'] ) === 'private' && ! current_user_can( 'read_private_posts' ) )
947 return '';
948
949 $images_args = [ 'exclude' => true ];
950
951 if ( isset( $args['preview'] ) )
952 $images_args['preview'] = (bool) $args['preview'];
953 elseif( isset( $_GET['rl_gallery_revision_id'], $_GET['preview'] ) && $_GET['preview'] === 'true' )
954 $images_args['preview'] = true;
955 else
956 $images_args['preview'] = false;
957
958 // get images
959 $images = $this->get_gallery_images( $args['id'], $images_args );
960
961 if ( ! $images )
962 return '';
963
964 $attachments = [];
965
966 // build config
967 foreach ( $images as $image ) {
968 if ( ! empty( $image['id'] ) )
969 $attachments[] = $image['id'];
970 }
971
972 // get config data
973 $config = get_post_meta( $args['id'], '_rl_config', true );
974 if ( ! is_array( $config ) )
975 $config = [];
976
977 // get main instance
978 $rl = Responsive_Lightbox();
979
980 // available gallery types
981 $gallery_types = apply_filters( 'rl_gallery_types', $rl->get_data( 'gallery_types' ) );
982 if ( ! is_array( $gallery_types ) )
983 $gallery_types = [];
984
985 // prepare gallery shortcode parameters
986 $fields = [];
987 $gallery_type = '';
988 $menu_item = ! empty( $config['menu_item'] ) ? $config['menu_item'] : 'default';
989 if ( ! empty( $menu_item ) && $menu_item !== 'default' && ! array_key_exists( $menu_item, $gallery_types ) )
990 $menu_item = 'default';
991
992 // valid menu item?
993 if ( ! empty( $menu_item ) ) {
994 // assign data from db
995 $data = isset( $config[$menu_item] ) && is_array( $config[$menu_item] ) ? $config[$menu_item] : [];
996
997 foreach ( $rl->frontend->get_default_gallery_fields() as $field_name => $field_args ) {
998 // replace default values
999 if ( array_key_exists( $field_name, $data ) )
1000 $fields[$field_name] = $data[$field_name];
1001 }
1002
1003 // is it default gallery type?
1004 if ( $menu_item === 'default' ) {
1005 // set new gallery type
1006 $gallery_type = $rl->options['settings']['builder_gallery'];
1007
1008 // fallback to a valid gallery type
1009 if ( empty( $gallery_type ) || ! array_key_exists( $gallery_type, $gallery_types ) )
1010 $gallery_type = $rl->defaults['settings']['builder_gallery'];
1011
1012 // assign gallery settings
1013 $gallery_fields = $rl->settings->get_setting_fields( $gallery_type . '_gallery' );
1014 // assign gallery defaults
1015 if ( array_key_exists( $gallery_type . '_gallery', $rl->options ) )
1016 $gallery_defaults = $rl->options[$gallery_type . '_gallery'];
1017 } else {
1018 $gallery_type = $menu_item;
1019
1020 // fallback to a valid gallery type
1021 if ( empty( $gallery_type ) || ! array_key_exists( $gallery_type, $gallery_types ) )
1022 $gallery_type = $rl->options['settings']['builder_gallery'];
1023
1024 // assign gallery settings
1025 $gallery_fields = $rl->settings->get_setting_fields( $menu_item . '_gallery' );
1026 // assign gallery defaults
1027 if ( array_key_exists( $menu_item . '_gallery', $rl->defaults ) )
1028 $gallery_defaults = $rl->defaults[$menu_item . '_gallery'];
1029 }
1030
1031 if ( ! isset( $gallery_defaults ) && ! empty( $gallery_type ) && array_key_exists( $gallery_type . '_gallery', $rl->defaults ) )
1032 $gallery_defaults = $rl->defaults[$gallery_type . '_gallery'];
1033
1034 if ( ! isset( $gallery_fields ) && ! empty( $gallery_type ) )
1035 $gallery_fields = $rl->settings->get_setting_fields( $gallery_type . '_gallery' );
1036
1037 if ( isset( $gallery_fields, $gallery_defaults ) ) {
1038 // run through all fields
1039 foreach ( $gallery_fields as $field_name => $field_args ) {
1040 if ( $field_args['type'] === 'multiple' ) {
1041 foreach ( $field_args['fields'] as $subfield_name => $subfield_args ) {
1042 // field exists in db?
1043 if ( array_key_exists( $subfield_name, $data ) )
1044 $fields[$subfield_name] = $data[$subfield_name];
1045 elseif ( isset( $rl->options[$gallery_type . '_gallery'][ $subfield_name ] ) )
1046 $fields[$subfield_name] = $rl->options[$gallery_type . '_gallery'][ $subfield_name ];
1047 else
1048 $fields[$subfield_name] = $gallery_defaults[$subfield_name];
1049 }
1050 } else {
1051 // field exists in db?
1052 if ( array_key_exists( $field_name, $data ) )
1053 $fields[$field_name] = $data[$field_name];
1054 elseif ( isset( $rl->options[$gallery_type . '_gallery'][ $field_name ] ) )
1055 $fields[$field_name] = $rl->options[$gallery_type . '_gallery'][ $field_name ];
1056 else
1057 $fields[$field_name] = $gallery_defaults[$field_name];
1058 }
1059 }
1060 }
1061 // add gallery type
1062 if ( ! empty( $gallery_type ) && array_key_exists( $gallery_type, $gallery_types ) )
1063 $fields['type'] = $gallery_type;
1064 }
1065
1066 // ensure gallery type is present and valid
1067 if ( empty( $fields['type'] ) || ! array_key_exists( $fields['type'], $gallery_types ) ) {
1068 $fallback_type = $rl->options['settings']['builder_gallery'];
1069 if ( empty( $fallback_type ) || ! array_key_exists( $fallback_type, $gallery_types ) )
1070 $fallback_type = $rl->defaults['settings']['builder_gallery'];
1071
1072 if ( ! empty( $fallback_type ) && array_key_exists( $fallback_type, $gallery_types ) )
1073 $fields['type'] = $fallback_type;
1074 }
1075
1076 $shortcode = '';
1077
1078 foreach ( $fields as $arg => $value ) {
1079 if ( is_array( $value ) )
1080 $shortcode .= ' ' . esc_attr( $arg ) . '="' . esc_attr( (string) implode( ',', $value ) ) . '"';
1081 else
1082 $shortcode .= ' ' . esc_attr( $arg ) . '="' . esc_attr( (string) $value ) . '"';
1083 }
1084
1085 // get design data
1086 $design = get_post_meta( $args['id'], '_rl_design', true );
1087
1088 if ( ! empty( $design['menu_item'] ) ) {
1089 $design_data = $design[$design['menu_item']];
1090
1091 // remove show_title to avoid shortcode attribute duplication
1092 if ( isset( $design_data['show_title'] ) ) {
1093 if ( ! isset( $design_data['design_show_title'] ) )
1094 $design_data['design_show_title'] = $design_data['show_title'];
1095
1096 unset( $design_data['show_title'] );
1097 }
1098
1099 // remove show_caption to avoid shortcode attribute duplication
1100 if ( isset( $design_data['show_caption'] ) ) {
1101 if ( ! isset( $design_data['design_show_caption'] ) )
1102 $design_data['design_show_caption'] = $design_data['show_caption'];
1103
1104 unset( $design_data['show_caption'] );
1105 }
1106
1107 foreach ( $design_data as $arg => $value ) {
1108 $shortcode .= ' ' . esc_attr( $arg ) . '="' . esc_attr( (string) $value ) . '"';
1109 }
1110 }
1111
1112 // get lightbox data
1113 $lightbox = get_post_meta( $args['id'], '_rl_lightbox', true );
1114
1115 if ( ! empty( $lightbox['menu_item'] ) ) {
1116 foreach ( $lightbox[$lightbox['menu_item']] as $arg => $value ) {
1117 $shortcode .= ' ' . esc_attr( $arg ) . '="' . esc_attr( (string) $value ) . '"';
1118 }
1119 }
1120
1121 $forced_gallery_no = 0;
1122
1123 // check forced gallery number
1124 if ( isset( $args['gallery_no'] ) ) {
1125 $args['gallery_no'] = (int) $args['gallery_no'];
1126
1127 if ( $args['gallery_no'] > 0 )
1128 $forced_gallery_no = $args['gallery_no'];
1129 }
1130
1131 // get content
1132 $content = do_shortcode( '[gallery rl_gallery_id="' . esc_attr( $args['id'] ) .'"' . ( $forced_gallery_no > 0 ? ' rl_gallery_no="' . (int) $forced_gallery_no .'"' : '' ) . ' include="' . ( empty( $attachments ) ? '' : esc_attr( implode( ',', $attachments ) ) ) . '"' . $shortcode . ']' );
1133
1134 // make sure every filter is available in frontend ajax
1135 if ( wp_doing_ajax() )
1136 $content = $rl->frontend->add_lightbox( $content );
1137
1138 return $content;
1139 }
1140
1141 /**
1142 * Add a gallery button.
1143 *
1144 * @param string $editor_id Editor ID
1145 * @return void
1146 */
1147 public function add_gallery_button( $editor_id ) {
1148 if ( get_post_type() === 'rl_gallery' )
1149 return;
1150
1151 $this->enqueue_gallery_scripts_styles();
1152
1153 echo '<button type="button" id="rl-insert-modal-gallery-button" class="button" data-editor="' . esc_attr( $editor_id ) . '"><span class="wp-media-buttons-icon dashicons dashicons-format-gallery"></span> ' . esc_html__( 'Add Gallery', 'responsive-lightbox' ) . '</button>';
1154 }
1155
1156 /**
1157 * Enqueue scripts and styles needed for gallery modal.
1158 *
1159 * @global string $pagenow
1160 *
1161 * @return void
1162 */
1163 public function enqueue_gallery_scripts_styles() {
1164 global $pagenow;
1165
1166 // count how many times function was executed
1167 static $run = 0;
1168
1169 // allow this only once
1170 if ( $run > 0 )
1171 return;
1172
1173 $run++;
1174
1175 // get main instance
1176 $rl = Responsive_Lightbox();
1177
1178 wp_enqueue_script( 'responsive-lightbox-admin-gallery', RESPONSIVE_LIGHTBOX_URL . '/js/admin-gallery.js', array( 'jquery', 'underscore' ), $rl->defaults['version'], false );
1179
1180 // prepare script data
1181 $script_data = [
1182 'nonce' => wp_create_nonce( 'rl-gallery-post' ),
1183 'post_id' => get_the_ID(),
1184 'page' => esc_url( $pagenow )
1185 ];
1186
1187 wp_add_inline_script( 'responsive-lightbox-admin-gallery', 'var rlArgsGallery = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
1188
1189 wp_enqueue_style( 'responsive-lightbox-admin-gallery', RESPONSIVE_LIGHTBOX_URL . '/css/admin-gallery.css', [], $rl->defaults['version'] );
1190 }
1191
1192 /**
1193 * Modal gallery HTML template.
1194 *
1195 * @global string $wp_version
1196 * @global string $pagenow
1197 *
1198 * @return void
1199 */
1200 public function modal_gallery_template() {
1201 global $wp_version;
1202 global $pagenow;
1203
1204 // display only for post edit pages
1205 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' ) ) ) )
1206 return;
1207
1208 // get main instance
1209 $rl = Responsive_Lightbox();
1210
1211 $categories = '';
1212
1213 // builder categories?
1214 if ( $rl->options['builder']['categories'] ) {
1215 $terms = get_terms(
1216 array(
1217 'taxonomy' => 'rl_category',
1218 'orderby' => 'name',
1219 'order' => 'ASC',
1220 'hide_empty' => false,
1221 'fields' => 'id=>name'
1222 )
1223 );
1224
1225 // get categories dropdown
1226 $categories = wp_dropdown_categories(
1227 array(
1228 'orderby' => 'name',
1229 'order' => 'asc',
1230 'show_option_none' => empty( $terms ) ? __( 'All categories', 'responsive-lightbox' ) : '',
1231 'show_option_all' => __( 'All categories', 'responsive-lightbox' ),
1232 'show_count' => false,
1233 'hide_empty' => false,
1234 'option_none_value' => 0,
1235 'hierarchical' => true,
1236 'selected' => 0,
1237 'taxonomy' => 'rl_category',
1238 'hide_if_empty' => false,
1239 'echo' => false,
1240 'id' => 'rl-media-attachment-categories',
1241 'class' => 'attachment-filters',
1242 'name' => ''
1243 )
1244 );
1245 }
1246
1247 echo '
1248 <div id="rl-modal-gallery" style="display: none;">
1249 <div class="media-modal wp-core-ui">
1250 <button type="button" class="media-modal-close"><span class="media-modal-icon"><span class="screen-reader-text">' . esc_html__( 'Close', 'responsive-lightbox' ) . '</span></span></button>
1251 <div class="media-modal-content">
1252 <div class="media-frame mode-select wp-core-ui hide-menu hide-router">
1253 <div class="media-frame-title">
1254 <h1 class="wrap">' . esc_html__( 'Insert Gallery', 'responsive-lightbox' ) . ' <a class="rl-reload-galleries page-title-action" href="#">' . esc_html__( 'Reload', 'responsive-lightbox' ). '</a><span class="rl-gallery-reload-spinner spinner"></span></h1>
1255 </div>
1256 <div class="media-frame-content" data-columns="0">
1257 <div class="attachments-browser">
1258 <div class="uploader-inline rl-no-galleries" style="display: none;">
1259 <div class="uploader-inline-content has-upload-message">
1260 <h2 class="upload-message">' . esc_html__( 'No items found.', 'responsive-lightbox' ) . '</h2>
1261 <div class="upload-ui">
1262 <h2 class="upload-instructions">' . esc_html__( 'No galleries? Create them first or try another search phrase.', 'responsive-lightbox' ) . '</h2>
1263 </div>
1264 </div>
1265 </div>
1266 <div class="media-toolbar">' . ( $rl->options['builder']['categories'] ? '
1267 <div class="media-toolbar-secondary"><label for="rl-media-attachment-categories" class="screen-reader-text">' . esc_html__( 'Filter by category', 'responsive-lightbox' ) . '</label>' . ( $categories !== '' ? wp_kses( $categories, $this->allowed_select_html ) : '' ) . '</div>' : '' ) . '
1268 <div class="media-toolbar-primary search-form">
1269 <label for="rl-media-search-input" class="screen-reader-text">' . esc_html__( 'Search galleries', 'responsive-lightbox' ) . '</label><input type="search" placeholder="' . esc_attr__( 'Search galleries', 'responsive-lightbox' ) . '" id="rl-media-search-input" class="search">
1270 </div>
1271 </div>
1272 <ul class="attachments rl-galleries-list ui-sortable ui-sortable-disabled">
1273 </ul>
1274 <div class="media-sidebar visible">
1275 <h2>' . esc_html__( 'Select A Gallery', 'responsive-lightbox' ) . '</h2>
1276 <p>' . esc_html__( 'To select a gallery simply click on one of the boxes to the left.', 'responsive-lightbox' ) . '</p>
1277 <p>' . esc_html__( 'To insert your gallery into the editor, click on the "Insert Gallery" button below.', 'responsive-lightbox' ) . '</p>
1278 </div>
1279 </div>
1280 </div>
1281 <div class="media-frame-toolbar">
1282 <div class="media-toolbar">
1283 <div class="media-toolbar-secondary">
1284 <div class="media-selection empty">
1285 <div class="selection-info">
1286 <span class="rl-gallery-count count">' . esc_html( sprintf( _n( '%s image', '%s images', 0, 'responsive-lightbox' ), 0 ) ) . '</span>
1287 <a href="" class="button-link rl-edit-gallery-link">' . esc_html__( 'Edit gallery', 'responsive-lightbox' ) . '</a>
1288 </div>
1289 <div class="selection-view">
1290 <span class="rl-gallery-images-spinner spinner" style="display: none;"></span>
1291 <ul class="attachments rl-attachments-list">
1292 </ul>
1293 </div>
1294 </div>
1295 </div>
1296 <div class="media-toolbar-primary search-form">
1297 <button style="display: none;" type="button" class="button media-button button-primary button-large rl-media-button-insert-gallery" disabled="disabled">' . esc_html__( 'Insert gallery into post', 'responsive-lightbox') . '</button>
1298 <button style="display: none;" type="button" class="button media-button button-primary button-large rl-media-button-select-gallery" disabled="disabled">' . esc_html__( 'Select gallery', 'responsive-lightbox') . '</button>
1299 <button type="button" class="button media-button button-secondary button-large rl-media-button-cancel-gallery">' . esc_html__( 'Cancel', 'responsive-lightbox') . '</button>
1300 </div>
1301 </div>
1302 </div>
1303 </div>
1304 </div>
1305 </div>
1306 <div class="media-modal-backdrop"></div>
1307 </div>';
1308 }
1309
1310 /**
1311 * Render gallery field.
1312 *
1313 * @param string $field Field name
1314 * @param string $tab_id Field tab
1315 * @param string $menu_item Field parent
1316 * @param array $args Field arguments
1317 * @param int $gallery_id Gallery ID
1318 * @param bool $subfield Is this a subfield
1319 * @return string
1320 */
1321 public function render_field( $field, $tab_id, $menu_item, $args, $gallery_id, $subfield = false ) {
1322 $disabled = ! empty( $args['disabled'] );
1323 $disabled_attr = $disabled ? ' disabled="disabled"' : '';
1324
1325 if ( $subfield ) {
1326 $template = '%s%s';
1327 $html = '';
1328 $subhtml = '';
1329 } else {
1330 $template = $args['type'] === 'section' ? '<th colspan="2"><h3>%s</h3></th>' : '<th><label for="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '">%s</label></th><td>%s</td>';
1331 $html = '<tr class="rl-gallery-field-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . ' rl-gallery-field-' . esc_attr( $args['type'] ) . ( $disabled ? ' rl-gallery-field-disabled' : '' ) . '" data-field_type="' . esc_attr( $args['type'] ) . '" data-field_name="' . esc_attr( $field ) . '">';
1332 $subhtml = '';
1333 }
1334
1335 switch ( $args['type'] ) {
1336 case 'range':
1337 $html .= sprintf(
1338 $template,
1339 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1340 '<input id="rl_' . esc_attr( $tab_id . '_' . $menu_item . '_' . $field ) . '" type="range" value="' . (int) $args['value'] . '" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']" min="' . ( ! empty( $args['min'] ) ? (int) $args['min'] : 0 ) . '"' . ( ! empty( $args['max'] ) ? ' max="' . (int) $args['max'] . '"' : '' ) . ' step="' . ( ! empty( $args['step'] ) ? (int) $args['step'] : 1 ) . '" oninput="this.form.rl_' . esc_attr( $tab_id ) . '_' . esc_attr( $menu_item ) . '_' . esc_attr( $field ) . '_range.value=this.value"' . $disabled_attr . ' /><output class="rl-gallery-field-output" name="rl_' . esc_attr( $tab_id ) . '_' . esc_attr( $menu_item ) . '_' . esc_attr( $field ) . '_range">' . (int) $args['value'] . '</output>' . ( ! empty( $args['append'] ) ? ' <span>' . esc_html( $args['append'] ) . '</span>' : '' ) . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1341 );
1342 break;
1343
1344 case 'radio':
1345 $subhtml = '';
1346
1347 foreach ( $args['options'] as $key => $label ) {
1348 $subhtml .= '<label class="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" for="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field . '-' . $key ) . '"><input id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field . '-' . $key ) . '" type="radio" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']" value="' . esc_attr( $key ) . '" ' . checked( $key, $args['value'], false ) . $disabled_attr . ' />' . esc_html( $label ) . '</label> ';
1349 }
1350
1351 $html .= sprintf(
1352 $template,
1353 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1354 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1355 );
1356 break;
1357
1358 case 'number':
1359 $html .= sprintf(
1360 $template,
1361 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1362 '<input id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" class="small-text" type="number" value="' . esc_attr( $args['value'] ) . '" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']" min="' . ( ! empty( $args['min'] ) ? (int) $args['min'] : 0 ) . '"' . ( ! empty( $args['max'] ) ? ' max="' . (int) $args['max'] . '"' : '' ) . ' step="' . ( ! empty( $args['step'] ) ? (int) $args['step'] : 1 ) . '"' . $disabled_attr . ' />' . ( ! empty( $args['append'] ) ? ' <span>' . esc_html( $args['append'] ) . '</span>' : '' ) . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1363 );
1364 break;
1365
1366 case 'text':
1367 $html .= sprintf(
1368 $template,
1369 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1370 '<input id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '"' . ( ! empty( $args['class'] ) ? ' class="' . esc_attr( $args['class'] ) . '"' : '' ) . ' type="text" value="' . esc_attr( $args['value'] ) . '" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']"' . $disabled_attr . ' />' . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1371 );
1372 break;
1373
1374 case 'class':
1375 case 'textarea':
1376 $html .= sprintf(
1377 $template,
1378 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1379 '<textarea id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '"' . ( ! empty( $args['class'] ) ? ' class="' . esc_attr( $args['class'] ) . '"' : '' ) . ' name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']"' . $disabled_attr . '>' . esc_textarea( $args['value'] ) . '</textarea>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1380 );
1381 break;
1382
1383 case 'select':
1384 $subhtml = '<select id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']"' . $disabled_attr . '>';
1385
1386 foreach ( $args['options'] as $key => $label ) {
1387 $subhtml .= '
1388 <option value="' . esc_attr( $key ) . '" ' . selected( $args['value'], $key, false ) . '>' . esc_html( $label ) . '</option>';
1389 }
1390
1391 $html .= sprintf(
1392 $template,
1393 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1394 $subhtml . '</select>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1395 );
1396 break;
1397
1398 case 'taxonomy':
1399 if ( taxonomy_exists( $args['taxonomy'] ) ) {
1400 $subhtml = wp_dropdown_categories(
1401 array(
1402 'orderby' => 'name',
1403 'order' => 'asc',
1404 'show_option_none' => __( 'Root Folder', 'responsive-lightbox' ),
1405 'show_option_all' => false,
1406 'show_count' => false,
1407 'hide_empty' => false,
1408 'option_none_value' => 0,
1409 'hierarchical' => true,
1410 'selected' => $args['value']['id'],
1411 'taxonomy' => $args['taxonomy'],
1412 'hide_if_empty' => false,
1413 'echo' => false,
1414 'id' => 'rl-' . $tab_id . '-' . $menu_item . '-' . $field,
1415 'name' => 'rl_gallery[' . $tab_id . '][' . $menu_item . '][' . $field . '][id]'
1416 )
1417 );
1418 } else
1419 $subhtml = '<select id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . '][]" ><option value="0">' . esc_html__( 'Root Folder', 'responsive-lightbox' ) . '</option></select> ';
1420
1421 if ( $disabled )
1422 $subhtml = preg_replace( '/<select /', '<select disabled="disabled" ', $subhtml, 1 );
1423
1424 if ( isset( $args['include_children'] ) && $args['include_children'] ) {
1425 $subhtml .= '<label class="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '-include-children" for="rl-' . esc_attr( $tab_id ) . '-' . esc_attr( $menu_item ) . '-' . esc_attr( $field ) . '-include-children"><input id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '-include-children" type="checkbox" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . '][children]" value="true" ' . checked( $args['value']['children'], true, false ) . $disabled_attr . ' />' . esc_html__( 'Include children.', 'responsive-lightbox' ) . '</label>';
1426 }
1427
1428 $html .= sprintf(
1429 $template,
1430 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1431 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1432 );
1433 break;
1434
1435 case 'multiselect':
1436 $subhtml = '<select multiple="multiple" class="select2" id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" data-empty="' . (int) empty( $args['value'] ) . '" data-type="' . esc_attr( $field ) . '" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . '][]"' . $disabled_attr . '>';
1437
1438 if ( $field === 'post_term' ) {
1439 foreach ( $args['options'] as $taxanomy => $data ) {
1440 $subhtml .= '<optgroup label="' . esc_attr( $data['label'] ) . '">';
1441
1442 foreach ( $data['terms'] as $term_id => $name ) {
1443 $subhtml .= '<option value="' . esc_attr( $term_id ) . '" ' . selected( in_array( $term_id, $args['value'], false ), true, false ) . '>' . esc_html( $name ) . '</option>';
1444 }
1445
1446 $subhtml .= '</optgroup>';
1447 }
1448 } else {
1449 foreach ( $args['options'] as $key => $label ) {
1450 $subhtml .= '
1451 <option value="' . esc_attr( $key ) . '" ' . selected( in_array( $key, $args['value'], false ), true, false ) . '>' . esc_html( $label ) . '</option>';
1452 }
1453 }
1454
1455 $html .= sprintf(
1456 $template,
1457 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1458 $subhtml . '</select>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1459 );
1460 break;
1461
1462 case 'boolean':
1463 $html .= sprintf(
1464 $template,
1465 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1466 '<label class="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" for="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '"><input id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" type="checkbox" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']" value="true" ' . checked( $args['value'], true, false ) . $disabled_attr . ' />' . esc_html( $args['label'] ) . '</label>' . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1467 );
1468 break;
1469
1470 case 'checkbox':
1471 $subhtml = '';
1472
1473 foreach ( $args['options'] as $key => $label ) {
1474 $subhtml .= '<label class="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field . '-' . $key ) . '" for="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field . '-' . $key ) . '"><input id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field . '-' . $key ) . '" type="checkbox" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . '][' . esc_attr( $key ) . ']" value="true" ' . checked( in_array( $key, $args['value'], true ), true, false ) . $disabled_attr . ' />' . esc_html( $label ) . '</label><br />';
1475 }
1476
1477 $html .= sprintf(
1478 $template,
1479 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1480 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1481 );
1482 break;
1483
1484 case 'multiple':
1485 $subhtml = '';
1486
1487 foreach ( $args['fields'] as $sub_field => $sub_args ) {
1488 if ( $disabled )
1489 $sub_args['disabled'] = true;
1490 $subhtml .= $this->render_field( $sub_field, $tab_id, $menu_item, $sub_args, $gallery_id, true ) . '<br />';
1491 }
1492
1493 $html .= sprintf(
1494 $template,
1495 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1496 $subhtml . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1497 );
1498 break;
1499
1500 case 'color_picker':
1501 $html .= sprintf(
1502 $template,
1503 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1504 '<input id="rl-' . esc_attr( $tab_id . '-' . $menu_item . '-' . $field ) . '" class="color-picker" type="text" value="' . esc_attr( $args['value'] ) . '" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . ']" data-default-color="' . esc_attr( $args['default'] ) . '"' . $disabled_attr . ' />' . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1505 );
1506 break;
1507
1508 case 'media_library':
1509 $data = get_post_meta( $gallery_id, '_rl_images', true );
1510
1511 // get images
1512 if ( ( ! empty( $data['menu_item'] ) && $data['menu_item'] === 'media' ) || ! ( wp_doing_ajax() && isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-menu-content' ) )
1513 $images = $this->get_gallery_images( $gallery_id );
1514 else
1515 $images = [];
1516
1517 // get media item template
1518 $media_item_template = $this->get_media_item_template( $args['preview'] );
1519
1520 // media buttons
1521 $buttons_desc = '';
1522
1523 // video support?
1524 if ( rl_current_lightbox_supports( 'video' ) ) {
1525 $buttons = [ '<a href="#" class="rl-gallery-select button button-secondary">' . __( 'Select images & videos', 'responsive-lightbox' ) . '</a>' ];
1526
1527 } else {
1528 $buttons[] = '<a href="#" class="rl-gallery-select button button-secondary">' . __( 'Select images', 'responsive-lightbox' ) . '</a>';
1529 $buttons[] = '<a href="#" class="rl-gallery-select button button-disabled" disabled="true">' . __( 'Select images & videos', 'responsive-lightbox' ) . '</a>';
1530 $buttons_desc_args = [ '<a href="http://www.dfactory.co/products/fancybox-pro/" target="_blank">Fancybox Pro</a>', '<a href="http://www.dfactory.co/products/lightgallery-lightbox/" target="_blank">Lightgallery Lightbox</a>', '<a href="http://www.dfactory.co/products/lightcase-lightbox/" target="_blank">Lightcase Lightbox</a>' ];
1531 $buttons_desc = '<p class="description">' . wp_sprintf( __( 'HTML5 Videos and Embed Videos available only in %l.', 'responsive-lightbox' ), $buttons_desc_args ) . '</p>';
1532 }
1533
1534 $html .= '
1535 <td colspan="2" class="rl-colspan">
1536 <input type="hidden" class="rl-gallery-ids" name="rl_gallery[' . esc_attr( $tab_id ) . '][' . esc_attr( $menu_item ) . '][' . esc_attr( $field ) . '][ids]" value="' . esc_attr( ! empty( $args['value']['ids'] ) ? implode( ',', $args['value']['ids'] ) : '' ) . '">';
1537
1538 // embed video support?
1539 if ( rl_current_lightbox_supports( [ 'youtube', 'vimeo' ], 'OR' ) )
1540 $buttons[] = '<a href="#" class="rl-gallery-select-videos button button-secondary">' . esc_html__( 'Embed videos', 'responsive-lightbox' ) . '</a>';
1541 else
1542 $buttons[] = '<a href="#" class="rl-gallery-select-videos button button-disabled" disabled="true">' . esc_html__( 'Embed videos', 'responsive-lightbox' ) . '</a>';
1543
1544 // add buttons
1545 $html .= '
1546 <div class="rl-gallery-buttons">'
1547 . implode( '', $buttons )
1548 . $buttons_desc .
1549 '</div>';
1550
1551 $html .= '
1552 <div class="rl-gallery-content">
1553 <ul class="rl-gallery-images rl-gallery-images-media">';
1554
1555 if ( ! empty( $images ) ) {
1556 foreach ( $images as $image ) {
1557 if ( $image['id'] === 0 )
1558 $excluded_item = $image['url'];
1559 else
1560 $excluded_item = $image['id'];
1561
1562 // get image content html
1563 $html .= $this->get_gallery_preview_image_content( $image, $tab_id, $menu_item, $field, $media_item_template, $args['value']['exclude'], $excluded_item );
1564 }
1565 }
1566
1567 $html .= '
1568 </ul>
1569 </div>
1570 </td>';
1571 break;
1572
1573 case 'media_preview':
1574 $this->menu_item = $menu_item;
1575
1576 // get images
1577 $images = $this->get_gallery_images( $gallery_id );
1578
1579 // get media item template
1580 $media_item_template = $this->get_media_item_template( $args['preview'] );
1581
1582 $html .= '
1583 <td colspan="2" class="rl-colspan">
1584 <div class="rl-gallery-preview-inside">
1585 <a href="#" class="rl-gallery-update-preview button button-secondary">' . esc_html__( 'Update preview', 'responsive-lightbox' ) . '</a><span class="spinner" style="display: none;"></span>
1586 <p class="description">' . esc_html__( 'Use this button after any change of the options below to see updated gallery preview.', 'responsive-lightbox' ) . '</p>
1587 </div>
1588 <div class="rl-gallery-content">
1589 <ul class="rl-gallery-images rl-gallery-images-' . esc_attr( $menu_item ) . '">';
1590
1591 if ( ! empty( $images ) ) {
1592 foreach ( $images as $image ) {
1593 if ( empty( $image['id'] ) ) {
1594 $excluded_item = $image['url'];
1595 $image['id'] = 0;
1596 } else
1597 $excluded_item = $image['id'];
1598
1599 // get image content html
1600 $html .= $this->get_gallery_preview_image_content( $image, $tab_id, $menu_item, $field, $media_item_template, $args['value']['exclude'], $excluded_item );
1601 }
1602 }
1603
1604 $html .= '
1605 </ul>
1606 </div>';
1607
1608 if ( ! empty( $args['preview'] ) && isset( $args['preview']['pagination'] )&& $args['preview']['pagination'] )
1609 $html .= $this->get_preview_pagination();
1610
1611 $html .= '
1612 </td>';
1613 break;
1614
1615 case 'hidden':
1616 // prepare args
1617 $args['tab_id'] = $tab_id;
1618 $args['menu_item'] = $menu_item;
1619 $args['field'] = $field;
1620
1621 $html .= sprintf(
1622 $template,
1623 '',
1624 call_user_func( $args['callback'], $args )
1625 );
1626 break;
1627
1628 default:
1629 $html .= sprintf(
1630 $template,
1631 ! empty( $args['title'] ) ? esc_html( $args['title'] ) : '',
1632 apply_filters( 'rl_render_gallery_field_' . $args['type'], $subhtml, $field, $tab_id, $menu_item, $args, $subfield ) . ( ! empty ( $args['description'] ) ? '<p class="description">' . wp_kses_post( $args['description'] ) . '</p>' : '' )
1633 );
1634 }
1635
1636 if ( ! $subfield )
1637 $html .= '</tr>';
1638
1639 return apply_filters( 'rl_render_gallery_field', $html, $field, $tab_id, $menu_item, $args, $subfield, $gallery_id );
1640 }
1641
1642 /**
1643 * Get preview pagination.
1644 *
1645 * @param int $current_page
1646 * @return string
1647 */
1648 public function get_preview_pagination( $current_page = 1 ) {
1649 $page_links = [];
1650 $total_pages = $current_page + 1;
1651 $current = $current_page;
1652 $disable_first = $disable_last = $disable_prev = $disable_next = false;
1653 $current_url = 'preview_page';
1654
1655 if ( $current == 1 ) {
1656 $disable_first = true;
1657 $disable_prev = true;
1658 } elseif ( $current == 2 )
1659 $disable_first = true;
1660
1661 if ( $current == $total_pages ) {
1662 $disable_last = true;
1663 $disable_next = true;
1664 }
1665
1666 if ( $current == $total_pages - 1 )
1667 $disable_last = true;
1668
1669 if ( $disable_first )
1670 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
1671 else {
1672 $page_links[] = sprintf(
1673 '<a class="first-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1674 $current_url,
1675 esc_html__( 'First page', 'responsive-lightbox' ),
1676 '&laquo;'
1677 );
1678 }
1679
1680 if ( $disable_prev )
1681 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
1682 else {
1683 $page_links[] = sprintf(
1684 '<a class="prev-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1685 $current_url . '/' . max( 1, $current - 1 ),
1686 esc_html__( 'Previous page', 'responsive-lightbox' ),
1687 '&lsaquo;'
1688 );
1689 }
1690
1691 $html_current_page = sprintf(
1692 '%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">',
1693 '<label for="current-page-selector" class="screen-reader-text">' . esc_html__( 'Current Page', 'responsive-lightbox' ) . '</label>',
1694 $current,
1695 strlen( $total_pages )
1696 );
1697
1698 $html_total_pages = sprintf( '<span class="total-pages">%s</span>', number_format_i18n( $total_pages ) );
1699 $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s', 'paging' ), $html_current_page, $html_total_pages ) . '</span></span>';
1700
1701 if ( $disable_next )
1702 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
1703 else {
1704 $page_links[] = sprintf(
1705 '<a class="next-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1706 $current_url . '/' . min( $total_pages, $current + 1 ),
1707 esc_html__( 'Next page', 'responsive-lightbox' ),
1708 '&rsaquo;'
1709 );
1710 }
1711
1712 if ( $disable_last )
1713 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
1714 else {
1715 $page_links[] = sprintf(
1716 '<a class="last-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
1717 $current_url . '/' . $total_pages,
1718 esc_html__( 'Last page', 'responsive-lightbox' ),
1719 '&raquo;'
1720 );
1721 }
1722
1723 if ( $total_pages )
1724 $page_class = $total_pages < 2 ? 'one-page' : '';
1725 else
1726 $page_class = 'no-pages';
1727
1728 return '<div class="rl-gallery-preview-pagination tablenav"><div class="tablenav-pages ' . esc_attr( $page_class ) . '"><span class="pagination-links">' . join( "\n", $page_links ) . '</span></div>';
1729 }
1730
1731 /**
1732 * Sanitize field based on type. Internal use only.
1733 *
1734 * @global string $wp_version
1735 *
1736 * @param string $field Field name
1737 * @param mixed $value Field value
1738 * @param array $args Field arguments
1739 * @return mixed
1740 */
1741 public function sanitize_field( $field, $value, $args ) {
1742 switch ( $args['type'] ) {
1743 case 'radio':
1744 case 'select':
1745 $value = array_key_exists( $value, $args['options'] ) ? $value : $args['default'];
1746 break;
1747
1748 case 'taxonomy':
1749 if ( is_array( $value ) ) {
1750 if ( isset( $value['id'] ) )
1751 $value['id'] = (int) $value['id'];
1752 else
1753 $value['id'] = 0;
1754
1755 $value['children'] = isset( $value['children'] );
1756 } else
1757 $value = $args['default'];
1758
1759 // flatten taxonomy options if needed
1760 if ( ! empty( $args['options'] ) && is_array( $args['options'] ) ) {
1761 $terms = [];
1762
1763 foreach ( $args['options'] as $option_data ) {
1764 if ( isset( $option_data['terms'] ) && is_array( $option_data['terms'] ) )
1765 $terms += $option_data['terms'];
1766 }
1767
1768 if ( ! empty( $terms ) )
1769 $args['options'] = $terms;
1770 }
1771
1772 if ( isset( $value['id'] ) && ! empty( $args['options'] ) && is_array( $args['options'] ) && ! array_key_exists( $value['id'], $args['options'] ) )
1773 $value['id'] = 0;
1774
1775 // validate term exists
1776 if ( isset( $value['id'] ) && $value['id'] ) {
1777 $term = get_term( $value['id'], $args['taxonomy'] );
1778 if ( ! is_a( $term, 'WP_Term' ) )
1779 $value['id'] = 0;
1780 }
1781 break;
1782 case 'multiselect':
1783 if ( is_array( $value ) ) {
1784 if ( $field === 'post_term' ) {
1785 $terms = [];
1786
1787 foreach ( $args['options'] as $data ) {
1788 $terms += $data['terms'];
1789 }
1790
1791 $args['options'] = $terms;
1792 }
1793
1794 $values = [];
1795
1796 foreach ( $value as $subvalue ) {
1797 if ( array_key_exists( $subvalue, $args['options'] ) )
1798 $values[] = $subvalue;
1799 }
1800
1801 $value = $values;
1802 } else
1803 $value = $args['default'];
1804 break;
1805 case 'checkbox':
1806 if ( is_array( $value ) && ! empty( $value ) ) {
1807 $sort = [];
1808
1809 foreach ( $value as $sort_key => $bool ) {
1810 if ( array_key_exists( $sort_key, $args['options'] ) )
1811 $sort[] = $sort_key;
1812 }
1813
1814 $value = $sort;
1815 } else
1816 $value = [];
1817 break;
1818
1819 case 'boolean':
1820 $value = $value === 'true';
1821 break;
1822
1823 case 'range':
1824 case 'number':
1825 $value = (int) $value;
1826
1827 // is value lower than?
1828 if ( isset( $args['min'] ) && $value < $args['min'] )
1829 $value = $args['min'];
1830
1831 // is value greater than?
1832 if ( isset( $args['max'] ) && $value > $args['max'] )
1833 $value = $args['max'];
1834 break;
1835
1836 case 'class':
1837 $value = trim( $value );
1838
1839 // more than 1 class?
1840 if ( strpos( $value, ' ' ) !== false ) {
1841 // get unique valid HTML classes
1842 $value = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $value ) ) ) );
1843
1844 if ( ! empty( $value ) )
1845 $value = implode( ' ', $value );
1846 else
1847 $value = '';
1848 // single class
1849 } else
1850 $value = sanitize_html_class( $value );
1851 break;
1852
1853 case 'text':
1854 $value = trim( sanitize_text_field( $value ) );
1855 break;
1856
1857 case 'textarea':
1858 global $wp_version;
1859
1860 // WP 4.7+
1861 if ( version_compare( $wp_version, '4.7', '>=' ) )
1862 $value = trim( sanitize_textarea_field( $value ) );
1863 // _sanitize_text_fields
1864 else {
1865 $value = wp_check_invalid_utf8( $value );
1866
1867 if ( strpos( $value, '<' ) !== false ) {
1868 $value = wp_pre_kses_less_than( $value );
1869
1870 // this will strip extra whitespace for us
1871 $value = wp_strip_all_tags( $value, false );
1872
1873 // use html entities in a special case to make sure no later newline stripping stage could lead to a functional tag
1874 $value = str_replace( "<\n", "&lt;\n", $value );
1875 }
1876
1877 $value = trim( $value );
1878 $found = false;
1879
1880 while ( preg_match('/%[a-f0-9]{2}/i', $value, $match ) ) {
1881 $value = str_replace( $match[0], '', $value );
1882 $found = true;
1883 }
1884
1885 // strip out the whitespace that may now exist after removing the octets
1886 if ( $found )
1887 $value = trim( preg_replace( '/ +/', ' ', $value ) );
1888 }
1889 break;
1890
1891 case 'color_picker':
1892 if ( preg_match( '/^#[a-f0-9]{6}$/i', $value ) !== 1 )
1893 $value = $args['default'];
1894 break;
1895
1896 case 'media_library':
1897 if ( is_array( $value ) ) {
1898 $data = $args['default'];
1899
1900 if ( rl_current_lightbox_supports( [ 'youtube', 'vimeo' ], 'OR' ) ) {
1901 $reindexed_embed = [];
1902
1903 // check embed items
1904 if ( array_key_exists( 'embed', $value ) && is_array( $value['embed'] ) && ! empty( $value['embed'] ) ) {
1905 $copy = $value['embed'];
1906
1907 $index = 0;
1908
1909 foreach ( $value['embed'] as $embed_id => $embed_data ) {
1910 // check url
1911 if ( ! array_key_exists( 'url', $embed_data ) ) {
1912 unset( $copy[$embed_id] );
1913
1914 continue;
1915 } else
1916 $copy[$embed_id]['url'] = esc_url_raw( $embed_data['url'] );
1917
1918 // check width
1919 if ( ! array_key_exists( 'width', $embed_data ) )
1920 $copy[$embed_id]['width'] = 0;
1921 else
1922 $copy[$embed_id]['width'] = (int) $embed_data['width'];
1923
1924 // check height
1925 if ( ! array_key_exists( 'height', $embed_data ) )
1926 $copy[$embed_id]['height'] = 0;
1927 else
1928 $copy[$embed_id]['height'] = (int) $embed_data['height'];
1929
1930 // check thumbnail url
1931 if ( empty( $embed_data['thumbnail_url'] ) )
1932 $copy[$embed_id]['thumbnail_url'] = '';
1933 else
1934 $copy[$embed_id]['thumbnail_url'] = esc_url_raw( $embed_data['thumbnail_url'] );
1935
1936 // check thumbnail width
1937 if ( ! array_key_exists( 'thumbnail_width', $embed_data ) )
1938 $copy[$embed_id]['thumbnail_width'] = 0;
1939 else
1940 $copy[$embed_id]['thumbnail_width'] = (int) $embed_data['thumbnail_width'];
1941
1942 // check thumbnail height
1943 if ( ! array_key_exists( 'thumbnail_height', $embed_data ) )
1944 $copy[$embed_id]['thumbnail_height'] = 0;
1945 else
1946 $copy[$embed_id]['thumbnail_height'] = (int) $embed_data['thumbnail_height'];
1947
1948 // check title
1949 if ( empty( $embed_data['title'] ) )
1950 $copy[$embed_id]['title'] = '';
1951 else
1952 $copy[$embed_id]['title'] = trim( sanitize_text_field( $embed_data['title'] ) );
1953
1954 // check caption
1955 if ( empty( $embed_data['caption'] ) )
1956 $copy[$embed_id]['caption'] = '';
1957 else
1958 $copy[$embed_id]['caption'] = trim( sanitize_textarea_field( $embed_data['caption'] ) );
1959
1960 // check date
1961 if ( empty( $embed_data['date'] ) )
1962 $copy[$embed_id]['date'] = '';
1963 else
1964 $copy[$embed_id]['date'] = date( 'Y-m-d H:i:s', strtotime( $embed_data['date'] ) );
1965
1966 // new embed id
1967 $new_id = 'e' . $index;
1968
1969 // add embed data
1970 $data['embed'][$new_id] = $copy[$embed_id];
1971 $data['embed'][$new_id]['id'] = $new_id;
1972
1973 // add special id
1974 $reindexed_embed[$embed_id] = 'em' . $index++;
1975 }
1976
1977 // last replacement is 'em' to avoid replacing same embed ids
1978 $reindexed_embed['em'] = 'e';
1979
1980 // prepare embed additional data
1981 $atts_args = [
1982 'embed_keys' => array_keys( $data['embed'] ),
1983 'providers' => [ 'youtube', 'vimeo' ]
1984 ];
1985 } else
1986 $atts_args = [];
1987 } else
1988 $atts_args = [];
1989
1990
1991 // check ids
1992 if ( array_key_exists( 'ids', $value ) ) {
1993 // prepare ids
1994 $ids = (string) trim( $value['ids'] );
1995
1996 if ( $ids !== '' ) {
1997 // reindex embed
1998 if ( ! empty( $reindexed_embed ) )
1999 $ids = str_replace( array_keys( $reindexed_embed ), array_values( $reindexed_embed ), $ids );
2000
2001 // get unique and non empty attachment ids only
2002 $data['ids'] = $this->check_attachments( array_unique( array_filter( explode( ',', $ids ) ) ), $atts_args );
2003 } else
2004 $data['ids'] = [];
2005 }
2006
2007 // check excluded items
2008 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
2009 // reindex embed
2010 if ( ! empty( $reindexed_embed ) )
2011 $value['exclude'] = explode( ',', str_replace( array_keys( $reindexed_embed ), array_values( $reindexed_embed ), implode( ',', array_filter( $value['exclude'] ) ) ) );
2012
2013 // get unique and non empty attachment ids only
2014 $data['exclude'] = $this->check_attachments( array_unique( array_filter( $value['exclude'] ) ), $atts_args );
2015 }
2016
2017 $value = $data;
2018 } else
2019 $value = $args['default'];
2020 break;
2021
2022 case 'media_preview':
2023 if ( is_array( $value ) ) {
2024 $data = $args['default'];
2025
2026 // check excluded items
2027 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
2028 $ids = $strings = [];
2029
2030 foreach ( $value['exclude'] as $exclude_item ) {
2031 $item = trim( $exclude_item );
2032
2033 if ( is_numeric( $item ) )
2034 $ids[] = (int) $item;
2035 elseif ( $item !== '' )
2036 $strings[] = $item;
2037 }
2038
2039 if ( ! empty( $ids ) ) {
2040 // get unique and non empty attachment ids only
2041 $ids = $this->check_attachments( array_unique( array_filter( $ids ) ) );
2042 }
2043
2044 $data['exclude'] = $ids + $strings;
2045 }
2046
2047 $value = $data;
2048 } else
2049 $value = $args['default'];
2050 }
2051
2052 return apply_filters( 'rl_sanitize_gallery_field', $value, $args );
2053 }
2054
2055 /**
2056 * Sanitize set of fields.
2057 *
2058 * @param array $items Fields
2059 * @param array $data POST data
2060 * @param string $tab_id Gallery tab
2061 * @param string $menu_item Gallery menu item
2062 * @return array
2063 */
2064 public function sanitize_fields( $items, $data, $tab_id, $menu_item ) {
2065 $safedata = [];
2066
2067 foreach ( $items as $field => $item ) {
2068 // skip this field
2069 if ( isset( $item['save'] ) && ! $item['save'] )
2070 continue;
2071
2072 // available field?
2073 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$field] ) )
2074 $safedata[$tab_id][$menu_item][$field] = $this->sanitize_field( $field, $data[$tab_id][$menu_item][$field], $item );
2075 // boolean field?
2076 elseif ( $item['type'] === 'boolean' )
2077 $safedata[$tab_id][$menu_item][$field] = false;
2078 // multiple fields?
2079 elseif ( $item['type'] === 'multiple' ) {
2080 foreach ( $item['fields'] as $subfield => $subitem ) {
2081 // available subfield?
2082 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$subfield] ) )
2083 $safedata[$tab_id][$menu_item][$subfield] = $this->sanitize_field( $subfield, $data[$tab_id][$menu_item][$subfield], $subitem );
2084 // boolean subfield?
2085 elseif ( $subitem['type'] === 'boolean' )
2086 $safedata[$tab_id][$menu_item][$subfield] = false;
2087 // any other case
2088 else
2089 $safedata[$tab_id][$menu_item][$subfield] = $subitem['default'];
2090 }
2091 // any other case
2092 } else
2093 $safedata[$tab_id][$menu_item][$field] = $item['default'];
2094 }
2095
2096 return $safedata;
2097 }
2098
2099 /**
2100 * Add menu tabs after the post title.
2101 *
2102 * @global array $wp_meta_boxes
2103 *
2104 * @param object $post Post object
2105 * @return void
2106 */
2107 public function after_title_nav_menu( $post ) {
2108 if ( $post->post_type !== 'rl_gallery' )
2109 return;
2110
2111 global $wp_meta_boxes;
2112
2113 // check active tab
2114 $active_tab = isset( $_GET['rl_active_tab'] ) ? sanitize_key( $_GET['rl_active_tab'] ) : '';
2115 $active_tab = ! empty( $active_tab ) && array_key_exists( $active_tab, $this->tabs ) ? $active_tab : 'images';
2116
2117 echo '
2118 <h2 class="nav-tab-wrapper">';
2119
2120 foreach ( $this->tabs as $key => $data ) {
2121 echo '
2122 <a id="rl-gallery-tab-' . esc_attr( $key ) . '" class="rl-gallery-tab nav-tab' . ( $key === $active_tab ? ' nav-tab-active' : '' ) . '" href="#' . esc_attr( $key ) . '">' . esc_html( $data['label'] ) . '</a>';
2123 }
2124
2125 echo '
2126 </h2>';
2127
2128 do_meta_boxes( $post->post_type, 'responsive_lightbox_metaboxes', $post );
2129
2130 unset( $wp_meta_boxes[$post->post_type]['responsive_lightbox_metaboxes'] );
2131 }
2132
2133 /**
2134 * Add class to hide metabox.
2135 *
2136 * @param array $classes
2137 * @return array
2138 */
2139 public function hide_metabox( $classes ) {
2140 $classes[] = 'rl-metabox-content';
2141 $classes[] = 'rl-hide-metabox';
2142
2143 return $classes;
2144 }
2145
2146 /**
2147 * Add class to display the metabox.
2148 *
2149 * @param array $classes
2150 * @return array
2151 */
2152 function display_metabox( $classes ) {
2153 $classes[] = 'rl-metabox-content';
2154 $classes[] = 'rl-display-metabox';
2155
2156 return $classes;
2157 }
2158
2159 /**
2160 * Add active tab to post redirect destination URL.
2161 *
2162 * @param string $location Destination URL
2163 * @return string
2164 */
2165 function add_active_tab( $location ) {
2166 // check active tab
2167 $active_tab = isset( $_POST['rl_active_tab'] ) ? sanitize_key( $_POST['rl_active_tab'] ) : '';
2168
2169 return add_query_arg( 'rl_active_tab', ! empty( $active_tab ) && array_key_exists( $active_tab, $this->tabs ) ? $active_tab : 'images', $location );
2170 }
2171
2172 /**
2173 * Add metaboxes.
2174 *
2175 * @return void
2176 */
2177 public function add_meta_boxes() {
2178 // check active tab
2179 $active_tab = isset( $_GET['rl_active_tab'] ) ? sanitize_key( $_GET['rl_active_tab'] ) : '';
2180 $active_tab = ! empty( $active_tab ) && array_key_exists( $active_tab, $this->tabs ) ? $active_tab : 'images';
2181
2182 // normal metaboxes
2183 foreach ( $this->tabs as $key => $args ) {
2184 if ( $key === 'images' )
2185 $new_args = $args + array( 'tab_id' => $key, 'active_tab' => $active_tab );
2186 else
2187 $new_args = $args + array( 'tab_id' => $key );
2188
2189 // handle metabox class
2190 if ( $active_tab === $key )
2191 add_filter( 'postbox_classes_rl_gallery_responsive-gallery-' . $key, array( $this, 'display_metabox' ) );
2192 else
2193 add_filter( 'postbox_classes_rl_gallery_responsive-gallery-' . $key, array( $this, 'hide_metabox' ) );
2194
2195 add_meta_box( 'responsive-gallery-' . $key, sprintf( esc_html__( 'Gallery %s', 'responsive-lightbox' ), $args['label'] ), array( $this, 'add_metabox' ), 'rl_gallery', 'responsive_lightbox_metaboxes', 'high', $new_args );
2196 }
2197
2198 // side metaboxes
2199 add_meta_box( 'responsive-gallery-shortcode', esc_html__( 'Gallery Code', 'responsive-lightbox' ), array( $this, 'shortcode_metabox' ), 'rl_gallery', 'side', 'core' );
2200 }
2201
2202 /**
2203 * Add single metabox.
2204 *
2205 * @param object $post Post object
2206 * @param array $callback_args Arguments
2207 * @return void
2208 */
2209 public function add_metabox( $post, $callback_args ) {
2210 $html = $callback_args['args']['tab_id'] === 'images' ? '<input type="hidden" name="rl_active_tab" value="' . esc_attr( $callback_args['args']['active_tab'] ) . '" />' : '';
2211
2212 // default menu item
2213 $menu_item = 'options';
2214
2215 // get tab data
2216 $data = get_post_meta( $post->ID, '_rl_' . $callback_args['args']['tab_id'], true );
2217
2218 if ( ! is_array( $data ) )
2219 $data = [];
2220
2221 if ( $callback_args['args']['tab_id'] === 'design' && ! empty( $data['menu_item'] ) && is_array( $data[$data['menu_item']] ) ) {
2222 $design_data = $data[$data['menu_item']];
2223
2224 // remove show_title
2225 if ( isset( $design_data['show_title'] ) ) {
2226 if ( ! isset( $design_data['design_show_title'] ) )
2227 $design_data['design_show_title'] = $design_data['show_title'];
2228
2229 unset( $design_data['show_title'] );
2230 }
2231
2232 // remove show_caption
2233 if ( isset( $design_data['show_caption'] ) ) {
2234 if ( ! isset( $design_data['design_show_caption'] ) )
2235 $design_data['design_show_caption'] = $design_data['show_caption'];
2236
2237 unset( $design_data['show_caption'] );
2238 }
2239
2240 $data[$data['menu_item']] = $design_data;
2241 }
2242
2243 // maybe add description
2244 $html .= ! empty( $callback_args['args']['description'] ) ? '<p class="rl-gallery-tab-description">' . esc_html( $callback_args['args']['description'] ) . '</p>' : '';
2245
2246 // get main instance
2247 $rl = Responsive_Lightbox();
2248
2249 // maybe add menu
2250 if ( ! empty( $callback_args['args']['menu_items'] ) ) {
2251 // get selected menu item
2252 $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'] );
2253
2254 $html .= '
2255 <div class="rl-gallery-tab-menu rl-gallery-tab-menu-' . esc_attr( $callback_args['args']['tab_id'] ) . '">';
2256
2257 foreach ( $callback_args['args']['menu_items'] as $menu_key => $menu_label ) {
2258 // disable select for remote library if needed
2259 if ( $menu_key === 'remote_library' && ! $rl->options['remote_library']['active'] ) {
2260 $title = __( 'Remote Library is disabled. Enable it in the settings.', 'responsive-lightbox' );
2261 $disabled = true;
2262 // disable select for media folders if needed
2263 } elseif ( $menu_key === 'folders' && ! $rl->options['folders']['active'] ) {
2264 $title = __( 'Media Folders are disabled. Enable it in the settings.', 'responsive-lightbox' );
2265 $disabled = true;
2266 // other menu items
2267 } else {
2268 $title = '';
2269 $disabled = false;
2270 }
2271
2272 $html .= '
2273 <label' . ( $title !== '' ? ' title="' . esc_attr( $title ). '"' : '' ) . '><input type="radio" class="rl-gallery-tab-menu-item" name="rl_gallery[' . esc_attr( $callback_args['args']['tab_id'] ) . '][menu_item]" value="' . esc_attr( $menu_key ) . '" ' . checked( $menu_item, $menu_key, false ) . ' ' . disabled( $disabled, true, false ) . ' />' . esc_html( $menu_label ) . ( $callback_args['args']['tab_id'] === 'config' && $menu_key === 'default' ? ' (' . esc_html( $this->tabs['config']['menu_items'][$rl->options['settings']['builder_gallery']] ) . ')' : '' ) . '</label>';
2274 }
2275
2276 $html .= '
2277 <span class="spinner" style="display: none;"></span>
2278 </div>';
2279 }
2280
2281 $class = '';
2282
2283 // disable gallery images content for remote library or media folders if needed
2284 if ( $callback_args['args']['tab_id'] === 'images' && ( ( $menu_item === 'remote_library' && ! $rl->options['remote_library']['active'] ) || ( $menu_item === 'folders' && ! $rl->options['folders']['active'] ) ) )
2285 $class = 'rl-loading-content';
2286
2287 $html .= '
2288 <div class="rl-gallery-tab-content rl-gallery-tab-content-' . esc_attr( $callback_args['args']['tab_id'] ) . ( $class !== '' ? ' ' . esc_attr( $class ) : '' ) . '">';
2289
2290 $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 );
2291
2292 $html .= '
2293 </div>';
2294
2295 // get allowed html
2296 $allowed_html = wp_kses_allowed_html( 'post' );
2297
2298 $allowed_html['a']['disabled'] = [];
2299 $allowed_html['span']['data-select2-id'] = [];
2300 $allowed_html['input'] = [
2301 'type' => [],
2302 'name' => [],
2303 'value' => [],
2304 'class' => [],
2305 'id' => [],
2306 'size' => [],
2307 'checked' => [],
2308 'disabled' => [],
2309 'aria-describedby' => [],
2310 'min' => [],
2311 'max' => [],
2312 'step' => [],
2313 'data-default-color' => []
2314 ];
2315 $allowed_html['select'] = [
2316 'name' => [],
2317 'id' => [],
2318 'class' => [],
2319 'multiple' => [],
2320 'data-empty' => [],
2321 'data-type' => [],
2322 'aria-hidden' => []
2323 ];
2324 $allowed_html['option'] = [
2325 'value' => [],
2326 'selected' => [],
2327 'class' => []
2328 ];
2329 $allowed_html['optgroup'] = [
2330 'label' => []
2331 ];
2332
2333 add_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
2334
2335 echo wp_kses( $html, $allowed_html );
2336
2337 remove_filter( 'safe_style_css', [ $this, 'allow_style_attributes' ] );
2338 }
2339
2340 /**
2341 * Add new properties to style safe list.
2342 *
2343 * @param array $styles
2344 * @return array
2345 */
2346 public function allow_style_attributes( $styles ) {
2347 $styles[] = 'display';
2348 $styles[] = 'visibility';
2349
2350 return $styles;
2351 }
2352
2353 /**
2354 * Get single metabox content.
2355 *
2356 * @param string $tab_id Tab ID
2357 * @param array $data Metabox data
2358 * @param string $menu_item Specified menu item
2359 * @param int $gallery_id Gallery ID
2360 * @return string
2361 */
2362 public function get_metabox_content( $tab_id, $data, $menu_item, $gallery_id = 0 ) {
2363 $html = '
2364 <div class="rl-gallery-tab-inside rl-gallery-tab-inside-' . esc_attr( $tab_id ) . '-' . esc_attr( $menu_item ) . '">
2365 <table class="form-table">';
2366
2367 switch ( $tab_id ) {
2368 case 'config':
2369 // get main instance
2370 $rl = Responsive_Lightbox();
2371
2372 // get default gallery fields
2373 $default_gallery = $rl->frontend->get_default_gallery_fields();
2374
2375 // assign settings and defaults
2376 $settings = $this->get_gallery_settings_data();
2377 $defaults = $rl->defaults;
2378 $default_gallery_type = $rl->options['settings']['builder_gallery'];
2379 $default_gallery_key = $default_gallery_type . '_gallery';
2380 $default_gallery_fields = [];
2381 $builder_gallery_fields = [];
2382 $disabled_fields = [];
2383 $global_settings = [];
2384 $disabled_notice = '';
2385 $disabled_notice_output = false;
2386
2387 // ensure default_gallery exists in settings for validation check at line 2356
2388 if ( ! array_key_exists( 'default_gallery', $settings ) )
2389 $settings['default_gallery'] = [];
2390 // always use canonical universal fields source
2391 $default_gallery_fields = $default_gallery;
2392 if ( ! empty( $settings[$default_gallery_key]['fields'] ) )
2393 $builder_gallery_fields = $settings[$default_gallery_key]['fields'];
2394 elseif ( $rl->settings && method_exists( $rl->settings, 'get_setting_fields' ) ) {
2395 $legacy_fields = $rl->settings->get_setting_fields( $default_gallery_key );
2396 if ( ! empty( $legacy_fields ) && is_array( $legacy_fields ) )
2397 $builder_gallery_fields = $legacy_fields;
2398 }
2399 if ( ! empty( $rl->options[$default_gallery_key] ) && is_array( $rl->options[$default_gallery_key] ) )
2400 $global_settings = $rl->options[$default_gallery_key];
2401
2402 // assign default values
2403 foreach ( $default_gallery as $field => $field_args ) {
2404 $defaults['default_gallery'][$field] = $field_args['default'];
2405 }
2406
2407 // valid gallery?
2408 if ( array_key_exists( $menu_item . '_gallery', $settings ) && array_key_exists( $menu_item . '_gallery', $defaults ) ) {
2409 if ( $menu_item === 'default' ) {
2410 $fields = $default_gallery_fields;
2411
2412 if ( ! empty( $builder_gallery_fields ) ) {
2413 $fields = $rl->frontend->get_unique_fields( $default_gallery_fields, $builder_gallery_fields );
2414
2415 foreach ( $defaults[$default_gallery_key] as $field => $default_value ) {
2416 if ( ! array_key_exists( $field, $defaults['default_gallery'] ) )
2417 $defaults['default_gallery'][$field] = $default_value;
2418 }
2419 }
2420
2421 $disabled_fields = array_diff_key( $fields, $default_gallery_fields );
2422
2423 if ( ! empty( $disabled_fields ) ) {
2424 $settings_menu = '';
2425 $settings_tab_label = '';
2426 $settings_section = '';
2427
2428 if ( ! empty( $rl->settings_api ) && method_exists( $rl->settings_api, 'get_pages' ) ) {
2429 $settings_pages = $rl->settings_api->get_pages();
2430 if ( ! empty( $settings_pages['settings'] ) ) {
2431 $settings_menu = ! empty( $settings_pages['settings']['menu_title'] ) ? $settings_pages['settings']['menu_title'] : '';
2432 if ( ! empty( $settings_pages['settings']['tabs']['gallery']['label'] ) )
2433 $settings_tab_label = $settings_pages['settings']['tabs']['gallery']['label'];
2434 }
2435 }
2436 if ( ! empty( $settings[$default_gallery_key]['sections'] ) && is_array( $settings[$default_gallery_key]['sections'] ) ) {
2437 $first_section = reset( $settings[$default_gallery_key]['sections'] );
2438 if ( ! empty( $first_section['title'] ) )
2439 $settings_section = $first_section['title'];
2440 }
2441
2442 if ( $settings_section === '' && ! empty( $this->tabs['config']['menu_items'][$default_gallery_type] ) )
2443 $settings_section = $this->tabs['config']['menu_items'][$default_gallery_type];
2444
2445 if ( $settings_section === '' )
2446 $settings_section = ucwords( str_replace( '_', ' ', $default_gallery_key ) );
2447
2448 $settings_url = admin_url( 'admin.php?page=responsive-lightbox-settings&tab=gallery' );
2449 if ( $settings_menu === '' )
2450 $settings_menu = __( 'Lightbox', 'responsive-lightbox' );
2451 if ( $settings_tab_label === '' )
2452 $settings_tab_label = __( 'Galleries', 'responsive-lightbox' );
2453
2454 $disabled_notice = '<tr class="rl-gallery-field-disabled-notice"><td colspan="2"><div class="rl-gallery-disabled-notice"><p>'
2455 . wp_kses_post( sprintf( __( 'Settings below are controlled globally in %1$s &rarr; %2$s &rarr; %3$s.', 'responsive-lightbox' ), esc_html( $settings_menu ), esc_html( $settings_tab_label ), esc_html( $settings_section ) ) )
2456 . '</p><a class="rl-gallery-disabled-notice-link" href="' . esc_url( $settings_url ) . '">'
2457 . esc_html( sprintf( __( 'Edit Global %s Settings ->', 'responsive-lightbox' ), $settings_section ) ) . '</a></div></td></tr>';
2458 }
2459 } else {
2460 $fields = $rl->frontend->get_unique_fields( $default_gallery_fields, $settings[$menu_item . '_gallery']['fields'] );
2461
2462 // add default gallery default values
2463 foreach ( $default_gallery as $field => $field_args ) {
2464 $defaults[$menu_item . '_gallery'][$field] = $field_args['default'];
2465 }
2466 }
2467
2468 foreach ( $fields as $field => $args ) {
2469 $is_disabled = ( $menu_item === 'default' && ! isset( $default_gallery_fields[$field] ) );
2470
2471 if ( $is_disabled && ! $disabled_notice_output && $disabled_notice !== '' ) {
2472 $html .= $disabled_notice;
2473 $disabled_notice_output = true;
2474 }
2475
2476 if ( $args['type'] === 'multiple' ) {
2477 $new_args = $args;
2478
2479 foreach ( $args['fields'] as $subfield => $subargs ) {
2480 $value = isset( $data[$menu_item], $data[$menu_item][$subfield] ) ? $data[$menu_item][$subfield] : $defaults[$menu_item . '_gallery'][$subfield];
2481
2482 if ( $is_disabled && isset( $global_settings[$subfield] ) )
2483 $value = $global_settings[$subfield];
2484
2485 $new_args['fields'][$subfield] = $subargs + array(
2486 'value' => $value,
2487 'default' => $defaults[$menu_item . '_gallery'][$subfield]
2488 );
2489 }
2490 } else {
2491 $value = isset( $data[$menu_item], $data[$menu_item][$field] ) ? $data[$menu_item][$field] : $defaults[$menu_item . '_gallery'][$field];
2492
2493 if ( $is_disabled && isset( $global_settings[$field] ) )
2494 $value = $global_settings[$field];
2495
2496 $new_args = $args + array(
2497 'value' => $value,
2498 'default' => $defaults[$menu_item . '_gallery'][$field]
2499 );
2500 }
2501
2502 if ( $is_disabled )
2503 $new_args['disabled'] = true;
2504
2505 $html .= $this->render_field( $field, $tab_id, $menu_item, $new_args, $gallery_id );
2506 }
2507 // just in case ajax would fail
2508 } else
2509 $html .= '<p>' . esc_html__( 'No data', 'responsive-lightbox' ) . '</p>';
2510 break;
2511
2512 default:
2513 foreach ( $this->fields[$tab_id][$menu_item] as $field => $args ) {
2514 // was this field stored in a database?
2515 if ( isset( $args['save'] ) && ! $args['save'] )
2516 $new_args = $args;
2517 elseif ( $args['type'] === 'multiple' ) {
2518 $new_args = $args;
2519
2520 foreach ( $args['fields'] as $subfield => $subargs ) {
2521 $new_args['fields'][$subfield] = $subargs + array( 'value' => isset( $data[$menu_item], $data[$menu_item][$subfield] ) ? $data[$menu_item][$subfield] : $subargs['default'] );
2522 }
2523 } else
2524 $new_args = $args + array( 'value' => isset( $data[$menu_item], $data[$menu_item][$field] ) ? $data[$menu_item][$field] : $args['default'] );
2525
2526 // media preview?
2527 // if ( $tab_id === 'images' && $menu_item === 'featured' && $field === 'attachments' && $args['type'] === 'media_preview' )
2528 // $new_args['subfields'] = $data['featured'];
2529
2530 $html .= $this->render_field( $field, $tab_id, $menu_item, $new_args, $gallery_id );
2531 }
2532 }
2533
2534 $html .= '
2535 </table>
2536 </div>';
2537
2538 return apply_filters( 'rl_gallery_tab_content', $html, $tab_id, $data, $menu_item );
2539 }
2540
2541 /**
2542 * Get gallery settings data from Settings API with legacy fallback.
2543 *
2544 * @return array
2545 */
2546 private function get_gallery_settings_data() {
2547 $settings = [];
2548 $settings_data = apply_filters( 'rl_settings_data', [] );
2549
2550 if ( is_array( $settings_data ) ) {
2551 foreach ( $settings_data as $setting_key => $setting ) {
2552 $fields = $this->get_settings_fields_from_data( $setting );
2553
2554 if ( ! empty( $fields ) ) {
2555 $settings[$setting_key]['fields'] = $fields;
2556 }
2557 }
2558 }
2559
2560 $rl = Responsive_Lightbox();
2561 $legacy_settings = isset( $rl->settings->settings ) && is_array( $rl->settings->settings ) ? $rl->settings->settings : [];
2562
2563 if ( empty( $settings ) )
2564 return $legacy_settings;
2565
2566 foreach ( $legacy_settings as $setting_key => $setting ) {
2567 if ( empty( $settings[$setting_key] ) && ! empty( $setting['fields'] ) ) {
2568 $settings[$setting_key] = $setting;
2569 }
2570 }
2571
2572 return $settings;
2573 }
2574
2575 /**
2576 * Extract fields from Settings API data.
2577 *
2578 * @param array $setting
2579 * @return array
2580 */
2581 private function get_settings_fields_from_data( $setting ) {
2582 $fields = [];
2583
2584 if ( ! empty( $setting['fields'] ) && is_array( $setting['fields'] ) ) {
2585 foreach ( $setting['fields'] as $field_key => $field ) {
2586 if ( $this->is_valid_gallery_field( $field ) )
2587 $fields[$field_key] = $field;
2588 }
2589 }
2590
2591 if ( ! empty( $setting['sections'] ) && is_array( $setting['sections'] ) ) {
2592 foreach ( $setting['sections'] as $section ) {
2593 if ( empty( $section['fields'] ) || ! is_array( $section['fields'] ) )
2594 continue;
2595
2596 foreach ( $section['fields'] as $field_key => $field ) {
2597 if ( isset( $fields[$field_key] ) )
2598 continue;
2599
2600 if ( $this->is_valid_gallery_field( $field ) )
2601 $fields[$field_key] = $field;
2602 }
2603 }
2604 }
2605
2606 return $fields;
2607 }
2608
2609 /**
2610 * Validate gallery field definition.
2611 *
2612 * @param mixed $field
2613 * @return bool
2614 */
2615 private function is_valid_gallery_field( $field ) {
2616 if ( ! is_array( $field ) )
2617 return false;
2618
2619 if ( empty( $field['type'] ) )
2620 return false;
2621
2622 if ( $field['type'] === 'multiple' && empty( $field['fields'] ) )
2623 return false;
2624
2625 return true;
2626 }
2627
2628 /**
2629 * Update number of gallery images when attachment is deleted.
2630 *
2631 * @param int $attachment_id
2632 * @return void
2633 */
2634 public function delete_attachment( $attachment_id ) {
2635 //@TODO
2636 }
2637
2638 /**
2639 * Get number of gallery images.
2640 *
2641 * @param int $gallery_id
2642 * @return int
2643 */
2644 public function get_gallery_images_number( $gallery_id ) {
2645 return count( $this->get_gallery_images( $gallery_id, [ 'count_images' => true, 'preview' => false, 'exclude' => true ] ) );
2646 }
2647
2648 /**
2649 * Get gallery images.
2650 *
2651 * @global string $pagenow
2652 *
2653 * @param int $gallery_id Gallery ID
2654 * @param array $args Gallery arguments
2655 * @return array
2656 */
2657 public function get_gallery_images( $gallery_id = 0, $args = [] ) {
2658 $images = [];
2659 $excluded = [];
2660
2661 // get main instance
2662 $rl = Responsive_Lightbox();
2663
2664 // get args
2665 $defaults = array(
2666 'count_images' => false,
2667 'exclude' => false,
2668 'posts_per_page' => -1,
2669 'images_per_page' => 0,
2670 'page' => 1,
2671 'limit' => 0,
2672 'nopaging' => true,
2673 'image_size' => 'large',
2674 'thumbnail_size' => 'thumbnail',
2675 'pagination_type' => 'paged',
2676 'pagination_position' => 'bottom',
2677 'orderby' => 'menu_order',
2678 'order' => 'asc',
2679 'preview' => is_admin(),
2680 'preview_type' => 'update',
2681 'preview_page' => 1,
2682 'preview_per_page' => 20,
2683 'taxonomy' => $rl->folders->get_active_taxonomy(),
2684 'folder' => array(
2685 'id' => 0,
2686 'children' => null // do not change!
2687 )
2688 );
2689
2690 // parse arguments
2691 $args = wp_parse_args( apply_filters( 'rl_get_gallery_images_args', $args, $gallery_id ), $defaults );
2692
2693 // disable counting mode
2694 if ( $args['preview'] )
2695 $args['count_images'] = false;
2696
2697 // sanitize args
2698 $args['exclude'] = (bool) ! empty( $args['exclude'] );
2699 $args['posts_per_page'] = ! empty( $args['posts_per_page'] ) ? (int) $args['posts_per_page'] : -1;
2700 $args['nopaging'] = (bool) ! empty( $args['nopaging'] );
2701
2702 // check gallery post type
2703 $valid_gallery_type = ( get_post_type( $gallery_id ) === 'rl_gallery' );
2704
2705 // is it rl_gallery? skip when counting mode is enabled
2706 if ( $valid_gallery_type && ! $args['count_images'] ) {
2707 $paging = get_post_meta( $gallery_id, '_rl_paging', true );
2708
2709 if ( isset( $paging['menu_item'] ) ) {
2710 $pagination = $paging[$paging['menu_item']];
2711
2712 if ( $pagination['pagination'] ) {
2713 $args['nopaging'] = false;
2714 $args['images_per_page'] = $pagination['images_per_page'];
2715 $args['pagination_type'] = $pagination['pagination_type'];
2716
2717 // infinite type?
2718 if ( $args['pagination_type'] === 'infinite' )
2719 $args['pagination_position'] = 'bottom';
2720 else
2721 $args['pagination_position'] = $pagination['pagination_position'];
2722 } else
2723 $args['nopaging'] = true;
2724 }
2725 }
2726
2727 global $pagenow;
2728
2729 // is it preview?
2730 if ( ( in_array( $pagenow, array( 'post.php', 'post-new.php' ), true ) && $gallery_id ) || ( isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-preview-content' ) || ( wp_doing_ajax() && isset( $_POST['action'] ) && ( $_POST['action'] === 'rl-post-gallery-preview' || $_POST['action'] === 'rl-get-menu-content' ) ) )
2731 $args['images_per_page'] = 0;
2732
2733 if ( isset( $_GET['rl_page'] ) )
2734 $args['page'] = (int) $_GET['rl_page'];
2735 else
2736 $args['page'] = (int) $args['page'];
2737
2738 // is it rl_gallery?
2739 if ( $valid_gallery_type ) {
2740 // no need order in counting mode
2741 if ( ! $args['count_images'] ) {
2742 // get config metadata
2743 $config_meta = get_post_meta( $gallery_id, '_rl_config', true );
2744
2745 // config order
2746 if ( isset( $config_meta['menu_item'] ) ) {
2747 $config = $config_meta[$config_meta['menu_item']];
2748
2749 $args['orderby'] = $config['orderby'];
2750 $args['order'] = $config['order'];
2751 }
2752 }
2753
2754 // get images metadata
2755 $data = get_post_meta( $gallery_id, '_rl_images', true );
2756
2757 // array?
2758 if ( ! is_array( $data ) )
2759 $data = [];
2760
2761 // get menu item
2762 if ( ! empty( $this->menu_item ) )
2763 $menu_item = $this->menu_item;
2764 elseif ( array_key_exists( 'menu_item', $data ) )
2765 $menu_item = $data['menu_item'];
2766 else
2767 $menu_item = 'media';
2768
2769 // valid data?
2770 if ( ! array_key_exists( $menu_item, $data ) )
2771 $data[$menu_item] = [];
2772
2773 if ( $args['preview'] && $this->fields['images'][$menu_item]['attachments']['preview']['pagination'] ) {
2774 if ( isset( $args['preview_page'] ) )
2775 $args['preview_page'] = (int) $args['preview_page'];
2776 else
2777 $args['preview_page'] = 1;
2778
2779 $args['preview_per_page'] = (int) $args['preview_per_page'];
2780 }
2781
2782 switch ( $menu_item ) {
2783 case 'media':
2784 // check embed data
2785 if ( ! empty( $data[$menu_item]['attachments']['embed'] ) ) {
2786 $atts_args = [
2787 'embed_keys' => array_keys( $data[$menu_item]['attachments']['embed'] ),
2788 'providers' => [ 'youtube', 'vimeo' ]
2789 ];
2790 } else
2791 $atts_args = [];
2792
2793 // get attachment ids
2794 $attachments = ! empty( $data[$menu_item]['attachments']['ids'] ) ? $this->check_attachments( array_unique( array_filter( $data[$menu_item]['attachments']['ids'] ) ), $atts_args ) : [];
2795
2796 // filter attachments
2797 $attachments = apply_filters( 'rl_get_gallery_images_attachments', $attachments, $atts_args );
2798
2799 // exclude any attachments?
2800 if ( $args['exclude'] && ! empty( $data[$menu_item]['attachments']['exclude'] ) )
2801 $attachments = array_diff( $attachments, $data[$menu_item]['attachments']['exclude'] );
2802
2803 // check filtered attachments
2804 $attachments = $this->check_attachments( $attachments, $atts_args );
2805
2806 // any attachments?
2807 if ( $attachments ) {
2808 if ( $args['limit'] )
2809 $counter = 0;
2810
2811 foreach ( $attachments as $attachment_id ) {
2812 // for counting mode get attachment id only
2813 if ( $args['count_images'] )
2814 $images[] = $attachment_id;
2815 else {
2816 // embed?
2817 if ( preg_match( '/^e\d+$/', $attachment_id ) === 1 ) {
2818 $attachment_data = $data[$menu_item]['attachments']['embed'][$attachment_id];
2819 $attachment_data['type'] = 'embed';
2820 } else
2821 $attachment_data = $attachment_id;
2822
2823 // get attachment image data
2824 $images[] = $this->get_gallery_image_src( $attachment_data, $args['image_size'], $args['thumbnail_size'] );
2825
2826 // limit attachments?
2827 if ( $args['limit'] ) {
2828 $counter++;
2829
2830 // limit reached?
2831 if ( $counter === $args['limit'] )
2832 break;
2833 }
2834 }
2835 }
2836 }
2837 break;
2838
2839 case 'featured':
2840 // only for featured frontend galleries
2841 if ( ! is_admin() || wp_doing_ajax() ) {
2842 // prepare featured fields
2843 $this->fields['images']['featured'] = $this->prepare_featured_fields( $this->fields['images']['featured'] );
2844 }
2845
2846 // copy arguments
2847 $query_args = $args;
2848
2849 // skip order for counting mode
2850 if ( ! $args['count_images'] ) {
2851 // prevent duplicating images order (config tab) with posts order (images tab), query will handle empty strings
2852 if ( array_key_exists( 'post_orderby', $args ) )
2853 $query_args['orderby'] = $args['post_orderby'];
2854 elseif ( array_key_exists( 'orderby', $data[$menu_item] ) )
2855 $query_args['orderby'] = $data[$menu_item]['orderby'];
2856 else
2857 $query_args['orderby'] = '';
2858
2859 if ( array_key_exists( 'post_order', $args ) )
2860 $query_args['order'] = $args['post_order'];
2861 elseif ( array_key_exists( 'order', $data[$menu_item] ) )
2862 $query_args['order'] = $data[$menu_item]['order'];
2863 else
2864 $query_args['order'] = '';
2865 }
2866
2867 // get attachment ids
2868 $attachments = $this->gallery_query( array_merge( $data[$menu_item], $query_args ) );
2869
2870 // filter attachments
2871 $attachments = apply_filters( 'rl_get_gallery_images_attachments', $attachments );
2872
2873 // exclude any attachments?
2874 if ( $args['exclude'] && ! empty( $data[$menu_item]['attachments']['exclude'] ) )
2875 $attachments = array_diff( $attachments, $data[$menu_item]['attachments']['exclude'] );
2876
2877 // any attachments?
2878 if ( $attachments ) {
2879 if ( $args['limit'] )
2880 $counter = 0;
2881
2882 foreach ( $attachments as $attachment_id ) {
2883 // real attachment?
2884 if ( ! wp_attachment_is_image( $attachment_id ) )
2885 continue;
2886
2887 // for counting mode get attachment id only
2888 if ( $args['count_images'] )
2889 $images[] = $attachment_id;
2890 else {
2891 // get attachment image data
2892 $images[] = $this->get_gallery_image_src( $attachment_id, $args['image_size'], $args['thumbnail_size'] );
2893
2894 // limit attachments?
2895 if ( $args['limit'] ) {
2896 $counter++;
2897
2898 // limit reached?
2899 if ( $counter === $args['limit'] )
2900 break;
2901 }
2902 }
2903 }
2904 }
2905 break;
2906
2907 case 'folders':
2908 // is folders active?
2909 if ( ! $rl->options['folders']['active'] )
2910 break;
2911
2912 if ( ! array_key_exists( 'folder', $data[$menu_item] ) )
2913 $data[$menu_item]['folder'] = $defaults['folder'];
2914
2915 // ajax requests
2916 if ( is_string( $args['folder']['id'] ) )
2917 $args['folder']['id'] = (int) $args['folder']['id'];
2918
2919 // not empty folder term id?
2920 if ( ! empty( $args['folder']['id'] ) ) {
2921 // get term
2922 $term = get_term( $args['folder']['id'], $args['taxonomy'] );
2923
2924 // valid term?
2925 if ( is_a( $term, 'WP_Term' ) )
2926 $folder_id = (int) $term->term_id;
2927 else
2928 $folder_id = (int) $data[$menu_item]['folder']['id'];
2929 } else {
2930 if ( isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-preview-content' )
2931 $folder_id = $args['folder']['id'];
2932 else
2933 $folder_id = (int) $data[$menu_item]['folder']['id'];
2934 }
2935
2936 if ( $folder_id >= 0 ) {
2937 $include_children = false;
2938
2939 // null means folder was not changed
2940 if ( $args['folder']['children'] === null ) {
2941 if ( array_key_exists( 'children', $data[$menu_item]['folder'] ) && $data[$menu_item]['folder']['children'] === true )
2942 $include_children = true;
2943 // overwritten by args
2944 } else {
2945 if ( is_string( $args['folder']['children'] ) ) {
2946 if ( $args['folder']['children'] === 'true' )
2947 $include_children = true;
2948 } elseif ( is_bool( $args['folder']['children'] ) ) {
2949 if ( $args['folder']['children'] )
2950 $include_children = true;
2951 }
2952 }
2953
2954 if ( $folder_id === 0 ) {
2955 if ( $include_children ) {
2956 $all_folders = get_terms(
2957 array(
2958 'taxonomy' => $args['taxonomy'],
2959 'hide_empty' => false,
2960 'fields' => 'ids',
2961 'hierarchical' => false,
2962 'number' => 0
2963 )
2964 );
2965
2966 $tax_query = array(
2967 array(
2968 'relation' => 'OR',
2969 array(
2970 'taxonomy' => $args['taxonomy'],
2971 'field' => 'term_id',
2972 'terms' => ( ! is_wp_error( $all_folders ) ) ? $all_folders : $folder_id,
2973 'include_children' => $include_children,
2974 'operator' => 'IN'
2975 ),
2976 array(
2977 'taxonomy' => $args['taxonomy'],
2978 'field' => 'term_id',
2979 'terms' => $folder_id,
2980 'include_children' => $include_children,
2981 'operator' => 'NOT EXISTS'
2982 )
2983 )
2984 );
2985 } else {
2986 $tax_query = array(
2987 array(
2988 'taxonomy' => $args['taxonomy'],
2989 'field' => 'term_id',
2990 'terms' => $folder_id,
2991 'include_children' => $include_children,
2992 'operator' => 'NOT EXISTS'
2993 )
2994 );
2995 }
2996 } else {
2997 $tax_query = array(
2998 array(
2999 'taxonomy' => $args['taxonomy'],
3000 'field' => 'term_id',
3001 'terms' => $folder_id,
3002 'include_children' => $include_children,
3003 'operator' => 'IN'
3004 )
3005 );
3006 }
3007
3008 // prepare query arguments
3009 $wp_query_args = array(
3010 'post_type' => 'attachment',
3011 'post_status' => 'inherit',
3012 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
3013 'nopaging' => true,
3014 'posts_per_page' => -1,
3015 'fields' => 'ids',
3016 'tax_query' => $tax_query
3017 );
3018
3019 // is it preview?
3020 if ( $args['preview'] ) {
3021 $wp_query_args['posts_per_page'] = $args['preview_per_page'];
3022 $wp_query_args['offset'] = ( $args['preview_page'] - 1 ) * $args['preview_per_page'];
3023 $wp_query_args['nopaging'] = false;
3024 }
3025
3026 // run query
3027 $query = new WP_Query( apply_filters( 'rl_folders_query_args', $wp_query_args ) );
3028
3029 // get attachment ids
3030 $attachments = $query->get_posts();
3031
3032 // valid attachments?
3033 if ( ! is_wp_error( $attachments ) ) {
3034 // cast ids to int
3035 $attachments = array_map( 'intval', $attachments );
3036
3037 // make sure to skip duplicates
3038 $attachments = array_unique( $attachments );
3039
3040 // filter attachments
3041 $attachments = apply_filters( 'rl_get_gallery_images_attachments', $attachments );
3042
3043 // exclude any attachments?
3044 if ( $args['exclude'] && ! empty( $data[$menu_item]['attachments']['exclude'] ) )
3045 $attachments = array_diff( $attachments, $data[$menu_item]['attachments']['exclude'] );
3046
3047 // any attachments?
3048 if ( $attachments ) {
3049 if ( $args['limit'] )
3050 $counter = 0;
3051
3052 foreach ( $attachments as $attachment_id ) {
3053 // real attachment?
3054 if ( ! wp_attachment_is_image( $attachment_id ) )
3055 continue;
3056
3057 // for counting mode get attachment id only
3058 if ( $args['count_images'] )
3059 $images[] = $attachment_id;
3060 else {
3061 // get attachment image data
3062 $images[] = $this->get_gallery_image_src( $attachment_id, $args['image_size'], $args['thumbnail_size'] );
3063
3064 // limit attachments?
3065 if ( $args['limit'] ) {
3066 $counter++;
3067
3068 // limit reached?
3069 if ( $counter === $args['limit'] )
3070 break;
3071 }
3072 }
3073 }
3074 }
3075 }
3076 }
3077 break;
3078
3079 case 'remote_library':
3080 // is remote library active?
3081 if ( ! $rl->options['remote_library']['active'] )
3082 break;
3083
3084 // no media search phrase?
3085 if ( ! isset( $args['media_search'] ) )
3086 $args['media_search'] = isset( $data[$menu_item]['media_search'] ) ? $data[$menu_item]['media_search'] : '';
3087
3088 // no media provider?
3089 if ( ! isset( $args['media_provider'] ) )
3090 $args['media_provider'] = isset( $data[$menu_item]['media_provider'] ) ? $data[$menu_item]['media_provider'] : 'all';
3091
3092 // get remote images
3093 $images = $rl->remote_library->get_remote_library_images( $args );
3094 break;
3095 }
3096 }
3097
3098 // skip order for counting mode
3099 if ( ! $args['count_images'] ) {
3100 // config sort order
3101 switch ( $args['orderby'] ) {
3102 case 'id':
3103 $sort = [];
3104
3105 foreach ( $images as $key => $image ) {
3106 // set sorting value
3107 $sort[$key] = $image['id'];
3108 }
3109
3110 // sort
3111 array_multisort( $sort, $args['order'] === 'asc' ? SORT_ASC : SORT_DESC, SORT_NUMERIC, $images );
3112 break;
3113
3114 case 'title':
3115 $sort = [];
3116
3117 if ( $valid_gallery_type ) {
3118 // get lightbox data
3119 $lightbox_meta = get_post_meta( $gallery_id, '_rl_lightbox', true );
3120
3121 // valid data?
3122 if ( isset( $lightbox_meta['menu_item'] ) )
3123 $title_arg = $lightbox_meta[$lightbox_meta['menu_item']]['lightbox_image_title'];
3124 else
3125 $title_arg = $rl->options['settings']['gallery_image_title'];
3126 } else
3127 $title_arg = $rl->options['settings']['gallery_image_title'];
3128
3129 $images_copy = $images;
3130
3131 foreach ( $images_copy as $key => $image ) {
3132 if ( $title_arg === 'global' )
3133 $images[$key]['title'] = $rl->frontend->get_attachment_title( $image['id'], $rl->options['settings']['gallery_image_title'] );
3134 elseif ( $title_arg === 'default' )
3135 $images[$key]['title'] = '';
3136 else
3137 $images[$key]['title'] = $rl->frontend->get_attachment_title( $image['id'], $title_arg );
3138
3139 // set sorting value
3140 $sort[$key] = function_exists( 'mb_strtolower' ) ? mb_strtolower( $images[$key]['title'] ) : strtolower( $images[$key]['title'] );
3141 }
3142
3143 // sort
3144 array_multisort( $sort, $args['order'] === 'asc' ? SORT_ASC : SORT_DESC, SORT_STRING, $images );
3145 break;
3146
3147 case 'post_date':
3148 $sort = [];
3149
3150 foreach ( $images as $key => $image ) {
3151 // set sorting value
3152 $sort[$key] = $image['date'];
3153 }
3154
3155 // sort
3156 array_multisort( $sort, $args['order'] === 'asc' ? SORT_ASC : SORT_DESC, $images );
3157 break;
3158
3159 case 'menu_order':
3160 // do nothing
3161 break;
3162
3163 case 'rand':
3164 shuffle( $images );
3165 break;
3166 }
3167 }
3168
3169 // filter images
3170 $images = apply_filters( 'rl_get_gallery_images_array', $images, $gallery_id, $args );
3171
3172 // count number of images
3173 $images_count = count( $images );
3174
3175 // no preview?
3176 if ( ! $args['preview'] && ! $args['count_images'] && $args['limit'] === 0 )
3177 update_post_meta( $gallery_id, '_rl_images_count', $images_count );
3178
3179 // images pagination?
3180 if ( $images && ! $args['nopaging'] && $args['images_per_page'] > 0 && ! $args['count_images'] ) {
3181 // get part of images
3182 $images = array_slice( $images, ( $args['page'] - 1 ) * $args['images_per_page'], $args['images_per_page'], true );
3183
3184 // pass gallery args
3185 $this->gallery_args = $args;
3186 $this->gallery_args['total'] = (int) ceil( $images_count / $args['images_per_page'] );
3187
3188 // remove actions to avoid issues with multiple galleries on single page
3189 remove_action( 'rl_before_gallery', [ $this, 'do_pagination' ], 10 );
3190 remove_action( 'rl_after_gallery', [ $this, 'do_pagination' ], 10 );
3191
3192 // pagination position
3193 if ( $args['pagination_position'] === 'top' )
3194 add_action( 'rl_before_gallery', [ $this, 'do_pagination' ], 10, 2 );
3195 elseif ( $args['pagination_position'] === 'bottom' )
3196 add_action( 'rl_after_gallery', [ $this, 'do_pagination' ], 10, 2 );
3197 else {
3198 add_action( 'rl_before_gallery', [ $this, 'do_pagination' ], 10, 2 );
3199 add_action( 'rl_after_gallery', [ $this, 'do_pagination' ], 10, 2 );
3200 }
3201 }
3202
3203 return apply_filters( 'rl_get_gallery_images', array_values( $images ), $gallery_id, $args );
3204 }
3205
3206 /**
3207 * Create gallery pagination.
3208 *
3209 * @global object $wp
3210 *
3211 * @param array $args
3212 * @param int $gallery_id
3213 * @return void
3214 */
3215 public function do_pagination( $args, $gallery_id ) {
3216 global $wp;
3217
3218 // get main instance
3219 $rl = Responsive_Lightbox();
3220
3221 // get current action
3222 $current_action = current_action();
3223
3224 if ( $current_action === 'rl_before_gallery' )
3225 $class = 'rl-pagination-top';
3226 elseif ( $current_action === 'rl_after_gallery' )
3227 $class = 'rl-pagination-bottom';
3228 else
3229 $class = '';
3230
3231 // set base arguments
3232 $base_args = [ 'rl_gallery_no' => $rl->frontend->get_data( 'gallery_no' ), 'rl_page' => '%#%' ];
3233
3234 if ( empty( $args['pagination_type'] ) )
3235 $args['pagination_type'] = 'paged';
3236
3237 // infinite scroll?
3238 if ( $args['pagination_type'] === 'infinite' )
3239 $base_args['rl_lightbox_script'] = $rl->get_data( 'current_script' );
3240
3241 echo
3242 '<div class="rl-pagination ' . esc_attr( $class ) . '"' . ( $args['pagination_type'] === 'infinite' ? ' data-button="' . esc_attr( $args['load_more'] ) . '"' : '' ) .'>' .
3243 paginate_links(
3244 [
3245 'format' => '?rl_page=%#%',
3246 'base' => add_query_arg( $base_args, $args['pagination_type'] !== 'paged' ? get_permalink( $gallery_id ) : home_url( $wp->request ) ),
3247 'total' => $this->gallery_args['total'],
3248 'current' => $this->gallery_args['page'],
3249 'show_all' => false,
3250 'end_size' => 1,
3251 'mid_size' => 2,
3252 'prev_next' => true,
3253 'prev_text' => esc_html__( '&laquo; Previous', 'responsive-lightbox' ),
3254 'next_text' => esc_html__( 'Next &raquo;', 'responsive-lightbox' ),
3255 'type' => 'plain',
3256 'add_args' => '',
3257 'add_fragment' => '',
3258 'before_page_number' => '',
3259 'after_page_number' => ''
3260 ]
3261 ) .
3262 '</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>' : '' );
3263 }
3264
3265 /**
3266 * Check whether is it valid gallery AJAX request (rl-get-gallery-page-content action).
3267 *
3268 * @return bool
3269 */
3270 public function gallery_ajax_verified() {
3271 return ( wp_doing_ajax() && isset( $_POST['action'], $_POST['gallery_id'], $_POST['gallery_no'], $_POST['page'], $_POST['nonce'], $_POST['preview'], $_POST['post_id'], $_POST['lightbox'] ) && $_POST['action'] === 'rl-get-gallery-page-content' && wp_verify_nonce( $_POST['nonce'], 'rl_nonce' ) );
3272 }
3273
3274 /**
3275 * Try to change lightbox in valid gallery AJAX request (rl-get-gallery-page-content action).
3276 *
3277 * @return void
3278 */
3279 public function maybe_change_lightbox() {
3280 // check whether is it valid gallery ajax request
3281 if ( $this->gallery_ajax_verified() ) {
3282 // set new lightbox script
3283 Responsive_Lightbox()->set_lightbox_script( sanitize_key( $_POST['lightbox'] ) );
3284 }
3285 }
3286
3287 /**
3288 * Get gallery page.
3289 *
3290 * @param array $args
3291 * @return void
3292 */
3293 public function get_gallery_page( $args ) {
3294 // check whether is it valid gallery ajax request
3295 if ( $this->gallery_ajax_verified() ) {
3296 // cast page number
3297 $_GET['rl_page'] = (int) $_POST['page'];
3298
3299 // check preview
3300 $preview = ( $_POST['preview'] === 'true' );
3301
3302 echo $this->gallery_shortcode(
3303 [
3304 'id' => (int) $_POST['gallery_id'],
3305 'gallery_no' => (int) $_POST['gallery_no'],
3306 'preview' => $preview
3307 ]
3308 );
3309 }
3310
3311 exit;
3312 }
3313
3314 /**
3315 * Generate gallery preview.
3316 *
3317 * @return void
3318 */
3319 public function post_gallery_preview() {
3320 // check data
3321 if ( ! isset( $_POST['post_id'], $_POST['gallery_id'], $_POST['nonce'], $_POST['page'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) )
3322 wp_send_json_error();
3323
3324 // check page
3325 $page = preg_replace( '/[^a-z-.]/i', '', $_POST['page'] );
3326
3327 // check page
3328 if ( ! in_array( $page, [ 'widgets.php', 'customize.php', 'post.php', 'post-new.php' ], true ) )
3329 wp_send_json_error();
3330
3331 // check edit_post capability
3332 if ( ( $page === 'post.php' || $page === 'post-new.php' ) && ! current_user_can( 'edit_post', (int) $_POST['post_id'] ) )
3333 wp_send_json_error();
3334
3335 // check edit_theme_options capability
3336 if ( ( $page === 'widgets.php' || $page === 'customize.php' ) && ! current_user_can( 'edit_theme_options' ) )
3337 wp_send_json_error();
3338
3339 // parse gallery id
3340 $gallery_id = (int) $_POST['gallery_id'];
3341
3342 // get gallery data
3343 $data = get_post_meta( $gallery_id, '_rl_images', true );
3344
3345 // prepare data
3346 $attachments = $exclude = [];
3347 $html = '';
3348
3349 // get images
3350 $images = $this->get_gallery_images(
3351 $gallery_id,
3352 [
3353 'exclude' => true,
3354 'limit' => 20
3355 ]
3356 );
3357
3358 // get number of images
3359 $images_count = (int) get_post_meta( $gallery_id, '_rl_images_count', true );
3360
3361 if ( ! empty( $images ) ) {
3362 foreach ( $images as $image ) {
3363 $html .= '
3364 <li tabindex="0" role="checkbox" aria-label="' . esc_attr( $image['title'] ) . '" aria-checked="true" data-id="' . esc_attr( $image['id'] ) . '" class="attachment selection selected rl-status-active">
3365 <div class="attachment-preview js--select-attachment type-image ' . esc_attr( $image['thumbnail_orientation'] ). '">
3366 <div class="thumbnail">
3367 <div class="centered">
3368 <img src="' . esc_url( $image['thumbnail_url'] ) . '" draggable="false" alt="" />
3369 </div>
3370 </div>
3371 </div>
3372 </li>';
3373 }
3374 }
3375
3376 // send attachments content
3377 wp_send_json_success(
3378 array(
3379 'attachments' => $html,
3380 'count' => esc_html( sprintf( _n( '%s image', '%s images', $images_count, 'responsive-lightbox' ), $images_count ) ),
3381 'edit_url' => current_user_can( 'edit_post', $gallery_id ) ? esc_url_raw( admin_url( 'post.php?post=' . $gallery_id . '&action=edit' ) ) : ''
3382 )
3383 );
3384 }
3385
3386 /**
3387 * Get all galleries.
3388 *
3389 * @return void
3390 */
3391 public function post_get_galleries() {
3392 // check data
3393 if ( ! isset( $_POST['post_id'], $_POST['search'], $_POST['nonce'], $_POST['page'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) )
3394 wp_send_json_error();
3395
3396 // check page
3397 $page = preg_replace( '/[^a-z-.]/i', '', $_POST['page'] );
3398
3399 // check page
3400 if ( ! in_array( $page, [ 'widgets.php', 'customize.php', 'post.php', 'post-new.php' ], true ) )
3401 wp_send_json_error();
3402
3403 // check edit_post capability
3404 if ( ( $page === 'post.php' || $page === 'post-new.php' ) && ! current_user_can( 'edit_post', (int) $_POST['post_id'] ) )
3405 wp_send_json_error();
3406
3407 // check edit_theme_options capability
3408 if ( ( $page === 'widgets.php' || $page === 'customize.php' ) && ! current_user_can( 'edit_theme_options' ) )
3409 wp_send_json_error();
3410
3411 $args = array(
3412 'post_type' => 'rl_gallery',
3413 'post_status' => 'publish',
3414 'nopaging' => true,
3415 'posts_per_page' => -1,
3416 'orderby' => 'title',
3417 'order' => 'ASC',
3418 'suppress_filters' => false,
3419 'no_found_rows' => true,
3420 'cache_results' => false
3421 );
3422
3423 // check category
3424 $category = isset( $_POST['category'] ) ? (int) $_POST['category'] : 0;
3425
3426 // specific category?
3427 if ( ! empty( $category ) ) {
3428 $args['tax_query'] = array(
3429 array(
3430 'taxonomy' => 'rl_category',
3431 'field' => 'term_id',
3432 'operator' => 'IN',
3433 'include_children' => false,
3434 'terms' => $category
3435 )
3436 );
3437 }
3438
3439 $search = wp_unslash( trim( $_POST['search'] ) );
3440
3441 if ( $search !== '' )
3442 $args['s'] = $search;
3443
3444 // get galleries
3445 $query = new WP_Query( $args );
3446
3447 $html = '';
3448 $ids = [];
3449
3450 // any galleries?
3451 if ( ! empty( $query->posts ) ) {
3452 foreach ( $query->posts as $gallery ) {
3453 // save gallery id
3454 $ids[] = (int) $gallery->ID;
3455
3456 // get featured image
3457 $featured = $this->get_featured_image_src( $gallery->ID );
3458
3459 if ( is_array( $featured ) && array_key_exists( 'url', $featured ) )
3460 $featured_image = $featured['url'];
3461 else
3462 $featured_image = '';
3463
3464 // get title
3465 $title = $gallery->post_title !== '' ? $gallery->post_title : esc_html__( '(no title)', 'responsive-gallery' );
3466
3467 $html .= '
3468 <li tabindex="0" role="checkbox" aria-label="' . esc_attr( $title ) . '" aria-checked="true" data-id="' . (int) $gallery->ID . '" class="attachment selection">
3469 <div class="attachment-preview js--select-attachment type-image ' . ( ! empty( $featured['thumbnail_orientation'] ) ? esc_attr( $featured['thumbnail_orientation'] ) : 'landscape' ) . '">
3470 <div class="thumbnail">
3471 <div class="centered" data-full-src="' . esc_url( $featured_image ) . '">
3472 ' . $this->get_featured_image( $gallery->ID, 'thumbnail' ) . '
3473 </div>
3474 <div class="filename">
3475 <div>' . esc_html( $title ) . '</div>
3476 </div>
3477 </div>
3478 </div>
3479 <button type="button" class="button-link check"><span class="media-modal-icon"></span><span class="screen-reader-text">' . esc_html__( 'Deselect', 'responsive-lightbox' ) . '</span></button>
3480 </li>';
3481 }
3482 }
3483
3484 // send galleries content
3485 wp_send_json_success(
3486 [
3487 'galleries' => $ids,
3488 'html' => $html
3489 ]
3490 );
3491 }
3492
3493 /**
3494 * Get gallery content based on request.
3495 *
3496 * @return void
3497 */
3498 public function get_menu_content() {
3499 if ( ! isset( $_POST['post_id'], $_POST['tab'], $_POST['menu_item'], $_POST['nonce'] ) || ! check_ajax_referer( 'rl-gallery', 'nonce', false ) )
3500 wp_send_json_error();
3501
3502 // check tab
3503 $tab = isset( $_POST['tab'] ) ? sanitize_key( $_POST['tab'] ) : '';
3504
3505 if ( ! array_key_exists( $tab, $this->tabs ) )
3506 wp_send_json_error();
3507
3508 // get post id
3509 $post_id = (int) $_POST['post_id'];
3510
3511 if ( ! current_user_can( 'edit_post', $post_id ) )
3512 wp_send_json_error();
3513
3514 // check menu item
3515 $menu_item = sanitize_key( $_POST['menu_item'] );
3516
3517 // get selected menu item
3518 $menu_item = ! empty( $menu_item ) && in_array( $menu_item, array_keys( $this->tabs[$tab]['menu_items'] ) ) ? $menu_item : key( $this->tabs[$tab]['menu_items'] );
3519
3520 // get tab content
3521 wp_send_json_success( $this->get_metabox_content( $tab, get_post_meta( $post_id, '_rl_' . $tab, true ), $menu_item, $post_id ) );
3522 }
3523
3524 /**
3525 * Get gallery preview content based on request.
3526 *
3527 * @return void
3528 */
3529 public function get_gallery_preview_content() {
3530 // initial checks
3531 if ( ! isset( $_POST['post_id'], $_POST['menu_item'], $_POST['nonce'], $_POST['preview_type'] ) || ! check_ajax_referer( 'rl-gallery', 'nonce', false ) )
3532 wp_send_json_error();
3533
3534 // cast gallery ID
3535 $post_id = (int) $_POST['post_id'];
3536
3537 // check user privileges
3538 if ( ! current_user_can( 'edit_post', $post_id ) || ! current_user_can( 'upload_files' ) )
3539 wp_send_json_error();
3540
3541 // get query args
3542 $args = ! empty( $_POST['query'] ) ? wp_unslash( $_POST['query'] ) : [];
3543
3544 // check orderby
3545 if ( array_key_exists( 'orderby', $args ) ) {
3546 $args['post_orderby'] = $args['orderby'];
3547
3548 unset( $args['orderby'] );
3549 }
3550
3551 // check order
3552 if ( array_key_exists( 'order', $args ) ) {
3553 $args['post_order'] = $args['order'];
3554
3555 unset( $args['order'] );
3556 }
3557
3558 // check preview type
3559 $preview_type = sanitize_key( $_POST['preview_type'] );
3560
3561 // check preview type
3562 if ( ! in_array( $preview_type, [ 'page', 'update' ], true ) )
3563 $args['preview_type'] = 'page';
3564 else
3565 $args['preview_type'] = $preview_type;
3566
3567 // check menu item
3568 $menu_item = sanitize_key( $_POST['menu_item'] );
3569
3570 // set images menu item
3571 $menu_item = $this->menu_item = ! empty( $menu_item ) && array_key_exists( $menu_item, $this->tabs['images']['menu_items'] ) ? $menu_item : 'media';
3572
3573 if ( $this->fields['images'][$menu_item]['attachments']['preview']['pagination'] ) {
3574 if ( isset( $args['preview_page'] ) )
3575 $args['preview_page'] = (int) $args['preview_page'];
3576 else
3577 $args['preview_page'] = 1;
3578 }
3579
3580 // get images
3581 $images = $this->get_gallery_images( $post_id, $args );
3582
3583 // prepare JSON array
3584 $data = [];
3585
3586 if ( $menu_item === 'remote_library' ) {
3587 // get main instance
3588 $rl = Responsive_Lightbox();
3589
3590 $response_data = [];
3591
3592 // single provider?
3593 if ( $args['media_provider'] !== 'all' ) {
3594 // get provider
3595 $provider = $rl->providers[$args['media_provider']];
3596
3597 // add response data arguments if needed
3598 if ( ! empty( $provider['response_args'] ) ) {
3599 $response = $provider['instance']->get_response_data();
3600
3601 foreach ( $provider['response_args'] as $arg ) {
3602 if ( array_key_exists( $arg, $response ) )
3603 $response_data[$provider['slug']][$arg] = base64_encode( wp_json_encode( $response[$arg] ) );
3604 }
3605 }
3606 } else {
3607 // get active providers
3608 $providers = $rl->remote_library->get_active_providers();
3609
3610 if ( ! empty( $providers ) ) {
3611 foreach ( $providers as $provider ) {
3612 // get provider
3613 $provider = $rl->providers[$provider];
3614
3615 // add response data arguments if needed
3616 if ( ! empty( $provider['response_args'] ) ) {
3617 $response = $provider['instance']->get_response_data();
3618
3619 foreach ( $provider['response_args'] as $arg ) {
3620 if ( array_key_exists( $arg, $response ) )
3621 $response_data[$provider['slug']][$arg] = base64_encode( wp_json_encode( $response[$arg] ) );
3622 }
3623 }
3624 }
3625 }
3626 }
3627
3628 $data['response_data'] = $response_data;
3629 }
3630
3631 // parse excluded images
3632 $excluded = ! empty( $_POST['excluded'] ) && is_array( $_POST['excluded'] ) ? array_map( 'intval', $_POST['excluded'] ) : [];
3633
3634 // get excluded images
3635 if ( ! empty( $excluded ) )
3636 $excluded = array_unique( array_filter( $excluded ) );
3637
3638 // get media item template
3639 $media_item_template = $this->get_media_item_template( $this->fields['images'][$menu_item]['attachments']['preview'] );
3640
3641 // build html
3642 $html = '';
3643
3644 // any images?
3645 if ( ! empty( $images ) ) {
3646 foreach ( $images as $image ) {
3647 // get image content html
3648 $html .= $this->get_gallery_preview_image_content( $image, 'images', $menu_item, 'attachments', $media_item_template, $excluded, $image['id'] );
3649 }
3650 }
3651
3652 $data['images'] = $html;
3653
3654 if ( $this->fields['images'][$menu_item]['attachments']['preview']['pagination'] )
3655 $data['pagination'] = $this->get_preview_pagination( $args['preview_page'] );
3656
3657 // send JSON
3658 wp_send_json_success( $data );
3659 }
3660
3661 /**
3662 * Get gallery preview image content HTML.
3663 *
3664 * @param array $image
3665 * @param string $tab_id
3666 * @param string $menu_item
3667 * @param string $field_name
3668 * @param string $template
3669 * @param array $excluded
3670 * @param string|int $excluded_item
3671 * @return string
3672 */
3673 public function get_gallery_preview_image_content( $image, $tab_id, $menu_item, $field_name, $template, $excluded, $excluded_item = '' ) {
3674 // set flag
3675 if ( empty( $excluded_item ) )
3676 $excluded_flag = false;
3677 else
3678 $excluded_flag = in_array( $excluded_item, $excluded, true );
3679
3680 if ( $image['type'] === 'embed' ) {
3681 // replace all embed data
3682 $media_html = str_replace(
3683 [
3684 '__EMBED_ID__',
3685 '__EMBED_URL__',
3686 '__EMBED_WIDTH__',
3687 '__EMBED_HEIGHT__',
3688 '__EMBED_THUMBNAIL_URL__',
3689 '__EMBED_THUMBNAIL_WIDTH__',
3690 '__EMBED_THUMBNAIL_HEIGHT__',
3691 '__EMBED_TITLE__',
3692 '__EMBED_DESCRIPTION__',
3693 '__EMBED_DATE__'
3694 ],
3695 [
3696 esc_attr( $image['id'] ),
3697 esc_url( $image['url'] ),
3698 (int) $image['width'],
3699 (int) $image['height'],
3700 esc_url( $image['thumbnail_url'] ),
3701 (int) $image['thumbnail_width'],
3702 (int) $image['thumbnail_height'],
3703 esc_attr( $image['title'] ),
3704 esc_textarea( $image['caption'] ),
3705 esc_attr( $image['date'] )
3706 ],
3707 $this->get_media_embed_template( false )
3708 );
3709 } else
3710 $media_html = '';
3711
3712 // replace id and url of an image
3713 return str_replace(
3714 [
3715 '__MEDIA_DATA__',
3716 '__MEDIA_ID__',
3717 '__MEDIA_STATUS__',
3718 '__MEDIA_TYPE__'
3719 ],
3720 [
3721 $this->get_media_exclude_input_template( $tab_id, $menu_item, $field_name, $excluded_flag ? $excluded_item : '' ) . $media_html . $image['thumbnail_link'],
3722 esc_attr( $image['id'] ),
3723 $excluded_flag ? ' rl-status-inactive' : ' rl-status-active',
3724 esc_attr( $image['type'] )
3725 ],
3726 $template
3727 );
3728 }
3729
3730 /**
3731 * Get gallery image link.
3732 *
3733 * @param array $image Image data
3734 * @param mixed $size Image size
3735 * @param array $attr Image attributes
3736 * @return string
3737 */
3738 public function get_gallery_image_link( $image, $size = 'thumbnail', $attr = [] ) {
3739 $link = '';
3740
3741 if ( $size === 'thumbnail' ) {
3742 $url = $image['thumbnail_url'];
3743 $width = $image['thumbnail_width'];
3744 $height = $image['thumbnail_height'];
3745 } else {
3746 $url = $image['url'];
3747 $width = $image['width'];
3748 $height = $image['height'];
3749 }
3750
3751 if ( ! empty( $image['url'] ) ) {
3752 $size_class = $size;
3753
3754 if ( is_array( $size_class ) )
3755 $size_class = join( 'x', $size_class );
3756
3757 // combine attributes
3758 $attr = wp_parse_args(
3759 $attr,
3760 array(
3761 'src' => $url,
3762 'class' => 'attachment-' . $size_class . ' size-' . $size_class . ' format-' . ( $height > $width ? 'portrait' : 'landscape' ),
3763 'alt' => $image['alt']
3764 )
3765 );
3766
3767 // apply filters if any
3768 $attr = apply_filters( 'rl_get_gallery_image_attributes', $attr, $image, $size );
3769
3770 // start link output
3771 $link = rtrim( '<img ' . image_hwstring( $width, $height ) );
3772
3773 // add attributes
3774 foreach ( $attr as $name => $value ) {
3775 $link .= ' ' . esc_attr( $name ) . '="' . ( $name === 'src' ? esc_url( $value ) : esc_attr( $value ) ) . '"';
3776 }
3777
3778 // end link output
3779 $link .= ' />';
3780 }
3781
3782 return apply_filters( 'rl_get_gallery_image_link', $link, $image, $size );
3783 }
3784
3785 /**
3786 * Get attachment image source.
3787 *
3788 * @param int|string|array $image Attachment ID, image URL or array of image data
3789 * @param string $image_size Image size
3790 * @param string $thumbnail_size Thumbnail size
3791 * @return array
3792 */
3793 public function get_gallery_image_src( $image, $image_size = 'large', $thumbnail_size = 'thumbnail' ) {
3794 $imagedata = [];
3795
3796 // check difference in size between image and thumbnail
3797 $diff_sizes = $thumbnail_size !== $image_size;
3798
3799 // attachment id?
3800 if ( is_int( $image ) ) {
3801 if ( $image ) {
3802 $type = 'image';
3803 $width = 0;
3804 $height = 0;
3805
3806 // image src
3807 if ( wp_attachment_is_image( $image ) ) {
3808 $image_src = wp_get_attachment_image_src( $image, $image_size, false );
3809
3810 // different image and thumbnail sizes?
3811 if ( $diff_sizes )
3812 $thumbnail_src = wp_get_attachment_image_src( $image, $thumbnail_size, false );
3813 else
3814 $thumbnail_src = $image_src;
3815
3816 $file_url = $image_src[0];
3817 $width = $image_src[1];
3818 $height = $image_src[2];
3819 $thumbnail_url = $thumbnail_src[0];
3820 $thumbnail_width = $thumbnail_src[1];
3821 $thumbnail_height = $thumbnail_src[2];
3822 // video, blank thumbnail src
3823 } elseif ( rl_current_lightbox_supports( 'video' ) && wp_attachment_is( 'video', $image ) ) {
3824 $type = 'video';
3825 $thumbnail_id = $this->get_video_thumbnail_id( $image );
3826 $thumbnail_src = wp_get_attachment_image_src( $thumbnail_id, $image_size, false );
3827
3828 // get video metadata
3829 $meta = wp_get_attachment_metadata( $image );
3830
3831 if ( $meta ) {
3832 $width = $meta['width'];
3833 $height = $meta['height'];
3834 } else {
3835 $width = $thumbnail_src[1];
3836 $height = $thumbnail_src[2];
3837 }
3838
3839 // different image and thumbnail sizes?
3840 if ( $diff_sizes )
3841 $thumbnail_src = wp_get_attachment_image_src( $thumbnail_id, $thumbnail_size, false );
3842
3843 // file url
3844 $file_url = wp_get_attachment_url( $image );
3845 $thumbnail_url = $thumbnail_src[0];
3846 $thumbnail_width = $thumbnail_src[1];
3847 $thumbnail_height = $thumbnail_src[2];
3848 }
3849
3850 // get alternative text
3851 $alt = get_post_meta( $image, '_wp_attachment_image_alt', true );
3852
3853 // allow only strings
3854 if ( ! is_string( $alt ) )
3855 $alt = '';
3856
3857 $imagedata = array(
3858 'id' => $image,
3859 'title' => get_the_title( $image ),
3860 'date' => get_the_date( 'Y-m-d H:i:s', $image ),
3861 'caption' => '',
3862 'alt' => $alt,
3863 'url' => $file_url, // $image_src[0],
3864 'width' => $width,
3865 'height' => $height,
3866 'orientation' => $height > $width ? 'portrait' : 'landscape',
3867 'thumbnail_url' => $thumbnail_url,
3868 'thumbnail_width' => $thumbnail_width,
3869 'thumbnail_height' => $thumbnail_height,
3870 'type' => $type
3871 );
3872
3873 if ( $diff_sizes )
3874 $imagedata['thumbnail_orientation'] = $thumbnail_src[2] > $thumbnail_src[1] ? 'portrait' : 'landscape';
3875 else
3876 $imagedata['thumbnail_orientation'] = $imagedata['orientation'];
3877 }
3878 // image url
3879 } elseif ( is_string( $image ) ) {
3880 $imagedata['url'] = $image;
3881
3882 @list( $imagedata['width'], $imagedata['height'] ) = rl_get_image_size_by_url( $imagedata['url'] );
3883
3884 $imagedata = array(
3885 'id' => 0,
3886 'title' => '',
3887 'date' => '',
3888 'caption' => '',
3889 'alt' => '',
3890 'url' => $imagedata['url'],
3891 'width' => $imagedata['width'],
3892 'height' => $imagedata['height'],
3893 'orientation' => $imagedata['height'] > $imagedata['width'] ? 'portrait' : 'landscape',
3894 'thumbnail_url' => $imagedata['url'],
3895 'thumbnail_width' => $imagedata['width'],
3896 'thumbnail_height' => $imagedata['height'],
3897 'type' => 'image'
3898 );
3899
3900 $imagedata['thumbnail_orientation'] = $imagedata['orientation'];
3901 // full image array
3902 } elseif ( is_array( $image ) ) {
3903 // set width and height from url, if not available
3904 if ( empty( $image['width'] ) || empty( $image['height'] ) )
3905 @list( $image['width'], $image['height'] ) = rl_get_image_size_by_url( $image['url'] );
3906
3907 // set thumbnail data, if not available
3908 if ( empty( $image['thumbnail_url'] ) ) {
3909 $image['thumbnail_url'] = $image['url'];
3910 $image['thumbnail_width'] = $image['width'];
3911 $image['thumbnail_height'] = $image['height'];
3912 } else {
3913 // set thumbnail width and height from url, if not available
3914 if ( empty( $image['thumbnail_width'] ) || empty( $image['thumbnail_height'] ) )
3915 @list( $image['thumbnail_width'], $image['thumbnail_height'] ) = rl_get_image_size_by_url( $image['thumbnail_url'] );
3916 }
3917
3918 $imagedata = array(
3919 'id' => ! empty( $image['id'] ) ? ( preg_match( '/^e\d+$/', $image['id'] ) === 1 ? $image['id'] : (int) $image['id'] ) : 0,
3920 'title' => ! empty( $image['title'] ) ? ( $image['title'] ) : '',
3921 'date' => ! empty( $image['date'] ) ? ( $image['date'] ) : '',
3922 'caption' => ! empty( $image['caption'] ) ? ( $image['caption'] ) : '',
3923 'alt' => ! empty( $image['alt'] ) ? ( $image['alt'] ) : '',
3924 'url' => ! empty( $image['url'] ) ? esc_url_raw( $image['url'] ) : '',
3925 'width' => ! empty( $image['width'] ) ? (int) $image['width'] : 0,
3926 'height' => ! empty( $image['height'] ) ? (int) $image['height'] : 0,
3927 'thumbnail_url' => ! empty( $image['thumbnail_url'] ) ? esc_url_raw( $image['thumbnail_url'] ) : '',
3928 'thumbnail_width' => ! empty( $image['thumbnail_width'] ) ? (int) $image['thumbnail_width'] : 0,
3929 'thumbnail_height' => ! empty( $image['thumbnail_height'] ) ? (int) $image['thumbnail_height'] : 0,
3930 'link' => ! empty( $image['link'] ) ? esc_url_raw( $image['link'] ) : '',
3931 'thumbnail_link' => ! empty( $image['thumbnail_link'] ) ? esc_url_raw( $image['thumbnail_link'] ) : '',
3932 'type' => ! empty( $image['type'] ) ? ( $image['type'] ) : 'image'
3933 );
3934
3935 $imagedata['orientation'] = $imagedata['height'] > $imagedata['width'] ? 'portrait' : 'landscape';
3936 $imagedata['thumbnail_orientation'] = $imagedata['thumbnail_height'] > $imagedata['thumbnail_width'] ? 'portrait' : 'landscape';
3937 }
3938
3939 if ( ! empty( $imagedata ) ) {
3940 // link does not exist?
3941 if ( empty( $imagedata['link'] ) )
3942 $imagedata['link'] = $this->get_gallery_image_link( $imagedata, $image_size );
3943
3944 // thumbnail link does not exist?
3945 if ( empty( $imagedata['thumbnail_link'] ) ) {
3946 // different image and thumbnail sizes?
3947 if ( $diff_sizes )
3948 $imagedata['thumbnail_link'] = $this->get_gallery_image_link( $imagedata, $thumbnail_size );
3949 else
3950 $imagedata['thumbnail_link'] = $imagedata['link'];
3951 }
3952 }
3953
3954 return apply_filters( 'rl_get_gallery_image_src', $imagedata, $image, $image_size, $thumbnail_size );
3955 }
3956
3957 /**
3958 * Get gallery featured image.
3959 *
3960 * @param int $gallery_id
3961 * @param string $size Image size
3962 * @param array $attr Image attributes
3963 * @return string
3964 */
3965 public function get_featured_image( $gallery_id, $size = 'thumbnail', $attr = [] ) {
3966 $image = $this->get_featured_image_src( $gallery_id );
3967 $html = '';
3968
3969 if ( $image )
3970 $html = $this->get_gallery_image_link( $this->get_gallery_image_src( $image, 'large', $size ), $size, $attr );
3971
3972 return apply_filters( 'rl_get_featured_image', $html, $gallery_id, $size );
3973 }
3974
3975 /**
3976 * Get gallery featured image data.
3977 *
3978 * @param int $gallery_id
3979 * @return array
3980 */
3981 public function get_featured_image_src( $gallery_id ) {
3982 // get featured image data
3983 $featured_image_type = get_post_meta( $gallery_id, '_rl_featured_image_type', true );
3984 $featured_image = get_post_meta( $gallery_id, '_rl_featured_image', true );
3985
3986 switch ( $featured_image_type ) {
3987 // custom url
3988 case 'url':
3989 $frontend = function_exists( 'Responsive_Lightbox' ) ? Responsive_Lightbox()->frontend : null;
3990 if ( $frontend && method_exists( $frontend, 'sanitize_remote_image_url' ) )
3991 $featured_image = $frontend->sanitize_remote_image_url( $featured_image );
3992 else
3993 $featured_image = '';
3994
3995 if ( $featured_image !== '' ) {
3996 $image = esc_url( $featured_image );
3997 break;
3998 }
3999
4000 $image = $this->get_first_gallery_featured_image( $gallery_id );
4001 break;
4002
4003 // attachment id
4004 case 'id':
4005 $featured_image = (int) $featured_image;
4006 $image = wp_attachment_is_image( $featured_image ) ? $featured_image : $this->maybe_generate_thumbnail();
4007 break;
4008
4009 // first image
4010 case 'image':
4011 default:
4012 $image = $this->get_first_gallery_featured_image( $gallery_id );
4013 }
4014
4015 return apply_filters( 'rl_get_featured_image_src', $image, $gallery_id, $featured_image_type, $featured_image );
4016 }
4017
4018 /**
4019 * Helper to fetch the first gallery image data.
4020 *
4021 * @param int $gallery_id
4022 * @return array|int
4023 */
4024 protected function get_first_gallery_featured_image( $gallery_id ) {
4025 $images = $this->get_gallery_images(
4026 $gallery_id,
4027 [
4028 'exclude' => true,
4029 'limit' => 1
4030 ]
4031 );
4032
4033 if ( $images )
4034 return reset( $images );
4035
4036 return 0;
4037 }
4038
4039 /**
4040 * Get featured gallery attachments.
4041 *
4042 * @param array $args
4043 * @return array
4044 */
4045 public function gallery_query( $args ) {
4046 $attachments = [];
4047
4048 // get fields
4049 $fields = $this->fields['images']['featured'];
4050
4051 // force these settings
4052 $args['fields'] = 'ids';
4053 $args['tax_query'] = [];
4054 $args['meta_query'] = [];
4055 $args['author__in'] = [];
4056 $args['post_parent__in'] = [];
4057
4058 // get image source
4059 $args['image_source'] = isset( $args['image_source'] ) && array_key_exists( $args['image_source'], $fields['image_source']['options'] ) ? $args['image_source'] : $fields['image_source']['default'];
4060
4061 // get images per post
4062 $args['images_per_post'] = isset( $args['images_per_post'] ) ? absint( $args['images_per_post'] ) : $fields['images_per_post']['default'];
4063
4064 // get number of posts
4065 $args['number_of_posts'] = isset( $args['number_of_posts'] ) ? (int) $args['number_of_posts'] : $fields['number_of_posts']['default'];
4066
4067 // get all posts?
4068 if ( $args['number_of_posts'] <= 0 )
4069 $args['number_of_posts'] = -1;
4070
4071 // convert to wp query arg
4072 $args['posts_per_page'] = $args['number_of_posts'];
4073
4074 $args['order'] = isset( $args['order'] ) && array_key_exists( $args['order'], $fields['order']['options'] ) ? $args['order'] : $fields['order']['default'];
4075 $args['orderby'] = isset( $args['orderby'] ) && array_key_exists( $args['orderby'], $fields['orderby']['options'] ) ? $args['orderby'] : $fields['orderby']['default'];
4076 $args['offset'] = isset( $args['offset'] ) ? absint( $args['offset'] ) : 0;
4077
4078 $tax_queries = array(
4079 'post_format' => [],
4080 'post_term' => []
4081 );
4082
4083 $meta_queries = array(
4084 'page_template' => [],
4085 'image_source' => []
4086 );
4087
4088 // post type
4089 if ( ! empty( $args['post_type'] ) ) {
4090 // assign post types
4091 $post_types = $args['post_type'];
4092
4093 // clear post types
4094 $args['post_type'] = [];
4095
4096 foreach ( $post_types as $post_type ) {
4097 if ( array_key_exists( $post_type, $fields['post_type']['options'] ) )
4098 $args['post_type'][] = $post_type;
4099 }
4100 } else
4101 $args['post_type'] = $this->get_post_types( true );
4102
4103 // post status
4104 if ( ! empty( $args['post_status'] ) ) {
4105 // assign post statuses
4106 $post_statuses = $args['post_status'];
4107
4108 // clear post statuses
4109 $args['post_status'] = [];
4110
4111 foreach ( $post_statuses as $post_status ) {
4112 if ( array_key_exists( $post_status, $fields['post_status']['options'] ) )
4113 $args['post_status'][] = $post_status;
4114 }
4115 }
4116
4117 // post format
4118 if ( ! empty( $args['post_format'] ) ) {
4119 // assign post formats
4120 $post_formats = $args['post_format'];
4121
4122 foreach ( $post_formats as $post_format ) {
4123 if ( array_key_exists( $post_format, $fields['post_format']['options'] ) ) {
4124 // standard format?
4125 if ( $post_format === 'standard' ) {
4126 $tax_queries['post_format'][] = array(
4127 'relation' => 'OR',
4128 array(
4129 'taxonomy' => 'post_format',
4130 'field' => 'slug',
4131 'terms' => array( 'post-format-standard' )
4132 ),
4133 array(
4134 'taxonomy' => 'post_format',
4135 'field' => 'slug',
4136 'operator' => 'NOT EXISTS'
4137 )
4138 );
4139 } else {
4140 $tax_queries['post_format'][] = array(
4141 'taxonomy' => 'post_format',
4142 'field' => 'slug',
4143 'terms' => array( 'post-format-' . $post_format )
4144 );
4145 }
4146 }
4147 }
4148
4149 unset( $args['post_format'] );
4150 }
4151
4152 // page template
4153 if ( ! empty( $args['page_template'] ) ) {
4154 foreach ( $args['page_template'] as $page_template ) {
4155 if ( array_key_exists( $page_template, $fields['page_template']['options'] ) ) {
4156 if ( $page_template === 'default' ) {
4157 $meta_queries['page_template'][] = array(
4158 'relation' => 'OR',
4159 array(
4160 'key' => '_wp_page_template',
4161 'value' => 'default'
4162 ),
4163 array(
4164 'key' => '_wp_page_template',
4165 'value' => ''
4166 ),
4167 array(
4168 'key' => '_wp_page_template',
4169 'compare' => 'NOT EXISTS'
4170 )
4171 );
4172 } else {
4173 $meta_queries['page_template'][] = array(
4174 'key' => '_wp_page_template',
4175 'value' => $page_template
4176 );
4177 }
4178 }
4179 }
4180 }
4181
4182 // post author
4183 if ( ! empty( $args['post_author'] ) ) {
4184 foreach ( $args['post_author'] as $post_author ) {
4185 if ( array_key_exists( $post_author, $fields['post_author']['options'] ) )
4186 $args['author__in'][] = $post_author;
4187 }
4188 }
4189
4190 // page parent
4191 if ( ! empty( $args['page_parent'] ) ) {
4192 foreach ( $args['page_parent'] as $page_parent ) {
4193 if ( array_key_exists( $page_parent, $fields['page_parent']['options'] ) )
4194 $args['post_parent__in'][] = $page_parent;
4195 }
4196 }
4197
4198 // post term
4199 if ( ! empty( $args['post_term'] ) ) {
4200 $terms = [];
4201
4202 // get all terms
4203 if ( ! empty( $fields['post_term']['options'] ) ) {
4204 foreach ( $fields['post_term']['options'] as $tax => $data ) {
4205 $terms = array_merge( $terms, array_map( 'intval', array_keys( $data['terms'] ) ) );
4206 }
4207 }
4208
4209 foreach ( $args['post_term'] as $post_term ) {
4210 if ( in_array( $post_term, $terms ) ) {
4211 $term = get_term( $post_term );
4212
4213 $tax_queries['post_term'][] = array(
4214 'taxonomy' => $term->taxonomy,
4215 'field' => 'term_id',
4216 'terms' => (int) $post_term
4217 );
4218 }
4219 }
4220 }
4221
4222 switch ( $args['image_source'] ) {
4223 case 'thumbnails':
4224 $meta_queries['image_source'][] = array(
4225 'relation' => 'OR',
4226 array(
4227 'key' => '_thumbnail_id',
4228 'compare' => 'EXISTS'
4229 )
4230 );
4231 }
4232
4233 // any tax queries?
4234 if ( ! empty( $tax_queries['post_term'] ) || ! empty( $tax_queries['post_format'] ) ) {
4235 $args['tax_query'] = array( 'relation' => 'AND' );
4236
4237 if ( ! empty( $tax_queries['post_term'] ) )
4238 $args['tax_query'][] = array( 'relation' => 'OR' ) + $tax_queries['post_term'];
4239
4240 if ( ! empty( $tax_queries['post_format'] ) )
4241 $args['tax_query'][] = array( 'relation' => 'OR' ) + $tax_queries['post_format'];
4242 }
4243
4244 // any tax queries?
4245 if ( ! empty( $meta_queries['page_template'] ) || ! empty( $meta_queries['image_source'] ) ) {
4246 $args['meta_query'] = array( 'relation' => 'AND' );
4247
4248 if ( ! empty( $meta_queries['page_template'] ) )
4249 $args['meta_query'][] = array( 'relation' => 'OR', $meta_queries['page_template'] );
4250
4251 if ( ! empty( $meta_queries['image_source'] ) )
4252 $args['meta_query'][] = array( 'relation' => 'OR', $meta_queries['image_source'] );
4253 }
4254
4255 // get posts
4256 $query = new WP_Query( apply_filters( 'rl_gallery_query_args', $args ) );
4257
4258 // get attachments
4259 if ( $query->have_posts() )
4260 $attachments = $this->get_gallery_query_attachments( $query->posts, $args );
4261
4262 return $attachments;
4263 }
4264
4265 /**
4266 * Get query attachments.
4267 *
4268 * @param array $posts Post IDs, array or objects
4269 * @param array $args Additional arguments
4270 * @return array
4271 */
4272 public function get_gallery_query_attachments( $posts, $args ) {
4273 $attachments = [];
4274
4275 // any posts?
4276 if ( ! empty( $posts ) ) {
4277 switch ( $args['image_source'] ) {
4278 case 'thumbnails':
4279 $nop = count( $posts ) - 1;
4280
4281 foreach ( $posts as $number => $post_id ) {
4282 $attachment_id = (int) get_post_thumbnail_id( $post_id );
4283
4284 // real attachment?
4285 if ( wp_attachment_is_image( $attachment_id ) )
4286 $attachments[] = $attachment_id;
4287 else
4288 continue;
4289
4290 if ( $args['preview'] ) {
4291 $attachments = array_unique( $attachments );
4292 $noa = count( $attachments );
4293
4294 if ( ( $noa >= ( $args['preview_per_page'] * $args['preview_page'] ) ) || $nop === $number ) {
4295 $attachments = array_slice( $attachments, ( $args['preview_page'] - 1 ) * $args['preview_per_page'], $args['preview_per_page'], false );
4296
4297 break;
4298 }
4299 }
4300 }
4301 break;
4302
4303 case 'attached_images':
4304 $nop = count( $posts ) - 1;
4305
4306 foreach ( $posts as $number => $post_id ) {
4307 // get attached images, do not use get_attached_media here!
4308 $attachment_ids = (array) get_children(
4309 array(
4310 'post_parent' => $post_id,
4311 'post_status' => 'inherit',
4312 'post_type' => 'attachment',
4313 'post_mime_type' => 'image',
4314 'posts_per_page' => $args['images_per_post'],
4315 'order' => 'ASC',
4316 'orderby' => 'menu_order',
4317 'nopaging' => false,
4318 'page' => 1,
4319 'fields' => 'ids'
4320 )
4321 );
4322
4323 if ( $attachment_ids ) {
4324 foreach ( $attachment_ids as $attachment_id ) {
4325 if ( ! empty( $attachment_id ) ) {
4326 $attachments[] = $attachment_id;
4327 }
4328 }
4329 }
4330
4331 if ( $args['preview'] ) {
4332 $attachments = array_unique( $attachments );
4333 $noa = count( $attachments );
4334
4335 if ( ( $noa >= ( $args['preview_per_page'] * $args['preview_page'] ) ) || $nop === $number ) {
4336 $attachments = array_slice( $attachments, ( $args['preview_page'] - 1 ) * $args['preview_per_page'], $args['preview_per_page'], false );
4337
4338 break;
4339 }
4340 }
4341 }
4342 }
4343 }
4344
4345 return apply_filters( 'rl_get_gallery_query_attachments', array_unique( $attachments ), $posts, $args );
4346 }
4347
4348 /**
4349 * Load featured content query args.
4350 *
4351 * @global string $pagenow
4352 *
4353 * @return void
4354 */
4355 public function init_admin() {
4356 global $pagenow;
4357
4358 // check values
4359 $post = isset( $_GET['post'] ) ? (int) $_GET['post'] : 0;
4360 $post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0;
4361 $action = isset( $_POST['action'] ) ? sanitize_key( $_POST['action'] ) : '';
4362 $post_type = isset( $_POST['post_type'] ) ? sanitize_key( $_POST['post_type'] ) : '';
4363
4364 // prepare query arguments if needed
4365 if ( ( $pagenow === 'post.php' && ( ( $post && get_post_type( $post ) === 'rl_gallery' ) || ( $post_id && get_post_type( $post_id ) === 'rl_gallery' ) ) ) || ( in_array( $pagenow, array( 'edit.php', 'post-new.php'), true ) && $post_type === 'rl_gallery' ) || ( $pagenow === 'admin-ajax.php' && $action && in_array( $action, array( 'rl-get-preview-content', 'rl-post-gallery-preview', 'rl-get-menu-content' ), true ) ) )
4366 $this->fields['images']['featured'] = $this->prepare_featured_fields( $this->fields['images']['featured'] );
4367
4368 // add default thumbnail image if needed
4369 if ( Responsive_Lightbox()->options['builder']['gallery_builder'] && $pagenow === 'edit.php' && $post_type && $post_type === 'rl_gallery' )
4370 $this->maybe_generate_thumbnail();
4371 }
4372
4373 /**
4374 * Generate post thumbnail replacement.
4375 *
4376 * @return int
4377 */
4378 public function maybe_generate_thumbnail() {
4379 // get old attachment
4380 $thumbnail_id = get_posts(
4381 array(
4382 'name' => 'responsive-lightbox-thumbnail',
4383 'post_type' => 'attachment',
4384 'post_status' => 'inherit',
4385 'numberposts' => 1,
4386 'fields' => 'ids'
4387 )
4388 );
4389
4390 // no attachment?
4391 if ( empty( $thumbnail_id ) ) {
4392 // get new attachment
4393 $thumbnail_id = get_posts(
4394 array(
4395 'name' => 'responsive-lightbox-thumbnail',
4396 'post_type' => 'attachment',
4397 'post_status' => 'pending',
4398 'numberposts' => 1,
4399 'fields' => 'ids'
4400 )
4401 );
4402
4403 // no attachment?
4404 if ( empty( $thumbnail_id ) ) {
4405 // get upload directory data
4406 $wp_upload_dir = wp_upload_dir();
4407
4408 // get file path
4409 $filepath = str_replace( '\\', '/', RESPONSIVE_LIGHTBOX_PATH . 'images/responsive-lightbox-thumbnail.png' );
4410
4411 // get file name
4412 $filename = basename( $filepath );
4413
4414 // new filepath in upload dir
4415 $new_filepath = $wp_upload_dir['path'] . '/' . $filename;
4416
4417 // copty file to upload dir
4418 copy( $filepath, $new_filepath );
4419
4420 // get type of file
4421 $filetype = wp_check_filetype( $filename );
4422
4423 // force pending status for the attachment
4424 add_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
4425
4426 // insert attachment
4427 $thumbnail_id = wp_insert_attachment(
4428 array(
4429 'guid' => $wp_upload_dir['url'] . '/' . $filename,
4430 'post_mime_type' => $filetype['type'],
4431 'post_title' => preg_replace( '/\.[^.]+$/', '', $filename ),
4432 'post_content' => '',
4433 'post_parent' => 0,
4434 'post_status' => 'inherit'
4435 ),
4436 $new_filepath,
4437 0
4438 );
4439
4440 remove_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
4441
4442 // success?
4443 if ( $thumbnail_id ) {
4444 // make sure that this file is included
4445 require_once( ABSPATH . 'wp-admin/includes/image.php' );
4446
4447 // update database with generated metadata for the attachment
4448 wp_update_attachment_metadata( $thumbnail_id, wp_generate_attachment_metadata( $thumbnail_id, $new_filepath ) );
4449 }
4450 } else
4451 $thumbnail_id = $thumbnail_id[0];
4452 } else {
4453 // force pending status for the attachment
4454 add_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
4455
4456 $thumbnail_id = wp_update_post(
4457 array(
4458 'ID' => $thumbnail_id[0],
4459 'post_status' => 'pending'
4460 )
4461 );
4462
4463 remove_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
4464 }
4465
4466 return (int) $thumbnail_id;
4467 }
4468
4469 /**
4470 * Get video thumbnail replacement.
4471 *
4472 * @param int $post_id
4473 * @return int
4474 */
4475 public function get_video_thumbnail_id( $post_id ) {
4476 $thumbnail_id = 0;
4477
4478 // try to get video thumbnail
4479 $attachment_id = (int) get_post_thumbnail_id( $post_id );
4480
4481 // real attachment?
4482 if ( wp_attachment_is_image( $attachment_id ) )
4483 $thumbnail_id = $attachment_id;
4484
4485 // try to get default video poster image
4486 if ( ! $thumbnail_id ) {
4487 $thumbnail_id = get_posts(
4488 array(
4489 'name' => 'responsive-lightbox-video-thumbnail',
4490 'post_type' => 'attachment',
4491 'post_status' => 'inherit',
4492 'numberposts' => 1,
4493 'fields' => 'ids'
4494 )
4495 );
4496 }
4497
4498 // no attachment?
4499 if ( ! $thumbnail_id ) {
4500 // get new attachment
4501 $thumbnail_id = get_posts(
4502 array(
4503 'name' => 'responsive-lightbox-video-thumbnail',
4504 'post_type' => 'attachment',
4505 'post_status' => 'pending',
4506 'numberposts' => 1,
4507 'fields' => 'ids'
4508 )
4509 );
4510
4511 // no attachment?
4512 if ( ! $thumbnail_id ) {
4513 // get upload directory data
4514 $wp_upload_dir = wp_upload_dir();
4515
4516 // get file path
4517 $filepath = str_replace( '\\', '/', RESPONSIVE_LIGHTBOX_PATH . 'images/responsive-lightbox-video-thumbnail.png' );
4518
4519 // get file name
4520 $filename = basename( $filepath );
4521
4522 // new filepath in upload dir
4523 $new_filepath = $wp_upload_dir['path'] . '/' . $filename;
4524
4525 // copty file to upload dir
4526 copy( $filepath, $new_filepath );
4527
4528 // get type of file
4529 $filetype = wp_check_filetype( $filename );
4530
4531 // force pending status for the attachment
4532 add_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
4533
4534 // insert attachment
4535 $thumbnail_id = wp_insert_attachment(
4536 array(
4537 'guid' => $wp_upload_dir['url'] . '/' . $filename,
4538 'post_mime_type' => $filetype['type'],
4539 'post_title' => preg_replace( '/\.[^.]+$/', '', $filename ),
4540 'post_content' => '',
4541 'post_parent' => 0,
4542 'post_status' => 'inherit'
4543 ),
4544 $new_filepath,
4545 0
4546 );
4547
4548 remove_filter( 'wp_insert_attachment_data', array( $this, 'set_attachment_post_status' ) );
4549
4550 // success?
4551 if ( $thumbnail_id ) {
4552 // make sure that this file is included
4553 require_once( ABSPATH . 'wp-admin/includes/image.php' );
4554
4555 // update database with generated metadata for the attachment
4556 wp_update_attachment_metadata( $thumbnail_id, wp_generate_attachment_metadata( $thumbnail_id, $new_filepath ) );
4557 }
4558 } else
4559 $thumbnail_id = $thumbnail_id[0];
4560 }
4561
4562 return (int) $thumbnail_id;
4563 }
4564
4565 /**
4566 * Change status of new attachment thumbnail replacement.
4567 *
4568 * @param array $data
4569 * @return array
4570 */
4571 function set_attachment_post_status( $data ) {
4572 $data['post_status'] = 'pending';
4573
4574 return $data;
4575 }
4576
4577 /**
4578 * Prepare featured content fields.
4579 *
4580 * @param array $fields
4581 * @return array
4582 */
4583 public function prepare_featured_fields( $fields ) {
4584 foreach ( array( 'post_type', 'post_status', 'post_format', 'post_term', 'post_author', 'page_parent', 'page_template' ) as $option ) {
4585 $fields[$option]['options'] = $this->prepare_query_args( $option );
4586 }
4587
4588 return $fields;
4589 }
4590
4591 /**
4592 * Prepare values option list.
4593 *
4594 * @param string $type
4595 * @return array
4596 */
4597 public function prepare_query_args( $type = '' ) {
4598 $html = '';
4599
4600 switch( $type ) {
4601 case 'post_type':
4602 $data = $this->get_post_types();
4603 break;
4604
4605 case 'post_status':
4606 $data = $this->get_post_statuses();
4607 break;
4608
4609 case 'post_format':
4610 $data = $this->get_post_formats();
4611 break;
4612
4613 case 'post_term':
4614 $taxonomies = $this->get_taxonomies();
4615 $new_terms = [];
4616
4617 if ( ! empty( $taxonomies ) ) {
4618 foreach ( $taxonomies as $tax_id => $label ) {
4619 $terms = get_terms(
4620 array(
4621 'taxonomy' => $tax_id,
4622 'orderby' => 'name',
4623 'order' => 'ASC',
4624 'hide_empty' => false,
4625 'fields' => 'id=>name'
4626 )
4627 );
4628
4629 if ( ! empty( $terms ) )
4630 $new_terms[$tax_id] = array(
4631 'label' => $label,
4632 'terms' => $terms
4633 );
4634 }
4635 }
4636
4637 $data = $new_terms;
4638 break;
4639
4640 case 'post_author':
4641 $data = $this->get_users();
4642 break;
4643
4644 case 'page_parent':
4645 $parents = [];
4646 $hierarchical = get_post_types(
4647 array(
4648 'public' => true,
4649 'hierarchical' => true
4650 ),
4651 'objects',
4652 'and'
4653 );
4654
4655 if ( ! empty( $hierarchical ) ) {
4656 foreach ( $hierarchical as $post_type => $object ) {
4657 // get top level hierarchical posts
4658 $query = new WP_Query(
4659 array(
4660 'post_type' => $post_type,
4661 'post_status' => 'publish',
4662 'nopaging' => true,
4663 'posts_per_page' => -1,
4664 'orderby' => 'title',
4665 'order' => 'ASC',
4666 'suppress_filters' => false,
4667 'no_found_rows' => true,
4668 'cache_results' => false,
4669 'post_parent' => 0
4670 )
4671 );
4672
4673 if ( ! empty( $query->posts ) ) {
4674 foreach ( $query->posts as $post ) {
4675 $parents[$post->ID] = trim( $post->post_title ) === '' ? __( 'Untitled' ) : $post->post_title;
4676 }
4677 }
4678 }
4679 }
4680
4681 $data = $parents;
4682 break;
4683
4684 case 'page_template':
4685 $data = $this->get_page_templates();
4686 break;
4687
4688 default:
4689 $data = [];
4690 }
4691
4692 return apply_filters( 'rl_galleries_prepare_query_args', $data, $type );
4693 }
4694
4695 /**
4696 * Get public post types.
4697 *
4698 * @param bool $simple Which data should be returned
4699 * @param bool $skip Which post types should be skipped
4700 * @return array
4701 */
4702 public function get_post_types( $simple = false, $skip = [ 'attachment', 'rl_gallery' ] ) {
4703 $post_types = get_post_types(
4704 array(
4705 'public' => true
4706 ),
4707 'objects',
4708 'and'
4709 );
4710
4711 $data = [];
4712
4713 if ( ! empty( $post_types ) ) {
4714 foreach ( $post_types as $post_type => $cpt ) {
4715 // skip unwanted post types
4716 if ( in_array( $post_type, $skip, true ) )
4717 continue;
4718
4719 if ( $simple )
4720 $data[] = $post_type;
4721 else
4722 $data[$post_type] = $cpt->labels->singular_name;
4723 }
4724 }
4725
4726 if ( ! $simple )
4727 asort( $data );
4728
4729 return $data;
4730 }
4731
4732 /**
4733 * Get post statuses.
4734 *
4735 * @return array
4736 */
4737 public function get_post_statuses() {
4738 $post_statuses = get_post_stati();
4739
4740 asort( $post_statuses );
4741
4742 // remove inherit post status
4743 if ( isset( $post_statuses['inherit'] ) )
4744 unset( $post_statuses['inherit'] );
4745
4746 return $post_statuses;
4747 }
4748
4749 /**
4750 * Get post formats.
4751 *
4752 * @return array
4753 */
4754 public function get_post_formats() {
4755 $post_formats = array(
4756 'aside' => __( 'Aside' ),
4757 'audio' => __( 'Audio' ),
4758 'chat' => __( 'Chat' ),
4759 'gallery' => __( 'Gallery' ),
4760 'link' => __( 'Link' ),
4761 'photo' => __( 'Photo' ),
4762 'quote' => __( 'Quote' ),
4763 'standard' => __( 'Standard' ),
4764 'status' => __( 'Status' ),
4765 'video' => __( 'Video' )
4766 );
4767
4768 asort( $post_formats );
4769
4770 return $post_formats;
4771 }
4772
4773 /**
4774 * Get taxonomies.
4775 *
4776 * @return array
4777 */
4778 public function get_taxonomies() {
4779 $taxonomies = get_taxonomies(
4780 array(
4781 'public' => true
4782 ),
4783 'objects',
4784 'and'
4785 );
4786
4787 // remove post format
4788 if ( array_key_exists( 'post_format', $taxonomies ) )
4789 unset( $taxonomies['post_format'] );
4790
4791 // get main instance
4792 $rl = Responsive_Lightbox();
4793
4794 // remove gallery categories
4795 if ( $rl->options['builder']['categories'] && array_key_exists( 'rl_category', $taxonomies ) )
4796 unset( $taxonomies['rl_category'] );
4797
4798 // remove gallery tags
4799 if ( $rl->options['builder']['tags'] && array_key_exists( 'rl_tag', $taxonomies ) )
4800 unset( $taxonomies['rl_tag'] );
4801
4802 if ( $rl->options['folders']['active'] ) {
4803 // remove active folders taxonomy from gallery source selector
4804 $active_taxonomy = $rl->folders->get_active_taxonomy();
4805 unset( $taxonomies[$active_taxonomy] );
4806
4807 // remove media folders tags
4808 if ( $rl->options['folders']['media_tags'] )
4809 unset( $taxonomies['rl_media_tag'] );
4810 }
4811
4812 $data = [];
4813
4814 if ( ! empty( $taxonomies ) ) {
4815 foreach ( $taxonomies as $tax_id => $taxonomy ) {
4816 $data[$tax_id] = $taxonomy->labels->singular_name;
4817 }
4818 }
4819
4820 // sort taxonomies
4821 asort( $data );
4822
4823 return $data;
4824 }
4825
4826 /**
4827 * Get users.
4828 *
4829 * @return array
4830 */
4831 public function get_users() {
4832 $users = get_users(
4833 array(
4834 'fields' => array( 'ID', 'user_login' )
4835 )
4836 );
4837
4838 $data = [];
4839
4840 if ( ! empty( $users ) ) {
4841 foreach ( $users as $user ) {
4842 $data[(int) $user->ID] = $user->user_login;
4843 }
4844 }
4845
4846 asort( $data );
4847
4848 return $data;
4849 }
4850
4851 /**
4852 * Get page templates.
4853 *
4854 * @return array
4855 */
4856 public function get_page_templates() {
4857 $data = [];
4858 $page_templates = wp_get_theme()->get_page_templates();
4859
4860 if ( ! empty( $page_templates ) )
4861 asort( $page_templates );
4862
4863 $data = array_merge( array( 'default' => apply_filters( 'default_page_template_title', __( 'Default Template' ) ) ), $page_templates );
4864
4865 return $data;
4866 }
4867
4868 /**
4869 * Fix possible misplaced or hidden metaboxes do to old 'after_title' metabox and possibility to move internal metaboxes.
4870 *
4871 * @return void
4872 */
4873 public function clear_metaboxes( $screen ) {
4874 global $pagenow;
4875
4876 if ( ! ( ( $pagenow === 'post.php' || $pagenow === 'post-new.php' ) && ! empty( $screen->post_type ) && $screen->post_type === 'rl_gallery' && empty( $_POST['rl_gallery'] ) ) )
4877 return;
4878
4879 // get user id
4880 $user_id = get_current_user_id();
4881
4882 // get rl metaboxes
4883 $order = get_user_meta( $user_id, 'meta-box-order_rl_gallery', true );
4884
4885 // any metabox order? fix possible misplaced metaboxes
4886 if ( is_array( $order ) && ! empty( $order ) ) {
4887 // save metaboxes
4888 $_order = $order;
4889
4890 // default rl metaboxes
4891 $rl_boxes = [ 'responsive-gallery-images', 'responsive-gallery-config', 'responsive-gallery-design', 'responsive-gallery-paging', 'responsive-gallery-lightbox', 'responsive-gallery-misc' ];
4892
4893 foreach ( $_order as $group => $metaboxes ) {
4894 if ( $group === 'after_title' ) {
4895 // remove deprecated after_title metabox
4896 unset( $order['after_title'] );
4897 } elseif ( $metaboxes !== '' ) {
4898 $boxes = explode( ',', $metaboxes );
4899 $new_boxes = [];
4900
4901 foreach ( $boxes as $box ) {
4902 if ( ! in_array( $box, $rl_boxes, true ) )
4903 $new_boxes[] = $box;
4904 }
4905
4906 if ( ! empty( $new_boxes ) )
4907 $order[$group] = implode( ',', $new_boxes );
4908 else
4909 $order[$group] = '';
4910 }
4911 }
4912
4913 // remove default metaboxes storage
4914 if ( array_key_exists( 'responsive_lightbox_metaboxes', $order ) )
4915 unset( $order['responsive_lightbox_metaboxes'] );
4916
4917 // update usermeta to prevent issues with rl metaboxes
4918 if ( $order !== $_order )
4919 update_user_meta( $user_id, 'meta-box-order_rl_gallery', $order );
4920 }
4921 }
4922
4923 /**
4924 * Save gallery metadata.
4925 *
4926 * @param int $post_id
4927 * @param object $post
4928 * @param bool $update Whether existing post is being updated or not
4929 * @return void
4930 */
4931 public function save_post( $post_id, $post, $update ) {
4932 // check action
4933 $action = isset( $_GET['action'] ) ? sanitize_key( $_GET['action'] ) : '';
4934
4935 if ( wp_is_post_revision( $post_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! $update || in_array( $post->post_status, array( 'trash', 'auto-draft' ), true ) || ( $action === 'untrash' ) || empty( $_POST['rl_gallery'] ) )
4936 return;
4937
4938 // save gallery
4939 $this->save_gallery( wp_unslash( $_POST ), $post_id );
4940 }
4941
4942 /**
4943 * Save gallery preview metadata.
4944 *
4945 * @param array $post_data Gallery data
4946 * @param int $post_id
4947 * @param bool $preview Whether is it preview
4948 * @return void
4949 */
4950 public function save_gallery( $post_data, $post_id, $preview = false ) {
4951 // get gallery data
4952 $data = $post_data['rl_gallery'];
4953
4954 // prepare sanitized data
4955 $safedata = [];
4956
4957 // sanitize all fields
4958 foreach ( $this->fields as $tab_id => $menu_items ) {
4959 switch ( $tab_id ) {
4960 case 'config':
4961 // get main instance
4962 $rl = Responsive_Lightbox();
4963
4964 // add menu item
4965 $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'] );
4966
4967 // get default gallery fields
4968 $default_gallery_fields = $rl->frontend->get_default_gallery_fields();
4969
4970 // prepare fields
4971 if ( $menu_item === 'default' )
4972 $items = $default_gallery_fields;
4973 else {
4974 // assign settings and defaults
4975 $fields = $rl->settings->get_setting_fields( $menu_item . '_gallery' );
4976 $defaults = $rl->defaults[$menu_item . '_gallery'];
4977
4978 // make a copy
4979 $fields_copy = $fields;
4980
4981 foreach ( $fields_copy as $field_id => $field ) {
4982 if ( $field['type'] === 'multiple' ) {
4983 foreach ( $field['fields'] as $subfield_id => $subfield ) {
4984 $fields[$field_id]['fields'][$subfield_id]['default'] = $defaults[$subfield_id];
4985 }
4986 } else
4987 $fields[$field_id]['default'] = $defaults[$field_id];
4988 }
4989
4990 $items = $rl->frontend->get_unique_fields( $default_gallery_fields, $fields );
4991 }
4992
4993 // sanitize fields
4994 $safedata = $this->sanitize_fields( $items, $data, $tab_id, $menu_item );
4995
4996 // add menu item
4997 $safedata[$tab_id]['menu_item'] = $menu_item;
4998 break;
4999
5000 default:
5001 // add menu item
5002 $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';
5003
5004 // sanitize fields
5005 $safedata = $this->sanitize_fields( $menu_items[$menu_item], $data, $tab_id, $menu_item );
5006
5007 // add menu item
5008 $safedata[$tab_id]['menu_item'] = $menu_item;
5009 }
5010
5011 $safedata[$tab_id] = apply_filters( 'rl_gallery_tab_metadata', $safedata[$tab_id], $tab_id );
5012
5013 // preview?
5014 if ( $preview )
5015 update_metadata( 'post', $post_id, '_rl_' . $tab_id, $safedata[$tab_id] );
5016 else
5017 update_post_meta( $post_id, '_rl_' . $tab_id, $safedata[$tab_id] );
5018 }
5019
5020 $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';
5021
5022 switch ( $featured_image_type ) {
5023 // custom url
5024 case 'url':
5025 $thumbnail_id = $this->maybe_generate_thumbnail();
5026 $frontend = function_exists( 'Responsive_Lightbox' ) ? Responsive_Lightbox()->frontend : null;
5027 $custom_url = isset( $post_data['_rl_thumbnail_url'] ) ? $post_data['_rl_thumbnail_url'] : '';
5028 if ( $frontend && method_exists( $frontend, 'sanitize_remote_image_url' ) )
5029 $featured_image = $frontend->sanitize_remote_image_url( $custom_url );
5030 else
5031 $featured_image = '';
5032
5033 if ( $featured_image === '' )
5034 $featured_image_type = 'image';
5035 break;
5036
5037 // first image
5038 case 'image':
5039 $thumbnail_id = $this->maybe_generate_thumbnail();
5040 $featured_image = '';
5041 break;
5042
5043 // attachment id
5044 case 'id':
5045 default:
5046 $featured_image = $thumbnail_id = isset( $post_data['_thumbnail_id'] ) ? (int) $post_data['_thumbnail_id'] : 0;
5047 }
5048
5049 // preview?
5050 if ( $preview ) {
5051 update_metadata( 'post', $post_id, '_rl_featured_image_type', $featured_image_type );
5052 update_metadata( 'post', $post_id, '_rl_featured_image', $featured_image );
5053 update_metadata( 'post', $post_id, '_thumbnail_id', $thumbnail_id );
5054 } else {
5055 // update featured image
5056 update_post_meta( $post_id, '_rl_featured_image_type', $featured_image_type );
5057 update_post_meta( $post_id, '_rl_featured_image', $featured_image );
5058 update_post_meta( $post_id, '_thumbnail_id', $thumbnail_id );
5059
5060 // save number of images
5061 update_post_meta( $post_id, '_rl_images_count', $this->get_gallery_images_number( $post_id ) );
5062 }
5063
5064 // update post excerpt
5065 if ( isset( $safedata['misc']['options']['gallery_description'] ) ) {
5066 remove_action( 'save_post_rl_gallery', [ $this, 'save_post' ], 10, 3 );
5067
5068 $postdata = [
5069 'ID' => $post_id,
5070 'post_excerpt' => sanitize_textarea_field( $safedata['misc']['options']['gallery_description'] )
5071 ];
5072
5073 wp_update_post( $postdata );
5074
5075 add_action( 'save_post_rl_gallery', [ $this, 'save_post' ], 10, 3 );
5076 }
5077 }
5078
5079 /**
5080 * Check attachments IDs.
5081 *
5082 * @param array $attachments Attachment ID's
5083 * @param array $args
5084 * @return array
5085 */
5086 public function check_attachments( $attachments, $args = [] ) {
5087 // no attachments?
5088 if ( empty( $attachments ) || ! is_array( $attachments ) )
5089 return [];
5090
5091 // check providers support
5092 if ( ! empty( $args['providers'] ) )
5093 $embed = rl_current_lightbox_supports( $args['providers'], 'OR' );
5094 else
5095 $embed = false;
5096
5097 // no embed data?
5098 if ( ! $embed )
5099 $copy = array_map( 'intval', $attachments );
5100 else
5101 $copy = $attachments;
5102
5103 // check attachments
5104 foreach ( $attachments as $key => $attachment_id ) {
5105 // embed?
5106 if ( $embed && preg_match( '/^e\d+$/', $attachment_id ) === 1 ) {
5107 if ( ! in_array( $attachment_id, $args['embed_keys'], true ) )
5108 unset( $copy[$key] );
5109 // video support?
5110 } elseif ( rl_current_lightbox_supports( 'video' ) ) {
5111 // is it an image or video?
5112 if ( ! wp_attachment_is( 'video', $attachment_id ) && ! wp_attachment_is( 'image', $attachment_id ) )
5113 unset( $copy[$key] );
5114 // make sure it's integer
5115 elseif ( $embed )
5116 $copy[$key] = (int) $copy[$key];
5117 } else {
5118 // is it an image?
5119 if ( ! wp_attachment_is_image( $attachment_id ) )
5120 unset( $copy[$key] );
5121 // make sure it's integer
5122 elseif ( $embed )
5123 $copy[$key] = (int) $copy[$key];
5124 }
5125 }
5126
5127 return array_values( $copy );
5128 }
5129
5130 /**
5131 * Display shortcode metabox.
5132 *
5133 * @param object $post
5134 * @return void
5135 */
5136 public function shortcode_metabox( $post ) {
5137 echo '
5138 <p>' . esc_html__( 'You can place this gallery anywhere into your posts, pages, custom post types or widgets by using the shortcode below', 'responsive-lightbox' ) . ':</p>
5139 <code class="rl-shortcode" data-number="0">[rl_gallery id=&quot;' . (int) $post->ID . '&quot;]</code>
5140 <p>' . esc_html__( 'You can also place this gallery into your template files by using the template tag below', 'responsive-lightbox' ) . ':</p>
5141 <code class="rl-shortcode" data-number="1">if ( function_exists( \'rl_gallery\' ) ) { rl_gallery( \'' . (int) $post->ID . '\' ); }</code>';
5142 }
5143
5144 /**
5145 * Add new gallery listing columns.
5146 *
5147 * @param array $columns
5148 * @return array
5149 */
5150 public function gallery_columns( $columns ) {
5151 // find title position
5152 $offset = array_search( 'title', array_keys( $columns ) );
5153
5154 // put image column before title
5155 $columns = array_merge(
5156 array_slice( $columns, 0, $offset ),
5157 array(
5158 'image' => esc_html__( 'Gallery', 'responsive-lightbox' )
5159 ),
5160 array_slice( $columns, $offset )
5161 );
5162
5163 // put new columns after title
5164 $columns = array_merge(
5165 array_slice( $columns, 0, $offset + 2 ),
5166 array(
5167 'shortcode' => esc_html__( 'Shortcode', 'responsive-lightbox' ),
5168 'type' => esc_html__( 'Type', 'responsive-lightbox' ),
5169 'source' => esc_html__( 'Source', 'responsive-lightbox' )
5170 ),
5171 array_slice( $columns, $offset + 2 )
5172 );
5173
5174 return $columns;
5175 }
5176
5177 /**
5178 * Add new gallery listing columns content.
5179 *
5180 * @global string $pagenow
5181 *
5182 * @param string $column_name
5183 * @param int $post_id
5184 * @return void
5185 */
5186 public function gallery_columns_content( $column_name, $post_id ) {
5187 global $pagenow;
5188
5189 if ( $pagenow === 'edit.php' ) {
5190 switch ( $column_name ) {
5191 case 'image':
5192 // get image data, based on gallery source type
5193 $image = $this->get_featured_image( $post_id, 'thumbnail' );
5194 $images_count = (int) get_post_meta( $post_id, '_rl_images_count', true );
5195
5196 // display count
5197 if ( ! empty( $image ) )
5198 echo '<span class="media-icon image-icon">' . wp_kses_post( $image ) . '</span><span>' . esc_html( sprintf( _n( '%s element', '%s elements', $images_count, 'responsive-lightbox' ), $images_count ) ) . '</span>';
5199 else
5200 echo '<span class="media-icon image-icon">' . wp_get_attachment_image( 0, array( 60, 60 ), true, array( 'alt' => '' ) ) . '</span>';
5201 break;
5202
5203 case 'shortcode':
5204 echo '<code>[rl_gallery id="' . (int) $post_id . '"]</code>';
5205 break;
5206
5207 case 'type':
5208 $config = get_post_meta( $post_id, '_rl_config', true );
5209
5210 if ( ! empty( $config['menu_item'] ) && array_key_exists( $config['menu_item'], $this->tabs['config']['menu_items'] ) ) {
5211 echo esc_html( $this->tabs['config']['menu_items'][$config['menu_item']] );
5212
5213 if ( $config['menu_item'] === 'default' )
5214 echo esc_html( ' (' . $this->tabs['config']['menu_items'][Responsive_Lightbox()->options['settings']['builder_gallery']] . ')' );
5215 } else
5216 echo '-';
5217 break;
5218
5219 case 'source':
5220 $images = get_post_meta( $post_id, '_rl_images', true );
5221
5222 if ( ! empty( $images['menu_item'] ) && array_key_exists( $images['menu_item'], $this->tabs['images']['menu_items'] ) )
5223 echo esc_html( $this->tabs['images']['menu_items'][$images['menu_item']] );
5224 else
5225 echo '-';
5226 break;
5227 }
5228 }
5229 }
5230
5231 /**
5232 * Get size information for all currently-registered image sizes.
5233 *
5234 * @global array $_wp_additional_image_sizes
5235 *
5236 * @return array
5237 */
5238 public function get_image_sizes() {
5239 global $_wp_additional_image_sizes;
5240
5241 $sizes = [];
5242
5243 foreach ( get_intermediate_image_sizes() as $_size ) {
5244 if ( in_array( $_size, [ 'thumbnail', 'medium', 'medium_large', 'large' ] ) ) {
5245 $sizes[$_size]['width'] = get_option( "{$_size}_size_w" );
5246 $sizes[$_size]['height'] = get_option( "{$_size}_size_h" );
5247 $sizes[$_size]['crop'] = (bool) get_option( "{$_size}_crop" );
5248 } elseif ( isset( $_wp_additional_image_sizes[$_size] ) ) {
5249 $sizes[$_size] = [
5250 'width' => $_wp_additional_image_sizes[$_size]['width'],
5251 'height' => $_wp_additional_image_sizes[$_size]['height'],
5252 'crop' => $_wp_additional_image_sizes[$_size]['crop'],
5253 ];
5254 }
5255 }
5256
5257 return $sizes;
5258 }
5259
5260 /**
5261 * Get size information for a specific image size.
5262 *
5263 * @param string $size The image size for which to retrieve data.
5264 * @return false|array
5265 */
5266 public function get_image_size( $size ) {
5267 if ( isset( $this->sizes[$size] ) )
5268 return $this->sizes[$size];
5269 else
5270 return false;
5271 }
5272
5273 /**
5274 * Filter the admin post thumbnail HTML markup.
5275 *
5276 * @param string $content
5277 * @param int $post_id
5278 * @param int $thumbnail_id
5279 * @return string
5280 */
5281 public function admin_post_thumbnail_html( $content, $post_id, $thumbnail_id ) {
5282 if ( get_post_type( $post_id ) === 'rl_gallery' ) {
5283 $value = get_post_meta( $post_id, '_rl_featured_image', true );
5284 $frontend = function_exists( 'Responsive_Lightbox' ) ? Responsive_Lightbox()->frontend : null;
5285 if ( $frontend && method_exists( $frontend, 'sanitize_remote_image_url' ) )
5286 $value = $frontend->sanitize_remote_image_url( $value );
5287 $type = get_post_meta( $post_id, '_rl_featured_image_type', true );
5288 $type = ! empty( $type ) && in_array( $type, array( 'image', 'id', 'url' ) ) ? $type : 'image';
5289
5290 // force media library image
5291 if ( wp_doing_ajax() )
5292 $type = 'id';
5293 // post featured image is post thumbnail replacement?
5294 elseif ( $this->maybe_generate_thumbnail() === (int) $thumbnail_id ) {
5295 remove_filter( 'admin_post_thumbnail_html', array( $this, 'admin_post_thumbnail_html' ), 10 );
5296
5297 $content = _wp_post_thumbnail_html( 0, $post_id );
5298 }
5299
5300 $content = '
5301 <div class="rl-gallery-featured-image-options">
5302 <p class="howto">' . esc_html__( 'Select gallery featured image source:', 'responsive-lightbox' ) . '</p>
5303 <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 ) . ' />' . esc_html__( 'First gallery image', 'responsive-lightbox' ) . '</label><br />
5304 <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 ) . ' />' . esc_html__( 'Media Library', 'responsive-lightbox' ) . '</label><br />
5305 <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 ) . ' />' . esc_html__( 'Custom URL', 'responsive-lightbox' ) . '</label>
5306 </div>
5307 <div class="rl-gallery-featured-image-select">
5308 <div class="rl-gallery-featured-image-select-id"' . ( $type === 'id' ? '' : ' style="display: none;"' ) . '>' . $content . '</div>
5309 <div class="rl-gallery-featured-image-select-url"' . ( $type === 'url' ? '' : ' style="display: none;"' ) . '>
5310 <p><input id="_rl_thumbnail_url" class="large-text" name="_rl_thumbnail_url" value="' . ( $type === 'url' ? esc_url( $value ) : '' ) . '" type="text" /></p>
5311 <p class="howto">' . esc_html__( 'Custom featured image URL', 'responsive-lightbox' ) . '</p>
5312 </div>
5313 <div class="rl-gallery-featured-image-select-image"' . ( $type === 'image' ? '' : ' style="display: none;"' ) . '><p class="howto">' . esc_html__( 'Dynamically generated first gallery image', 'responsive-lightbox' ) . '</p></div>
5314 </div>
5315 ';
5316 }
5317
5318 return $content;
5319 }
5320
5321 /**
5322 * Modify the resulting HTML so that the feature image is set as a background property.
5323 *
5324 * @param string $html The HTML image tag.
5325 * @param int $post_id The post whose featured image is to be printed.
5326 * @param int $post_thumbnail_id The post thumbnail ID.
5327 * @param array|string $size The size of the featured image.
5328 * @param array $attr Additional attributes.
5329 * @return string
5330 */
5331 public function post_thumbnail_html( $html, $post_id = 0, $post_thumbnail_id = 0, $size = false, $attr = [] ) {
5332 if ( get_post_type( $post_id ) === 'rl_gallery' ) {
5333 // get featured image type
5334 $image_type = get_post_meta( $post_id, '_rl_featured_image_type', true );
5335
5336 // break if featured image type is media library
5337 if ( ! $image_type || $image_type == 'id' )
5338 return $html;
5339
5340 // get image source
5341 $image_src = $this->get_gallery_image_src( $this->get_featured_image_src( $post_id ) );
5342
5343 // no image?
5344 if ( empty( $image_src ) )
5345 return $html;
5346
5347 // add featured image as background in style tag
5348 $style = 'style="background:url( ' . esc_url( $image_src['url'] ) . ' ) no-repeat center center;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size: cover;"';
5349
5350 $html = str_replace( 'src=', $style . ' src=', $html );
5351
5352 // fix the alt tag (if possible)
5353 $alt = $image_src['alt'];
5354
5355 if ( isset( $attr['alt'] ) )
5356 $alt = $attr['alt'];
5357
5358 if ( $alt ) {
5359 $html = str_replace( '/(alt=\'[^\']+\'\|alt="[^"]+")/', '', $html );
5360 $html = str_replace( 'src=', ' alt="' . esc_attr( $alt ) . '" src=', $html );
5361 }
5362 }
5363
5364 return $html;
5365 }
5366
5367 /**
5368 * Save the revision meta data. For example, used when saving a preview.
5369 *
5370 * @param int $revision_id
5371 * @return void
5372 */
5373 public function save_revision( $revision_id ) {
5374 // get revision
5375 $revision = get_post( $revision_id );
5376
5377 // get gallery ID
5378 $post_id = $revision->post_parent;
5379
5380 // is it rl gallery?
5381 if ( get_post_type( $post_id ) !== 'rl_gallery' )
5382 return;
5383
5384 $this->revision_id = $revision_id;
5385
5386 if ( ! wp_is_post_revision( $revision_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || empty( $_POST['rl_gallery'] ) )
5387 return;
5388
5389 // save revisioned meta data
5390 $this->save_gallery( wp_unslash( $_POST ), $revision_id, true );
5391 }
5392
5393 /**
5394 * Update preview link.
5395 *
5396 * @param string $link Preview link
5397 * @return string
5398 */
5399 public function preview_post_link( $link ) {
5400 // add gallery revision id
5401 if ( property_exists( $this, 'revision_id' ) && ! is_null( $this->revision_id ) ) {
5402 $post_id = wp_get_post_parent_id( $this->revision_id );
5403
5404 // is it valid rl_gallery post?
5405 if ( $post_id && get_post_type( $post_id ) === 'rl_gallery' )
5406 return add_query_arg( 'rl_gallery_revision_id', $this->revision_id, $link );
5407 }
5408
5409 return $link;
5410 }
5411
5412 /**
5413 * Delete gallery revision at shutdown.
5414 *
5415 * @global object $post
5416 *
5417 * @return void
5418 */
5419 public function shutdown_preview() {
5420 // is it a frontend preview?
5421 if ( is_preview() && isset( $_GET['rl_gallery_revision_id'] ) ) {
5422 global $post;
5423
5424 // cast revision ID
5425 $revision_id = (int) $_GET['rl_gallery_revision_id'];
5426
5427 // is it a valid revision?
5428 if ( get_post_type( $post->ID ) === 'rl_gallery' && wp_is_post_revision( $revision_id ) === (int) $post->ID )
5429 wp_delete_post_revision( $revision_id );
5430 }
5431 }
5432
5433 /**
5434 * Filter gallery meta data needed for frontend gallery preview.
5435 *
5436 * @param mixed $value Meta value to filter
5437 * @param int $object_id
5438 * @param string $meta_key Meta key to filter a value for
5439 * @param bool $single Whether to return a single value
5440 * @return mixed
5441 */
5442 public function filter_preview_metadata( $value, $object_id, $meta_key, $single ) {
5443 // ignore other post types
5444 if ( get_post_type( $object_id ) !== 'rl_gallery' )
5445 return $value;
5446
5447 // get current post
5448 $post = get_post();
5449
5450 // prepare keys
5451 $keys = array( '_rl_featured_image_type', '_rl_featured_image', '_rl_images_count', '_thumbnail_id' );
5452
5453 // add other metakeys
5454 foreach ( array_keys( $this->tabs ) as $key ) {
5455 $keys[] = '_rl_' . $key;
5456 }
5457
5458 // restrict only to specified data
5459 if ( empty( $post ) || (int) $post->ID !== (int) $object_id || ! in_array( $meta_key, $keys, true ) || $post->post_type === 'revision' )
5460 return $value;
5461
5462 // grab the last autosave
5463 $preview = wp_get_post_autosave( $post->ID );
5464
5465 // invalid revision?
5466 if ( ! is_object( $preview ) )
5467 return $value;
5468
5469 // finally replace metadata
5470 return array( get_post_meta( $preview->ID, $meta_key, $single ) );
5471 }
5472 }
5473