PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0
Elementor Website Builder – more than just a page builder v4.3.0
4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 All 453 releases
elementor / modules / atomic-widgets / styles / atomic-widget-styles.php

atomic-widget-styles.php in Elementor Website Builder – more than just a page builder 4.3.0, at modules/atomic-widgets/styles/atomic-widget-styles.php

153 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\AtomicWidgets\Styles;
4
5 use Elementor\Core\Base\Document;
6 use Elementor\Modules\AtomicWidgets\Utils\Utils;
7 use Elementor\Modules\GlobalClasses\Utils\Atomic_Elements_Utils;
8 use Elementor\Utils as ElementorUtils;
9 use Elementor\Plugin;
10
11 class Atomic_Widget_Styles {
12 const STYLES_KEY = 'local';
13 const CONTEXT_FRONTEND = 'frontend';
14 const CONTEXT_PREVIEW = 'preview';
15
16 public function register_hooks() {
17 add_action( 'elementor/atomic-widgets/styles/register', function( Atomic_Styles_Manager $styles_manager, array $post_ids ) {
18 $this->register_styles( $styles_manager, $post_ids );
19 }, 30, 2 );
20
21 add_action( 'elementor/document/after_save', fn( Document $document ) => $this->invalidate_cache(
22 [ $document->get_main_post()->ID ],
23 $this->get_context( ! Utils::is_post_published( $document ) )
24 ), 20, 2 );
25
26 add_action(
27 'elementor/core/files/clear_cache',
28 fn() => $this->invalidate_cache(),
29 );
30
31 add_action(
32 'deleted_post',
33 fn( $post_id ) => $this->invalidate_cache( [ $post_id ] )
34 );
35
36 add_action(
37 'update_option__elementor_pro_license_v2_data',
38 fn( $old_value, $new_value ) => $this->on_license_data_update( $old_value, $new_value ),
39 10,
40 2
41 );
42
43 add_action( 'delete_option__elementor_pro_license_v2_data', fn() => Plugin::$instance->files_manager->clear_cache() );
44 }
45
46 /**
47 * Pro stores the license under a transient-style wrapper whose `timeout` is recomputed on
48 * every write, so a routine re-validation reports a changed option even when the license
49 * itself is identical. Purging the whole CSS directory on those refreshes deletes files that
50 * in-flight requests have already enqueued, so only act on a real license change.
51 */
52 private function on_license_data_update( $old_value, $new_value ): void {
53 $old_payload = $this->get_license_payload( $old_value );
54
55 // Anything we can't positively read as an unchanged license falls through to a purge.
56 if ( null !== $old_payload && $old_payload === $this->get_license_payload( $new_value ) ) {
57 return;
58 }
59
60 Plugin::$instance->files_manager->clear_cache();
61 }
62
63 private function get_license_payload( $option_value ): ?string {
64 if ( ! is_array( $option_value ) || ! isset( $option_value['value'] ) || ! is_string( $option_value['value'] ) ) {
65 return null;
66 }
67
68 return $option_value['value'];
69 }
70
71 private function register_styles( Atomic_Styles_Manager $styles_manager, array $post_ids ) {
72 $context = $this->get_context( Plugin::$instance->preview->is_editor_or_preview() );
73
74 foreach ( $post_ids as $post_id ) {
75 $get_styles = fn() => $this->parse_post_styles( $post_id );
76
77 $styles_manager->register( [ self::STYLES_KEY, $post_id, $context ], $get_styles );
78 }
79 }
80
81 private function parse_post_styles( $post_id ) {
82 $post_styles = [];
83
84 Utils::traverse_post_elements( $post_id, function( $element_data ) use ( &$post_styles ) {
85 $post_styles = array_merge( $post_styles, $this->parse_element_style( $element_data ) );
86 } );
87
88 return self::get_license_based_filtered_styles( $post_styles );
89 }
90
91 private function parse_element_style( array $element_data ) {
92 $element_type = Atomic_Elements_Utils::get_element_type( $element_data );
93 $element_instance = Atomic_Elements_Utils::get_element_instance( $element_type );
94
95 if ( ! Utils::is_atomic( $element_instance ) ) {
96 return [];
97 }
98
99 return $element_data['styles'] ?? [];
100 }
101
102 private function invalidate_cache( ?array $post_ids = null, ?string $context = null ) {
103 if ( empty( $post_ids ) ) {
104 do_action( 'elementor/atomic-widgets/styles/clear', [ self::STYLES_KEY ] );
105
106 return;
107 }
108
109 $is_post_status_publish = self::CONTEXT_FRONTEND === $context;
110
111 // When a user publishes a post, we should invalidate the styles of the draft too
112 foreach ( $post_ids as $post_id ) {
113 do_action( 'elementor/atomic-widgets/styles/clear',
114 empty( $context ) || $is_post_status_publish
115 ? [ self::STYLES_KEY, $post_id ]
116 : [ self::STYLES_KEY, $post_id, $context ]
117 );
118 }
119 }
120
121 private function get_context( bool $is_preview ) {
122 return $is_preview ? self::CONTEXT_PREVIEW : self::CONTEXT_FRONTEND;
123 }
124
125 public static function get_license_based_filtered_styles( $styles ) {
126 if ( ElementorUtils::has_pro() && version_compare( ELEMENTOR_PRO_VERSION, '3.35', '<' ) ) {
127 return $styles;
128 }
129
130 return apply_filters(
131 'elementor/atomic_widgets/editor_data/element_styles',
132 self::remove_custom_css_from_styles( $styles ),
133 $styles
134 );
135 }
136
137 public static function remove_custom_css_from_styles( array $styles ) {
138 if ( empty( $styles ) ) {
139 return $styles;
140 }
141
142 foreach ( $styles as $style_id => $style ) {
143 if ( isset( $style['variants'] ) && is_array( $style['variants'] ) ) {
144 foreach ( $style['variants'] as $variant_index => $variant ) {
145 unset( $styles[ $style_id ]['variants'][ $variant_index ]['custom_css'] );
146 }
147 }
148 }
149
150 return $styles;
151 }
152 }
153