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