PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / trunk
Responsive Lightbox & Gallery vtrunk
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 / galleries / trait-gallery-ajax.php
responsive-lightbox / includes / galleries Last commit date
class-gallery-api.php 5 months ago class-gallery-base.php 4 months ago class-gallery-config.php 5 months ago class-gallery-design.php 5 months ago class-gallery-field-provider.php 5 months ago class-gallery-images.php 5 months ago class-gallery-lightbox.php 5 months ago class-gallery-misc.php 5 months ago class-gallery-paging.php 5 months ago trait-gallery-ajax.php 4 months ago trait-gallery-duplicate.php 5 months ago trait-gallery-image-methods.php 3 weeks ago trait-gallery-preview.php 5 months ago trait-gallery-sanitize.php 5 months ago
trait-gallery-ajax.php
598 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 /**
7 * Responsive Lightbox Gallery AJAX Trait.
8 *
9 * Handles all AJAX endpoints for gallery operations.
10 *
11 * @trait Responsive_Lightbox_Gallery_Ajax
12 */
13 trait Responsive_Lightbox_Gallery_Ajax {
14
15 /**
16 * Check whether is it valid gallery AJAX request (rl-get-gallery-page-content action).
17 *
18 * @return bool
19 */
20 public function gallery_ajax_verified() {
21 return ( wp_doing_ajax() && isset( $_POST['action'], $_POST['gallery_id'], $_POST['gallery_no'], $_POST['page'], $_POST['nonce'], $_POST['preview'], $_POST['post_id'], $_POST['lightbox'] ) && $_POST['action'] === 'rl-get-gallery-page-content' && wp_verify_nonce( $_POST['nonce'], 'rl_nonce' ) );
22 }
23
24 /**
25 * Try to change lightbox in valid gallery AJAX request (rl-get-gallery-page-content action).
26 *
27 * @return void
28 */
29 public function maybe_change_lightbox() {
30 // check whether is it valid gallery ajax request
31 if ( $this->gallery_ajax_verified() ) {
32 // set new lightbox script
33 Responsive_Lightbox()->set_lightbox_script( sanitize_key( $_POST['lightbox'] ) );
34 }
35 }
36
37 /**
38 * Get gallery page.
39 *
40 * @param array $args
41 * @return void
42 */
43 public function get_gallery_page( $args ) {
44 // check whether is it valid gallery ajax request
45 if ( $this->gallery_ajax_verified() ) {
46 // check rate limiting (60 requests per minute)
47 if ( ! Responsive_Lightbox()->check_rate_limit( 'rl_get_gallery_page', 60, 60 ) ) {
48 wp_send_json_error( __( 'Rate limit exceeded. Please try again later.', 'responsive-lightbox' ) );
49 }
50
51 // cast page number
52 $_GET['rl_page'] = (int) $_POST['page'];
53
54 // check preview
55 $preview = ( $_POST['preview'] === 'true' );
56
57 echo $this->gallery_shortcode(
58 [
59 'id' => (int) $_POST['gallery_id'],
60 'gallery_no' => (int) $_POST['gallery_no'],
61 'preview' => $preview
62 ]
63 );
64 }
65
66 exit;
67 }
68
69 /**
70 * Generate gallery preview.
71 *
72 * @return void
73 */
74 public function post_gallery_preview() {
75 // check data
76 if ( ! isset( $_POST['post_id'], $_POST['gallery_id'], $_POST['nonce'], $_POST['page'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) )
77 wp_send_json_error();
78
79 // check page
80 $page = preg_replace( '/[^a-z-.]/i', '', $_POST['page'] );
81
82 // check page
83 if ( ! in_array( $page, [ 'widgets.php', 'customize.php', 'post.php', 'post-new.php' ], true ) )
84 wp_send_json_error();
85
86 // check edit_post capability
87 if ( ( $page === 'post.php' || $page === 'post-new.php' ) && ! current_user_can( 'edit_post', (int) $_POST['post_id'] ) )
88 wp_send_json_error();
89
90 // check edit_theme_options capability
91 if ( ( $page === 'widgets.php' || $page === 'customize.php' ) && ! current_user_can( 'edit_theme_options' ) )
92 wp_send_json_error();
93
94 // parse gallery id
95 $gallery_id = (int) $_POST['gallery_id'];
96
97 // get gallery data
98 $data = get_post_meta( $gallery_id, '_rl_images', true );
99
100 // prepare data
101 $attachments = $exclude = [];
102 $html = '';
103
104 // get images
105 $images = $this->get_gallery_images(
106 $gallery_id,
107 [
108 'exclude' => true,
109 'limit' => 20
110 ]
111 );
112
113 // get number of images
114 $images_count = (int) get_post_meta( $gallery_id, '_rl_images_count', true );
115
116 if ( ! empty( $images ) ) {
117 foreach ( $images as $image ) {
118 $html .= '
119 <li tabindex="0" role="checkbox" aria-label="' . esc_attr( $image['title'] ) . '" aria-checked="true" data-id="' . esc_attr( $image['id'] ) . '" class="attachment selection selected rl-status-active">
120 <div class="attachment-preview js--select-attachment type-image ' . esc_attr( $image['thumbnail_orientation'] ). '">
121 <div class="thumbnail">
122 <div class="centered">
123 <img src="' . esc_url( $image['thumbnail_url'] ) . '" draggable="false" alt="" />
124 </div>
125 </div>
126 </div>
127 </li>';
128 }
129 }
130
131 // send attachments content
132 wp_send_json_success(
133 array(
134 'attachments' => $html,
135 'count' => esc_html( sprintf( _n( '%s image', '%s images', $images_count, 'responsive-lightbox' ), $images_count ) ),
136 'edit_url' => current_user_can( 'edit_post', $gallery_id ) ? esc_url_raw( admin_url( 'post.php?post=' . $gallery_id . '&action=edit' ) ) : ''
137 )
138 );
139 }
140
141 /**
142 * Get all galleries.
143 *
144 * @return void
145 */
146 public function post_get_galleries() {
147 // check rate limiting (60 requests per minute)
148 if ( ! Responsive_Lightbox()->check_rate_limit( 'rl_post_get_galleries', 60, 60 ) ) {
149 wp_send_json_error( __( 'Rate limit exceeded. Please try again later.', 'responsive-lightbox' ) );
150 }
151
152 // check data
153 if ( ! isset( $_POST['post_id'], $_POST['search'], $_POST['nonce'], $_POST['page'] ) || ! check_ajax_referer( 'rl-gallery-post', 'nonce', false ) )
154 wp_send_json_error();
155
156 // check page
157 $page = preg_replace( '/[^a-z-.]/i', '', $_POST['page'] );
158
159 // check page
160 if ( ! in_array( $page, [ 'widgets.php', 'customize.php', 'post.php', 'post-new.php' ], true ) )
161 wp_send_json_error();
162
163 // check edit_post capability
164 if ( ( $page === 'post.php' || $page === 'post-new.php' ) && ! current_user_can( 'edit_post', (int) $_POST['post_id'] ) )
165 wp_send_json_error();
166
167 // check edit_theme_options capability
168 if ( ( $page === 'widgets.php' || $page === 'customize.php' ) && ! current_user_can( 'edit_theme_options' ) )
169 wp_send_json_error();
170
171 $args = array(
172 'post_type' => 'rl_gallery',
173 'post_status' => 'publish',
174 'nopaging' => true,
175 'posts_per_page' => -1,
176 'orderby' => 'title',
177 'order' => 'ASC',
178 'suppress_filters' => false,
179 'no_found_rows' => true,
180 'cache_results' => false
181 );
182
183 // check category
184 $category = isset( $_POST['category'] ) ? (int) $_POST['category'] : 0;
185
186 // specific category?
187 if ( ! empty( $category ) ) {
188 $args['tax_query'] = array(
189 array(
190 'taxonomy' => 'rl_category',
191 'field' => 'term_id',
192 'operator' => 'IN',
193 'include_children' => false,
194 'terms' => $category
195 )
196 );
197 }
198
199 $search = wp_unslash( trim( $_POST['search'] ) );
200
201 if ( $search !== '' )
202 $args['s'] = $search;
203
204 // get galleries
205 $query = new WP_Query( $args );
206
207 $html = '';
208 $ids = [];
209
210 // any galleries?
211 if ( ! empty( $query->posts ) ) {
212 foreach ( $query->posts as $gallery ) {
213 // save gallery id
214 $ids[] = (int) $gallery->ID;
215
216 // get featured image
217 $featured = $this->get_featured_image_src( $gallery->ID );
218
219 if ( is_array( $featured ) && array_key_exists( 'url', $featured ) )
220 $featured_image = $featured['url'];
221 else
222 $featured_image = '';
223
224 // get title
225 $title = $gallery->post_title !== '' ? $gallery->post_title : esc_html__( '(no title)', 'responsive-gallery' );
226
227 $html .= '
228 <li tabindex="0" role="checkbox" aria-label="' . esc_attr( $title ) . '" aria-checked="true" data-id="' . (int) $gallery->ID . '" class="attachment selection">
229 <div class="attachment-preview js--select-attachment type-image ' . ( ! empty( $featured['thumbnail_orientation'] ) ? esc_attr( $featured['thumbnail_orientation'] ) : 'landscape' ) . '">
230 <div class="thumbnail">
231 <div class="centered" data-full-src="' . esc_url( $featured_image ) . '">
232 ' . $this->get_featured_image( $gallery->ID, 'thumbnail' ) . '
233 </div>
234 <div class="filename">
235 <div>' . esc_html( $title ) . '</div>
236 </div>
237 </div>
238 </div>
239 <button type="button" class="button-link check"><span class="media-modal-icon"></span><span class="screen-reader-text">' . esc_html__( 'Deselect', 'responsive-lightbox' ) . '</span></button>
240 </li>';
241 }
242 }
243
244 // send galleries content
245 wp_send_json_success(
246 [
247 'galleries' => $ids,
248 'html' => $html
249 ]
250 );
251 }
252
253 /**
254 * Get gallery content based on request.
255 *
256 * @return void
257 */
258 public function get_menu_content() {
259 if ( ! isset( $_POST['post_id'], $_POST['tab'], $_POST['menu_item'], $_POST['nonce'] ) || ! check_ajax_referer( 'rl-gallery', 'nonce', false ) )
260 wp_send_json_error();
261
262 // check tab
263 $tab = isset( $_POST['tab'] ) ? sanitize_key( $_POST['tab'] ) : '';
264
265 if ( ! array_key_exists( $tab, $this->tabs ) )
266 wp_send_json_error();
267
268 // get post id
269 $post_id = (int) $_POST['post_id'];
270
271 if ( ! current_user_can( 'edit_post', $post_id ) )
272 wp_send_json_error();
273
274 // check menu item
275 $menu_item = sanitize_key( $_POST['menu_item'] );
276
277 // get selected menu item
278 $menu_item = ! empty( $menu_item ) && in_array( $menu_item, array_keys( $this->tabs[$tab]['menu_items'] ) ) ? $menu_item : key( $this->tabs[$tab]['menu_items'] );
279
280 $content = Responsive_Lightbox()->gallery_api->render_menu_content( $post_id, $tab, $menu_item );
281 wp_send_json_success( $content );
282 }
283
284 /**
285 * Get gallery preview content based on request.
286 *
287 * @return void
288 */
289 public function get_gallery_preview_content() {
290 // check rate limiting (60 requests per minute)
291 if ( ! Responsive_Lightbox()->check_rate_limit( 'rl_get_gallery_preview_content', 60, 60 ) ) {
292 wp_send_json_error( __( 'Rate limit exceeded. Please try again later.', 'responsive-lightbox' ) );
293 }
294
295 // initial checks
296 if ( ! isset( $_POST['post_id'], $_POST['menu_item'], $_POST['nonce'], $_POST['preview_type'] ) || ! check_ajax_referer( 'rl-gallery', 'nonce', false ) )
297 wp_send_json_error();
298
299 // cast gallery ID
300 $post_id = (int) $_POST['post_id'];
301
302 // check user privileges
303 if ( ! current_user_can( 'edit_post', $post_id ) || ! current_user_can( 'upload_files' ) )
304 wp_send_json_error();
305
306 // get query args
307 $args = ! empty( $_POST['query'] ) ? wp_unslash( $_POST['query'] ) : [];
308
309 // check orderby
310 if ( array_key_exists( 'orderby', $args ) ) {
311 $args['post_orderby'] = $args['orderby'];
312
313 unset( $args['orderby'] );
314 }
315
316 // check order
317 if ( array_key_exists( 'order', $args ) ) {
318 $args['post_order'] = $args['order'];
319
320 unset( $args['order'] );
321 }
322
323 // check preview type
324 $preview_type = sanitize_key( $_POST['preview_type'] );
325
326 // check preview type
327 if ( ! in_array( $preview_type, [ 'page', 'update' ], true ) )
328 $args['preview_type'] = 'page';
329 else
330 $args['preview_type'] = $preview_type;
331
332 // check menu item
333 $menu_item = sanitize_key( $_POST['menu_item'] );
334
335 // Resolve menu item against available image fields to avoid stale/disabled sources.
336 $image_fields = ( isset( $this->fields['images'] ) && is_array( $this->fields['images'] ) ) ? $this->fields['images'] : [];
337 if ( ! empty( $menu_item ) && isset( $image_fields[$menu_item] ) && is_array( $image_fields[$menu_item] ) )
338 $menu_item = $this->menu_item = $menu_item;
339 elseif ( isset( $image_fields['media'] ) )
340 $menu_item = $this->menu_item = 'media';
341 else {
342 $fallback_menu_item = key( $image_fields );
343 $menu_item = $this->menu_item = is_string( $fallback_menu_item ) ? $fallback_menu_item : '';
344 }
345
346 if ( $menu_item === '' )
347 wp_send_json_error();
348
349 $preview_args = isset( $image_fields[$menu_item]['attachments']['preview'] ) && is_array( $image_fields[$menu_item]['attachments']['preview'] ) ? $image_fields[$menu_item]['attachments']['preview'] : [];
350 $has_preview_pagination = ! empty( $preview_args['pagination'] );
351
352 if ( $has_preview_pagination ) {
353 if ( isset( $args['preview_page'] ) )
354 $args['preview_page'] = (int) $args['preview_page'];
355 else
356 $args['preview_page'] = 1;
357 }
358
359 // get images
360 $images = $this->get_gallery_images( $post_id, $args );
361
362 // prepare JSON array
363 $data = [];
364
365 if ( $menu_item === 'remote_library' ) {
366 // get main instance
367 $rl = Responsive_Lightbox();
368
369 $response_data = [];
370
371 // single provider?
372 if ( $args['media_provider'] !== 'all' ) {
373 // get provider
374 $provider = $rl->providers[$args['media_provider']];
375
376 // add response data arguments if needed
377 if ( ! empty( $provider['response_args'] ) ) {
378 $response = $provider['instance']->get_response_data();
379
380 foreach ( $provider['response_args'] as $arg ) {
381 if ( array_key_exists( $arg, $response ) )
382 $response_data[$provider['slug']][$arg] = base64_encode( wp_json_encode( $response[$arg] ) );
383 }
384 }
385 } else {
386 // get active providers
387 $providers = $rl->remote_library->get_active_providers();
388
389 if ( ! empty( $providers ) ) {
390 foreach ( $providers as $provider ) {
391 // get provider
392 $provider = $rl->providers[$provider];
393
394 // add response data arguments if needed
395 if ( ! empty( $provider['response_args'] ) ) {
396 $response = $provider['instance']->get_response_data();
397
398 foreach ( $provider['response_args'] as $arg ) {
399 if ( array_key_exists( $arg, $response ) )
400 $response_data[$provider['slug']][$arg] = base64_encode( wp_json_encode( $response[$arg] ) );
401 }
402 }
403 }
404 }
405 }
406
407 $data['response_data'] = $response_data;
408 }
409
410 // parse excluded images
411 $excluded = ! empty( $_POST['excluded'] ) && is_array( $_POST['excluded'] ) ? array_map( 'intval', $_POST['excluded'] ) : [];
412
413 // get excluded images
414 if ( ! empty( $excluded ) )
415 $excluded = array_unique( array_filter( $excluded ) );
416
417 // get media item template
418 $media_item_template = $this->get_media_item_template( $preview_args );
419
420 // build html
421 $html = '';
422
423 // any images?
424 if ( ! empty( $images ) ) {
425 foreach ( $images as $image ) {
426 // get image content html
427 $html .= $this->get_gallery_preview_image_content( $image, 'images', $menu_item, 'attachments', $media_item_template, $excluded, $image['id'] );
428 }
429 }
430
431 $data['images'] = $html;
432
433 if ( $has_preview_pagination )
434 $data['pagination'] = $this->get_preview_pagination( $args['preview_page'] );
435
436 // send JSON
437 wp_send_json_success( $data );
438 }
439
440 /**
441 * Get gallery preview image content HTML.
442 *
443 * @param array $image
444 * @param string $tab_id
445 * @param string $menu_item
446 * @param string $field_name
447 * @param string $template
448 * @param array $excluded
449 * @param string|int $excluded_item
450 * @return string
451 */
452 public function get_gallery_preview_image_content( $image, $tab_id, $menu_item, $field_name, $template, $excluded, $excluded_item = '' ) {
453 // set flag
454 if ( empty( $excluded_item ) )
455 $excluded_flag = false;
456 else
457 $excluded_flag = in_array( $excluded_item, $excluded, true );
458
459 if ( $image['type'] === 'embed' ) {
460 // replace all embed data
461 $media_html = str_replace(
462 [
463 '__EMBED_ID__',
464 '__EMBED_URL__',
465 '__EMBED_WIDTH__',
466 '__EMBED_HEIGHT__',
467 '__EMBED_THUMBNAIL_URL__',
468 '__EMBED_THUMBNAIL_WIDTH__',
469 '__EMBED_THUMBNAIL_HEIGHT__',
470 '__EMBED_TITLE__',
471 '__EMBED_DESCRIPTION__',
472 '__EMBED_DATE__'
473 ],
474 [
475 esc_attr( $image['id'] ),
476 esc_url( $image['url'] ),
477 (int) $image['width'],
478 (int) $image['height'],
479 esc_url( $image['thumbnail_url'] ),
480 (int) $image['thumbnail_width'],
481 (int) $image['thumbnail_height'],
482 esc_attr( $image['title'] ),
483 esc_textarea( $image['caption'] ),
484 esc_attr( $image['date'] )
485 ],
486 $this->get_media_embed_template( false )
487 );
488 } else
489 $media_html = '';
490
491 // replace id and url of an image
492 return str_replace(
493 [
494 '__MEDIA_DATA__',
495 '__MEDIA_ID__',
496 '__MEDIA_STATUS__',
497 '__MEDIA_TYPE__'
498 ],
499 [
500 $this->get_media_exclude_input_template( $tab_id, $menu_item, $field_name, $excluded_flag ? $excluded_item : '' ) . $media_html . $image['thumbnail_link'],
501 esc_attr( $image['id'] ),
502 $excluded_flag ? ' rl-status-inactive' : ' rl-status-active',
503 esc_attr( $image['type'] )
504 ],
505 $template
506 );
507 }
508
509 /**
510 * Get preview pagination.
511 *
512 * @param int $current_page
513 * @return string
514 */
515 public function get_preview_pagination( $current_page = 1 ) {
516 $page_links = [];
517 $total_pages = $current_page + 1;
518 $current = $current_page;
519 $disable_first = $disable_last = $disable_prev = $disable_next = false;
520 $current_url = 'preview_page';
521
522 if ( $current === 1 ) {
523 $disable_first = true;
524 $disable_prev = true;
525 } elseif ( $current === 2 )
526 $disable_first = true;
527
528 if ( $current === $total_pages ) {
529 $disable_last = true;
530 $disable_next = true;
531 }
532
533 if ( $current === $total_pages - 1 )
534 $disable_last = true;
535
536 if ( $disable_first )
537 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
538 else {
539 $page_links[] = sprintf(
540 '<a class="first-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
541 $current_url,
542 esc_html__( 'First page', 'responsive-lightbox' ),
543 '&laquo;'
544 );
545 }
546
547 if ( $disable_prev )
548 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
549 else {
550 $page_links[] = sprintf(
551 '<a class="prev-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
552 $current_url . '/' . max( 1, $current - 1 ),
553 esc_html__( 'Previous page', 'responsive-lightbox' ),
554 '&lsaquo;'
555 );
556 }
557
558 $html_current_page = sprintf(
559 '%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">',
560 '<label for="current-page-selector" class="screen-reader-text">' . esc_html__( 'Current Page', 'responsive-lightbox' ) . '</label>',
561 $current,
562 strlen( $total_pages )
563 );
564
565 $html_total_pages = sprintf( '<span class="total-pages">%s</span>', number_format_i18n( $total_pages ) );
566 $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s', 'paging' ), $html_current_page, $html_total_pages ) . '</span></span>';
567
568 if ( $disable_next )
569 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
570 else {
571 $page_links[] = sprintf(
572 '<a class="next-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
573 $current_url . '/' . min( $total_pages, $current + 1 ),
574 esc_html__( 'Next page', 'responsive-lightbox' ),
575 '&rsaquo;'
576 );
577 }
578
579 if ( $disable_last )
580 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
581 else {
582 $page_links[] = sprintf(
583 '<a class="last-page button" href="%s"><span class="screen-reader-text">%s</span><span aria-hidden="true">%s</span></a>',
584 $current_url . '/' . $total_pages,
585 esc_html__( 'Last page', 'responsive-lightbox' ),
586 '&raquo;'
587 );
588 }
589
590 if ( $total_pages )
591 $page_class = $total_pages < 2 ? 'one-page' : '';
592 else
593 $page_class = 'no-pages';
594
595 return '<div class="rl-gallery-preview-pagination tablenav"><div class="tablenav-pages ' . esc_attr( $page_class ) . '"><span class="pagination-links">' . join( "\n", $page_links ) . '</span></div>';
596 }
597 }
598