PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 3.33
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v3.33
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
photonic / Core / Photonic.php

Photonic.php in Photonic Gallery & Lightbox for Flickr, SmugMug & Others 3.33, at Core/Photonic.php

841 lines 29.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Photonic_Plugin\Core;
4
5 use Photonic_Plugin\Admin\Admin_Menu;
6 use Photonic_Plugin\Options\Defaults;
7 use Photonic_Plugin\Options\Options;
8 use WP_Error;
9
10 class Photonic {
11 public $defaults;
12 public bool $localized;
13 public array $provider_map;
14 public ?Admin_Menu $admin_menu;
15 public static string $library;
16 public static array $lightbox_replacements;
17 public static array $safe_tags;
18 public static array $safe_title_tags;
19
20 public function __construct() {
21 // $start = microtime(true);
22 global $photonic_options;
23
24 self::$lightbox_replacements = [
25 'fancybox' => 'fancybox3',
26 'magnific' => 'venobox',
27 'prettyphoto' => 'spotlight',
28 ];
29
30 self::$safe_tags = array_merge_recursive(
31 [
32 // Videos
33 'video' => [
34 'width' => true,
35 'height' => true,
36 'class' => true,
37 'controls' => true,
38 'preload' => true,
39 'poster' => true,
40 ],
41
42 'source' => [
43 'src' => true,
44 'type' => true,
45 ],
46
47 // Password prompters
48 'input' => [
49 'type' => true,
50 'name' => true,
51 'id' => true,
52 'class' => true,
53 'value' => true,
54 'data-photonic-shortcode' => true,
55 ],
56
57 'button' => [
58 'class' => true,
59 ],
60
61 // Custom data attributes
62 'div' => [
63 'data-photonic' => true,
64 'data-photonic-gallery-columns' => true,
65 'data-photonic-query' => true,
66 'data-photonic-platform' => true,
67 'data-photonic-prompt' => true,
68
69 // Slideshow
70 'data-splide' => true,
71 ],
72
73 /* 'ul' => [
74 // Slideshows
75 'data-photonic-columns' => true,
76 'data-photonic-controls' => true,
77 'data-photonic-fx' => true,
78 'data-photonic-layout' => true,
79 'data-photonic-pause' => true,
80 'data-photonic-speed' => true,
81 'data-photonic-strip-style' => true,
82 'data-photonic-timeout' => true,
83 ],*/
84
85 'img' => [
86 // Lazy loading
87 'data-src' => true,
88
89 // Tooltips
90 'data-photonic-tooltip' => true,
91 ],
92
93 'a' => [
94 // Non-photonic
95 'data-html5-href' => true,
96 'data-title' => true,
97 'data-type' => true,
98
99 // Non-Photonic - BaguetteBox
100 'data-content-type' => true,
101
102 // Non-Photonic - BigPicture
103 'data-bp' => true,
104 'data-bp-type' => true,
105
106 // Non-Photonic - Fancybox
107 'data-fancybox' => true,
108
109 // Non-Photonic - Featherlight
110 'data-featherlight' => true,
111 'data-featherlight-type' => true,
112
113 // Non-Photonic - GLightbox
114 'data-format' => true,
115
116 // Non-Photonic - Lightcase
117 'data-lc-options' => true,
118
119 // Non-Photonic - LightGallery
120 'data-download-url' => true,
121 'data-video' => true,
122 'data-sub-html' => true,
123 'data-photonic-thumb' => true,
124
125 // Non-Photonic - PhotoSwipe5
126 'data-pswp-height' => true,
127 'data-pswp-width' => true,
128
129 // Non-Photonic - Spotlight
130 'data-media' => true,
131 'data-src-mp4' => true,
132 'data-poster' => true,
133
134 // Non-Photonic - Strip
135 'data-strip-group' => true,
136 'data-strip-group-options' => true,
137 'data-strip-caption' => true,
138
139 // Non-Photonic - VenoBox
140 'data-gall' => true,
141 'data-vbtype' => true,
142
143 // Tooltips
144 'data-photonic-tooltip' => true,
145
146 // Level 3
147 'data-photonic-layout' => true,
148 'data-photonic-level-3' => true,
149
150 // Photonic photos
151 'data-photonic-deep' => true,
152 'data-photonic-media-type' => true,
153 'data-rel' => true,
154
155 // Photonic albums, common
156
157 // Albums, Google
158
159 // Photos, SmugMug
160 'data-photonic-buy' => true,
161
162 // Albums, Zenfolio
163 'data-photonic-realm' => true,
164 ],
165
166 'figure' => [
167 // Layouts - Horizontal Masonry
168 'data-photonic-idx' => true,
169 ],
170 ],
171 wp_kses_allowed_html('post')
172 );
173
174 self::$safe_title_tags = [
175 'h4' => [],
176 ];
177
178 require_once PHOTONIC_PATH . "/Options/Options.php";
179 add_action('admin_init', [Options::get_instance(), 'prepare_options'], 20); // Setting to 20 so that CPTs can be picked up - Utilities are loaded with a priority 10
180
181 $this->localized = false;
182 $this->provider_map = [
183 'flickr' => 'Flickr',
184 'smug' => 'SmugMug',
185 'smugmug' => 'SmugMug',
186 'google' => 'Google',
187 'zenfolio' => 'Zenfolio',
188 'instagram' => 'Instagram',
189 'deviantart' => 'DeviantArt'
190 ];
191
192 add_action('admin_menu', [&$this, 'add_admin_menu']);
193 add_action('admin_init', [&$this, 'admin_init']);
194
195 $photonic_options = get_option('photonic_options');
196 $set_options = isset($photonic_options) && is_array($photonic_options) ? $photonic_options : [];
197
198 $defaults = Defaults::get_options();
199 $all_options = array_merge($defaults, $set_options);
200
201 foreach ($all_options as $key => $value) {
202 $mod_key = 'photonic_' . $key;
203 global ${$mod_key};
204 ${$mod_key} = $value; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
205 }
206
207 define('PHOTONIC_SSL_VERIFY', empty($photonic_ssl_verify_off));
208 define('PHOTONIC_DEBUG', !empty($photonic_debug_on));
209
210 if (!empty($photonic_script_dev_mode)) {
211 define('PHOTONIC_DEV_MODE', '');
212 }
213 else {
214 define('PHOTONIC_DEV_MODE', '.min');
215 }
216
217 if (!empty($photonic_curl_timeout) && is_numeric($photonic_curl_timeout)) {
218 define('PHOTONIC_CURL_TIMEOUT', $photonic_curl_timeout);
219 }
220 else {
221 define('PHOTONIC_CURL_TIMEOUT', 30);
222 }
223
224 global $photonic_slideshow_library, $photonic_custom_lightbox;
225 if ('custom' !== $photonic_slideshow_library) {
226 self::$library = esc_attr($photonic_slideshow_library);
227 self::$library = empty(self::$lightbox_replacements[self::$library]) ? self::$library : self::$lightbox_replacements[self::$library];
228 }
229 elseif (empty($photonic_slideshow_library)) {
230 self::$library = 'baguettebox';
231 }
232 else {
233 self::$library = esc_attr($photonic_custom_lightbox);
234 }
235
236 // Gallery
237 if (!empty($photonic_alternative_shortcode)) {
238 add_shortcode($photonic_alternative_shortcode, [&$this, 'modify_gallery']);
239 add_filter('shortcode_atts_' . $photonic_alternative_shortcode, [&$this, 'native_gallery_attributes'], 10, 3);
240 }
241 else {
242 add_filter('post_gallery', [&$this, 'modify_gallery'], 20, 2);
243 add_filter('shortcode_atts_gallery', [&$this, 'native_gallery_attributes'], 10, 3);
244 }
245
246 add_shortcode('photonic_helper', [&$this, 'helper_shortcode']);
247
248 add_action('wp_enqueue_scripts', [&$this, 'always_add_styles'], 20);
249 if (!empty($photonic_always_load_scripts)) {
250 add_action('wp_enqueue_scripts', [&$this, 'conditionally_add_scripts'], 20, 0);
251 }
252
253 require_once PHOTONIC_PATH . "/Core/AJAX.php";
254 AJAX::get_instance($this);
255
256 /*
257 add_action('photonic_token_monitor', [&$this, 'monitor_token_validity']);
258 if (!wp_next_scheduled('photonic_token_monitor')) {
259 wp_schedule_event(time(), 'hourly', 'photonic_token_monitor');
260 }
261 */
262 // The above code was commented out in March 2023, Photonic v 2.85, to prevent running the cron for Instagram.
263 // The code below was added to clean out any previously scheduled cron jobs.
264 // This will be removed not before March 2024, to give users the opportunity to install the plugin and have it un-schedule their jobs.
265 $photonic_token_monitor_timestamp = wp_next_scheduled('photonic_token_monitor');
266 wp_unschedule_event($photonic_token_monitor_timestamp, 'photonic_token_monitor');
267
268 $this->add_extensions();
269 $this->add_gutenberg_support();
270
271 add_action('http_api_curl', [&$this, 'curl_timeout'], 100, 1);
272
273 add_action('plugins_loaded', [&$this, 'enable_translations']);
274
275 add_filter('body_class', [&$this, 'body_class']);
276
277 add_filter('safe_style_css', [&$this, 'safe_styles']);
278
279 // $end = microtime(true);
280 // print_r("<!-- Photonic initialization: ".($end - $start)." -->\n");
281
282 add_action('widgets_init', [&$this, 'load_widget']);
283
284 // add_action('elementor/common/after_register_scripts', [&$this, 'enqueue_widget_scripts']);
285 add_action('elementor/editor/before_enqueue_scripts', [&$this, 'enqueue_widget_scripts']);
286
287 require_once PHOTONIC_PATH . "/Core/Template.php";
288 }
289
290 /**
291 * Adds a menu item to the "Settings" section of the admin page.
292 *
293 * @return void
294 */
295 public function add_admin_menu() {
296 if (current_user_can('edit_theme_options')) {
297 $parent_slug = 'photonic-options-manager';
298 }
299 elseif (current_user_can('edit_posts')) {
300 $parent_slug = 'photonic-getting-started';
301 }
302
303 if (!empty($parent_slug)) {
304 add_menu_page('Photonic', 'Photonic', 'edit_posts', $parent_slug, [&$this->admin_menu, 'settings'], PHOTONIC_URL . 'include/images/Photonic-20-gr.png');
305 add_submenu_page($parent_slug, esc_html__('Settings', 'photonic'), esc_html__('Settings', 'photonic'), 'edit_theme_options', 'photonic-options-manager', [&$this->admin_menu, 'settings']);
306 add_submenu_page($parent_slug, 'Getting Started', 'Getting Started', 'edit_posts', 'photonic-getting-started', [&$this->admin_menu, 'getting_started']);
307 add_submenu_page($parent_slug, 'Authentication', 'Authentication', 'edit_theme_options', 'photonic-auth', [&$this->admin_menu, 'authentication']);
308 add_submenu_page($parent_slug, esc_html__('Shortcode Replacement', 'photonic'), esc_html__('Shortcode Replacement', 'photonic'), 'edit_posts', 'photonic-shortcode-replace', [&$this->admin_menu, 'shortcode']);
309 add_submenu_page($parent_slug, 'Helpers', 'Helpers', 'edit_posts', 'photonic-helpers', [&$this->admin_menu, 'helpers']);
310 }
311 }
312
313 /**
314 * Adds all scripts and their dependencies to the end of the <body> element only on pages using Photonic.
315 *
316 * @return void
317 */
318 public function conditionally_add_scripts() {
319 global $photonic_slideshow_library, $photonic_custom_lightbox_js, $photonic_custom_lightbox, $photonic_always_load_scripts,
320 $photonic_disable_photonic_lightbox_scripts, $photonic_disable_photonic_slider_scripts, $photonic_js_in_header;
321
322 $library_versions = [
323 'baguettebox' => '1.11.1',
324 'bigpicture' => '2022-03-31',
325 'colorbox' => '1.6.4',
326 'fancybox3' => '3.5.7',
327 'featherlight' => '1.7.14',
328 'glightbox' => '2022-03-12',
329 'imagelightbox' => '2018-08-17',
330 'lightcase' => '2.5.0',
331 'lightgallery' => '2.7.1',
332 'photoswipe' => '4.1.3',
333 'photoswipe5' => '5.3.7',
334 'prettyphoto' => '3.1.6',
335 'spotlight' => '0.7.8',
336 'splide' => '4.1.4',
337 'strip' => '1.8.0',
338 'swipebox' => '1.5.2',
339 'venobox' => '2.0.4',
340 ];
341
342 $requires_jq = [
343 'colorbox',
344 'fancybox',
345 'fancybox2',
346 'fancybox3',
347 'featherlight',
348 'imagelightbox',
349 'lightcase',
350 'magnific',
351 'prettyphoto',
352 'strip',
353 'swipebox',
354 ];
355
356 $photonic_dependencies = [];
357 $lb_deps = [];
358 if (in_array(self::$library, $requires_jq, true)) {
359 $photonic_dependencies[] = 'jquery';
360 $lb_deps[] = 'jquery';
361 }
362
363 if (in_array(self::$library, ['colorbox', 'fancybox', 'fancybox2', 'prettyphoto'], true)) {
364 wp_enqueue_script('jquery-detect-swipe', PHOTONIC_URL . 'include/ext/jquery.detect_swipe.js', ['jquery'], $this->get_version(PHOTONIC_PATH . '/include/ext/jquery.detect_swipe.js'), !($photonic_always_load_scripts && $photonic_js_in_header));
365 $photonic_dependencies[] = 'jquery-detect-swipe';
366 }
367
368 if ('thickbox' === self::$library) {
369 wp_enqueue_script('thickbox');
370 $photonic_dependencies[] = 'thickbox';
371 }
372 elseif ('custom' === $photonic_slideshow_library && 'strip' !== $photonic_custom_lightbox) {
373 $counter = 1;
374 $dependencies = ['jquery'];
375 foreach (preg_split("/((\r?\n)|(\r\n?))/", $photonic_custom_lightbox_js) as $line) {
376 wp_enqueue_script('photonic-lightbox-' . $counter, trim($line), $dependencies, PHOTONIC_VERSION, !($photonic_always_load_scripts && $photonic_js_in_header));
377 $photonic_dependencies[] = 'photonic-lightbox-' . $counter;
378 $counter++;
379 }
380 }
381 elseif ('none' !== self::$library) {
382 if (empty($photonic_disable_photonic_lightbox_scripts)) {
383 $photonic_dependencies[] = self::$library;
384 }
385
386 if (empty($photonic_disable_photonic_lightbox_scripts)) {
387 if ('lightgallery' === self::$library) {
388 $lightgallery_plugins = self::get_lightgallery_plugins();
389 if (!empty($lightgallery_plugins)) {
390 wp_enqueue_script('lightgallery', PHOTONIC_URL . 'include/ext/' . self::$library . '/' . self::$library . PHOTONIC_DEV_MODE . '.js', $lb_deps, $this->get_version(PHOTONIC_PATH . '/include/ext/' . self::$library . '/' . self::$library . PHOTONIC_DEV_MODE . '.js'), !($photonic_always_load_scripts && $photonic_js_in_header));
391 $photonic_dependencies[] = 'lightgallery';
392 }
393 if (!empty(PHOTONIC_DEV_MODE)) {
394 foreach ($lightgallery_plugins as $plugin) {
395 wp_enqueue_script('photonic-lightbox-' . $plugin, PHOTONIC_URL . 'include/ext/' . self::$library . '/lg-plugin-' . $plugin . '.min.js', ['lightgallery'], $this->get_version(PHOTONIC_PATH . '/include/ext/' . self::$library . '/lg-plugin-' . $plugin . '.min.js'), !($photonic_always_load_scripts && $photonic_js_in_header));
396 }
397 }
398 else {
399 wp_enqueue_script('photonic-lightbox-plugins', PHOTONIC_URL . 'include/ext/' . self::$library . '/lightgallery-plugins.js', ['lightgallery'], $this->get_version(PHOTONIC_PATH . '/include/ext/' . self::$library . '/lightgallery-plugins.js'), !($photonic_always_load_scripts && $photonic_js_in_header));
400 }
401 }
402 elseif ('photoswipe5' === self::$library) {
403 wp_deregister_script('photoswipe'); // Remove any older version of PhotoSwipe, since the new version is not compatible with it
404 }
405 }
406 }
407
408 if (empty($photonic_disable_photonic_slider_scripts)) {
409 wp_enqueue_script('splide', PHOTONIC_URL . 'include/ext/splide/splide' . PHOTONIC_DEV_MODE . '.js', [], $library_versions['splide'] . '-' . $this->get_version(PHOTONIC_PATH . '/include/ext/splide/splide' . PHOTONIC_DEV_MODE . '.js'), !($photonic_always_load_scripts && $photonic_js_in_header));
410 $photonic_dependencies[] = 'splide';
411 }
412
413 $slideshow_library = self::$library;
414
415 if (empty($photonic_disable_photonic_lightbox_scripts) && 'none' !== $slideshow_library && 'thickbox' !== $slideshow_library && $slideshow_library !== $photonic_custom_lightbox/* && 'photoswipe5' !== $slideshow_library*/) {
416 wp_enqueue_script($slideshow_library, PHOTONIC_URL . 'include/ext/' . $slideshow_library . '/' . $slideshow_library . PHOTONIC_DEV_MODE . '.js', $lb_deps, (empty($library_versions[$slideshow_library]) ? $this->get_version(PHOTONIC_PATH . "/include/ext/$slideshow_library/$slideshow_library" . PHOTONIC_DEV_MODE . ".js") : $library_versions[$slideshow_library]), !($photonic_always_load_scripts && $photonic_js_in_header));
417 }
418
419 $module = "include/js/front-end/out/photonic-" . $slideshow_library . PHOTONIC_DEV_MODE . '.js';
420
421 wp_enqueue_script('photonic', PHOTONIC_URL . $module, $photonic_dependencies, $this->get_version(PHOTONIC_PATH . "/" . $module), !($photonic_always_load_scripts && $photonic_js_in_header));
422
423 $this->localize_variables_once();
424 }
425
426 /**
427 * Special function to ensure that wp_localize_script, defining Photonic_JS is called at the most once.
428 * Since <code>conditionally_add_scripts</code> is called from <code>modify_gallery</code>, it can include the Photonic_JS
429 * definition multiple times. This code ensures that it is included just once.
430 */
431 public function localize_variables_once() {
432 if ($this->localized) {
433 return;
434 }
435 // Technically JS, but needs to happen here, otherwise the script is repeated multiple times, once for each time
436 // <code>conditionally_add_scripts</code> is called.
437 require_once PHOTONIC_PATH . '/Core/Front_End.php';
438 $js_array = Front_End::get_instance()->get_localized_js_variables();
439 wp_localize_script('photonic', 'Photonic_JS', $js_array);
440 $this->localized = true;
441 }
442
443 /**
444 * Adds all styles to all pages because styles, if not added in the header can cause issues.
445 *
446 * @return void
447 */
448 public function always_add_styles() {
449 global $photonic_slideshow_library, $photonic_custom_lightbox_css, $photonic_disable_photonic_lightbox_scripts, $photonic_disable_photonic_slider_scripts;
450
451 if ('custom' === $photonic_slideshow_library) {
452 $counter = 1;
453 foreach (preg_split("/((\r?\n)|(\r\n?))/", $photonic_custom_lightbox_css) as $line) {
454 wp_enqueue_style('photonic-lightbox-' . $counter, trim($line), [], PHOTONIC_VERSION);
455 $counter++;
456 }
457 }
458
459 $slideshow_library = esc_attr(!empty($photonic_disable_photonic_lightbox_scripts) ? 'none' : self::$library);
460
461 $this->enqueue_lightbox_styles($slideshow_library, empty($photonic_disable_photonic_slider_scripts));
462
463 global $photonic_css_in_file;
464 $file = trailingslashit(PHOTONIC_UPLOAD_DIR) . 'custom-styles.css';
465 if (@file_exists($file) && !empty($photonic_css_in_file)) { // phpcs:ignore WordPress.PHP.NoSilencedErrors
466 wp_enqueue_style('photonic-custom', trailingslashit(PHOTONIC_UPLOAD_URL) . 'custom-styles.css', ['photonic'], $this->get_version($file));
467 }
468 else {
469 wp_add_inline_style('photonic', $this->generate_css());
470 }
471
472 if (class_exists('\FLBuilder')) {
473 $this->load_beaver();
474 }
475 }
476
477 public function enqueue_lightbox_styles($slideshow_library = 'swipebox', $include_slider = true) {
478 if ($include_slider) {
479 wp_enqueue_style('photonic-slider', PHOTONIC_URL . 'include/ext/splide/splide' . PHOTONIC_DEV_MODE . '.css', [], $this->get_version(PHOTONIC_PATH . '/include/ext/splide/splide' . PHOTONIC_DEV_MODE . '.css'));
480 }
481
482 $no_css = [
483 'bigpicture',
484
485 'none',
486 'fancybox',
487 'fancybox2',
488 'fancybox4',
489 'magnific',
490 'prettyphoto',
491 ];
492
493 if ('colorbox' === $slideshow_library) {
494 global $photonic_cbox_theme;
495 if ('theme' === $photonic_cbox_theme) {
496 wp_enqueue_style('photonic-lightbox', PHOTONIC_URL . 'include/ext/colorbox/style-1/colorbox.css', [], $this->get_version(PHOTONIC_PATH . '/include/ext/colorbox/style-1/colorbox.css'));
497 }
498 else {
499 wp_enqueue_style('photonic-lightbox', PHOTONIC_URL . 'include/ext/colorbox/style-' . $photonic_cbox_theme . '/colorbox.css', [], $this->get_version(PHOTONIC_PATH . '/include/ext/colorbox/style-' . $photonic_cbox_theme . '/colorbox.css'));
500 }
501 }
502 elseif ('lightgallery' === $slideshow_library) {
503 global $photonic_enable_lg_transitions;
504 wp_enqueue_style('photonic-lightbox', PHOTONIC_URL . 'include/ext/lightgallery/lightgallery' . PHOTONIC_DEV_MODE . '.css', [], $this->get_version(PHOTONIC_PATH . '/include/ext/lightgallery/lightgallery' . PHOTONIC_DEV_MODE . '.css'));
505 if (!empty($photonic_enable_lg_transitions)) {
506 wp_enqueue_style('photonic-lightbox-lg-transitions', PHOTONIC_URL . 'include/ext/lightgallery/lightgallery-transitions.min.css', [], $this->get_version(PHOTONIC_PATH . '/include/ext/lightgallery/lightgallery-transitions.min.css'));
507 }
508 }
509 elseif ('thickbox' === $slideshow_library) {
510 wp_enqueue_style('thickbox');
511 }
512 elseif (!in_array($slideshow_library, $no_css, true)) {
513 wp_enqueue_style('photonic-lightbox', PHOTONIC_URL . 'include/ext/' . $slideshow_library . '/' . $slideshow_library . PHOTONIC_DEV_MODE . '.css', [], $this->get_version(PHOTONIC_PATH . '/include/ext/' . $slideshow_library . '/' . $slideshow_library . PHOTONIC_DEV_MODE . '.css'));
514 }
515
516 wp_enqueue_style('photonic', PHOTONIC_URL . "include/css/front-end/core/photonic" . PHOTONIC_DEV_MODE . ".css", [], $this->get_version(PHOTONIC_PATH . "/include/css/front-end/core/photonic" . PHOTONIC_DEV_MODE . ".css"));
517 }
518
519 /**
520 * Prints the dynamically generated CSS based on option selections.
521 *
522 * @param bool $header
523 * @return string
524 */
525 public function generate_css($header = true): string {
526 global $photonic_tile_spacing, $photonic_masonry_tile_spacing, $photonic_mosaic_tile_spacing;
527
528 $css = '';
529 $saved_css = get_option('photonic_css');
530
531 if ($header && !empty($saved_css)) {
532 $css .= "/* Retrieved from saved CSS */\n";
533 $css .= $saved_css;
534 }
535 else {
536 require_once PHOTONIC_PATH . '/Core/Front_End.php';
537 $front_end = Front_End::get_instance();
538
539 if ($header) {
540 $css .= "/* Dynamically generated CSS */\n";
541 }
542 $css .= ".photonic-panel { " .
543 $front_end->get_bg_css('photonic_flickr_gallery_panel_background') .
544 " }\n";
545
546 $css .= ".photonic-random-layout .photonic-thumb { padding: " . esc_attr($photonic_tile_spacing) . "px}\n";
547 $css .= ".photonic-masonry-layout .photonic-thumb, .photonic-masonry-horizontal-layout .photonic-thumb { padding: " . esc_attr($photonic_masonry_tile_spacing) . "px}\n";
548 $css .= ".photonic-mosaic-layout .photonic-thumb { padding: " . esc_attr($photonic_mosaic_tile_spacing) . "px}\n";
549 }
550
551 return $css;
552 }
553
554 public static function get_version($file) {
555 return gmdate("Ymd-Gis", @filemtime($file)); // phpcs:ignore WordPress.PHP.NoSilencedErrors
556 }
557
558 public function admin_init(): void {
559 require_once PHOTONIC_PATH . "/Admin/Admin.php";
560
561 if (!empty($_REQUEST['page']) && // phpcs:ignore WordPress.Security.NonceVerification
562 in_array($_REQUEST['page'], ['photonic-options-manager', 'photonic-options', 'photonic-helpers', 'photonic-getting-started', 'photonic-auth', 'photonic-shortcode-replace'], true)) { // phpcs:ignore WordPress.Security.NonceVerification
563 require_once PHOTONIC_PATH . "/Admin/Admin_Menu.php";
564 $this->admin_menu = new Admin_Menu(__FILE__, $this);
565 }
566 }
567
568 public function add_extensions() {
569 require_once "Gallery.php";
570 require_once PHOTONIC_PATH . "/Platforms/Base.php";
571 require_once PHOTONIC_PATH . '/Layouts/Core_Layout.php';
572 }
573
574 /**
575 * Overrides the native gallery short code, and does a lot more.
576 *
577 * @param $content
578 * @param array $attr
579 * @return string
580 */
581 public function modify_gallery($content, $attr = []) {
582 global $photonic_disable_on_home_page, $photonic_disable_on_archives;
583 if ((is_archive() && !empty($photonic_disable_on_archives)) ||
584 (is_home() && !empty($photonic_disable_on_home_page))) {
585 return false;
586 }
587
588 global $photonic_alternative_shortcode;
589
590 // If an alternative shortcode is used, then $content has the shortcode attributes
591 if (!empty($photonic_alternative_shortcode)) {
592 $attr = $content;
593 }
594 if (empty($attr)) {
595 $attr = [];
596 }
597
598 $this->conditionally_add_scripts();
599 $images = $this->get_gallery_images($attr);
600
601 if (!is_array($images)) {
602 return wp_kses($images, self::$safe_tags);
603 }
604
605 return wp_kses($content, self::$safe_tags);
606 }
607
608 /**
609 * Adds Photonic attributes to the native WP galleries. This cannot be called in <code>Photonic_Plugin\Platforms\Native</code> because
610 * that class is not initialised until a gallery of the native type is encountered
611 *
612 * @param array $out
613 * @param array $pairs Not used, but needed since this is for a standard gallery filter.
614 * @param array $attributes
615 * @return mixed
616 */
617 public function native_gallery_attributes(array $out, array $pairs, array $attributes): array { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
618 global $photonic_wp_title_caption, $photonic_thumbnail_style, $photonic_alternative_shortcode;
619
620 $defaults = [
621 'layout' => esc_attr($photonic_thumbnail_style ?: 'square'),
622
623 'custom_classes' => '',
624 'alignment' => '',
625
626 'caption' => esc_attr($photonic_wp_title_caption),
627 'page' => 1,
628 'count' => -1,
629 'thumb_size' => 'thumbnail',
630 'slide_size' => 'large',
631 ];
632
633 $attributes = array_merge($defaults, $attributes);
634 if (empty($attributes['style']) || ('default' === $attributes['style'] && !empty($photonic_alternative_shortcode) && 'gallery' !== $photonic_alternative_shortcode)) {
635 $attributes['style'] = $attributes['layout'];
636 }
637
638 foreach ($attributes as $key => $value) {
639 $out[$key] = $value;
640 }
641 return $out;
642 }
643
644 /**
645 * @param array $attr
646 * @return string
647 */
648 public function helper_shortcode($attr = []): string {
649 if (empty($attr)) {
650 $attr = [];
651 }
652
653 $this->conditionally_add_scripts();
654
655 if (empty($attr['type']) || !in_array(strtolower($attr['type']), ['google', 'flickr', 'smugmug', 'zenfolio'], true)) {
656 return sprintf(esc_html__('Please specify a value for %1$s. Accepted values are %2$s, %3$s, %4$s, %5$s', 'photonic'), '<code>type</code>', '<code>google</code>', '<code>flickr</code>', '<code>smugmug</code>', '<code>zenfolio</code>');
657 }
658
659 $gallery = new Gallery($attr);
660 return $gallery->get_helper_contents();
661 }
662
663 /**
664 * @param array $attr
665 * @return string
666 */
667 public function get_gallery_images(array $attr): string {
668 require_once PHOTONIC_PATH . '/Core/Front_End.php';
669 return Front_End::get_instance()->get_gallery_images($attr);
670 }
671
672 /**
673 * Make an HTTP request
674 *
675 * @static
676 * @param $url
677 * @param string $method GET | POST | DELETE.
678 * @param null $post_fields
679 * @param string $user_agent
680 * @param int $timeout
681 * @param bool $ssl_verify_peer
682 * @param array $headers
683 * @param array $cookies
684 * @return array|WP_Error
685 */
686 public static function http($url, $method = 'POST', $post_fields = null, $user_agent = null, $timeout = 90, $ssl_verify_peer = false, $headers = [], $cookies = []) {
687 $curl_args = [
688 'user-agent' => $user_agent,
689 'timeout' => $timeout,
690 'sslverify' => $ssl_verify_peer,
691 'headers' => array_merge(['Expect:'], $headers),
692 'method' => $method,
693 'body' => $post_fields,
694 'cookies' => $cookies,
695 ];
696
697 switch ($method) {
698 case 'DELETE':
699 if (!empty($post_fields)) {
700 $url = "{$url}?{$post_fields}";
701 }
702 break;
703 }
704
705 return wp_remote_request($url, $curl_args);
706 }
707
708 public function enable_translations() {
709 load_plugin_textdomain('photonic', false, false);
710 }
711
712 /**
713 * @param string|array $classes
714 * @return array
715 */
716 public function body_class($classes = []) {
717 if (!is_array($classes)) {
718 $classes = explode(' ', $classes);
719 }
720
721 return $classes;
722 }
723
724 /**
725 * Used for handling the front-end for Gutenberg blocks
726 *
727 * @param $attributes
728 * @return string
729 */
730 public function render_block($attributes): string {
731 if (!empty($attributes['shortcode'])) {
732 $shortcode = (array) (json_decode($attributes['shortcode']));
733
734 if (!empty($attributes['align'])) {
735 $shortcode['alignment'] = $attributes['align'];
736 }
737 if (!empty($attributes['className'])) {
738 $shortcode['custom_classes'] = $attributes['className'];
739 }
740
741 $this->conditionally_add_scripts();
742 return $this->get_gallery_images($shortcode);
743 }
744 return '';
745 }
746
747 private function add_gutenberg_support() {
748 if (function_exists('register_block_type')) {
749 register_block_type(
750 'photonic/gallery',
751 [
752 'attributes' => [
753 'shortcode' => [
754 'type' => 'string',
755 ],
756 ],
757 'render_callback' => [&$this, 'render_block'],
758 ]
759 );
760 }
761 }
762
763 public function curl_timeout($handle) {
764 // Forcing phpcs:ignore here, since the explicit purpose is to change cURL's timeout.
765 curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, PHOTONIC_CURL_TIMEOUT); // phpcs:ignore WordPress.WP.AlternativeFunctions
766 curl_setopt($handle, CURLOPT_TIMEOUT, PHOTONIC_CURL_TIMEOUT < 30 ? 30 : PHOTONIC_CURL_TIMEOUT); // phpcs:ignore WordPress.WP.AlternativeFunctions
767 }
768
769 public static function log($element) {
770 if (PHOTONIC_DEBUG) {
771 echo wp_kses($element, self::$safe_tags);
772 }
773 }
774
775 /**
776 * @param $link
777 * @return string
778 */
779 public static function doc_link($link): string {
780 return ' ' . sprintf(esc_html__('See %1$shere%2$s for documentation.', 'photonic'), "<a href='$link'>", '</a>');
781 }
782
783 public function load_widget() {
784 require_once PHOTONIC_PATH . '/Add_Ons/WP/Widget.php';
785 register_widget("Photonic_Plugin\Add_Ons\WP\Widget");
786 }
787
788 public function load_beaver() {
789 require_once PHOTONIC_PATH . '/Add_Ons/Beaver/Beaver_Module.php';
790 if (class_exists('\FLBuilderModel') && \FLBuilderModel::is_builder_active()) {
791 $this->enqueue_widget_scripts();
792 }
793 }
794
795 public static function enqueue_widget_scripts() {
796 global $photonic_alternative_shortcode;
797 $js_array = [
798 'ajaxurl' => admin_url('admin-ajax.php'),
799 'shortcode' => esc_js($photonic_alternative_shortcode ?: 'gallery'),
800 'current_shortcode' => esc_html__('Current shortcode', 'photonic'),
801 'edit_message' => esc_html__('Click on the icon to edit your gallery.', 'photonic'),
802 ];
803 wp_enqueue_script('photonic-native-ui', PHOTONIC_URL . 'include/js/admin/native-ui.js', ['shortcode', 'thickbox'], self::get_version(PHOTONIC_PATH . '/include/js/admin/native-ui.js'), false);
804 wp_enqueue_script('photonic-widget', PHOTONIC_URL . 'include/js/admin/widget.js', ['photonic-native-ui'], self::get_version(PHOTONIC_PATH . '/include/js/admin/widget.js'), true);
805 wp_localize_script('photonic-widget', 'Photonic_Widget_JS', $js_array);
806 wp_enqueue_style('photonic-widget', PHOTONIC_URL . 'include/css/admin/widget.css', [], self::get_version(PHOTONIC_PATH . '/include/css/admin/widget.css'));
807 }
808
809 /**
810 * Custom style attributes, primarily required for the Justified Grid layout. Since <code>wp_kses_post</code> strips out tags that it doesn't recognize, we have this.
811 *
812 * @param $styles
813 * @return mixed
814 */
815 public function safe_styles($styles) {
816 $styles[] = '--dw';
817 $styles[] = '--dh';
818 $styles[] = '--tile-min-height';
819 $styles[] = 'display';
820 return $styles;
821 }
822
823 public static function get_lightgallery_plugins(): array {
824 global $photonic_enable_lg_zoom, $photonic_enable_lg_thumbnail, $photonic_enable_lg_fullscreen, $photonic_enable_lg_autoplay;
825 $lightgallery_plugins = [];
826 if (!empty($photonic_enable_lg_autoplay)) {
827 $lightgallery_plugins[] = 'autoplay';
828 }
829 if (!empty($photonic_enable_lg_fullscreen)) {
830 $lightgallery_plugins[] = 'fullscreen';
831 }
832 if (!empty($photonic_enable_lg_thumbnail)) {
833 $lightgallery_plugins[] = 'thumbnail';
834 }
835 if (!empty($photonic_enable_lg_zoom)) {
836 $lightgallery_plugins[] = 'zoom';
837 }
838 return $lightgallery_plugins;
839 }
840 }
841