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