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 / class-frontend.php
responsive-lightbox / includes Last commit date
galleries 1 week ago providers 4 months ago settings 4 months ago class-fast-image.php 2 years ago class-folders.php 1 week ago class-frontend.php 1 week ago class-galleries.php 4 months ago class-multilang.php 2 years ago class-remote-library-api.php 1 week ago class-remote-library.php 1 week ago class-settings-api.php 1 month ago class-settings-data.php 5 months ago class-settings-pages.php 4 months ago class-settings.php 4 months ago class-tour.php 5 months ago class-welcome.php 4 months ago class-widgets.php 2 years ago functions.php 3 years ago
class-frontend.php
2914 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 new Responsive_Lightbox_Frontend();
7
8 /**
9 * Responsive Lightbox frontend class.
10 *
11 * @class Responsive_Lightbox_Frontend
12 */
13 class Responsive_Lightbox_Frontend {
14
15 public $gallery_no = 0;
16
17 private $script_data = [
18 'gallery' => '',
19 'basicgrid' => '',
20 'basicslider' => '',
21 'basicmasonry' => ''
22 ];
23 private $style_data = [
24 'gallery' => '',
25 'basicgrid' => '',
26 'basicslider' => '',
27 'basicmasonry' => ''
28 ];
29
30 /**
31 * Class constructor.
32 *
33 * @return void
34 */
35 public function __construct() {
36 // set instance
37 Responsive_Lightbox()->frontend = $this;
38
39 // actions
40 add_action( 'wp_enqueue_scripts', [ $this, 'wp_enqueue_scripts' ] );
41 add_action( 'wp_enqueue_scripts', [ $this, 'wp_dequeue_scripts' ], 100 );
42 add_action( 'rl_before_gallery', [ $this, 'before_gallery' ], 10, 2 );
43 add_action( 'rl_after_gallery', [ $this, 'after_gallery' ], 10, 2 );
44
45 // filters
46 add_filter( 'rl_gallery_container_class', [ $this, 'gallery_container_class' ], 10, 3 );
47 add_filter( 'the_content', [ $this, 'gallery_preview' ] );
48 add_filter( 'the_content', [ $this, 'add_lightbox' ], 11 );
49 add_filter( 'wp_get_attachment_link', [ $this, 'wp_get_attachment_link' ], 1000, 2 );
50 add_filter( 'get_comment_text', [ $this, 'get_comment_text' ] );
51 add_filter( 'dynamic_sidebar_params', [ $this, 'dynamic_sidebar_params' ] );
52 add_filter( 'rl_widget_output', [ $this, 'widget_output' ], 10, 3 );
53 add_filter( 'post_gallery', [ $this, 'gallery_attributes' ], 1000, 2 );
54 add_filter( 'post_gallery', [ $this, 'basic_grid_gallery_shortcode' ], 1001, 2 );
55 add_filter( 'post_gallery', [ $this, 'basic_slider_gallery_shortcode' ], 1001, 2 );
56 add_filter( 'post_gallery', [ $this, 'basic_masonry_gallery_shortcode' ], 1001, 2 );
57 add_filter( 'post_gallery', [ $this, 'force_custom_gallery_lightbox' ], 2000 );
58
59 // visual composer
60 add_filter( 'vc_shortcode_content_filter_after', [ $this, 'vc_shortcode_content_filter_after' ], 10, 2 );
61
62 // woocommerce
63 add_filter( 'woocommerce_single_product_image_html', [ $this, 'woocommerce_single_product_image_html' ], 100 );
64 add_filter( 'woocommerce_single_product_image_thumbnail_html', [ $this, 'woocommerce_single_product_image_thumbnail_html' ], 100, 2 );
65 }
66
67 /**
68 * Get class data.
69 *
70 * @param string $attr
71 * @return mixed
72 */
73 public function get_data( $attr ) {
74 return property_exists( $this, $attr ) ? $this->{$attr} : null;
75 }
76
77 /**
78 * Determine whether gallery assets should be preloaded for the current request.
79 *
80 * @return bool
81 */
82 private function should_preload_gallery_assets() {
83 global $post;
84
85 if ( ! is_object( $post ) )
86 return false;
87
88 if ( get_post_type( $post ) === 'rl_gallery' && is_singular( 'rl_gallery' ) )
89 return true;
90
91 return has_shortcode( $post->post_content, 'gallery' ) || has_shortcode( $post->post_content, 'rl_gallery' );
92 }
93
94 /**
95 * Determine whether a matched image link is nested inside malformed anchor markup.
96 *
97 * @param string $content Original content.
98 * @param int $offset Matched link offset.
99 * @param string $inner_html Matched link inner HTML.
100 * @return bool
101 */
102 private function is_nested_anchor_context( $content, $offset, $inner_html ) {
103 if ( preg_match( '/<a(?=[\s>])/i', $inner_html ) === 1 )
104 return true;
105
106 if ( $offset <= 0 )
107 return false;
108
109 $prefix = substr( $content, 0, $offset );
110
111 return preg_match_all( '/<a(?=[\s>])/i', $prefix, $matches ) > preg_match_all( '/<\/a>/i', $prefix, $matches );
112 }
113
114 /**
115 * Add lightbox to images, galleries and videos.
116 *
117 * @param string $content HTML content
118 * @return string
119 */
120 public function add_lightbox( $content ) {
121 // get main instance
122 $rl = Responsive_Lightbox();
123
124 // get current script
125 $script = $rl->get_data( 'current_script' );
126
127 // get scripts
128 $scripts = $rl->settings->get_data( 'scripts' );
129
130 // prepare arguments
131 $args = [
132 'selector' => $rl->options['settings']['selector'],
133 'script' => $script,
134 'settings' => [
135 'script' => $rl->options['configuration'][$script],
136 'plugin' => $rl->options['settings']
137 ],
138 'supports' => isset( $scripts[$script]['supports'] ) ? $scripts[$script]['supports'] : []
139 ];
140
141 // workaround for builder galleries to bypass images_as_gallery option, applied only to rl_gallery posts
142 if ( is_singular( 'rl_gallery' ) )
143 $args['settings']['plugin']['images_as_gallery'] = true;
144
145 // search for links containing data-rl_content attribute
146 preg_match_all( '/<a[^>]*?\bdata-rl_content=(["\'])(.*?)\1[^>]*?>/i', $content, $links );
147
148 // found any links?
149 if ( ! empty ( $links[0] ) ) {
150 foreach ( $links[0] as $link_number => $link ) {
151 // set content type
152 $args['content'] = $links[2][$link_number];
153
154 // set link number
155 $args['link_number'] = $link_number;
156
157 // update link
158 $content = str_replace( $link, $this->lightbox_content_link( $link, $args ), $content );
159 }
160 }
161
162 // images
163 if ( $args['settings']['plugin']['image_links'] || $args['settings']['plugin']['images_as_gallery'] || $args['settings']['plugin']['force_custom_gallery'] ) {
164 // search for image links
165 preg_match_all( '/<a([^>]*?)\bhref=(["\'])([^"\']*?)\.(bmp|gif|jpeg|jpg|png|webp|avif)((?:[?#][^"\']*?)?)\2(.*?)>(.*?)<\/a>/is', $content, $links );
166
167 // found any links?
168 if ( ! empty ( $links[0] ) ) {
169 $source_content = $content;
170 $search_offset = 0;
171
172 // generate hash for single images gallery
173 if ( $args['settings']['plugin']['images_as_gallery'] )
174 $args['rel_hash'] = '-gallery-' . $this->generate_hash();
175 else
176 $args['rel_hash'] = '';
177
178 foreach ( $links[0] as $link_number => $link ) {
179 $link_offset = strpos( $source_content, $link, $search_offset );
180
181 if ( $link_offset === false )
182 continue;
183
184 $search_offset = $link_offset + strlen( $link );
185
186 if ( $this->is_nested_anchor_context( $source_content, $link_offset, $links[7][$link_number] ) )
187 continue;
188
189 // get attachment id
190 $args['image_id'] = $this->get_attachment_id_by_url( $links[3][$link_number] . '.' . $links[4][$link_number] );
191
192 // set link number
193 $args['link_number'] = $link_number;
194
195 // link parts
196 $args['link_parts'] = [ $links[1][$link_number], $links[3][$link_number], $links[4][$link_number], $links[5][$link_number], $links[6][$link_number], $links[7][$link_number] ];
197
198 // get title type
199 $title_arg = $args['settings']['plugin']['force_custom_gallery'] ? $args['settings']['plugin']['gallery_image_title'] : $args['settings']['plugin']['image_title'];
200
201 // update title if needed
202 if ( $title_arg !== 'default' && $args['image_id'] )
203 $args['title'] = $this->get_attachment_title( $args['image_id'], apply_filters( 'rl_lightbox_attachment_image_title_arg', $title_arg, $args['image_id'], $links[3][$link_number] . '.' . $links[4][$link_number] ) );
204 else
205 $args['title'] = '';
206
207 // get caption type
208 $caption_arg = $args['settings']['plugin']['force_custom_gallery'] ? $args['settings']['plugin']['gallery_image_caption'] : $args['settings']['plugin']['image_caption'];
209
210 // update caption if needed
211 if ( $caption_arg !== 'default' && $args['image_id'] )
212 $args['caption'] = $this->get_attachment_title( $args['image_id'], apply_filters( 'rl_lightbox_attachment_image_title_arg', $caption_arg, $args['image_id'], $links[3][$link_number] . '.' . $links[4][$link_number] ) );
213 else
214 $args['caption'] = '';
215
216 // rl gallery link?
217 if ( preg_match( '/class="(?:.*?)rl-gallery-link[^"]*?"/i', $links[1][$link_number] ) === 1 || preg_match( '/class="(?:.*?)rl-gallery-link[^"]*?"/i', $links[6][$link_number] ) === 1 ) {
218 // update link allowing only filter to run, bypass default changes
219 $content = str_replace( $link, $this->lightbox_image_link( $link, $args, true ), $content );
220 } else {
221 // update link
222 $content = str_replace( $link, $this->lightbox_image_link( $link, $args ), $content );
223 }
224 }
225 }
226 }
227
228 // videos
229 if ( $args['settings']['plugin']['videos'] && rl_current_lightbox_supports( 'video' ) ) {
230 // search for video links
231 preg_match_all('/<a([^>]*?)\bhref=(["\'])((http|https)(?::\/\/|)(?:(?:(?:youtu\.be\/|(?:www\.)?youtube\.com\/)(?:embed\/|v\/|watch\?v=)?([\w-]{11})(?:\?)?([a-z0-9;:@#&%=+\/\$_.-]*))|(?:(?:www\.)?vimeo\.com\/([0-9]+)(?:\?)?([a-z0-9;:@#&%=+\/\$_.-]*))))\2(.*?)>(.*?)<\/a>/i', $content, $links );
232
233 // set empty video arguments
234 $args['video_id'] = $args['video_type'] = $args['video_query'] = $args['video_protocol'] = '';
235
236 // found any links?
237 if ( ! empty ( $links[0] ) ) {
238 foreach ( $links[0] as $link_number => $link ) {
239 // youtube?
240 if ( $links[5][$link_number] !== '' ) {
241 $args['video_id'] = $links[5][$link_number];
242 $args['video_type'] = 'youtube';
243 $args['video_query'] = $links[6][$link_number];
244 // vimeo?
245 } elseif ( $links[7][$link_number] !== '' ) {
246 $args['video_id'] = $links[7][$link_number];
247 $args['video_type'] = 'vimeo';
248 $args['video_query'] = $links[8][$link_number];
249 }
250
251 // set video protocol
252 $args['video_protocol'] = $links[4][$link_number];
253
254 // set link number
255 $args['link_number'] = $link_number;
256
257 // link parts
258 $args['link_parts'] = [ $links[1][$link_number], $links[3][$link_number], $links[9][$link_number], $links[10][$link_number] ];
259
260 // rl gallery link?
261 if ( preg_match( '/class="(?:.*?)rl-gallery-link[^"]*?"/i', $links[1][$link_number] ) === 1 || preg_match( '/class="(?:.*?)rl-gallery-link[^"]*?"/i', $links[9][$link_number] ) === 1 ) {
262 // update link allowing only filter to run, bypass default changes
263 $content = str_replace( $link, $this->lightbox_video_link( $link, $args, true ), $content );
264 } else {
265 // update link
266 $content = str_replace( $link, $this->lightbox_video_link( $link, $args ), $content );
267 }
268 }
269 }
270 }
271
272 return $content;
273 }
274
275 /**
276 * Add lightbox to video links.
277 *
278 * @param string $link Video link
279 * @param array $args Link arguments
280 * @param bool $only_filter Whether function should run only filter
281 * @return string
282 */
283 public function lightbox_video_link( $link, $args, $only_filter = false ) {
284 if ( ! $only_filter ) {
285 // link already contains data-rel attribute?
286 if ( preg_match( '/<a[^>]*?\bdata-rel=(["\'])(.*?)\1[^>]*?>/is', $link, $result ) === 1 ) {
287 // allow to modify link?
288 if ( $result[2] !== 'norl' ) {
289 // swipebox video fix
290 if ( $args['script'] === 'swipebox' && $args['video_type'] === 'vimeo' )
291 $link = str_replace( $args['link_parts'][1], add_query_arg( 'width', $args['settings']['script']['video_max_width'], $args['link_parts'][1] ), $link );
292
293 // replace data-rel
294 $link = preg_replace( '/\bdata-rel=(["\'])(.*?)\1/s', 'data-rel="' . esc_attr( $args['selector'] ) . '-video-' . (int) $args['link_number'] . '"', $link, 1 );
295
296 if ( $args['script'] === 'magnific' )
297 $link = preg_replace( '/(<a.*?)>/is', '$1 data-magnific_type="video">', $link );
298 }
299 } else {
300 // swipebox video fix
301 if ( $args['script'] === 'swipebox' && $args['video_type'] === 'vimeo' )
302 $args['link_parts'][1] = add_query_arg( 'width', $args['settings']['script']['video_max_width'], $args['link_parts'][1] );
303
304 // add data-rel
305 $link = '<a' . $args['link_parts'][0] . 'href="' . $args['link_parts'][1] . '" data-rel="' . esc_attr( $args['selector'] ) . '-video-' . (int) $args['link_number'] . '"' . $args['link_parts'][2] . '>' . $args['link_parts'][3] . '</a>';
306
307 if ( $args['script'] === 'magnific' )
308 $link = preg_replace( '/(<a.*?)>/is', '$1 data-magnific_type="video">', $link );
309 }
310 }
311
312 return apply_filters( 'rl_lightbox_video_link', $link, $args );
313 }
314
315 /**
316 * Add lightbox to image links.
317 *
318 * @param string $link Image link
319 * @param array $args Link arguments
320 * @param bool $only_filter Whether function should run only filter
321 * @return string
322 */
323 public function lightbox_image_link( $link, $args, $only_filter = false ) {
324 if ( ! $only_filter ) {
325 if ( isset( $_GET['rl_gallery_no'], $_GET['rl_page'] ) )
326 $this->gallery_no = (int) $_GET['rl_gallery_no'];
327
328 // preserve explicit opt-outs without adding lightbox attributes or title/caption data
329 if ( preg_match( '/<a[^>]*?\b(?:data-rel|rel)=(["\'])norl\1[^>]*?>/is', $link ) === 1 )
330 return apply_filters( 'rl_lightbox_image_link', $link, $args );
331
332 // link already contains data-rel attribute?
333 if ( preg_match( '/<a[^>]*?\bdata-rel=(["\'])(.*?)\1[^>]*?>/is', $link, $result ) === 1 ) {
334 // allow to modify link?
335 if ( $result[2] !== 'norl' ) {
336 // gallery?
337 if ( $args['settings']['plugin']['images_as_gallery'] || $args['settings']['plugin']['force_custom_gallery'] )
338 $link = preg_replace( '/\bdata-rel=(["\'])(.*?)\1/s', 'data-rel="' . esc_attr( $args['selector'] ) . '-gallery-' . esc_attr( base64_encode( sanitize_text_field( $result[2] ) ) ) . '" data-rl_title="__RL_IMAGE_TITLE__" data-rl_caption="__RL_IMAGE_CAPTION__"' . ( $args['script'] === 'magnific' ? ' data-magnific_type="gallery"' : '' ) . ( $args['script'] === 'imagelightbox' ? ' data-imagelightbox="' . (int) $args['link_number'] . '"' : '' ), $link, 1 );
339 // single image
340 else
341 $link = preg_replace( '/\bdata-rel=(["\'])(.*?)\1/s', 'data-rel="' . esc_attr( $args['selector'] ) . '-image-' . esc_attr( base64_encode( sanitize_text_field( $result[2] ) ) ) . '"' . ( $args['script'] === 'magnific' ? ' data-magnific_type="image"' : '' ) . ( $args['script'] === 'imagelightbox' ? ' data-imagelightbox="' . (int) $args['link_number'] . '"' : '' ) . ' data-rl_title="__RL_IMAGE_TITLE__" data-rl_caption="__RL_IMAGE_CAPTION__"', $link, 1 );
342 }
343 // link without data-rel
344 } else {
345 // force images?
346 if ( $args['settings']['plugin']['force_custom_gallery'] ) {
347 // link already contains rel attribute?
348 if ( preg_match( '/<a[^>]*?\brel=(["\'])(.*?)\1[^>]*?>/is', $link, $result ) === 1 ) {
349 // allow to modify link?
350 if ( $result[2] !== 'norl' )
351 $link = preg_replace( '/\brel=(["\'])(.*?)\1/s', 'data-rel="' . esc_attr( $args['selector'] ) . '-gallery-' . (int) $this->gallery_no . '" data-rl_title="__RL_IMAGE_TITLE__" data-rl_caption="__RL_IMAGE_CAPTION__"' . ( $args['script'] === 'magnific' ? ' data-magnific_type="gallery"' : '' ) . ( $args['script'] === 'imagelightbox' ? ' data-imagelightbox="' . (int) $args['link_number'] . '"' : '' ), $link, 1 );
352 } else
353 $link = '<a' . $args['link_parts'][0] . ' href="' . $args['link_parts'][1] . '.' . $args['link_parts'][2] . $args['link_parts'][3] . '" data-rel="' . esc_attr( $args['selector'] ) . '-gallery-' . (int) $this->gallery_no . '" data-rl_title="__RL_IMAGE_TITLE__" data-rl_caption="__RL_IMAGE_CAPTION__"' . ( $args['script'] === 'magnific' ? ' data-magnific_type="gallery"' : '' ) . ( $args['script'] === 'imagelightbox' ? ' data-imagelightbox="' . (int) $args['link_number'] . '"' : '' ) . $args['link_parts'][4] . '>' . $args['link_parts'][5] . '</a>';
354 } else
355 $link = '<a' . $args['link_parts'][0] . 'href="' . $args['link_parts'][1] . '.' . $args['link_parts'][2] . $args['link_parts'][3] . '"' . $args['link_parts'][4] . ' data-rel="' . esc_attr( $args['selector'] ) . ( $args['settings']['plugin']['images_as_gallery'] ? esc_attr( $args['rel_hash'] ) : '-image-' . (int) $args['link_number'] ) . '"' . ( $args['script'] === 'magnific' ? ' data-magnific_type="image"' : '' ) . ( $args['script'] === 'imagelightbox' ? ' data-imagelightbox="' . (int) $args['link_number'] . '"' : '' ) . ' data-rl_title="__RL_IMAGE_TITLE__" data-rl_caption="__RL_IMAGE_CAPTION__">' . $args['link_parts'][5] . '</a>';
356 }
357
358 // prepare title and caption
359 $title = trim ( nl2br( $args['title'] ) );
360 $caption = trim( nl2br( $args['caption'] ) );
361
362 if ( ! rl_current_lightbox_supports( 'html_caption' ) ) {
363 $title = wp_strip_all_tags( $title, true );
364 $caption = wp_strip_all_tags( $caption, true );
365 }
366
367 // use safe replacement for data-rl_title and data-rl_caption
368 $link = str_replace( '__RL_IMAGE_TITLE__', esc_attr( $title ), str_replace( '__RL_IMAGE_CAPTION__', esc_attr( $caption ), $link ) );
369
370 // title exists?
371 if ( preg_match( '/<a.*? title=(?:\'|").*?(?:\'|").*?>/is', $link ) === 1 ) {
372 $link = preg_replace( '/(<a.*? title=(?:\'|")).*?((?:\'|").*?>)/s', '${1}__RL_IMAGE_TITLE__$2', $link );
373 } else
374 $link = preg_replace( '/(<a.*?)>/s', '$1 title="__RL_IMAGE_TITLE__">', $link );
375
376 // last safe replacement for title
377 $link = str_replace( '__RL_IMAGE_TITLE__', esc_attr( $title ), $link );
378 }
379
380 return apply_filters( 'rl_lightbox_image_link', $link, $args );
381 }
382
383 /**
384 * Add lightbox to gallery image links.
385 *
386 * @param string $link
387 * @param int|object $id
388 * @return string
389 */
390 public function wp_get_attachment_link( $link, $id ) {
391 // get main instance
392 $rl = Responsive_Lightbox();
393
394 if ( $rl->options['settings']['galleries'] && wp_attachment_is_image( $id ) ) {
395 // get current script
396 $script = $rl->get_data( 'current_script' );
397
398 // get scripts
399 $scripts = $rl->settings->get_data( 'scripts' );
400
401 // prepare arguments
402 $args = [
403 'selector' => $rl->options['settings']['selector'],
404 'script' => $script,
405 'settings' => [
406 'script' => $rl->options['configuration'][$script],
407 'plugin' => $rl->options['settings']
408 ],
409 'supports' => $scripts[$script]['supports'],
410 'image_id' => is_object( $id ) ? $id->id : $id,
411 'title' => '',
412 'caption' => '',
413 'src' => []
414 ];
415
416 $link = $this->lightbox_gallery_link( $link, $args );
417 }
418
419 return $link;
420 }
421
422 /**
423 * Add lightbox to gallery image links.
424 *
425 * @param string $link Gallery image link
426 * @param array $args Gallery link arguments
427 * @return string
428 */
429 public function lightbox_gallery_link( $link, $args ) {
430 // gallery image title
431 $title = ! empty( $args['title'] ) ? $args['title'] : '';
432
433 // get title type
434 $title_arg = $args['settings']['plugin']['gallery_image_title'];
435
436 // update title if needed
437 if ( ! empty( $args['image_id'] ) && $title_arg !== 'default' ) {
438 // original title
439 $args['title'] = $this->get_attachment_title( $args['image_id'], apply_filters( 'rl_lightbox_attachment_image_title_arg', $title_arg, $args['image_id'], $link ) );
440 }
441
442 // prepare title
443 $title = trim ( nl2br( $args['title'] ) );
444
445 if ( ! rl_current_lightbox_supports( 'html_caption' ) )
446 $title = wp_strip_all_tags( $title, true );
447
448 // use safe replacement for title and data-rl_title
449 if ( preg_match( '/<a.*? title=(?:\'|").*?(?:\'|").*?>/is', $link ) === 1 )
450 $link = str_replace( '__RL_IMAGE_TITLE__', esc_attr( $title ), preg_replace( '/(<a.*? title=(?:\'|")).*?((?:\'|").*?>)/s', '$1__RL_IMAGE_TITLE__" data-rl_title="__RL_IMAGE_TITLE__$2', $link ) );
451 else
452 $link = str_replace( '__RL_IMAGE_TITLE__', esc_attr( $title ), preg_replace( '/(<a.*?)>/s', '$1 title="__RL_IMAGE_TITLE__" data-rl_title="__RL_IMAGE_TITLE__">', $link ) );
453
454 // add class if needed
455 if ( preg_match( '/<a[^>]*? class=(?:\'|").*?(?:\'|").*?>/is', $link ) === 1 )
456 $link = preg_replace( '/(<a.*?) class=(?:\'|")(.*?)(?:\'|")(.*?>)/s', '$1 class="$2 rl-gallery-link" $3', $link );
457 else
458 $link = preg_replace( '/(<a.*?)>/s', '$1 class="rl-gallery-link">', $link );
459
460 // gallery image caption
461 $caption = ! empty( $args['caption'] ) ? $args['caption'] : '';
462
463 // get caption type
464 $caption_arg = $args['settings']['plugin']['gallery_image_caption'];
465
466 // update caption if needed
467 if ( ! empty( $args['image_id'] ) && $caption_arg !== 'default' ) {
468 // original caption
469 $args['caption'] = $this->get_attachment_title( $args['image_id'], apply_filters( 'rl_lightbox_attachment_image_title_arg', $caption_arg, $args['image_id'], $link ) );
470 }
471
472 // prepare caption
473 $caption = trim( nl2br( $args['caption'] ) );
474
475 if ( ! rl_current_lightbox_supports( 'html_caption' ) )
476 $caption = wp_strip_all_tags( $caption, true );
477
478 // use safe replacement for data-rl_caption
479 $link = str_replace( '__RL_IMAGE_CAPTION__', esc_attr( $caption ), preg_replace( '/(<a.*?)>/s', '$1 data-rl_caption="__RL_IMAGE_CAPTION__">', $link ) );
480
481 if ( isset( $_GET['rl_gallery_no'], $_GET['rl_page'] ) )
482 $this->gallery_no = (int) $_GET['rl_gallery_no'];
483
484 // link already contains data-rel attribute?
485 if ( preg_match( '/<a[^>]*?\bdata-rel=(["\'])(.*?)\1[^>]*?>/is', $link, $result ) === 1 ) {
486 if ( $result[2] !== 'norl' )
487 $link = preg_replace( '/\bdata-rel=(["\'])(.*?)\1/s', 'data-rel="' . esc_attr( $args['selector'] ) . '-gallery-' . (int) $this->gallery_no . '"', $link, 1 );
488 } else
489 $link = preg_replace( '/(<a.*?)>/s', '$1 data-rel="' . esc_attr( $args['selector'] ) . '-gallery-' . (int) $this->gallery_no . '">', $link );
490
491 if ( ! ( isset( $args['link'] ) && $args['link'] !== 'file' ) ) {
492 // gallery image size
493 if ( ! empty( $args['image_id'] ) ) {
494 if ( empty( $args['src'] ) )
495 $args['src'] = wp_get_attachment_image_src( $args['image_id'], $args['settings']['plugin']['gallery_image_size'] );
496
497 // valid source?
498 if ( ! empty( $args['src'][0] ) ) {
499 if ( preg_match( '/<a[^>]*?\bhref=(["\']).*?\1[^>]*?>/is', $link ) === 1 )
500 $link = preg_replace( '/(<a[^>]*?\bhref=)(["\']).*?\2/is', '$1$2' . $args['src'][0] . '$2', $link, 1 );
501 else
502 $link = preg_replace( '/(<a.*?)>/', '$1 href="' . $args['src'][0] . '">', $link );
503 }
504 }
505
506 if ( $args['script'] === 'magnific' )
507 $link = preg_replace( '/(<a.*?)>/is', '$1 data-magnific_type="gallery">', $link );
508 }
509
510 return apply_filters( 'rl_lightbox_gallery_link', $link, $args );
511 }
512
513 /**
514 * Add lightbox to content links.
515 *
516 * @param string $link
517 * @param array $args
518 *
519 * @return string
520 */
521 public function lightbox_content_link( $link, $args ) {
522 if ( in_array( $args['content'], $args['supports'], true ) ) {
523 libxml_use_internal_errors( true );
524
525 $dom = new DOMDocument();
526 $dom->loadHTML('<?xml encoding="utf-8" ?>' . $link, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
527
528 $anchors = $dom->getElementsByTagName( 'a' );
529
530 if ( $anchors->length > 0 ) {
531 $a = $anchors->item( 0 );
532
533 if ( $a->hasAttribute( 'data-rel' ) ) {
534 $value = $a->getAttribute( 'data-rel' );
535 $a->setAttribute( 'data-rel', esc_attr( $args['selector'] ) . '-content-' . esc_attr( base64_encode( $value ) ) );
536 } else
537 $a->setAttribute( 'data-rel', esc_attr( $args['selector'] ) . '-content-' . (int) $args['link_number'] );
538
539 // remove ending </a> tag
540 $link = preg_replace( '/<\/a>$/', '', $dom->saveHTML($a));
541 }
542
543 libxml_use_internal_errors( false );
544
545 switch ( $args['script'] ) {
546 case 'nivo':
547 $link = preg_replace( '/(<a.*?)>/s', '$1 data-lightbox-type="' . esc_attr( $args['content'] ) . '">', $link );
548 break;
549
550 case 'featherlight':
551 $link = preg_replace( '/(<a.*?)>/s', '$1 data-featherlight="' . esc_attr( $args['content'] ) . '">', $link );
552 break;
553
554 case 'prettyphoto':
555 if ( $args['content'] === 'iframe' )
556 $link = preg_replace( '/(<a[^>]*?\bhref=)(["\'])(.*?)\2/is', '$1$2' . add_query_arg( [ 'iframe' => 'true', 'width' => (int) $args['settings']['width'], 'height' => (int) $args['settings']['height'] ], '$3' ) . '$2', $link, 1 );
557 }
558 }
559
560 return apply_filters( 'rl_lightbox_content_link', $link, $args );
561 }
562
563 /**
564 * Get gallery fields.
565 *
566 * @param string $type Gallery type
567 * @return array
568 */
569 public function get_gallery_fields( $type ) {
570 // get main instance
571 $rl = Responsive_Lightbox();
572
573 // get gallery fields
574 $gallery_fields = $rl->settings->get_setting_fields( $type . '_gallery' );
575
576 // assign settings and defaults
577 $gallery_defaults = $rl->defaults[$type . '_gallery'];
578 $gallery_values = $rl->options[$type . '_gallery'];
579
580 // make a copy
581 $fields_copy = $gallery_fields;
582
583 foreach ( $fields_copy as $field_key => $field ) {
584 if ( $field['type'] === 'multiple' ) {
585 foreach ( $field['fields'] as $subfield_key => $subfield ) {
586 $gallery_fields[$field_key]['fields'][$subfield_key]['default'] = $gallery_defaults[$subfield_key];
587 $gallery_fields[$field_key]['fields'][$subfield_key]['value'] = array_key_exists( $subfield_key, $gallery_values ) ? $gallery_values[$subfield_key] : $gallery_defaults[$subfield_key];
588 }
589 } else {
590 $gallery_fields[$field_key]['default'] = $gallery_defaults[$field_key];
591 $gallery_fields[$field_key]['value'] = array_key_exists( $field_key, $gallery_values ) ? $gallery_values[$field_key] : $gallery_defaults[$field_key];
592 }
593 }
594
595 // get shortcode gallery fields combined with defaults
596 return apply_filters( 'rl_get_gallery_fields', $this->get_unique_fields( $this->get_default_gallery_fields(), $gallery_fields ) );
597 }
598
599 /**
600 * Get unique gallery fields.
601 *
602 * @param array $defaults Default gallery fields
603 * @param array $fields Custom gallery fields
604 * @return array
605 */
606 public function get_unique_fields( $defaults, $fields ) {
607 // check duplicated fields
608 $duplicates = array_intersect_key( $defaults, $fields );
609
610 // any duplicated fields?
611 if ( ! empty( $duplicates ) ) {
612 foreach ( $duplicates as $field_id => $field ) {
613 unset( $defaults[$field_id] );
614 }
615 }
616
617 // get default and custom fields all together
618 return $defaults + $fields;
619 }
620
621 /**
622 * Get gallery fields combined with shortcode attributes.
623 *
624 * @param array $fields Gallery fields
625 * @param array $shortcode_atts Gallery shortcode attributes
626 * @param bool $gallery Whether is it rl_gallery shortcode
627 * @return array
628 */
629 public function get_gallery_fields_atts( $fields, $shortcode_atts, $gallery = true ) {
630 // prepare default values
631 $field_atts = [];
632
633 // get all default field values
634 foreach ( $fields as $field_key => $field ) {
635 if ( $field['type'] === 'multiple' ) {
636 foreach ( $field['fields'] as $subfield_key => $subfield ) {
637 $field_atts[$subfield_key] = array_key_exists( 'value', $subfield ) ? $subfield['value'] : $subfield['default'];
638 }
639 } else
640 $field_atts[$field_key] = array_key_exists( 'value', $field ) ? $field['value'] : $field['default'];
641 }
642
643 // is it rl gallery?
644 if ( $gallery ) {
645 // get tabs
646 $tabs = Responsive_Lightbox()->galleries->get_data( 'tabs' );
647
648 if ( ! empty( $tabs ) ) {
649 foreach ( $tabs as $key => $args ) {
650 if ( in_array( $key, [ 'images', 'config' ] ) )
651 continue;
652
653 // get additional fields
654 $data = get_post_meta( $shortcode_atts['rl_gallery_id'], '_rl_' . $key, true );
655
656 // add those fields
657 if ( is_array( $data ) && ! empty( $data['menu_item'] ) && isset( $data[$data['menu_item']] ) && is_array( $data[$data['menu_item']] ) ) {
658 $new_data = $data[$data['menu_item']];
659
660 if ( $key === 'design' ) {
661 // remove show_title to avoid shortcode attribute duplication
662 if ( isset( $new_data['show_title'] ) ) {
663 if ( ! isset( $new_data['design_show_title'] ) )
664 $new_data['design_show_title'] = $new_data['show_title'];
665
666 unset( $new_data['show_title'] );
667 }
668
669 // remove show_caption to avoid shortcode attribute duplication
670 if ( isset( $new_data['show_caption'] ) ) {
671 if ( ! isset( $new_data['design_show_caption'] ) )
672 $new_data['design_show_caption'] = $new_data['show_caption'];
673
674 unset( $new_data['show_caption'] );
675 }
676 }
677
678 $field_atts += $new_data;
679 }
680 }
681 }
682
683 if ( $field_atts['hover_effect'] !== '0' )
684 $field_atts['gallery_custom_class'] .= ' rl-hover-effect-' . $field_atts['hover_effect'];
685
686 if ( $field_atts['show_icon'] !== '0' )
687 $field_atts['gallery_custom_class'] .= ' rl-hover-icon-' . $field_atts['show_icon'];
688 }
689
690 return (array) apply_filters( 'rl_get_gallery_fields_atts', $field_atts );
691 }
692
693 /**
694 * Get default gallery fields.
695 *
696 * @return array
697 */
698 public function get_default_gallery_fields() {
699 $sizes = get_intermediate_image_sizes();
700 $sizes['full'] = 'full';
701
702 return [
703 'size' => [
704 'title' => __( 'Image Size', 'responsive-lightbox' ),
705 'type' => 'select',
706 'description' => __( 'Specify the image size to use for the thumbnail display.', 'responsive-lightbox' ),
707 'default' => 'medium',
708 'options' => array_combine( $sizes, $sizes )
709 ],
710 'link' => [
711 'title' => __( 'Link To', 'responsive-lightbox' ),
712 'type' => 'select',
713 'description' => __( 'Specify where you want the image to link.', 'responsive-lightbox' ),
714 'default' => 'file',
715 'options' => [
716 'post' => __( 'Attachment Page', 'responsive-lightbox' ),
717 'file' => __( 'Media File', 'responsive-lightbox' ),
718 'none' => __( 'None', 'responsive-lightbox' )
719 ]
720 ],
721 'orderby' => [
722 'title' => __( 'Order By', 'responsive-lightbox' ),
723 'type' => 'select',
724 'description' => __( 'Specify how to sort the display thumbnails.', 'responsive-lightbox' ),
725 'default' => 'menu_order',
726 'options' => [
727 'id' => __( 'ID', 'responsive-lightbox' ),
728 'title' => __( 'Title', 'responsive-lightbox' ),
729 'post_date' => __( 'Date', 'responsive-lightbox' ),
730 'menu_order' => __( 'Menu Order', 'responsive-lightbox' ),
731 'rand' => __( 'Random', 'responsive-lightbox' )
732 ]
733 ],
734 'order' => [
735 'title' => __( 'Order', 'responsive-lightbox' ),
736 'type' => 'radio',
737 'description' => __( 'Specify the sort order.', 'responsive-lightbox' ),
738 'default' => 'asc',
739 'options' => [
740 'asc' => __( 'Ascending', 'responsive-lightbox' ),
741 'desc' => __( 'Descending', 'responsive-lightbox' )
742 ]
743 ],
744 'columns' => [
745 'title' => __( 'Columns', 'responsive-lightbox' ),
746 'type' => 'number',
747 'description' => __( 'Specify the number of columns.', 'responsive-lightbox' ),
748 'default' => 3,
749 'min' => 1,
750 'max' => 12
751 ]
752 ];
753 }
754
755 /**
756 * Sanitize shortcode gallery arguments.
757 *
758 * @param array $atts Shortcode arguments
759 * @param array $fields Gallery fields
760 * @return array
761 */
762 public function sanitize_shortcode_args( $atts, $fields ) {
763 // get main instance
764 $rl = Responsive_Lightbox();
765
766 // validate gallery fields
767 foreach ( $fields as $field_key => $field ) {
768 // checkbox field?
769 if ( $field['type'] === 'checkbox' ) {
770 // valid argument?
771 if ( array_key_exists( $field_key, $atts ) ) {
772 if ( is_array( $atts[$field_key] ) )
773 $array = $atts[$field_key];
774 elseif ( is_string( $atts[$field_key] ) ) {
775 if ( $atts[$field_key] === '' )
776 $array = [];
777 else
778 $array = explode( ',', $atts[$field_key] );
779 } else
780 $array = [];
781
782 $atts[$field_key] = $rl->galleries->sanitize_field( $field_key, array_flip( $array ), $field );
783 }
784 // boolean field?
785 } elseif ( $field['type'] === 'boolean' ) {
786 // multiple field?
787 if ( $field['type'] === 'multiple' ) {
788 foreach ( $field['fields'] as $subfield_key => $subfield ) {
789 // valid argument?
790 if ( array_key_exists( $subfield_key, $atts ) ) {
791 // true value?
792 if ( $atts[$subfield_key] === true || $atts[$subfield_key] === 'true' || $atts[$subfield_key] === '1' )
793 $atts[$subfield_key] = 1;
794 // false value?
795 elseif ( $atts[$subfield_key] === false || $atts[$subfield_key] === 'false' || $atts[$subfield_key] === '0' || $atts[$subfield_key] === '' )
796 $atts[$subfield_key] = 0;
797 // default value
798 else
799 $atts[$subfield_key] = (int) $field['default'];
800 }
801 }
802 } else {
803 // valid argument?
804 if ( array_key_exists( $field_key, $atts ) ) {
805 // true value?
806 if ( $atts[$field_key] === true || $atts[$field_key] === 'true' || $atts[$field_key] === '1' )
807 $atts[$field_key] = 1;
808 // false value?
809 elseif ( $atts[$field_key] === false || $atts[$field_key] === 'false' || $atts[$field_key] === '0' || $atts[$field_key] === '' )
810 $atts[$field_key] = 0;
811 // default value
812 else
813 $atts[$field_key] = (int) $field['default'];
814 }
815 }
816 // multiple field?
817 } elseif ( $field['type'] === 'multiple' ) {
818 foreach ( $field['fields'] as $subfield_key => $subfield ) {
819 // valid argument?
820 if ( array_key_exists( $subfield_key, $atts ) )
821 $atts[$subfield_key] = $rl->galleries->sanitize_field( $subfield_key, $atts[$subfield_key], $subfield );
822 }
823 // other field?
824 } else {
825 // valid argument?
826 if ( array_key_exists( $field_key, $atts ) )
827 $atts[$field_key] = $rl->galleries->sanitize_field( $field_key, $atts[$field_key], $field );
828 }
829 }
830
831 return (array) apply_filters( 'rl_sanitize_shortcode_args', $atts );
832 }
833
834 /**
835 * Get gallery images.
836 *
837 * @param array $shortcode_atts Gallery arguments
838 * @return array
839 */
840 public function get_gallery_shortcode_images( $shortcode_atts ) {
841 // get main instance
842 $rl = Responsive_Lightbox();
843
844 if ( ! isset( $shortcode_atts['design_show_title'] ) || $shortcode_atts['design_show_title'] === 'global' )
845 $shortcode_atts['design_show_title'] = $rl->options['settings']['gallery_image_title'];
846
847 if ( ! isset( $shortcode_atts['design_show_caption'] ) || $shortcode_atts['design_show_caption'] === 'global' )
848 $shortcode_atts['design_show_caption'] = $rl->options['settings']['gallery_image_caption'];
849
850 $images = [];
851
852 // get gallery id
853 $gallery_id = ! empty( $shortcode_atts['rl_gallery_id'] ) ? absint( $shortcode_atts['rl_gallery_id'] ) : 0;
854
855 // get images from gallery
856 if ( $gallery_id ) {
857 $images = $rl->galleries->get_gallery_images(
858 $gallery_id,
859 [
860 'exclude' => true,
861 'image_size' => $shortcode_atts['src_size'],
862 'thumbnail_size' => $shortcode_atts['size'],
863 'preview' => ( isset( $_GET['rl_gallery_revision_id'], $_GET['preview'] ) && $_GET['preview'] === 'true' ) || ( isset( $_POST['action'], $_POST['preview'] ) && $_POST['action'] === 'rl-get-gallery-page-content' && $_POST['preview'] === 'true' && wp_doing_ajax() )
864 ]
865 );
866 // get images from shortcode atts
867 } else {
868 $ids = [];
869
870 if ( ! empty( $shortcode_atts['include'] ) ) {
871 // Normalize input from shortcode strings and widget/programmatic array payloads.
872 $include = wp_parse_id_list( $shortcode_atts['include'] );
873
874 // any attachments?
875 if ( ! empty( $include ) ) {
876 // get attachments
877 $ids = get_posts(
878 [
879 'include' => implode( ',', $include ),
880 'post_status' => 'inherit',
881 'post_type' => 'attachment',
882 'post_mime_type' => 'image',
883 'order' => $shortcode_atts['order'],
884 'orderby' => ( $shortcode_atts['orderby'] === 'menu_order' || $shortcode_atts['orderby'] === '' ? 'post__in' : $shortcode_atts['orderby'] ),
885 'fields' => 'ids'
886 ]
887 );
888 }
889 } elseif ( ! empty( $shortcode_atts['exclude'] ) ) {
890 // Normalize input from shortcode strings and widget/programmatic array payloads.
891 $exclude = wp_parse_id_list( $shortcode_atts['exclude'] );
892
893 // any attachments?
894 if ( ! empty( $exclude ) ) {
895 // get attachments
896 $ids = get_children(
897 [
898 'post_parent' => $shortcode_atts['id'],
899 'exclude' => $exclude,
900 'post_status' => 'inherit',
901 'post_type' => 'attachment',
902 'post_mime_type' => 'image',
903 'order' => $shortcode_atts['order'],
904 'orderby' => $shortcode_atts['orderby'],
905 'fields' => 'ids'
906 ]
907 );
908 }
909 } else {
910 // get attachments
911 $ids = get_children(
912 [
913 'post_parent' => $shortcode_atts['id'],
914 'post_status' => 'inherit',
915 'post_type' => 'attachment',
916 'post_mime_type' => 'image',
917 'order' => $shortcode_atts['order'],
918 'orderby' => $shortcode_atts['orderby'],
919 'fields' => 'ids'
920 ]
921 );
922 }
923
924 // any attachments?
925 if ( ! empty( $ids ) ) {
926 foreach ( $ids as $attachment_id ) {
927 // get thumbnail image data
928 $images[] = $rl->galleries->get_gallery_image_src( $attachment_id, $shortcode_atts['src_size'], $shortcode_atts['size'] );
929 }
930 }
931 }
932
933 // apply adjustments, as per settings
934 if ( $images ) {
935 // get current script
936 $script = $rl->get_data( 'current_script' );
937
938 // get scripts
939 $scripts = $rl->settings->get_data( 'scripts' );
940
941 // prepare arguments
942 $args = [
943 'selector' => $rl->options['settings']['selector'],
944 'script' => $script,
945 'settings' => [
946 'script' => $rl->options['configuration'][$script],
947 'plugin' => $rl->options['settings']
948 ],
949 'supports' => isset( $scripts[$script]['supports'] ) ? $scripts[$script]['supports'] : [],
950 'image_id' => 0,
951 'caption' => '',
952 'title' => '',
953 'src' => []
954 ];
955
956 // lightbox image title
957 $args['settings']['plugin']['gallery_image_title'] = ! empty( $shortcode_atts['lightbox_image_title'] ) ? ( $shortcode_atts['lightbox_image_title'] === 'global' ? $rl->options['settings']['gallery_image_title'] : $shortcode_atts['lightbox_image_title'] ) : $rl->options['settings']['gallery_image_title'];
958
959 // lightbox image caption
960 $args['settings']['plugin']['gallery_image_caption'] = ! empty( $shortcode_atts['lightbox_image_caption'] ) ? ( $shortcode_atts['lightbox_image_caption'] === 'global' ? $rl->options['settings']['gallery_image_caption'] : $shortcode_atts['lightbox_image_caption'] ) : $rl->options['settings']['gallery_image_caption'];
961
962 // get gallery image link
963 $args['link'] = isset( $shortcode_atts['link'] ) ? $shortcode_atts['link'] : '';
964
965 // copy images
966 $images_tmp = $images;
967
968 // apply adjustments, according to gallery settings
969 foreach ( $images_tmp as $index => $image ) {
970 // assign image
971 $new_image = $images[$index] = array_merge( $image, $rl->galleries->get_gallery_image_src( $image, $shortcode_atts['src_size'], $shortcode_atts['size'] ) );
972
973 // create image source data
974 $args['src'] = [ $new_image['url'], $new_image['width'], $new_image['height'], $new_image ];
975
976 // update image id
977 if ( ! empty( $new_image['id'] ) )
978 $args['image_id'] = $new_image['id'];
979
980 // set alt text
981 $images[$index]['alt'] = $shortcode_atts['alt'] = ! empty( $new_image['alt'] ) ? $new_image['alt'] : ( ! empty( $new_image['id'] ) ? get_post_meta( $new_image['id'], '_wp_attachment_image_alt', true ) : '' );
982
983 // set lightbox image title
984 if ( $args['settings']['plugin']['gallery_image_title'] === 'default' )
985 $images[$index]['title'] = $args['title'] = '';
986 else {
987 // embed element?
988 if ( preg_match( '/^e\d+$/', $new_image['id'] ) === 1 )
989 $shortcode_atts['title'] = $images[$index]['title'] = $args['title'] = $this->get_embed_title( $new_image['id'], apply_filters( 'rl_lightbox_embed_image_title_arg', $args['settings']['plugin']['gallery_image_title'], $images[$index]['link'] ), $new_image );
990 else
991 $images[$index]['title'] = $args['title'] = ! empty( $new_image['id'] ) ? $this->get_attachment_title( $new_image['id'], apply_filters( 'rl_lightbox_attachment_image_title_arg', $args['settings']['plugin']['gallery_image_title'], $new_image['id'], $images[$index]['link'] ) ) : $new_image['title'];
992 }
993
994 // set lightbox image caption
995 if ( $args['settings']['plugin']['gallery_image_caption'] === 'default' )
996 $images[$index]['caption'] = $args['caption'] = '';
997 else {
998 // embed element?
999 if ( preg_match( '/^e\d+$/', $new_image['id'] ) === 1 )
1000 $shortcode_atts['caption'] = $images[$index]['caption'] = $args['caption'] = $this->get_embed_title( $new_image['id'], apply_filters( 'rl_lightbox_embed_image_title_arg', $args['settings']['plugin']['gallery_image_caption'], $images[$index]['link'] ), $new_image );
1001 else
1002 $images[$index]['caption'] = $args['caption'] = ! empty( $new_image['id'] ) ? $this->get_attachment_title( $new_image['id'], apply_filters( 'rl_lightbox_attachment_image_title_arg', $args['settings']['plugin']['gallery_image_caption'], $images[$index]['link'] ) ) : $new_image['caption'];
1003 }
1004
1005 // set image gallery link
1006 $images[$index]['link'] = $this->lightbox_gallery_link( $this->get_gallery_image_link( $new_image['id'], $args['src'], [ $new_image['thumbnail_url'], $new_image['thumbnail_width'], $new_image['thumbnail_height'] ], $shortcode_atts ), $args );
1007
1008 // is lightbox active?
1009 if ( isset( $shortcode_atts['lightbox_enable'] ) && $shortcode_atts['lightbox_enable'] === 0 )
1010 $images[$index]['link'] = preg_replace( '/\bdata-rel=(["\'])(.*?)\1/', 'data-rel="norl"', $images[$index]['link'], 1 );
1011 }
1012 }
1013
1014 return (array) apply_filters( 'rl_get_gallery_shortcode_images', $images, $gallery_id, $shortcode_atts );
1015 }
1016
1017 /**
1018 * Get gallery image link.
1019 *
1020 * @param int $attachment_id Attachment ID
1021 * @param array $image Source image data
1022 * @param array $thumbnail Thumbnail image data
1023 * @param array $args Arguments
1024 * @return string
1025 */
1026 function get_gallery_image_link( $attachment_id, $image, $thumbnail, $args ) {
1027 // link type
1028 switch ( $args['link'] ) {
1029 case 'post':
1030 // embed element?
1031 if ( preg_match( '/^e\d+$/', $attachment_id ) === 1 )
1032 $attr = [ 'href' => $image[0] ];
1033 else
1034 $attr = [ 'href' => get_permalink( $attachment_id ) ];
1035 break;
1036
1037 case 'none':
1038 $attr = [ 'href' => 'javascript:void(0);', 'style' => 'cursor: default;' ];
1039 break;
1040
1041 default:
1042 case 'file':
1043 $attr = [ 'href' => $image[0] ];
1044 }
1045
1046 // filter attributes
1047 $attr = apply_filters( 'rl_gallery_image_link_attributes', $attr, $attachment_id, $image, $args );
1048
1049 // start link
1050 $link = '<a';
1051
1052 // escape attributes
1053 foreach ( $attr as $name => $value ) {
1054 $link .= ' ' . esc_attr( $name ) . '="' . ( $name === 'href' ? esc_url( $value ) : esc_attr( $value ) ) . '"';
1055 }
1056
1057 $link .= '>';
1058 $link .= apply_filters( 'rl_gallery_image_link_before', '', $attachment_id, $args );
1059 $link .= '<img src="' . esc_url( $thumbnail[0] ) . '" width="' . (int) $thumbnail[1] . '" height="' . (int) $thumbnail[2] . '" alt="' . esc_attr( $args['alt'] ) . '"' . ( isset( $args['hide_image'] ) && $args['hide_image'] ? ' style="display: none;"' : '' ) . '/>';
1060
1061 // embed element?
1062 if ( preg_match( '/^e\d+$/', $attachment_id ) === 1 ) {
1063 $title = ! empty( $args['design_show_title'] ) ? $this->get_embed_title( $attachment_id, $args['design_show_title'], $args ) : '';
1064 $caption = ! empty( $args['design_show_caption'] ) ? $this->get_embed_title( $attachment_id, $args['design_show_caption'], $args ) : '';
1065 } else {
1066 $title = ! empty( $args['design_show_title'] ) ? $this->get_attachment_title( $attachment_id, $args['design_show_title'] ) : '';
1067 $caption = ! empty( $args['design_show_caption'] ) ? $this->get_attachment_title( $attachment_id, $args['design_show_caption'] ) : '';
1068 }
1069
1070 if ( $title || $caption ) {
1071 $link .= '<span class="rl-gallery-caption">';
1072
1073 if ( $title )
1074 $link .= '<span class="rl-gallery-item-title">' . esc_html( $title ) . '</span>';
1075
1076 if ( $caption )
1077 $link .= '<span class="rl-gallery-item-caption">' . esc_html( $caption ) . '</span>';
1078
1079 $link .= '</span>';
1080 }
1081
1082 $link .= apply_filters( 'rl_gallery_image_link_after', '', $attachment_id, $args );
1083 $link .= '</a>';
1084
1085 return apply_filters( 'rl_gallery_image_link', $link, $attachment_id, $image, $thumbnail, $args );
1086 }
1087
1088 /**
1089 * Add lightbox to Jetpack tiled gallery.
1090 *
1091 * @param string $content
1092 * @return string
1093 */
1094 public function force_custom_gallery_lightbox( $content ) {
1095 // get main instance
1096 $rl = Responsive_Lightbox();
1097
1098 if ( $rl->options['settings']['force_custom_gallery'] ) {
1099 // search for image links
1100 preg_match_all( '/<a(.*?)\bhref=(["\'])([^"\']*?)\.(bmp|gif|jpeg|jpg|png|webp|avif)((?:[?#][^"\']*?)?)\2(.*?)>/i', $content, $links );
1101
1102 // found any links?
1103 if ( ! empty ( $links[0] ) ) {
1104 // get current script
1105 $script = $rl->get_data( 'current_script' );
1106
1107 foreach ( $links[0] as $link_number => $link ) {
1108 // get attachment id
1109 $image_id = $this->get_attachment_id_by_url( $links[3][$link_number] . '.' . $links[4][$link_number] );
1110
1111 // get title type
1112 $title_arg = $rl->options['settings']['gallery_image_title'];
1113
1114 // update title if needed
1115 if ( $title_arg !== 'default' && $image_id )
1116 $title = wp_strip_all_tags( $this->get_attachment_title( $image_id, apply_filters( 'rl_lightbox_attachment_image_title_arg', $title_arg, $image_id, $links[3][$link_number] . '.' . $links[4][$link_number] ) ), true );
1117 else
1118 $title = '';
1119
1120 // get caption type
1121 $caption_arg = $rl->options['settings']['gallery_image_caption'];
1122
1123 // update caption if needed
1124 if ( $caption_arg !== 'default' )
1125 $caption = wp_strip_all_tags( $this->get_attachment_title( $image_id, apply_filters( 'rl_lightbox_attachment_image_title_arg', $caption_arg, $image_id, $links[3][$link_number] . '.' . $links[4][$link_number] ) ), true );
1126 else
1127 $caption = '';
1128
1129 // link already contains data-rel attribute?
1130 if ( preg_match( '/<a[^>]*?\bdata-rel=(["\'])(.*?)\1[^>]*?>/i', $link, $result ) === 1 ) {
1131 // do not modify this link
1132 if ( $result[2] === 'norl' )
1133 continue;
1134
1135 $content = str_replace( $link, preg_replace( '/\bdata-rel=(["\'])(.*?)\1/', 'data-rel="' . esc_attr( $rl->options['settings']['selector'] ) . '-gallery-' . esc_attr( base64_encode( sanitize_text_field( $result[2] ) ) ) . '" data-rl_title="' . esc_attr( $title ) . '" data-rl_caption="' . esc_attr( $caption ) . '"' . ( $script === 'imagelightbox' ? ' data-imagelightbox="' . (int) $link_number . '"' : '' ), $link, 1 ), $content );
1136 } elseif ( preg_match( '/<a[^>]*?\brel=(["\'])(.*?)\1[^>]*?>/i', $link, $result ) === 1 ) {
1137 // do not modify this link
1138 if ( $result[2] === 'norl' )
1139 continue;
1140
1141 $content = str_replace( $link, preg_replace( '/\brel=(["\'])(.*?)\1/', 'data-rel="' . esc_attr( $rl->options['settings']['selector'] ) . '-gallery-' . esc_attr( base64_encode( sanitize_text_field( $result[2] ) ) ) . '" data-rl_title="' . esc_attr( $title ) . '" data-rl_caption="' . esc_attr( $caption ) . '"' . ( $script === 'imagelightbox' ? ' data-imagelightbox="' . (int) $link_number . '"' : '' ), $link, 1 ), $content );
1142 } else
1143 $content = str_replace( $link, '<a' . $links[1][$link_number] . ' href="' . $links[3][$link_number] . '.' . $links[4][$link_number] . $links[5][$link_number] . '" data-rel="' . esc_attr( $rl->options['settings']['selector'] ) . '-gallery-' . esc_attr( base64_encode( $this->gallery_no ) ) . '" data-rl_title="' . esc_attr( $title ) . '" data-rl_caption="' . esc_attr( $caption ) . '"' . ( $script === 'imagelightbox' ? ' data-imagelightbox="' . (int) $link_number . '"' : '' ) . $links[6][$link_number] . '>', $content );
1144 }
1145 }
1146 }
1147
1148 return $content;
1149 }
1150
1151 /**
1152 * Remove specific styles and scripts.
1153 *
1154 * @global object $woocommerce
1155 *
1156 * @return void
1157 */
1158 public function wp_dequeue_scripts() {
1159 // woocommerce
1160 if ( class_exists( 'WooCommerce' ) ) {
1161 global $woocommerce;
1162
1163 // get main instance
1164 $rl = Responsive_Lightbox();
1165
1166 // specific woocommerce gallery?
1167 if ( ! empty( $rl->options['settings']['default_woocommerce_gallery'] ) && $rl->options['settings']['default_woocommerce_gallery'] !== 'default' ) {
1168 // replace default woocommerce lightbox?
1169 if ( $rl->options['settings']['woocommerce_gallery_lightbox'] === true ) {
1170 if ( version_compare( $woocommerce->version, '3.0', ">=" ) ) {
1171 // dequeue scripts
1172 wp_dequeue_script( 'flexslider' );
1173 wp_dequeue_script( 'photoswipe' );
1174 wp_dequeue_script( 'photoswipe-ui-default' );
1175
1176 // dequeue styles
1177 wp_dequeue_style( 'photoswipe' );
1178 wp_dequeue_style( 'photoswipe-default-skin' );
1179
1180 // remove theme supports
1181 remove_theme_support( 'wc-product-gallery-lightbox' );
1182 remove_theme_support( 'wc-product-gallery-slider' );
1183 } else {
1184 // remove styles
1185 wp_dequeue_style( 'woocommerce_prettyPhoto_css' );
1186
1187 // remove scripts
1188 wp_dequeue_script( 'prettyPhoto' );
1189 wp_dequeue_script( 'prettyPhoto-init' );
1190 wp_dequeue_script( 'enable-lightbox' );
1191 }
1192 } else {
1193 if ( version_compare( $woocommerce->version, '3.0', ">=" ) ) {
1194 // dequeue scripts
1195 wp_dequeue_script( 'flexslider' );
1196 }
1197 }
1198 // default gallery?
1199 } else {
1200 // replace default woocommerce lightbox?
1201 if ( $rl->options['settings']['woocommerce_gallery_lightbox'] === true ) {
1202 if ( version_compare( $woocommerce->version, '3.0', ">=" ) ) {
1203 // dequeue scripts
1204 wp_dequeue_script( 'photoswipe' );
1205 wp_dequeue_script( 'photoswipe-ui-default' );
1206
1207 // dequeue styles
1208 wp_dequeue_style( 'photoswipe' );
1209 wp_dequeue_style( 'photoswipe-default-skin' );
1210
1211 // remove theme supports
1212 remove_theme_support( 'wc-product-gallery-lightbox' );
1213 } else {
1214 // remove styles
1215 wp_dequeue_style( 'woocommerce_prettyPhoto_css' );
1216
1217 // remove scripts
1218 wp_dequeue_script( 'prettyPhoto' );
1219 wp_dequeue_script( 'prettyPhoto-init' );
1220 wp_dequeue_script( 'enable-lightbox' );
1221 }
1222 }
1223 }
1224 }
1225
1226 // visual composer
1227 if ( class_exists( 'Vc_Manager' ) ) {
1228 wp_dequeue_script( 'prettyphoto' );
1229 wp_deregister_script( 'prettyphoto' );
1230 wp_dequeue_style( 'prettyphoto' );
1231 wp_deregister_style( 'prettyphoto' );
1232 }
1233 }
1234
1235 /**
1236 * Apply lightbox to WooCommerce product image.
1237 *
1238 * @param string $html
1239 * @return string
1240 */
1241 public function woocommerce_single_product_image_html( $html ) {
1242 // get main instance
1243 $rl = Responsive_Lightbox();
1244
1245 if ( $rl->options['settings']['woocommerce_gallery_lightbox'] )
1246 $html = preg_replace( '/data-rel=\"(.*?)\"/', 'data-rel="' . esc_attr( $rl->options['settings']['selector'] ) . '-gallery-' . (int) $this->gallery_no . '"', $html );
1247
1248 return $html;
1249 }
1250
1251 /**
1252 * Apply lightbox to WooCommerce product gallery.
1253 *
1254 * @param string $html
1255 * @param int $attachment_id
1256 * @return string
1257 */
1258 public function woocommerce_single_product_image_thumbnail_html( $html, $attachment_id ) {
1259 // get main instance
1260 $rl = Responsive_Lightbox();
1261
1262 if ( $rl->options['settings']['woocommerce_gallery_lightbox'] ) {
1263 // make sure main product image has same gallery number
1264 $gallery_no = $this->gallery_no + 1;
1265
1266 $html = preg_replace( '/data-rel=\"(.*?)\"/', 'data-rel="' . esc_attr( $rl->options['settings']['selector'] ) . '-gallery-' . (int) $gallery_no . '"', $html );
1267
1268 preg_match( '/<a(.*?)((?:data-rel)=(?:\'|").*?(?:\'|"))(.*?)>/i', $html, $result );
1269
1270 // no data-rel?
1271 if ( empty( $result ) ) {
1272 preg_match( '/^(.*?)<a(.*?)((?:href)=(?:\'|").*?(?:\'|"))(.*?)>(.*?)$/i', $html, $result );
1273
1274 // found valid link?
1275 if ( ! empty( $result ) )
1276 $html = $result[1] . '<a' . $result[2] . 'data-rel="' . esc_attr( $rl->options['settings']['selector'] ) . '-gallery-' . (int) $gallery_no . '" ' . $result[3] . $result[4] . '>' . $result[5];
1277 }
1278
1279 $html = $this->woocommerce_gallery_link( $html, $attachment_id );
1280 }
1281
1282 return $html;
1283 }
1284
1285 /**
1286 * Add title and caption to WooCommerce gallery image links.
1287 *
1288 * @param string $link
1289 * @param int $attachment_id
1290 * @return string
1291 */
1292 public function woocommerce_gallery_link( $link, $attachment_id ) {
1293 // get main instance
1294 $rl = Responsive_Lightbox();
1295
1296 // gallery image title
1297 $title = '';
1298
1299 // get title type
1300 $title_arg = $rl->options['settings']['gallery_image_title'];
1301
1302 // update title if needed
1303 if ( $title_arg !== 'default' ) {
1304 // original title
1305 $title = $this->get_attachment_title( $attachment_id, apply_filters( 'rl_lightbox_attachment_image_title_arg', $title_arg, $attachment_id, $link ) );
1306 }
1307
1308 if ( $title !== '' ) {
1309 // title
1310 $title = trim( nl2br( $title ) );
1311
1312 if ( ! rl_current_lightbox_supports( 'html_caption' ) )
1313 $title = wp_strip_all_tags( $title, true );
1314
1315 // add title and rl_title if needed
1316 if ( preg_match( '/<a[^>]*?title=(?:\'|")[^>]*?(?:\'|").*?>/is', $link ) === 1 )
1317 $link = str_replace( '__RL_IMAGE_TITLE__', esc_attr( $title ), preg_replace( '/(<a[^>]*?title=(?:\'|"))[^>]*?((?:\'|").*?>)/is', '$1__RL_IMAGE_TITLE__" data-rl_title="__RL_IMAGE_TITLE__$2', $link ) );
1318 else
1319 $link = str_replace( '__RL_IMAGE_TITLE__', esc_attr( $title ), preg_replace( '/(<a[^>]*?)>/is', '$1 title="__RL_IMAGE_TITLE__" data-rl_title="__RL_IMAGE_TITLE__">', $link ) );
1320 }
1321
1322 // gallery image caption
1323 $caption = '';
1324
1325 // get caption type
1326 $caption_arg = $rl->options['settings']['gallery_image_caption'];
1327
1328 // update caption if needed
1329 if ( $caption_arg !== 'default' ) {
1330 // original caption
1331 $caption = $this->get_attachment_title( $attachment_id, apply_filters( 'rl_lightbox_attachment_image_title_arg', $caption_arg, $attachment_id, $link ) );
1332 }
1333
1334 if ( $caption !== '' ) {
1335 // caption
1336 $caption = trim( nl2br( $caption ) );
1337
1338 if ( ! rl_current_lightbox_supports( 'html_caption' ) )
1339 $caption = wp_strip_all_tags( $caption, true );
1340
1341 // add rl_caption
1342 $link = str_replace( '__RL_IMAGE_CAPTION__', esc_attr( $caption ), preg_replace( '/(<a[^>]*?)>/is', '$1 data-rl_caption="__RL_IMAGE_CAPTION__">', $link ) );
1343 }
1344
1345 if ( $rl->get_data( 'current_script' ) === 'magnific' )
1346 $link = preg_replace( '/(<a[^>]*?)>/is', '$1 data-magnific_type="gallery">', $link );
1347
1348 return $link;
1349 }
1350
1351 /**
1352 * WooCommerce gallery init.
1353 *
1354 * @return void
1355 */
1356 public function woocommerce_gallery_init() {
1357 // get main instance
1358 $rl = Responsive_Lightbox();
1359
1360 if ( ( $priority = has_action( 'woocommerce_product_thumbnails', 'woocommerce_show_product_thumbnails' ) ) !== false && ! empty( $rl->options['settings']['default_woocommerce_gallery'] ) && $rl->options['settings']['default_woocommerce_gallery'] !== 'default' ) {
1361 // remove default gallery
1362 remove_action( 'woocommerce_product_thumbnails', 'woocommerce_show_product_thumbnails', $priority );
1363
1364 // handle product gallery
1365 add_action( 'woocommerce_product_thumbnails', [ $this, 'woocommerce_gallery' ], $priority );
1366 }
1367 }
1368
1369 /**
1370 * WooCommerce gallery support.
1371 *
1372 * @global object $product
1373 *
1374 * @return void
1375 */
1376 public function woocommerce_gallery() {
1377 global $product;
1378
1379 $attachment_ids = [];
1380
1381 // woocommerce 3.x
1382 if ( method_exists( $product, 'get_gallery_image_ids' ) )
1383 $attachment_ids = $product->get_gallery_image_ids();
1384 // woocommerce 2.x
1385 elseif ( method_exists( $product, 'get_gallery_attachment_ids' ) )
1386 $attachment_ids = $product->get_gallery_attachment_ids();
1387
1388 if ( ! empty( $attachment_ids ) && is_array( $attachment_ids ) )
1389 echo do_shortcode( '[gallery type="' . esc_attr( Responsive_Lightbox()->options['settings']['default_woocommerce_gallery'] ) . '" size="medium" ids="' . esc_attr( implode( ',', $attachment_ids ) ) . '"]' );
1390 }
1391
1392 /**
1393 * Get embed text.
1394 *
1395 * @param string $id
1396 * @param string $title_arg
1397 * @param array $embed
1398 * @return false|string
1399 */
1400 public function get_embed_title( $id, $title_arg, $embed ) {
1401 if ( empty( $title_arg ) || empty( $id ) )
1402 return false;
1403
1404 switch( $title_arg ) {
1405 case 'title':
1406 $text = $embed['title'];
1407 break;
1408
1409 // caption is always the same for these options
1410 case 'caption':
1411 case 'alt':
1412 case 'description':
1413 $text = $embed['caption'];
1414 break;
1415
1416 default:
1417 $text = '';
1418 }
1419
1420 return trim( apply_filters( 'rl_get_embed_title', $text, $id, $title_arg, $embed ) );
1421 }
1422
1423 /**
1424 * Get attachment text.
1425 *
1426 * @param int $id
1427 * @param string $title_arg
1428 * @return false|string
1429 */
1430 public function get_attachment_title( $id, $title_arg ) {
1431 if ( empty( $title_arg ) || empty( $id ) )
1432 return false;
1433
1434 switch( $title_arg ) {
1435 case 'title':
1436 $text = get_the_title( $id );
1437 break;
1438
1439 case 'caption':
1440 $text = get_post_field( 'post_excerpt', $id ) ;
1441 break;
1442
1443 case 'alt':
1444 $text = get_post_meta( $id, '_wp_attachment_image_alt', true );
1445 break;
1446
1447 case 'description':
1448 $text = get_post_field( 'post_content', $id ) ;
1449 break;
1450
1451 default:
1452 $text = '';
1453 }
1454
1455 return trim( apply_filters( 'rl_get_attachment_title', $text, $id, $title_arg ) );
1456 }
1457
1458 /**
1459 * Get attachment ID by url, adjusted to work for cropped and scaled images.
1460 *
1461 * @param string $url
1462 * @return int
1463 */
1464 public function get_attachment_id_by_url( $url ) {
1465 $org_url = $url;
1466
1467 // parse url
1468 $url = ! empty( $url ) ? esc_url_raw( $url ) : '';
1469
1470 // get url with both schemes
1471 $url_http = set_url_scheme( $url, 'http' );
1472 $url_https = set_url_scheme( $url, 'https' );
1473
1474 // https? set scheme order
1475 if ( is_ssl() )
1476 $urls = [ $url_https, $url_http ];
1477 else
1478 $urls = [ $url_http, $url_https ];
1479
1480 // get upload dir
1481 $dir = wp_get_upload_dir();
1482
1483 // set base url
1484 $base_url = $dir['baseurl'];
1485
1486 if ( is_ssl() )
1487 $base_url = set_url_scheme( $base_url, 'https' );
1488
1489 // set post id
1490 $post_id = 0;
1491
1492 // get cached data
1493 $post_ids = get_transient( 'rl-attachment_ids_by_url' );
1494
1495 // set default flag
1496 $update_transient = false;
1497
1498 // check url with forced scheme based on is_ssl(), then fallback to second one
1499 foreach ( $urls as $url_with_scheme ) {
1500 // set current url
1501 $url = $url_with_scheme;
1502
1503 // cached url not found?
1504 if ( $post_ids === false || ! in_array( $url_with_scheme, array_keys( $post_ids ), true ) ) {
1505 // try to get post id
1506 $post_id = $this->_get_attachment_id_by_url( $url_with_scheme, $base_url );
1507
1508 // set flag
1509 $update_transient = true;
1510 // cached url found
1511 } elseif ( ! empty( $post_ids[$url_with_scheme] ) )
1512 $post_id = (int) $post_ids[$url_with_scheme];
1513 // found post id but it is zero
1514 else {
1515 // try to refresh post id
1516 $post_id = $this->_get_attachment_id_by_url( $url_with_scheme, $base_url );
1517
1518 // set flag
1519 $update_transient = true;
1520 }
1521
1522 if ( $post_id )
1523 break;
1524
1525 // set default flag
1526 $update_transient = false;
1527 }
1528
1529 if ( $update_transient ) {
1530 // set the cache expiration, 24 hours by default
1531 $expire = (int) apply_filters( 'rl_object_cache_expire', DAY_IN_SECONDS );
1532
1533 if ( ! is_array( $post_ids ) )
1534 $post_ids = [];
1535
1536 // update post ids
1537 $post_ids[$url] = $post_id;
1538
1539 // set transient
1540 set_transient( 'rl-attachment_ids_by_url', $post_ids, $expire );
1541 }
1542
1543 return (int) apply_filters( 'rl_get_attachment_id_by_url', $post_id, $org_url );
1544 }
1545
1546 /**
1547 * Get attachment ID by url.
1548 *
1549 * @param string $url
1550 * @param string $base_url
1551 * @return int
1552 */
1553 private function _get_attachment_id_by_url( $url, $base_url ) {
1554 // try to get post id
1555 $post_id = (int) attachment_url_to_postid( $url );
1556
1557 // no post id?
1558 if ( ! $post_id ) {
1559 $path = $url;
1560
1561 if ( strpos( $path, $base_url . '/' ) === 0 )
1562 $path = substr( $path, strlen( $base_url . '/' ) );
1563
1564 // try to check full size image
1565 if ( preg_match( '/^(.*)(\-\d*x\d*)(\.\w{1,})/i', $path, $matches ) )
1566 $post_id = (int) attachment_url_to_postid( $base_url . '/' . $matches[1] . $matches[3] );
1567
1568 // try to check scaled size image
1569 if ( ! $post_id && ! empty( $matches[1] ) && ! empty( $matches[3] ) )
1570 $post_id = (int) attachment_url_to_postid( $base_url . '/' . $matches[1] . '-scaled' . $matches[3] );
1571 }
1572
1573 return $post_id;
1574 }
1575
1576 /**
1577 * Get image size by URL.
1578 *
1579 * @param string $url Image URL
1580 * @return array
1581 */
1582 public function get_image_size_by_url( $url ) {
1583 $size = [ 0, 0 ];
1584 $sanitized_url = $this->sanitize_remote_image_url( $url );
1585
1586 if ( empty( $sanitized_url ) )
1587 return (array) apply_filters( 'rl_get_image_size_by_url', $size, $sanitized_url );
1588
1589 $url = $sanitized_url;
1590
1591 $image_sizes = get_transient( 'rl-image_sizes_by_url' );
1592
1593 if ( ! is_array( $image_sizes ) )
1594 $image_sizes = [];
1595
1596 if ( isset( $image_sizes[$url] ) && is_array( $image_sizes[$url] ) ) {
1597 $size = array_map( 'absint', $image_sizes[$url] );
1598 } else {
1599 $size = $this->remote_image_size_lookup( $url );
1600
1601 if ( $size[0] > 0 && $size[1] > 0 ) {
1602 $image_sizes[$url] = $size;
1603 $expire = absint( apply_filters( 'rl_object_cache_expire', DAY_IN_SECONDS ) );
1604 set_transient( 'rl-image_sizes_by_url', $image_sizes, $expire );
1605 }
1606 }
1607
1608 return (array) apply_filters( 'rl_get_image_size_by_url', $size, $url );
1609 }
1610
1611 /**
1612 * Sanitize and validate a remote image URL.
1613 *
1614 * @param string $url
1615 * @return string
1616 */
1617 public function sanitize_remote_image_url( $url ) {
1618 $url = ! empty( $url ) ? esc_url_raw( $url ) : '';
1619
1620 if ( empty( $url ) )
1621 return '';
1622
1623 $validated_url = wp_http_validate_url( $url );
1624
1625 if ( ! $validated_url )
1626 return '';
1627
1628 $is_allowed = $this->is_remote_image_url_allowed( $validated_url );
1629 $is_allowed = apply_filters( 'rl_is_remote_image_url_allowed', $is_allowed, $validated_url );
1630
1631 return $is_allowed ? $validated_url : '';
1632 }
1633
1634 /**
1635 * Add gallery shortcode to gallery post content.
1636 *
1637 * @param string $content
1638 * @return string
1639 */
1640 public function gallery_preview( $content ) {
1641 if ( get_post_type() === 'rl_gallery' && ! ( is_archive() && is_main_query() ) )
1642 $content .= do_shortcode( '[rl_gallery id="' . (int) get_the_ID() . '"]' );
1643
1644 return $content;
1645 }
1646
1647 /**
1648 * Helper: gallery number function.
1649 *
1650 * @param string $content
1651 * @param array $shortcode_atts
1652 * @return string
1653 */
1654 public function gallery_attributes( $content, $shortcode_atts ) {
1655 // private gallery?
1656 if ( isset( $shortcode_atts['rl_gallery_id'] ) && get_post_status( $shortcode_atts['rl_gallery_id'] ) === 'private' && ! current_user_can( 'read_private_posts' ) )
1657 return '';
1658
1659 // check forced gallery number
1660 if ( isset( $shortcode_atts['rl_gallery_no'] ) ) {
1661 $shortcode_atts['rl_gallery_no'] = (int) $shortcode_atts['rl_gallery_no'];
1662
1663 if ( $shortcode_atts['rl_gallery_no'] > 0 )
1664 $this->gallery_no = $shortcode_atts['rl_gallery_no'];
1665 } else
1666 ++$this->gallery_no;
1667
1668 // add inline style, to our galleries only
1669 if ( isset( $shortcode_atts['type'] ) ) {
1670 // get main instance
1671 $rl = Responsive_Lightbox();
1672
1673 // gallery style
1674 wp_enqueue_style( 'responsive-lightbox-gallery' );
1675 wp_enqueue_style( 'responsive-lightbox-gallery-inline' );
1676
1677 // is there rl_gallery ID?
1678 $rl_gallery_id = ! empty( $shortcode_atts['rl_gallery_id'] ) ? (int) $shortcode_atts['rl_gallery_id'] : 0;
1679
1680 // is it rl gallery?
1681 $rl_gallery = $rl->options['builder']['gallery_builder'] && $rl_gallery_id && get_post_type( $rl_gallery_id ) === 'rl_gallery';
1682
1683 // is it rl gallery? add design options
1684 if ( $rl_gallery ) {
1685 $gallery_no = $this->gallery_no;
1686
1687 // get fields
1688 $fields = $rl->galleries->get_data( 'fields' );
1689
1690 // get gallery fields attributes
1691 $field_atts = rl_get_gallery_fields_atts( $fields['design']['options'], $shortcode_atts, $rl_gallery );
1692
1693 // get only valid arguments
1694 $atts = shortcode_atts( $field_atts, array_merge( $field_atts, $shortcode_atts ), 'gallery' );
1695
1696 // sanitize gallery fields
1697 $atts = $this->sanitize_shortcode_args( $atts, $fields['design']['options'] );
1698
1699 // convert color
1700 $background_color = $rl->hex2rgb( $atts['background_color'] );
1701
1702 // invalid color?
1703 if ( ! $background_color )
1704 $background_color = '0,0,0';
1705 else
1706 $background_color = implode( ',', $background_color );
1707
1708 // get opacity
1709 $opacity = (string) round( $atts['background_opacity'] / 100, 2 );
1710
1711 // prepare style data
1712 $style_data = '
1713 #rl-gallery-container-' . $gallery_no . ' .rl-gallery .rl-gallery-link {
1714 border: ' . (int) $atts['border_width'] . 'px solid ' . esc_attr( $atts['border_color'] ) . ';
1715 }
1716 #rl-gallery-container-' . $gallery_no . ' .rl-gallery .rl-gallery-link .rl-gallery-item-title {
1717 color: ' . esc_attr( $atts['title_color'] ) . ';
1718 }
1719 #rl-gallery-container-' . $gallery_no . ' .rl-gallery .rl-gallery-link .rl-gallery-item-caption {
1720 color: ' . esc_attr( $atts['caption_color'] ) . ';
1721 }
1722 #rl-gallery-container-' . $gallery_no . ' .rl-gallery .rl-gallery-link .rl-gallery-caption {
1723 font-size: ' . absint( $atts['caption_font_size'] ) . 'px;
1724 padding: ' . absint( $atts['caption_padding'] ) . 'px;
1725 }
1726 #rl-gallery-container-' . $gallery_no . ' .rl-gallery .rl-gallery-link .rl-gallery-caption,
1727 #rl-gallery-container-' . $gallery_no . ' .rl-gallery .rl-gallery-link:after {
1728 background-color: rgba( ' . esc_attr( $background_color ) . ', ' . esc_attr( $opacity ) . ' );
1729 }
1730 #rl-gallery-container-' . $gallery_no . ' [class^="rl-hover-icon-"] .rl-gallery-link:before,
1731 #rl-gallery-container-' . $gallery_no . ' [class*=" rl-hover-icon-"] .rl-gallery-link:before {
1732 color: ' . esc_attr( $atts['title_color'] ) . ';
1733 background-color: rgba( ' . esc_attr( $background_color ) . ', ' . esc_attr( $opacity ) . ' );
1734 }';
1735
1736 // load style data
1737 $style_loaded = wp_add_inline_style( 'responsive-lightbox-gallery-inline', $style_data );
1738
1739 if ( ! $style_loaded )
1740 $this->style_data['gallery'] .= $style_data;
1741 }
1742 }
1743
1744 return $content;
1745 }
1746
1747 /**
1748 * Generate unique hash.
1749 *
1750 * @param int $length
1751 * @return string
1752 */
1753 private function generate_hash( $length = 8 ) {
1754 $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
1755 $hash = '';
1756
1757 for( $i = 0; $i < $length; $i++ ) {
1758 $hash .= substr( $chars, mt_rand( 0, strlen( $chars ) - 1 ), 1 );
1759 }
1760
1761 return $hash;
1762 }
1763
1764 /**
1765 * Replace widget callback function.
1766 *
1767 * @global array $wp_registered_widgets
1768 *
1769 * @param array $sidebar_params
1770 * @return array
1771 */
1772 public function dynamic_sidebar_params( $sidebar_params ) {
1773 if ( ( is_admin() && ! wp_doing_ajax() ) || Responsive_Lightbox()->options['settings']['widgets'] !== true )
1774 return $sidebar_params;
1775
1776 global $wp_registered_widgets;
1777
1778 $widget_id = $sidebar_params[0]['widget_id'];
1779 $wp_registered_widgets[ $widget_id ]['original_callback'] = $wp_registered_widgets[ $widget_id ]['callback'];
1780 $wp_registered_widgets[ $widget_id ]['callback'] = [ $this, 'widget_callback_function' ];
1781
1782 return $sidebar_params;
1783 }
1784
1785 /**
1786 * Widget callback function.
1787 *
1788 * @global array $wp_registered_widgets
1789 *
1790 * @return void
1791 */
1792 public function widget_callback_function() {
1793 global $wp_registered_widgets;
1794
1795 $original_callback_params = func_get_args();
1796 $widget_id = $original_callback_params[0]['widget_id'];
1797 $original_callback = $wp_registered_widgets[ $widget_id ]['original_callback'];
1798 $wp_registered_widgets[ $widget_id ]['callback'] = $original_callback;
1799 $widget_id_base = $wp_registered_widgets[ $widget_id ]['callback'][0]->id_base;
1800
1801 if ( is_callable( $original_callback ) ) {
1802 ob_start();
1803
1804 call_user_func_array( $original_callback, $original_callback_params );
1805
1806 $widget_output = ob_get_clean();
1807
1808 echo apply_filters( 'rl_widget_output', $widget_output, $widget_id_base, $widget_id );
1809 }
1810 }
1811
1812 /**
1813 * Filter widget output.
1814 *
1815 * @param string $content
1816 * @param string $widget_id_base
1817 * @param id $widget_id
1818 * @return string
1819 */
1820 public function widget_output( $content, $widget_id_base, $widget_id ) {
1821 if ( ( is_admin() && ! wp_doing_ajax() ) || Responsive_Lightbox()->options['settings']['widgets'] !== true )
1822 return $content;
1823
1824 // Widgets can contain valid form controls and inline scripts (e.g. core Archives dropdown handlers).
1825 // Reuse the pre-2.7.4 behavior and only apply lightbox rewriting.
1826 return $this->add_lightbox( $content );
1827 }
1828
1829 /**
1830 * Get allowed HTML tags/attributes for filtered comment content.
1831 *
1832 * @return array
1833 */
1834 private function get_comment_lightbox_allowed_html() {
1835 static $allowed = null;
1836
1837 if ( $allowed !== null )
1838 return $allowed;
1839
1840 $allowed = wp_kses_allowed_html( 'post' );
1841
1842 if ( ! is_array( $allowed ) )
1843 $allowed = [];
1844
1845 if ( ! isset( $allowed['a'] ) || ! is_array( $allowed['a'] ) )
1846 $allowed['a'] = [];
1847
1848 foreach ( [ 'data-rel', 'data-rl_title', 'data-rl_caption', 'data-magnific_type', 'data-imagelightbox', 'data-lightbox-type', 'data-featherlight' ] as $attr )
1849 $allowed['a'][$attr] = true;
1850
1851 return $allowed;
1852 }
1853
1854 /**
1855 * Filter comment content.
1856 *
1857 * @param string $content
1858 * @return string
1859 */
1860 public function get_comment_text( $content ) {
1861 if ( ( is_admin() && ! wp_doing_ajax() ) || Responsive_Lightbox()->options['settings']['comments'] !== true )
1862 return $content;
1863
1864 return wp_kses( $this->add_lightbox( $content ), $this->get_comment_lightbox_allowed_html() );
1865 }
1866
1867 /**
1868 * Modify gallery container class.
1869 *
1870 * @param string $class
1871 * @param array $args
1872 * @param int $gallery_id
1873 * @return string
1874 */
1875 public function gallery_container_class( $class, $args, $gallery_id ) {
1876 if ( $gallery_id ) {
1877 $class .= ' rl-loading';
1878
1879 if ( $args['pagination'] )
1880 $class .= ' rl-pagination-' . $args['pagination_type'];
1881 }
1882
1883 return $class;
1884 }
1885
1886 /**
1887 * Display content before the gallery.
1888 *
1889 * @param array $args
1890 * @param int $gallery_id
1891 * @return void
1892 */
1893 public function before_gallery( $args, $gallery_id ) {
1894 if ( $gallery_id ) {
1895 // get current post id
1896 if ( isset( $_POST['action'], $_POST['post_id'] ) && $_POST['action'] === 'rl-get-gallery-page-content' && wp_doing_ajax() )
1897 $current_id = (int) $_POST['post_id'];
1898 else
1899 $current_id = (int) get_the_ID();
1900
1901 if ( isset( $args['gallery_title_position'] ) && $args['gallery_title_position'] === 'top' && get_post_type( $current_id ) )
1902 echo '<h4 class="rl-gallery-title">' . esc_html( get_the_title( $gallery_id ) ) . '</h4>';
1903
1904 if ( isset( $args['gallery_description_position'] ) && $args['gallery_description_position'] === 'top' )
1905 echo '<div class="rl-gallery-description">' . nl2br( esc_html( $args['gallery_description'] ) ) . '</div>';
1906 }
1907 }
1908
1909 /**
1910 * Display content after the gallery.
1911 *
1912 * @param array $args
1913 * @param int $gallery_id
1914 * @return void
1915 */
1916 public function after_gallery( $args, $gallery_id ) {
1917 if ( $gallery_id ) {
1918 // get current post id
1919 if ( isset( $_POST['action'], $_POST['post_id'] ) && $_POST['action'] === 'rl-get-gallery-page-content' && wp_doing_ajax() )
1920 $current_id = (int) $_POST['post_id'];
1921 else
1922 $current_id = (int) get_the_ID();
1923
1924 if ( isset( $args['gallery_title_position'] ) && $args['gallery_title_position'] === 'bottom' )
1925 echo '<h4 class="rl-gallery-title">' . esc_html( get_the_title( $gallery_id ) ) . '</h4>';
1926
1927 if ( isset( $args['gallery_description_position'] ) && $args['gallery_description_position'] === 'bottom' )
1928 echo '<div class="rl-gallery-description">' . nl2br( esc_html( $args['gallery_description'] ) ) . '</div>';
1929 }
1930 }
1931
1932 /**
1933 * Add lightbox to Visual Composer shortcodes.
1934 *
1935 * @param string $content HTML content
1936 * @param string $shortcode Shortcode type
1937 * @return string
1938 */
1939 public function vc_shortcode_content_filter_after( $content, $shortcode ) {
1940 if ( in_array( $shortcode, apply_filters( 'rl_lightbox_vc_allowed_shortcode', [ 'vc_gallery', 'vc_single_image', 'vc_images_carousel' ] ), true ) )
1941 $content = $this->add_lightbox( $content );
1942
1943 return $content;
1944 }
1945
1946 /**
1947 * Render Basic Grid gallery shortcode.
1948 *
1949 * @global object $post
1950 *
1951 * @param string $output HTML output
1952 * @param array $shortcode_atts Shortcode attributes
1953 * @return string
1954 */
1955 public function basic_grid_gallery_shortcode( $output, $shortcode_atts ) {
1956 if ( ! empty( $output ) )
1957 return $output;
1958
1959 global $post;
1960
1961 $defaults = [
1962 'rl_gallery_id' => 0,
1963 'id' => isset( $post->ID ) ? (int) $post->ID : 0,
1964 'class' => '',
1965 'include' => '',
1966 'exclude' => '',
1967 'urls' => '',
1968 'type' => '',
1969 'order' => 'asc',
1970 'orderby' => 'menu_order',
1971 'size' => 'medium',
1972 'link' => 'file',
1973 'columns' => 3
1974 ];
1975
1976 // get main instance
1977 $rl = Responsive_Lightbox();
1978
1979 if ( ! is_array( $shortcode_atts ) )
1980 $shortcode_atts = wp_parse_args( $shortcode_atts, $defaults );
1981
1982 // is there rl_gallery ID?
1983 $rl_gallery_id = $defaults['rl_gallery_id'] = ! empty( $shortcode_atts['rl_gallery_id'] ) ? (int) $shortcode_atts['rl_gallery_id'] : 0;
1984
1985 // is it rl gallery?
1986 $rl_gallery = $rl->options['builder']['gallery_builder'] && $rl_gallery_id && get_post_type( $rl_gallery_id ) === 'rl_gallery';
1987
1988 // private gallery?
1989 if ( $rl_gallery && get_post_status( $rl_gallery_id ) === 'private' && ! current_user_can( 'read_private_posts' ) )
1990 return '';
1991
1992 if ( ! array_key_exists( 'type', $shortcode_atts ) )
1993 $shortcode_atts['type'] = '';
1994
1995 // break if it is not basic grid gallery - first check
1996 if ( ! ( $shortcode_atts['type'] === 'basicgrid' || ( $shortcode_atts['type'] === '' && ( ( $rl_gallery && $rl->options['settings']['builder_gallery'] === 'basicgrid' ) || ( ! $rl_gallery && $rl->options['settings']['default_gallery'] === 'basicgrid' ) ) ) ) )
1997 return $output;
1998
1999 // get shortcode gallery fields combined with defaults
2000 $fields = rl_get_gallery_fields( 'basicgrid' );
2001
2002 // get gallery fields attributes
2003 $field_atts = rl_get_gallery_fields_atts( $fields, $shortcode_atts, $rl_gallery );
2004
2005 // is it rl gallery? add misc and lightbox fields
2006 if ( $rl_gallery ) {
2007 // get fields
2008 $fields_data = $rl->galleries->get_data( 'fields' );
2009
2010 $fields += $fields_data['lightbox']['options'] + $fields_data['misc']['options'];
2011 }
2012
2013 // get only valid arguments
2014 $atts = shortcode_atts( array_merge( $defaults, $field_atts ), $shortcode_atts, 'gallery' );
2015
2016 // sanitize gallery fields
2017 $atts = $this->sanitize_shortcode_args( $atts, $fields );
2018
2019 // break if it is not basic grid gallery
2020 if ( ! ( $atts['type'] === 'basicgrid' || ( $atts['type'] === '' && ( ( $rl_gallery && $rl->options['settings']['builder_gallery'] === 'basicgrid' ) || ( ! $rl_gallery && $rl->options['settings']['default_gallery'] === 'basicgrid' ) ) ) ) )
2021 return $output;
2022
2023 // ID
2024 $atts['id'] = (int) $atts['id'];
2025
2026 // add custom classes if needed
2027 if ( $rl_gallery )
2028 $atts['class'] .= ' ' . $atts['gallery_custom_class'];
2029
2030 // any classes?
2031 if ( $atts['class'] !== '' ) {
2032 $atts['class'] = trim( $atts['class'] );
2033
2034 // more than 1 class?
2035 if ( strpos( $atts['class'], ' ' ) !== false ) {
2036 // get unique valid HTML classes
2037 $atts['class'] = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $atts['class'] ) ) ) );
2038
2039 if ( ! empty( $atts['class'] ) )
2040 $atts['class'] = implode( ' ', $atts['class'] );
2041 else
2042 $atts['class'] = '';
2043 // single class
2044 } else
2045 $atts['class'] = sanitize_html_class( $atts['class'] );
2046 }
2047
2048 // orderby
2049 if ( empty( $atts['orderby'] ) ) {
2050 $atts['orderby'] = sanitize_sql_orderby( $atts['orderby'] );
2051
2052 if ( empty( $atts['orderby'] ) )
2053 $atts['orderby'] = $defaults['orderby'];
2054 }
2055
2056 // order
2057 if ( strtolower( $atts['order'] ) === 'rand' )
2058 $atts['orderby'] = 'rand';
2059
2060 // check columns
2061 if ( $atts['columns_lg'] === 0 )
2062 $atts['columns_lg'] = $atts['columns'];
2063
2064 if ( $atts['columns_md'] === 0 )
2065 $atts['columns_md'] = $atts['columns'];
2066
2067 if ( $atts['columns_sm'] === 0 )
2068 $atts['columns_sm'] = $atts['columns'];
2069
2070 if ( $atts['columns_xs'] === 0 )
2071 $atts['columns_xs'] = $atts['columns'];
2072
2073 // gallery lightbox source size
2074 if ( ! empty( $atts['lightbox_image_size'] ) ) {
2075 if ( $atts['lightbox_image_size'] === 'global' )
2076 $atts['src_size'] = $rl->options['settings']['gallery_image_size'];
2077 elseif ( $atts['lightbox_image_size'] === 'lightbox_custom_size' && isset( $atts['lightbox_custom_size_width'], $atts['lightbox_custom_size_height'] ) )
2078 $atts['src_size'] = [ $atts['lightbox_custom_size_width'], $atts['lightbox_custom_size_height'] ];
2079 else
2080 $atts['src_size'] = $atts['lightbox_image_size'];
2081 } else
2082 $atts['src_size'] = $rl->options['settings']['gallery_image_size'];
2083
2084 // filter all shortcode arguments
2085 $atts = apply_filters( 'rl_gallery_shortcode_atts', $atts, $rl_gallery_id );
2086
2087 // get gallery images
2088 $images = rl_get_gallery_shortcode_images( $atts );
2089
2090 if ( empty( $images ) || is_feed() || defined( 'IS_HTML_EMAIL' ) )
2091 return $output;
2092
2093 // make sure it is integer
2094 $gallery_no = (int) $this->gallery_no;
2095
2096 ob_start();
2097
2098 // $gallery_no and $rl_gallery_id are both integers ?>
2099 <div class="rl-gallery-container <?php echo esc_attr( apply_filters( 'rl_gallery_container_class', '', $atts, $rl_gallery_id ) ); ?>" id="rl-gallery-container-<?php echo (int) $gallery_no; ?>" data-gallery_id="<?php echo (int) $rl_gallery_id; ?>">
2100
2101 <?php do_action( 'rl_before_gallery', $atts, $rl_gallery_id ); ?>
2102
2103 <div class="rl-gallery rl-basicgrid-gallery <?php echo esc_attr( $atts['class'] ); ?>" id="rl-gallery-<?php echo (int) $gallery_no; ?>" data-gallery_no="<?php echo (int) $gallery_no; ?>">
2104
2105 <?php foreach ( $images as $image ) {
2106 // $image['link'] is already escaped via get_gallery_image_link(), but we apply wp_kses_post() for defense-in-depth
2107 echo '<div class="rl-gallery-item">' . wp_kses_post( $image['link'] ) . '</div>';
2108 } ?>
2109
2110 </div>
2111
2112 <?php do_action( 'rl_after_gallery', $atts, $rl_gallery_id ); ?>
2113
2114 </div>
2115
2116 <?php $gallery_html = ob_get_contents();
2117
2118 ob_end_clean();
2119
2120 // styles
2121 wp_enqueue_style( 'responsive-lightbox-basicgrid-gallery', plugins_url( 'css/gallery-basicgrid.css', dirname( __FILE__ ) ), [], $rl->defaults['version'] );
2122 wp_enqueue_style( 'responsive-lightbox-basicgrid-gallery-inline' );
2123
2124 // prepare style data
2125 $style_data = '
2126 #rl-gallery-container-' . $gallery_no . ' .rl-basicgrid-gallery .rl-gallery-item {
2127 width: calc(' . (string) round( 100 / (int) $atts['columns'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2128 margin: ' . (string) round( (int) $atts['gutter'] / 2, 2 ) . 'px;
2129 }
2130 @media all and (min-width: 1200px) {
2131 #rl-gallery-container-' . $gallery_no . ' .rl-basicgrid-gallery .rl-gallery-item {
2132 width: calc(' . (string) round( 100 / (int) $atts['columns_lg'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2133 }
2134 }
2135 @media all and (min-width: 992px) and (max-width: 1200px) {
2136 #rl-gallery-container-' . $gallery_no . ' .rl-basicgrid-gallery .rl-gallery-item {
2137 width: calc(' . (string) round( 100 / (int) $atts['columns_md'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2138 }
2139 }
2140 @media all and (min-width: 768px) and (max-width: 992px) {
2141 #rl-gallery-container-' . $gallery_no . ' .rl-basicgrid-gallery .rl-gallery-item {
2142 width: calc(' . (string) round( 100 / (int) $atts['columns_sm'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2143 }
2144 }
2145 @media all and (max-width: 768px) {
2146 #rl-gallery-container-' . $gallery_no . ' .rl-basicgrid-gallery .rl-gallery-item {
2147 width: calc(' . (string) round( 100 / (int) $atts['columns_xs'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2148 }
2149 }';
2150
2151 if ( $atts['force_height'] ) {
2152 $style_data .= '
2153 #rl-gallery-container-' . $gallery_no . ' .rl-basicgrid-gallery .rl-gallery-item {
2154 height: ' . (int) $atts['row_height'] . 'px;
2155 }
2156 #rl-gallery-container-' . $gallery_no . ' .rl-basicgrid-gallery .rl-gallery-item img {
2157 height: ' . (int) $atts['row_height'] . 'px;
2158 object-fit: cover;
2159 max-width: 100%;
2160 min-width: 100%;
2161 }';
2162 }
2163
2164 // load style data
2165 $style_loaded = wp_add_inline_style( 'responsive-lightbox-basicgrid-gallery-inline', $style_data );
2166
2167 if ( ! $style_loaded )
2168 $this->style_data['basicgrid'] .= $style_data;
2169
2170 // remove any new lines from the output so that the reader parses it better
2171 return apply_filters( 'rl_gallery_shortcode_html', trim( preg_replace( '/\s+/', ' ', $gallery_html ) ), $atts, $rl_gallery_id );
2172 }
2173
2174 /**
2175 * Render Basic Slider gallery shortcode.
2176 *
2177 * @global object $post
2178 *
2179 * @param string $output HTML output
2180 * @param array $shortcode_atts Shortcode attributes
2181 * @return string
2182 */
2183 public function basic_slider_gallery_shortcode( $output, $shortcode_atts ) {
2184 if ( ! empty( $output ) )
2185 return $output;
2186
2187 global $post;
2188
2189 $defaults = [
2190 'rl_gallery_id' => 0,
2191 'id' => isset( $post->ID ) ? (int) $post->ID : 0,
2192 'class' => '',
2193 'include' => '',
2194 'exclude' => '',
2195 'urls' => '',
2196 'type' => '',
2197 'order' => 'asc',
2198 'orderby' => 'menu_order',
2199 'size' => 'medium',
2200 'link' => 'file',
2201 'columns' => 3
2202 ];
2203
2204 // get main instance
2205 $rl = Responsive_Lightbox();
2206
2207 if ( ! is_array( $shortcode_atts ) )
2208 $shortcode_atts = wp_parse_args( $shortcode_atts, $defaults );
2209
2210 // is there rl_gallery ID?
2211 $rl_gallery_id = $defaults['rl_gallery_id'] = ! empty( $shortcode_atts['rl_gallery_id'] ) ? (int) $shortcode_atts['rl_gallery_id'] : 0;
2212
2213 // is it rl gallery?
2214 $rl_gallery = $rl->options['builder']['gallery_builder'] && $rl_gallery_id && get_post_type( $rl_gallery_id ) === 'rl_gallery';
2215
2216 // private gallery?
2217 if ( $rl_gallery && get_post_status( $rl_gallery_id ) === 'private' && ! current_user_can( 'read_private_posts' ) )
2218 return '';
2219
2220 if ( ! array_key_exists( 'type', $shortcode_atts ) )
2221 $shortcode_atts['type'] = '';
2222
2223 // break if it is not basic slider gallery - first check
2224 if ( ! ( $shortcode_atts['type'] === 'basicslider' || ( $shortcode_atts['type'] === '' && ( ( $rl_gallery && $rl->options['settings']['builder_gallery'] === 'basicslider' ) || ( ! $rl_gallery && $rl->options['settings']['default_gallery'] === 'basicslider' ) ) ) ) )
2225 return $output;
2226
2227 // get shortcode gallery fields combined with defaults
2228 $fields = rl_get_gallery_fields( 'basicslider' );
2229
2230 // get gallery fields attributes
2231 $field_atts = rl_get_gallery_fields_atts( $fields, $shortcode_atts, $rl_gallery );
2232
2233 // is it rl gallery? add misc and lightbox fields
2234 if ( $rl_gallery ) {
2235 // get fields
2236 $fields_data = $rl->galleries->get_data( 'fields' );
2237
2238 $fields += $fields_data['lightbox']['options'] + $fields_data['misc']['options'];
2239 }
2240
2241 // get only valid arguments
2242 $atts = shortcode_atts( array_merge( $defaults, $field_atts ), $shortcode_atts, 'gallery' );
2243
2244 // sanitize gallery fields
2245 $atts = $this->sanitize_shortcode_args( $atts, $fields );
2246
2247 // break if it is not basic slider gallery
2248 if ( ! ( $atts['type'] === 'basicslider' || ( $atts['type'] === '' && ( ( $rl_gallery && $rl->options['settings']['builder_gallery'] === 'basicslider' ) || ( ! $rl_gallery && $rl->options['settings']['default_gallery'] === 'basicslider' ) ) ) ) )
2249 return $output;
2250
2251 // ID
2252 $atts['id'] = (int) $atts['id'];
2253
2254 // add custom classes if needed
2255 if ( $rl_gallery )
2256 $atts['class'] .= ' ' . $atts['gallery_custom_class'];
2257
2258 // any classes?
2259 if ( $atts['class'] !== '' ) {
2260 $atts['class'] = trim( $atts['class'] );
2261
2262 // more than 1 class?
2263 if ( strpos( $atts['class'], ' ' ) !== false ) {
2264 // get unique valid HTML classes
2265 $atts['class'] = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $atts['class'] ) ) ) );
2266
2267 if ( ! empty( $atts['class'] ) )
2268 $atts['class'] = implode( ' ', $atts['class'] );
2269 else
2270 $atts['class'] = '';
2271 // single class
2272 } else
2273 $atts['class'] = sanitize_html_class( $atts['class'] );
2274 }
2275
2276 // orderby
2277 if ( empty( $atts['orderby'] ) ) {
2278 $atts['orderby'] = sanitize_sql_orderby( $atts['orderby'] );
2279
2280 if ( empty( $atts['orderby'] ) )
2281 $atts['orderby'] = $defaults['orderby'];
2282 }
2283
2284 // order
2285 if ( strtolower( $atts['order'] ) === 'rand' )
2286 $atts['orderby'] = 'rand';
2287
2288 // gallery lightbox source size
2289 if ( ! empty( $atts['lightbox_image_size'] ) ) {
2290 if ( $atts['lightbox_image_size'] === 'global' )
2291 $atts['src_size'] = $rl->options['settings']['gallery_image_size'];
2292 elseif ( $atts['lightbox_image_size'] === 'lightbox_custom_size' && isset( $atts['lightbox_custom_size_width'], $atts['lightbox_custom_size_height'] ) )
2293 $atts['src_size'] = [ $atts['lightbox_custom_size_width'], $atts['lightbox_custom_size_height'] ];
2294 else
2295 $atts['src_size'] = $atts['lightbox_image_size'];
2296 } else
2297 $atts['src_size'] = $rl->options['settings']['gallery_image_size'];
2298
2299 // filter all shortcode arguments
2300 $atts = apply_filters( 'rl_gallery_shortcode_atts', $atts, $rl_gallery_id );
2301
2302 // get gallery images
2303 $images = rl_get_gallery_shortcode_images( $atts );
2304
2305 if ( empty( $images ) || is_feed() || defined( 'IS_HTML_EMAIL' ) )
2306 return $output;
2307
2308 // make sure it is integer
2309 $gallery_no = (int) $this->gallery_no;
2310
2311 ob_start();
2312
2313 // $gallery_no and $rl_gallery_id are both integers ?>
2314 <div class="rl-gallery-container splide <?php echo esc_attr( apply_filters( 'rl_gallery_container_class', '', $atts, $rl_gallery_id ) ); ?>" id="rl-gallery-container-<?php echo (int) $gallery_no; ?>" data-gallery_id="<?php echo (int) $rl_gallery_id; ?>">
2315
2316 <?php do_action( 'rl_before_gallery', $atts, $rl_gallery_id ); ?>
2317
2318 <div class="rl-gallery rl-basicslider-gallery splide__track <?php echo esc_attr( $atts['class'] ); ?>" id="rl-gallery-<?php echo (int) $gallery_no; ?>" data-gallery_no="<?php echo (int) $gallery_no; ?>">
2319 <ul class="splide__list">
2320
2321 <?php foreach ( $images as $image ) {
2322 echo '
2323 <li class="rl-gallery-item splide__slide" ' . implode( ' ', apply_filters( 'rl_gallery_item_extra_args', [], $atts, $image ) ) . ' data-thumb="' . $image['thumbnail_url'] . '">
2324 ' . wp_kses_post( $image['link'] ) . '
2325 </li>';
2326 } ?>
2327
2328 </ul>
2329 </div>
2330
2331 <?php do_action( 'rl_after_gallery', $atts, $rl_gallery_id ); ?>
2332
2333 </div>
2334
2335 <?php $gallery_html = ob_get_contents();
2336
2337 ob_end_clean();
2338
2339 // enqueue scripts and styles
2340 wp_enqueue_script( 'responsive-lightbox-basicslider-gallery' );
2341 wp_enqueue_style( 'responsive-lightbox-basicslider-gallery' );
2342 wp_enqueue_style( 'responsive-lightbox-basicslider-gallery-inline' );
2343
2344 // prepare style data
2345 $style_data = '
2346 #rl-gallery-container-' . $gallery_no . ' .rl-basicslider-gallery .rl-gallery-item img {
2347 width: 100%;
2348 height: auto;
2349 }';
2350
2351 // load style data
2352 $style_loaded = wp_add_inline_style( 'responsive-lightbox-basicslider-gallery-inline', $style_data );
2353
2354 if ( ! $style_loaded )
2355 $this->style_data['basicslider'] .= $style_data;
2356
2357 // prepare script data
2358 $script_data = [
2359 'type' => $atts['slider_type'],
2360 'height' => ( $atts['height'] > 0 ? $atts['height'] . 'px' : 0 ),
2361 'width' => ( $atts['width'] > 0 ? $atts['width'] . '%' : 0 ),
2362 'speed' => $atts['speed'],
2363 'gap' => $atts['gap'] . 'px',
2364 'arrows' => $atts['arrows_navigation'],
2365 'pagination' => $atts['dots_navigation'],
2366 'drag' => $atts['drag'],
2367 'autoplay' => $atts['autoplay'],
2368 'interval' => $atts['interval'],
2369 'wheel' => $atts['wheel'],
2370 'perPage' => $atts['slides_per_page'],
2371 'perMove' => $atts['slides_per_move'],
2372 'start' => $atts['slides_start']
2373 ];
2374
2375 // load script data
2376 $script_data = 'var rlArgsBasicSliderGallery' . ( $gallery_no + 1 ) . ' = ' . json_encode( $script_data ) . ";\n";
2377 $script_loaded = wp_add_inline_script( 'responsive-lightbox-basicslider-gallery', $script_data, 'before' );
2378
2379 if ( ! $script_loaded )
2380 $this->script_data['basicslider'] .= $script_data;
2381
2382 // remove any new lines from the output so that the reader parses it better
2383 return apply_filters( 'rl_gallery_shortcode_html', trim( preg_replace( '/\s+/', ' ', $gallery_html ) ), $atts, $rl_gallery_id );
2384 }
2385
2386 /**
2387 * Render Basic Masonry gallery shortcode.
2388 *
2389 * @global object $post
2390 *
2391 * @param string $output HTML output
2392 * @param array $shortcode_atts Shortcode attributes
2393 * @return string
2394 */
2395 public function basic_masonry_gallery_shortcode( $output, $shortcode_atts ) {
2396 if ( ! empty( $output ) )
2397 return $output;
2398
2399 global $post;
2400
2401 $defaults = [
2402 'rl_gallery_id' => 0,
2403 'id' => isset( $post->ID ) ? (int) $post->ID : 0,
2404 'class' => '',
2405 'include' => '',
2406 'exclude' => '',
2407 'urls' => '',
2408 'type' => '',
2409 'order' => 'asc',
2410 'orderby' => 'menu_order',
2411 'size' => 'medium',
2412 'link' => 'file',
2413 'columns' => 3
2414 ];
2415
2416 // get main instance
2417 $rl = Responsive_Lightbox();
2418
2419 if ( ! is_array( $shortcode_atts ) )
2420 $shortcode_atts = wp_parse_args( $shortcode_atts, $defaults );
2421
2422 // is there rl_gallery ID?
2423 $rl_gallery_id = $defaults['rl_gallery_id'] = ! empty( $shortcode_atts['rl_gallery_id'] ) ? (int) $shortcode_atts['rl_gallery_id'] : 0;
2424
2425 // is it rl gallery?
2426 $rl_gallery = $rl->options['builder']['gallery_builder'] && $rl_gallery_id && get_post_type( $rl_gallery_id ) === 'rl_gallery';
2427
2428 // private gallery?
2429 if ( $rl_gallery && get_post_status( $rl_gallery_id ) === 'private' && ! current_user_can( 'read_private_posts' ) )
2430 return '';
2431
2432 if ( ! array_key_exists( 'type', $shortcode_atts ) )
2433 $shortcode_atts['type'] = '';
2434
2435 // break if it is not basic masonry gallery - first check
2436 if ( ! ( $shortcode_atts['type'] === 'basicmasonry' || ( $shortcode_atts['type'] === '' && ( ( $rl_gallery && $rl->options['settings']['builder_gallery'] === 'basicmasonry' ) || ( ! $rl_gallery && $rl->options['settings']['default_gallery'] === 'basicmasonry' ) ) ) ) )
2437 return $output;
2438
2439 // get shortcode gallery fields combined with defaults
2440 $fields = rl_get_gallery_fields( 'basicmasonry' );
2441
2442 // get gallery fields attributes
2443 $field_atts = rl_get_gallery_fields_atts( $fields, $shortcode_atts, $rl_gallery );
2444
2445 // is it rl gallery? add misc and lightbox fields
2446 if ( $rl_gallery ) {
2447 // get fields
2448 $fields_data = $rl->galleries->get_data( 'fields' );
2449
2450 $fields += $fields_data['lightbox']['options'] + $fields_data['misc']['options'];
2451 }
2452
2453 // get only valid arguments
2454 $atts = shortcode_atts( array_merge( $defaults, $field_atts ), $shortcode_atts, 'gallery' );
2455
2456 // sanitize gallery fields
2457 $atts = $this->sanitize_shortcode_args( $atts, $fields );
2458
2459 // break if it is not basic masonry gallery
2460 if ( ! ( $atts['type'] === 'basicmasonry' || ( $atts['type'] === '' && ( ( $rl_gallery && $rl->options['settings']['builder_gallery'] === 'basicmasonry' ) || ( ! $rl_gallery && $rl->options['settings']['default_gallery'] === 'basicmasonry' ) ) ) ) )
2461 return $output;
2462
2463 // ID
2464 $atts['id'] = (int) $atts['id'];
2465
2466 // add custom classes if needed
2467 if ( $rl_gallery )
2468 $atts['class'] .= ' ' . $atts['gallery_custom_class'];
2469
2470 // any classes?
2471 if ( $atts['class'] !== '' ) {
2472 $atts['class'] = trim( $atts['class'] );
2473
2474 // more than 1 class?
2475 if ( strpos( $atts['class'], ' ' ) !== false ) {
2476 // get unique valid HTML classes
2477 $atts['class'] = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $atts['class'] ) ) ) );
2478
2479 if ( ! empty( $atts['class'] ) )
2480 $atts['class'] = implode( ' ', $atts['class'] );
2481 else
2482 $atts['class'] = '';
2483 // single class
2484 } else
2485 $atts['class'] = sanitize_html_class( $atts['class'] );
2486 }
2487
2488 // orderby
2489 if ( empty( $atts['orderby'] ) ) {
2490 $atts['orderby'] = sanitize_sql_orderby( $atts['orderby'] );
2491
2492 if ( empty( $atts['orderby'] ) )
2493 $atts['orderby'] = $defaults['orderby'];
2494 }
2495
2496 // order
2497 if ( strtolower( $atts['order'] ) === 'rand' )
2498 $atts['orderby'] = 'rand';
2499
2500 // check columns
2501 if ( $atts['columns_lg'] === 0 )
2502 $atts['columns_lg'] = $atts['columns'];
2503
2504 if ( $atts['columns_md'] === 0 )
2505 $atts['columns_md'] = $atts['columns'];
2506
2507 if ( $atts['columns_sm'] === 0 )
2508 $atts['columns_sm'] = $atts['columns'];
2509
2510 if ( $atts['columns_xs'] === 0 )
2511 $atts['columns_xs'] = $atts['columns'];
2512
2513 // gallery lightbox source size
2514 if ( ! empty( $atts['lightbox_image_size'] ) ) {
2515 if ( $atts['lightbox_image_size'] === 'global' )
2516 $atts['src_size'] = $rl->options['settings']['gallery_image_size'];
2517 elseif ( $atts['lightbox_image_size'] === 'lightbox_custom_size' && isset( $atts['lightbox_custom_size_width'], $atts['lightbox_custom_size_height'] ) )
2518 $atts['src_size'] = [ $atts['lightbox_custom_size_width'], $atts['lightbox_custom_size_height'] ];
2519 else
2520 $atts['src_size'] = $atts['lightbox_image_size'];
2521 } else
2522 $atts['src_size'] = $rl->options['settings']['gallery_image_size'];
2523
2524 // filter all shortcode arguments
2525 $atts = apply_filters( 'rl_gallery_shortcode_atts', $atts, $rl_gallery_id );
2526
2527 // get gallery images
2528 $images = rl_get_gallery_shortcode_images( $atts );
2529
2530 if ( empty( $images ) || is_feed() || defined( 'IS_HTML_EMAIL' ) )
2531 return $output;
2532
2533 // make sure it is integer
2534 $gallery_no = (int) $this->gallery_no;
2535
2536 ob_start();
2537
2538 // $gallery_no and $rl_gallery_id are both integers ?>
2539 <div class="rl-gallery-container <?php echo esc_attr( apply_filters( 'rl_gallery_container_class', '', $atts, $rl_gallery_id ) ); ?>" id="rl-gallery-container-<?php echo (int) $gallery_no; ?>" data-gallery_id="<?php echo (int) $rl_gallery_id; ?>">
2540
2541 <?php do_action( 'rl_before_gallery', $atts, $rl_gallery_id ); ?>
2542
2543 <div class="rl-gallery rl-basicmasonry-gallery <?php echo esc_attr( $atts['class'] ); ?>" id="rl-gallery-<?php echo (int) $gallery_no; ?>" data-gallery_no="<?php echo (int) $gallery_no; ?>">
2544
2545 <?php
2546 $count = 0;
2547
2548 if ( $count === 0 )
2549 echo '<div class="rl-gutter-sizer"></div><div class="rl-grid-sizer"></div>';
2550
2551 foreach ( $images as $image ) {
2552 // $image['link'] is already escaped via get_gallery_image_link(), but we apply wp_kses_post() for defense-in-depth
2553 echo '
2554 <div class="rl-gallery-item' . ( $count === 0 ? ' rl-gallery-item-width-4' : '' ) . '" ' . implode( ' ', apply_filters( 'rl_gallery_item_extra_args', [], $atts, $image ) ) . '>
2555 <div class="rl-gallery-item-content">
2556 ' . wp_kses_post( $image['link'] ) . '
2557 </div>
2558 </div>';
2559
2560 $count++;
2561 } ?>
2562
2563 </div>
2564
2565 <?php do_action( 'rl_after_gallery', $atts, $rl_gallery_id ); ?>
2566
2567 </div>
2568
2569 <?php $gallery_html = ob_get_contents();
2570
2571 ob_clean();
2572
2573 // enqueue scripts and styles
2574 wp_enqueue_script( 'responsive-lightbox-basicmasonry-gallery' );
2575 wp_enqueue_style( 'responsive-lightbox-basicmasonry-gallery' );
2576 wp_enqueue_style( 'responsive-lightbox-basicmasonry-gallery-inline' );
2577
2578 // prepare style data
2579 $style_data = '
2580 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery {
2581 margin: ' . -(string) round( (int) $atts['margin'] / 2, 1 ) . 'px ' . -(string) round( (int) $atts['gutter'] / 2, 1 ) . 'px;
2582 padding: ' . (int) $atts['margin'] . 'px 0;
2583 }
2584 #rl-gallery-container-' . $gallery_no . ' .rl-pagination-bottom {
2585 margin-top: ' . ( (int) $atts['margin'] / 2 ) . 'px
2586 }
2587 #rl-gallery-container-' . $gallery_no . ' .rl-pagination-top {
2588 margin-bottom: ' . ( (int) $atts['margin'] / 2 ) . 'px
2589 }
2590 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-gallery-item,
2591 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-grid-sizer {
2592 width: calc(' . (string) round( 100 / (int) $atts['columns'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2593 margin: ' . ( (int) $atts['margin'] / 2 ) . 'px ' . ( (int) $atts['gutter'] / 2 ) . 'px;
2594 }
2595 @media all and (min-width: 1200px) {
2596 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-gallery-item,
2597 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-grid-sizer {
2598 width: calc(' . (string) round( 100 / (int) $atts['columns_lg'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2599 margin: ' . ( (int) $atts['margin'] / 2 ) . 'px ' . ( (int) $atts['gutter'] / 2 ) . 'px;
2600 }
2601 }
2602 @media all and (min-width: 992px) and (max-width: 1200px) {
2603 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-gallery-item,
2604 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-grid-sizer {
2605 width: calc(' . (string) round( 100 / (int) $atts['columns_md'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2606 margin: ' . ( (int) $atts['margin'] / 2 ) . 'px ' . ( (int) $atts['gutter'] / 2 ) . 'px;
2607 }
2608 }
2609 @media all and (min-width: 768px) and (max-width: 992px) {
2610 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-gallery-item,
2611 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-grid-sizer {
2612 width: calc(' . (string) round( 100 / (int) $atts['columns_sm'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2613 margin: ' . ( (int) $atts['margin'] / 2 ) . 'px ' . ( (int) $atts['gutter'] / 2 ) . 'px;
2614 }
2615 }
2616 @media all and (max-width: 768px) {
2617 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-gallery-item,
2618 #rl-gallery-container-' . $gallery_no . ' .rl-basicmasonry-gallery .rl-grid-sizer {
2619 width: calc(' . (string) round( 100 / (int) $atts['columns_xs'], 2 ) . '% - ' . (int) $atts['gutter'] . 'px);
2620 margin: ' . ( (int) $atts['margin'] / 2 ) . 'px ' . ( (int) $atts['gutter'] / 2 ) . 'px;
2621 }
2622 }';
2623
2624 // load style data
2625 $style_loaded = wp_add_inline_style( 'responsive-lightbox-basicmasonry-gallery-inline', $style_data );
2626
2627 if ( ! $style_loaded )
2628 $this->style_data['basicmasonry'] .= $style_data;
2629
2630 // prepare script data
2631 $script_data = [
2632 'originLeft' => $atts['origin_left'],
2633 'originTop' => $atts['origin_top']
2634 ];
2635
2636 // load script data
2637 $script_data = 'var rlArgsBasicMasonryGallery' . ( $gallery_no + 1 ) . ' = ' . json_encode( $script_data ) . ";\n";
2638 $script_loaded = wp_add_inline_script( 'responsive-lightbox-basicmasonry-gallery', $script_data, 'before' );
2639
2640 if ( ! $script_loaded )
2641 $this->script_data['basicmasonry'] .= $script_data;
2642
2643 // remove any new lines from the output so that the reader parses it better
2644 return apply_filters( 'rl_gallery_shortcode_html', trim( preg_replace( '/\s+/', ' ', $gallery_html ) ), $atts, $rl_gallery_id );
2645 }
2646
2647 /**
2648 * Register frontend scripts.
2649 *
2650 * @return void
2651 */
2652 public function wp_enqueue_scripts() {
2653 // get main instance
2654 $rl = Responsive_Lightbox();
2655
2656 // gallery style
2657 wp_register_style( 'responsive-lightbox-gallery', plugins_url( 'css/gallery.css', dirname( __FILE__ ) ), [], $rl->defaults['version'] );
2658 wp_register_style( 'responsive-lightbox-gallery-inline', false, [ 'responsive-lightbox-gallery' ], $rl->defaults['version'] );
2659
2660 // load style data?
2661 if ( ! empty( $this->style_data['gallery'] ) )
2662 wp_add_inline_style( 'responsive-lightbox-gallery-inline', $this->style_data['gallery'] );
2663
2664 // Basic Grid
2665 // styles
2666 wp_register_style( 'responsive-lightbox-basicgrid-gallery', plugins_url( 'css/gallery-basicgrid.css', dirname( __FILE__ ) ), [], $rl->defaults['version'] );
2667 wp_register_style( 'responsive-lightbox-basicgrid-gallery-inline', false, [ 'responsive-lightbox-basicgrid-gallery' ], $rl->defaults['version'] );
2668
2669 // load style data?
2670 if ( ! empty( $this->style_data['basicgrid'] ) )
2671 wp_add_inline_style( 'responsive-lightbox-basicgrid-gallery-inline', $this->style_data['basicgrid'] );
2672
2673 // Basic Slider
2674 // scripts
2675 wp_register_script( 'responsive-lightbox-basicslider', plugins_url( 'assets/splide/splide.min.js', dirname( __FILE__ ) ), [], '4.1.4', $rl->options['settings']['loading_place'] === 'footer' );
2676 wp_register_script( 'responsive-lightbox-basicslider-gallery', plugins_url( 'js/front-basicslider.js', dirname( __FILE__ ) ), [ 'jquery', 'responsive-lightbox-basicslider' ], $rl->defaults['version'], $rl->options['settings']['loading_place'] === 'footer' );
2677
2678 // load script data?
2679 if ( ! empty( $this->script_data['basicslider'] ) )
2680 wp_add_inline_script( 'responsive-lightbox-basicslider-gallery', $this->script_data['basicslider'], 'before' );
2681
2682 // styles
2683 wp_register_style( 'responsive-lightbox-basicslider-gallery', plugins_url( 'assets/splide/splide.min.css', dirname( __FILE__ ) ), [], '4.1.4' );
2684 wp_register_style( 'responsive-lightbox-basicslider-gallery-inline', false, [ 'responsive-lightbox-basicslider-gallery' ], $rl->defaults['version'] );
2685
2686 // load style data?
2687 if ( ! empty( $this->style_data['basicslider'] ) )
2688 wp_add_inline_style( 'responsive-lightbox-basicslider-gallery-inline', $this->style_data['basicslider'] );
2689
2690 // Basic Masonry
2691 // scripts
2692 wp_register_script( 'responsive-lightbox-images-loaded', plugins_url( 'assets/imagesloaded/imagesloaded.pkgd' . ( ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.min' : '' ) . '.js', dirname( __FILE__ ) ), [ 'jquery' ], '5.0.0' );
2693 wp_register_script( 'responsive-lightbox-masonry', plugins_url( 'assets/masonry/masonry.pkgd' . ( ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.min' : '' ) . '.js', dirname( __FILE__ ) ), [ 'jquery' ], '4.2.2', $rl->options['settings']['loading_place'] === 'footer' );
2694 wp_register_script( 'responsive-lightbox-basicmasonry-gallery', plugins_url( 'js/front-basicmasonry.js', dirname( __FILE__ ) ), [ 'jquery', 'responsive-lightbox-masonry', 'responsive-lightbox-images-loaded' ], $rl->defaults['version'], ( $rl->options['settings']['loading_place'] === 'footer' ) );
2695
2696 // load script data?
2697 if ( ! empty( $this->script_data['basicmasonry'] ) )
2698 wp_add_inline_script( 'responsive-lightbox-basicmasonry-gallery', $this->script_data['basicmasonry'], 'before' );
2699
2700 // styles
2701 wp_register_style( 'responsive-lightbox-basicmasonry-gallery', plugins_url( 'css/gallery-basicmasonry.css', dirname( __FILE__ ) ), [], $rl->defaults['version'] );
2702 wp_register_style( 'responsive-lightbox-basicmasonry-gallery-inline', false, [ 'responsive-lightbox-basicmasonry-gallery' ], $rl->defaults['version'] );
2703
2704 // load style data?
2705 if ( ! empty( $this->style_data['basicmasonry'] ) )
2706 wp_add_inline_style( 'responsive-lightbox-basicmasonry-gallery-inline', $this->style_data['basicmasonry'] );
2707
2708 if ( $this->should_preload_gallery_assets() ) {
2709 $styles = apply_filters(
2710 'rl_gallery_preload_styles',
2711 [
2712 'responsive-lightbox-gallery',
2713 'responsive-lightbox-basicgrid-gallery',
2714 'responsive-lightbox-basicslider-gallery',
2715 'responsive-lightbox-basicmasonry-gallery'
2716 ]
2717 );
2718
2719 foreach ( $styles as $style ) {
2720 if ( is_string( $style ) && $style !== '' )
2721 wp_enqueue_style( $style );
2722 }
2723
2724 $scripts = apply_filters( 'rl_gallery_preload_scripts', [] );
2725
2726 foreach ( $scripts as $script ) {
2727 if ( is_string( $script ) && $script !== '' )
2728 wp_enqueue_script( $script );
2729 }
2730 }
2731 }
2732
2733 /**
2734 * Fetch remote image dimensions safely.
2735 *
2736 * @param string $url
2737 * @return array
2738 */
2739 private function remote_image_size_lookup( $url ) {
2740 $args = [
2741 'timeout' => 5,
2742 'redirection' => 0,
2743 'reject_unsafe_urls' => true,
2744 'limit_response_size' => 1048576,
2745 'headers' => [ 'Accept' => 'image/*' ]
2746 ];
2747
2748 $args = apply_filters( 'rl_remote_image_request_args', $args, $url );
2749 $max_redirects = absint( apply_filters( 'rl_remote_image_max_redirects', 3, $url ) );
2750 $current_url = $url;
2751
2752 for ( $redirects = 0; $redirects <= $max_redirects; $redirects++ ) {
2753 $response = wp_safe_remote_get( $current_url, $args );
2754
2755 if ( is_wp_error( $response ) )
2756 return [ 0, 0 ];
2757
2758 $status = wp_remote_retrieve_response_code( $response );
2759
2760 if ( in_array( $status, [ 301, 302, 303, 307, 308 ], true ) ) {
2761 $location = wp_remote_retrieve_header( $response, 'location' );
2762
2763 if ( empty( $location ) )
2764 return [ 0, 0 ];
2765
2766 if ( class_exists( 'WP_Http' ) )
2767 $location = WP_Http::make_absolute_url( $location, $current_url );
2768
2769 $next_url = $this->sanitize_remote_image_url( $location );
2770
2771 if ( empty( $next_url ) )
2772 return [ 0, 0 ];
2773
2774 $current_url = $next_url;
2775 continue;
2776 }
2777
2778 if ( $status < 200 || $status >= 300 )
2779 return [ 0, 0 ];
2780
2781 $body = wp_remote_retrieve_body( $response );
2782
2783 if ( empty( $body ) )
2784 return [ 0, 0 ];
2785
2786 $dimensions = @getimagesizefromstring( $body );
2787
2788 if ( is_array( $dimensions ) && isset( $dimensions[0], $dimensions[1] ) )
2789 return [ absint( $dimensions[0] ), absint( $dimensions[1] ) ];
2790
2791 return [ 0, 0 ];
2792 }
2793
2794 return [ 0, 0 ];
2795 }
2796
2797 /**
2798 * Ensure the remote URL points to an allowed host.
2799 *
2800 * @param string $url
2801 * @return bool
2802 */
2803 private function is_remote_image_url_allowed( $url ) {
2804 $parts = wp_parse_url( $url );
2805
2806 if ( empty( $parts['host'] ) )
2807 return false;
2808
2809 $host = strtolower( trim( $parts['host'], '[]' ) );
2810
2811 if ( in_array( $host, [ 'localhost', 'localhost.localdomain' ], true ) )
2812 return false;
2813
2814 if ( function_exists( 'idn_to_ascii' ) ) {
2815 $converted = defined( 'INTL_IDNA_VARIANT_UTS46' ) ? idn_to_ascii( $host, 0, INTL_IDNA_VARIANT_UTS46 ) : idn_to_ascii( $host );
2816
2817 if ( ! empty( $converted ) )
2818 $host = strtolower( $converted );
2819 }
2820
2821 $ips = $this->resolve_host_ips( $host );
2822
2823 if ( empty( $ips ) )
2824 return false;
2825
2826 foreach ( $ips as $ip ) {
2827 if ( $this->is_blocked_ip( $ip ) )
2828 return false;
2829 }
2830
2831 return true;
2832 }
2833
2834 /**
2835 * Resolve host into a list of IP addresses.
2836 *
2837 * @param string $host
2838 * @return array
2839 */
2840 private function resolve_host_ips( $host ) {
2841 $host = trim( $host );
2842
2843 if ( $host === '' )
2844 return [];
2845
2846 if ( filter_var( $host, FILTER_VALIDATE_IP ) )
2847 return [ $host ];
2848
2849 $ips = [];
2850
2851 if ( function_exists( 'dns_get_record' ) && defined( 'DNS_A' ) ) {
2852 $dns_types = defined( 'DNS_A' ) ? DNS_A : 0;
2853
2854 if ( defined( 'DNS_AAAA' ) )
2855 $dns_types |= DNS_AAAA;
2856
2857 if ( $dns_types > 0 ) {
2858 $records = @dns_get_record( $host, $dns_types );
2859
2860 if ( is_array( $records ) ) {
2861 foreach ( $records as $record ) {
2862 if ( ! empty( $record['ip'] ) )
2863 $ips[] = $record['ip'];
2864 elseif ( ! empty( $record['ipv6'] ) )
2865 $ips[] = $record['ipv6'];
2866 }
2867 }
2868 }
2869 }
2870
2871 if ( empty( $ips ) && function_exists( 'gethostbynamel' ) ) {
2872 $resolved = @gethostbynamel( $host );
2873
2874 if ( ! empty( $resolved ) )
2875 $ips = array_merge( $ips, $resolved );
2876 }
2877
2878 return array_unique( array_filter( $ips ) );
2879 }
2880
2881 /**
2882 * Check if an IP address belongs to a blocked range.
2883 *
2884 * @param string $ip
2885 * @return bool
2886 */
2887 private function is_blocked_ip( $ip ) {
2888 $ip = trim( $ip );
2889
2890 if ( $ip === '' )
2891 return true;
2892
2893 if ( strpos( $ip, '%' ) !== false )
2894 list( $ip ) = explode( '%', $ip );
2895
2896 $flags = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
2897
2898 if ( filter_var( $ip, FILTER_VALIDATE_IP, $flags ) === false )
2899 return true;
2900
2901 if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
2902 if ( preg_match( '/^(169\.254\.|100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\.)/', $ip ) )
2903 return true;
2904 } elseif ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
2905 $normalized = strtolower( $ip );
2906
2907 if ( $normalized === '::1' || strpos( $normalized, 'fe80:' ) === 0 )
2908 return true;
2909 }
2910
2911 return false;
2912 }
2913 }
2914