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