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