PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.4.3
Block Animations, Motion & Scroll Effects – Ghost Kit v3.4.3
3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / classes / class-assets.php

class-assets.php in Block Animations, Motion & Scroll Effects – Ghost Kit 3.4.3, at classes/class-assets.php

832 lines 24.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Assets static and dynamic.
4 *
5 * @package ghostkit
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Class GhostKit_Assets
14 */
15 class GhostKit_Assets {
16 /**
17 * List with stored assets.
18 *
19 * @var array
20 */
21 private static $stored_assets = array(
22 'script' => array(),
23 'style' => array(),
24 'custom-css' => array(),
25 );
26
27 /**
28 * Already added custom assets in head.
29 *
30 * @var boolean
31 */
32 private static $already_added_custom_assets = false;
33
34 /**
35 * Already add styles.
36 *
37 * @var array
38 */
39 private static $already_added_styles = array();
40
41 /**
42 * List with assets to skip from Autoptimize when CSS generated.
43 *
44 * @var array
45 */
46 protected static $skip_from_autoptimize = array(
47 'ghostkit-blocks-content-custom-css',
48 'ghostkit-blocks-widget-custom-css',
49 );
50
51 /**
52 * GhostKit_Assets constructor.
53 */
54 public function __construct() {
55 add_action( 'init', array( $this, 'register_scripts' ) );
56 add_action( 'plugins_loaded', array( $this, 'enqueue_scripts_action' ), 11 );
57 add_action( 'ghostkit_parse_blocks', array( $this, 'maybe_enqueue_blocks_assets' ), 11, 2 );
58 add_action( 'wp_enqueue_scripts', array( $this, 'add_custom_assets' ), 100 );
59
60 add_action( 'autoptimize_filter_css_exclude', 'GhostKit_Assets::autoptimize_filter_css_exclude' );
61
62 // enqueue runtime.
63 add_action( 'enqueue_block_editor_assets', 'GhostKit_Assets::enqueue_runtime', 11 );
64 add_action( 'wp_enqueue_scripts', 'GhostKit_Assets::enqueue_runtime', 8 );
65 }
66
67 /**
68 * Check if Webpack HMR file available.
69 *
70 * @return boolean
71 */
72 public static function is_webpack_hmr_support() {
73 return file_exists( ghostkit()->plugin_path . 'build/runtime.js' );
74 }
75
76 /**
77 * Enqueue runtime script.
78 */
79 public static function enqueue_runtime() {
80 // HMR Webpack.
81 if ( self::is_webpack_hmr_support() ) {
82 self::enqueue_script( 'ghostkit-runtime', 'build/runtime', array(), null, false );
83 }
84 }
85
86 /**
87 * Get .asset.php file data.
88 *
89 * @param string $filepath asset file path.
90 * @param string $filetype asset file type [style|script].
91 *
92 * @return array
93 */
94 public static function get_asset_file( $filepath, $filetype = '' ) {
95 $asset_path = ghostkit()->plugin_path . str_replace( '.min', '', $filepath ) . '.asset.php';
96
97 if ( file_exists( $asset_path ) ) {
98 // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
99 return include $asset_path;
100 } elseif ( ! empty( $filetype ) ) {
101 $file_ext = 'style' === $filetype ? 'css' : 'js';
102 $full_file_path = ghostkit()->plugin_path . $filepath . '.' . $file_ext;
103 $file_version = file_exists( $full_file_path ) ? filemtime( $full_file_path ) : null;
104 }
105
106 return array(
107 'dependencies' => array(),
108 'version' => $file_version ?? GHOSTKIT_VERSION,
109 );
110 }
111
112 /**
113 * Register script.
114 *
115 * @param string $name asset name.
116 * @param string $path file path.
117 * @param array $dependencies asset dependencies.
118 * @param string $version asset version.
119 * @param boolean $in_footer render in footer.
120 */
121 public static function register_script( $name, $path, $dependencies = array(), $version = null, $in_footer = true ) {
122 global $current_screen;
123
124 $script_data = self::get_asset_file( $path, 'script' );
125
126 if ( ! empty( $dependencies ) ) {
127 $script_data['dependencies'] = array_unique(
128 array_merge(
129 $script_data['dependencies'],
130 $dependencies
131 )
132 );
133 }
134
135 // Fix for Widgets screen.
136 if ( isset( $current_screen->id ) && 'widgets' === $current_screen->id ) {
137 foreach ( array( 'wp-edit-post', 'wp-editor' ) as $skip ) {
138 $key = array_search( $skip, $script_data['dependencies'], true );
139
140 if ( false !== $key ) {
141 unset( $script_data['dependencies'][ $key ] );
142 }
143 }
144 }
145
146 wp_register_script(
147 $name,
148 ghostkit()->plugin_url . $path . '.js',
149 $script_data['dependencies'],
150 $version ?? $script_data['version'],
151 $in_footer
152 );
153 }
154
155 /**
156 * Enqueue script.
157 *
158 * @param string $name asset name.
159 * @param string $path file path.
160 * @param array $dependencies asset dependencies.
161 * @param string $version asset version.
162 * @param boolean $in_footer render in footer.
163 */
164 public static function enqueue_script( $name, $path, $dependencies = array(), $version = null, $in_footer = true ) {
165 self::register_script( $name, $path, $dependencies, $version, $in_footer );
166
167 wp_enqueue_script( $name );
168 }
169
170 /**
171 * Register style
172 *
173 * @param string $name asset name.
174 * @param string $path file path.
175 * @param array $dependencies asset dependencies.
176 * @param string $version asset version.
177 */
178 public static function register_style( $name, $path, $dependencies = array(), $version = null ) {
179 $style_data = self::get_asset_file( $path, 'style' );
180
181 wp_register_style(
182 $name,
183 ghostkit()->plugin_url . $path . '.css',
184 $dependencies,
185 $version ?? $style_data['version']
186 );
187 }
188
189 /**
190 * Enqueue style
191 *
192 * @param string $name asset name.
193 * @param string $path file path.
194 * @param array $dependencies asset dependencies.
195 * @param string $version asset version.
196 */
197 public static function enqueue_style( $name, $path, $dependencies = array(), $version = null ) {
198 self::register_style( $name, $path, $dependencies, $version );
199
200 wp_enqueue_style( $name );
201 }
202
203 /**
204 * Store used assets, so we can enqueue it later.
205 *
206 * @param string $name - asset name.
207 * @param bool|string $value - just enqueue flag or url to asset.
208 * @param string $type - assets type [script|style|custom-css].
209 * @param int $priority - asset enqueue priority.
210 */
211 public static function store_used_assets( $name, $value = true, $type = 'script', $priority = 10 ) {
212 if ( ! isset( self::$stored_assets[ $type ] ) ) {
213 return;
214 }
215
216 // We need to check for duplicate assets, which may be added because of custom locations.
217 // Sometimes custom CSS is duplicated in Astra or Blocksy themes.
218 if ( 'custom-css' === $type ) {
219 if ( in_array( $value, self::$already_added_styles, true ) ) {
220 return;
221 }
222 self::$already_added_styles[] = $value;
223 }
224
225 if ( isset( self::$stored_assets[ $type ][ $name ] ) ) {
226 if ( 'custom-css' === $type ) {
227 if ( ! self::$stored_assets[ $type ][ $name ]['value'] ) {
228 self::$stored_assets[ $type ][ $name ]['value'] = '';
229 }
230
231 self::$stored_assets[ $type ][ $name ]['value'] .= $value;
232 }
233
234 do_action( 'gkt_assets_store', $name, $value, $type, $priority );
235
236 return;
237 }
238
239 self::$stored_assets[ $type ][ $name ] = array(
240 'value' => $value,
241 'priority' => $priority,
242 );
243
244 do_action( 'gkt_assets_store', $name, $value, $type, $priority );
245 }
246
247 /**
248 * Enqueue stored assets.
249 *
250 * @param string $type - assets type [script|style|custom-css].
251 */
252 public static function enqueue_stored_assets( $type = 'script' ) {
253 if ( ! isset( self::$stored_assets[ $type ] ) || empty( self::$stored_assets[ $type ] ) ) {
254 return;
255 }
256
257 uasort(
258 self::$stored_assets[ $type ],
259 function ( $a, $b ) {
260 if ( $a === $b ) {
261 return 0;
262 }
263
264 if ( isset( $a['priority'] ) && isset( $b['priority'] ) ) {
265 return $a['priority'] < $b['priority'] ? -1 : 1;
266 }
267
268 return 0;
269 }
270 );
271
272 foreach ( self::$stored_assets[ $type ] as $name => $data ) {
273 if ( isset( $data['value'] ) && $data['value'] ) {
274 if ( 'script' === $type ) {
275 wp_enqueue_script( $name );
276 } elseif ( 'style' === $type ) {
277 wp_enqueue_style( $name );
278 } elseif ( 'custom-css' === $type ) {
279 self::add_custom_css( $name, $data['value'] );
280 }
281
282 self::$stored_assets[ $type ]['value'] = false;
283 }
284 }
285 }
286
287 /**
288 * Enqueue assets for blocks.
289 *
290 * @param array $blocks - blocks array.
291 * @param string $location - blocks location [content,widget].
292 */
293 public static function enqueue( $blocks = array(), $location = 'content' ) {
294 self::store_used_assets( 'ghostkit', true, 'style', 9 );
295 self::store_used_assets( 'ghostkit', true, 'script', 11 );
296
297 $blocks_css = '';
298
299 // Prepare blocks assets.
300 foreach ( $blocks as $block ) {
301 // GhostKit blocks.
302 if ( isset( $block['blockName'] ) && strpos( $block['blockName'], 'ghostkit/' ) === 0 ) {
303 $block_name = preg_replace( '/^ghostkit\//', '', $block['blockName'] );
304
305 self::store_used_assets( 'ghostkit-block-' . $block_name, true, 'style' );
306 self::store_used_assets( 'ghostkit-block-' . $block_name, true, 'script' );
307 }
308
309 // Filter blocks custom CSS.
310 if ( isset( $block['blockName'] ) ) {
311 $custom_styles = apply_filters( 'gkt_block_custom_styles', '', $block );
312
313 if ( ! empty( $custom_styles ) ) {
314 if ( ! empty( $blocks_css ) ) {
315 $blocks_css .= ' ';
316 }
317
318 $blocks_css .= $custom_styles;
319 }
320 }
321 }
322
323 // Store custom CSS.
324 if ( ! empty( $blocks_css ) && $blocks_css ) {
325 self::store_used_assets( 'ghostkit-blocks-' . $location . '-custom-css', ghostkit()->replace_vars( $blocks_css ), 'custom-css' );
326 }
327 }
328
329 /**
330 * Enqueue scripts and styles actions.
331 * We need this to be used inside 'plugins_loaded' action to prevent conflicts with plugins and themes.
332 *
333 * 1. Enqueue plugins assets
334 * 2. Enqueue Ghost Kit assets
335 * 3. Enqueue theme assets
336 * 4. Enqueue Ghost Kit custom css
337 */
338 public function enqueue_scripts_action() {
339 add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_head_assets' ) );
340 add_action( 'wp_footer', array( $this, 'wp_enqueue_foot_assets' ) );
341
342 // Custom css with higher priority to overwrite theme styles.
343 add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_head_custom_assets' ), 11 );
344 add_action( 'wp_footer', array( $this, 'wp_enqueue_foot_custom_assets' ), 11 );
345 }
346
347 /**
348 * Register scripts that will be used in the future when portfolio will be printed.
349 */
350 public function register_scripts() {
351 $css_deps = array();
352 $js_deps = array( 'ghostkit-helper', 'ghostkit-event-fallbacks' );
353
354 do_action( 'gkt_before_assets_register' );
355
356 // Motion.
357 if ( apply_filters( 'gkt_enqueue_plugin_motion', true ) ) {
358 self::register_script( 'motion', 'assets/vendor/motion/dist/motion.min', array(), '11.15.0' );
359
360 $js_deps[] = 'motion';
361 }
362
363 // Ivent.
364 if ( apply_filters( 'gkt_enqueue_plugin_ivent', true ) ) {
365 self::register_script( 'ivent', 'assets/vendor/ivent/dist/ivent.min', array(), '0.2.0' );
366 }
367
368 // Jarallax.
369 if ( apply_filters( 'gkt_enqueue_plugin_jarallax', true ) ) {
370 self::register_script( 'jarallax', 'assets/vendor/jarallax/dist/jarallax.min', array(), '2.0.1' );
371 self::register_script( 'jarallax-video', 'assets/vendor/jarallax/dist/jarallax-video.min', array( 'jarallax' ), '2.0.1' );
372 }
373
374 // Swiper.
375 if ( apply_filters( 'gkt_enqueue_plugin_swiper', true ) ) {
376 // Add legacy swiper version in order to support Elementor plugin.
377 // https://wordpress.org/support/topic/visual-portfolio-elementor-issue/.
378 if ( class_exists( '\Elementor\Plugin' ) ) {
379 self::register_style( 'swiper', 'assets/vendor/swiper-5-4-5/swiper.min', array(), '5.4.5' );
380 self::register_script( 'swiper', 'assets/vendor/swiper-5-4-5/swiper.min', array(), '5.4.5' );
381 } else {
382 self::register_style( 'swiper', 'assets/vendor/swiper/swiper-bundle.min', array(), '8.4.6' );
383 self::register_script( 'swiper', 'assets/vendor/swiper/swiper-bundle.min', array(), '8.4.6' );
384 }
385 }
386
387 // Luxon.
388 if ( apply_filters( 'gkt_enqueue_plugin_luxon', true ) ) {
389 self::register_script( 'luxon', 'assets/vendor/luxon/build/global/luxon.min', array(), '3.3.0' );
390 }
391
392 // Lottie Player.
393 if ( apply_filters( 'gkt_enqueue_plugin_lottie_player', true ) ) {
394 self::register_script( 'lottie-player', 'assets/vendor/lottie-player/dist/lottie-player', array(), '2.0.3' );
395 wp_script_add_data( 'lottie-player', 'async', true );
396 }
397
398 // GistEmbed.
399 if ( apply_filters( 'gkt_enqueue_plugin_gist_simple', true ) ) {
400 self::register_style( 'gist-simple', 'assets/vendor/gist-simple/dist/gist-simple', array(), '2.0.0' );
401 self::register_script( 'gist-simple', 'assets/vendor/gist-simple/dist/gist-simple.min', array(), '2.0.0' );
402 }
403
404 // Google reCaptcha.
405 $recaptcha_site_key = get_option( 'ghostkit_google_recaptcha_api_site_key' );
406 $recaptcha_secret_key = get_option( 'ghostkit_google_recaptcha_api_secret_key' );
407
408 if ( apply_filters( 'gkt_enqueue_google_recaptcha', true ) && $recaptcha_site_key && $recaptcha_secret_key ) {
409 wp_register_script( 'google-recaptcha', 'https://www.google.com/recaptcha/api.js?render=' . esc_attr( $recaptcha_site_key ), array(), '3.0.0', true );
410 }
411
412 // Get all sidebars.
413 $sidebars = array();
414 if ( ! empty( $GLOBALS['wp_registered_sidebars'] ) ) {
415 foreach ( $GLOBALS['wp_registered_sidebars'] as $k => $sidebar ) {
416 $sidebars[ $k ] = array(
417 'id' => $sidebar['id'],
418 'name' => $sidebar['name'],
419 );
420 }
421 }
422
423 // helper script.
424 self::register_script(
425 'ghostkit-helper',
426 'build/assets/js/helper',
427 array( 'ivent' )
428 );
429
430 // Google Maps prepare localization as in WordPress settings.
431 $gmaps_locale = get_locale();
432 $gmaps_suffix = '.com';
433 switch ( $gmaps_locale ) {
434 case 'he_IL':
435 // Hebrew correction.
436 $gmaps_locale = 'iw';
437 break;
438 case 'zh_CN':
439 // Chinese integration.
440 $gmaps_suffix = '.cn';
441 break;
442 }
443 $gmaps_locale = substr( $gmaps_locale, 0, 2 );
444
445 $theme_data = wp_get_theme( get_template() );
446
447 $breakpoints = GhostKit_Breakpoints::get_breakpoints();
448
449 $timezone = wp_timezone_string();
450
451 if ( substr( $timezone, 0, 1 ) === '+' || substr( $timezone, 0, 1 ) === '-' ) {
452 $timezone = 'UTC' . $timezone;
453 }
454
455 $global_data = array(
456 'version' => GHOSTKIT_VERSION,
457 'pro' => false,
458
459 'themeName' => $theme_data->get( 'Name' ),
460 'settings' => get_option( 'ghostkit_settings', array() ),
461 'disabledBlocks' => get_option( 'ghostkit_disabled_blocks', array() ),
462
463 // TODO: Due to different formats in scss and assets there is an offset.
464 'media_sizes' => array(
465 'sm' => $breakpoints['xs'],
466 'md' => $breakpoints['sm'],
467 'lg' => $breakpoints['md'],
468 'xl' => $breakpoints['lg'],
469 ),
470 'timezone' => $timezone,
471 'googleMapsAPIKey' => get_option( 'ghostkit_google_maps_api_key' ),
472 'googleMapsAPIUrl' => 'https://maps.googleapis' . $gmaps_suffix . '/maps/api/js?v=3.exp&language=' . esc_attr( $gmaps_locale ),
473 'googleReCaptchaAPISiteKey' => $recaptcha_site_key,
474 'googleReCaptchaAPISecretKey' => is_admin() ? $recaptcha_secret_key : '',
475 'sidebars' => $sidebars,
476 'icons' => is_admin() ? apply_filters( 'gkt_icons_list', array() ) : array(),
477 'shapes' => is_admin() ? apply_filters( 'gkt_shapes_list', array() ) : array(),
478 'fonts' => is_admin() ? apply_filters( 'gkt_fonts_list', array() ) : array(),
479 'customTypographyList' => is_admin() ? apply_filters( 'gkt_custom_typography', array() ) : array(),
480 'admin_url' => admin_url(),
481 'admin_templates_url' => admin_url( 'edit.php?post_type=ghostkit_template' ),
482 );
483
484 $global_data = apply_filters( 'gkt_global_data', $global_data );
485
486 wp_localize_script(
487 'ghostkit-helper',
488 'ghostkitVariables',
489 $global_data
490 );
491
492 // events fallback script.
493 self::register_script(
494 'ghostkit-event-fallbacks',
495 'build/assets/js/event-fallbacks',
496 array( 'ghostkit-helper' )
497 );
498
499 // Fallback for classic themes.
500 if ( ! wp_is_block_theme() ) {
501 self::register_style(
502 'ghostkit-classic-theme-fallback',
503 'assets/css/fallback-classic-theme'
504 );
505 $css_deps[] = 'ghostkit-classic-theme-fallback';
506 }
507
508 // Ghost Kit.
509 self::register_style(
510 'ghostkit',
511 'build/gutenberg/style',
512 $css_deps
513 );
514 wp_style_add_data( 'ghostkit', 'rtl', 'replace' );
515 wp_style_add_data( 'ghostkit', 'suffix', '.min' );
516
517 self::register_script(
518 'ghostkit',
519 'build/assets/js/main',
520 $js_deps
521 );
522
523 // Extensions.
524 foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/extend/*/frontend.js' ) as $file ) {
525 $ext_name = basename( dirname( $file ) );
526 $ext_script_url = 'build/gutenberg/extend/' . $ext_name . '/frontend';
527 $ext_js_deps = array( 'ghostkit' );
528
529 switch ( $ext_name ) {
530 case 'effects':
531 $ext_js_deps[] = 'motion';
532 break;
533 }
534
535 self::register_script(
536 'ghostkit-extension-' . $ext_name,
537 $ext_script_url,
538 array_unique( $ext_js_deps )
539 );
540 self::store_used_assets( 'ghostkit-extension-' . $ext_name, true, 'script' );
541 }
542
543 // Style Variants.
544 foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/style-variants/*/frontend.js' ) as $template ) {
545 $ext_name = basename( dirname( $template ) );
546 $ext_script_url = 'build/gutenberg/style-variants/' . $ext_name . '/frontend';
547 $ext_js_deps = array( 'ghostkit' );
548
549 self::register_script(
550 'ghostkit-style-variant-' . $ext_name,
551 $ext_script_url,
552 array_unique( $ext_js_deps )
553 );
554 self::store_used_assets( 'ghostkit-style-variant-' . $ext_name, true, 'script' );
555 }
556
557 // Blocks.
558 foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/blocks/*/frontend.js' ) as $file ) {
559 $block_name = basename( dirname( $file ) );
560 $block_script_url = 'build/gutenberg/blocks/' . $block_name . '/frontend';
561 $block_js_deps = array( 'ghostkit' );
562
563 switch ( $block_name ) {
564 case 'accordion':
565 case 'alert':
566 $block_js_deps[] = 'motion';
567 break;
568 case 'grid':
569 case 'grid-column':
570 if ( wp_script_is( 'jarallax-video' ) || wp_script_is( 'jarallax-video', 'registered' ) ) {
571 $block_js_deps[] = 'jarallax-video';
572 }
573 if ( wp_script_is( 'jarallax' ) || wp_script_is( 'jarallax', 'registered' ) ) {
574 $block_js_deps[] = 'jarallax';
575 }
576 break;
577 case 'video':
578 if ( wp_script_is( 'jarallax-video' ) || wp_script_is( 'jarallax-video', 'registered' ) ) {
579 $block_js_deps[] = 'jarallax-video';
580 }
581 break;
582 case 'gist':
583 if ( wp_script_is( 'gist-simple' ) || wp_script_is( 'gist-simple', 'registered' ) ) {
584 $block_js_deps[] = 'gist-simple';
585 }
586 break;
587 case 'carousel':
588 if ( wp_script_is( 'swiper' ) || wp_script_is( 'swiper', 'registered' ) ) {
589 $block_js_deps[] = 'swiper';
590 }
591 break;
592 case 'countdown':
593 $block_js_deps[] = 'luxon';
594 break;
595 case 'form':
596 if ( wp_script_is( 'google-recaptcha' ) || wp_script_is( 'google-recaptcha', 'registered' ) ) {
597 $block_js_deps[] = 'google-recaptcha';
598 }
599 $block_js_deps[] = 'wp-i18n';
600 break;
601 case 'lottie':
602 $block_js_deps[] = 'motion';
603 $block_js_deps[] = 'lottie-player';
604 break;
605 case 'tabs':
606 $block_name = 'tabs-v2';
607 break;
608 }
609
610 self::register_script(
611 'ghostkit-block-' . $block_name,
612 $block_script_url,
613 array_unique( $block_js_deps )
614 );
615 }
616 foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/blocks/*/styles/style.css' ) as $file ) {
617 $block_name = basename( dirname( dirname( $file ) ) );
618 $block_style_url = 'build/gutenberg/blocks/' . $block_name . '/styles/style';
619 $block_css_deps = array( 'ghostkit' );
620
621 switch ( $block_name ) {
622 case 'gist':
623 $block_css_deps[] = 'gist-simple';
624 break;
625 case 'carousel':
626 $block_css_deps[] = 'swiper';
627 break;
628 case 'tabs':
629 $block_name = 'tabs-v2';
630 break;
631 }
632
633 self::register_style(
634 'ghostkit-block-' . $block_name,
635 $block_style_url,
636 array_unique( $block_css_deps )
637 );
638 wp_style_add_data( 'ghostkit-block-' . $block_name, 'rtl', 'replace' );
639 wp_style_add_data( 'ghostkit-block-' . $block_name, 'suffix', '.min' );
640 }
641
642 do_action( 'gkt_after_assets_register' );
643 }
644
645 /**
646 * Enqueue styles in head.
647 */
648 public function wp_enqueue_head_assets() {
649 self::enqueue_stored_assets( 'style' );
650 self::enqueue_stored_assets( 'script' );
651 }
652
653 /**
654 * Enqueue custom styles in head.
655 */
656 public function wp_enqueue_head_custom_assets() {
657 self::enqueue_stored_assets( 'custom-css' );
658 }
659
660 /**
661 * Enqueue scripts and styles in foot.
662 */
663 public function wp_enqueue_foot_assets() {
664 self::enqueue_stored_assets( 'style' );
665 self::enqueue_stored_assets( 'script' );
666 }
667
668 /**
669 * Enqueue custom styles in foot.
670 */
671 public function wp_enqueue_foot_custom_assets() {
672 self::enqueue_stored_assets( 'custom-css' );
673 }
674
675 /**
676 * Enqueue blocks assets.
677 *
678 * @param array $blocks - blocks array.
679 * @param array $location - blocks location [content,widget].
680 */
681 public function maybe_enqueue_blocks_assets( $blocks, $location ) {
682 if ( self::$already_added_custom_assets ) {
683 $location = 'widget';
684 }
685
686 self::enqueue( $blocks, $location );
687 }
688
689 /**
690 * Add styles from blocks to the head section.
691 *
692 * @param int $post_id - current post id.
693 */
694 public function add_custom_assets( $post_id ) {
695 $global_code = get_option( 'ghostkit_custom_code', array() );
696
697 if ( is_singular() && ! $post_id ) {
698 $post_id = get_the_ID();
699 }
700
701 $is_single = is_singular() && $post_id;
702
703 // Global custom CSS.
704 if ( $global_code && isset( $global_code['ghostkit_custom_css'] ) && $global_code['ghostkit_custom_css'] ) {
705 self::add_custom_css( 'ghostkit-global-custom-css', $global_code['ghostkit_custom_css'] );
706 }
707
708 // Local custom CSS.
709 if ( $is_single ) {
710 $meta_css = get_post_meta( $post_id, 'ghostkit_custom_css', true );
711
712 if ( ! empty( $meta_css ) ) {
713 self::add_custom_css( 'ghostkit-custom-css', $meta_css );
714 }
715 }
716
717 // Global custom JS head.
718 if ( $global_code && isset( $global_code['ghostkit_custom_js_head'] ) && $global_code['ghostkit_custom_js_head'] ) {
719 self::add_custom_js( 'ghostkit-global-custom-js-head', $global_code['ghostkit_custom_js_head'] );
720 }
721
722 // Local custom JS head.
723 if ( $is_single ) {
724 $meta_js_head = get_post_meta( $post_id, 'ghostkit_custom_js_head', true );
725
726 if ( ! empty( $meta_js_head ) ) {
727 self::add_custom_js( 'ghostkit-custom-js-head', $meta_js_head );
728 }
729 }
730
731 // Global custom JS foot.
732 if ( $global_code && isset( $global_code['ghostkit_custom_js_foot'] ) && $global_code['ghostkit_custom_js_foot'] ) {
733 self::add_custom_js( 'ghostkit-global-custom-js-foot', $global_code['ghostkit_custom_js_foot'], true );
734 }
735
736 // Local custom JS foot.
737 if ( $is_single ) {
738 $meta_js_foot = get_post_meta( $post_id, 'ghostkit_custom_js_foot', true );
739
740 if ( ! empty( $meta_js_foot ) ) {
741 self::add_custom_js( 'ghostkit-custom-js-foot', $meta_js_foot, true );
742 }
743 }
744
745 self::$already_added_custom_assets = true;
746 }
747
748 /**
749 * Skip custom styles from Autoptimize.
750 * We need this since generated CSS with custom breakpoints are excluded
751 * from Autoptimize by default and this cause conflicts.
752 *
753 * @param string $result - allowed list.
754 * @return string
755 */
756 public static function autoptimize_filter_css_exclude( $result ) {
757 $upload_dir = defined( 'UPLOADS' ) ? UPLOADS : 'wp-content/uploads/';
758
759 // By default in Autoptimize excluded folder `wp-content/uploads/`.
760 // We need to check, if this folder is not excluded, then we
761 // don't need to use our hack.
762 if ( $result && strpos( $result, $upload_dir ) === false ) {
763 return $result;
764 }
765
766 foreach ( self::$skip_from_autoptimize as $name ) {
767 if ( $result ) {
768 $result .= ',';
769 } else {
770 $result = '';
771 }
772
773 $result .= $name;
774 }
775
776 return $result;
777 }
778
779 /**
780 * Add custom CSS.
781 *
782 * @param string $name - handle name.
783 * @param string $css - code.
784 */
785 public static function add_custom_css( $name, $css ) {
786 if ( ! wp_style_is( $name, 'enqueued' ) ) {
787 $css = wp_kses( $css, array( '\'', '\"' ) );
788 $css = str_replace( '&gt;', '>', $css );
789
790 $allow_js_fallback = apply_filters( 'gkt_custom_css_allow_js_fallback', self::$already_added_custom_assets, $name, $css );
791
792 // Enqueue custom CSS.
793 if ( ! $allow_js_fallback ) {
794 wp_register_style( $name, false, array(), GHOSTKIT_VERSION );
795 wp_enqueue_style( $name );
796 wp_add_inline_style( $name, $css );
797
798 // Enqueue JS instead of CSS when rendering in <body> to prevent W3C errors.
799 } elseif ( ! wp_script_is( $name, 'enqueued' ) ) {
800 wp_register_script( $name, false, array(), GHOSTKIT_VERSION, true );
801 wp_enqueue_script( $name );
802 wp_add_inline_script(
803 $name,
804 '(function(){
805 var styleTag = document.createElement("style");
806 styleTag.id = "' . esc_attr( $name ) . '-inline-css";
807 styleTag.innerHTML = ' . wp_json_encode( $css ) . ';
808 document.body.appendChild(styleTag);
809 }());'
810 );
811 }
812 }
813
814 self::$stored_assets[] = $name;
815 }
816
817 /**
818 * Add custom JS.
819 *
820 * @param string $name - handle name.
821 * @param string $js - code.
822 * @param boolean $footer - print in footer.
823 */
824 public static function add_custom_js( $name, $js, $footer = false ) {
825 wp_register_script( $name, '', array(), GHOSTKIT_VERSION, $footer );
826 wp_enqueue_script( $name );
827 wp_add_inline_script( $name, $js );
828 }
829 }
830
831 new GhostKit_Assets();
832