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