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