PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.0-dev2
Elementor Website Builder – more than just a page builder v4.0.0-dev2
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 4.1.0-dev1 4.0.7 All 451 releases
← All changes | modules/interactions/interactions-frontend-handler.php +118 -27 4.1.24.0.0-dev2 View file →
@@ -2,9 +2,8 @@
2 2
3 3 namespace Elementor\Modules\Interactions;
4 4
5 5 use Elementor\Plugin;
6 -use Elementor\Modules\Interactions\Cache\Interactions_Postmeta;
7 6
8 7 if ( ! defined( 'ABSPATH' ) ) {
9 8 exit; // Exit if accessed directly.
10 9 }
@@ -47,23 +46,74 @@
47 46 if ( empty( $elements_data ) || ! is_array( $elements_data ) ) {
48 47 return $elements_data;
49 48 }
50 49
51 - $interactions_postmeta = new Interactions_Postmeta();
52 - $cached_rows = $interactions_postmeta->load_content( $post_id );
50 + $collector = Interactions_Collector::instance();
53 51
54 - if ( empty( $cached_rows ) ) {
55 - $cached_rows = $interactions_postmeta->process_content( $post_id, [
56 - 'elements' => $elements_data,
57 - ] );
52 + // Recursively collect interactions from all elements
53 + $this->collect_interactions_recursive( $elements_data, $collector );
54 +
55 + return $elements_data;
56 + }
57 +
58 + /**
59 + * Recursively iterate through all elements and collect interactions.
60 + *
61 + * @param array $elements Array of element data.
62 + * @param Interactions_Collector $collector The collector instance.
63 + */
64 + private function collect_interactions_recursive( $elements, $collector ) {
65 + if ( ! is_array( $elements ) ) {
66 + return;
58 67 }
59 68
60 - $collector = Interactions_Collector::instance();
61 - foreach ( $cached_rows as $element_id => $interactions ) {
62 - $collector->register( $element_id, $interactions );
69 + foreach ( $elements as $element ) {
70 + if ( ! is_array( $element ) ) {
71 + continue;
72 + }
73 +
74 + // Check if this element has interactions
75 + if ( ! empty( $element['id'] ) && isset( $element['interactions'] ) ) {
76 + $element_id = $element['id'];
77 + $interactions = $element['interactions'];
78 +
79 + // Decode if it's a JSON string
80 + if ( is_string( $interactions ) ) {
81 + $decoded = json_decode( $interactions, true );
82 + if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) {
83 + $interactions = $decoded;
84 + } else {
85 + $interactions = null;
86 + }
87 + }
88 +
89 + // Normalize the interactions format - ensure we have items array
90 + if ( is_array( $interactions ) ) {
91 + // If interactions has 'items' key, it's already in the right format
92 + // If not, check if it's a direct array of items or has other structure
93 + if ( ! isset( $interactions['items'] ) ) {
94 + // Check if this looks like a direct array of interaction items
95 + // (first element has 'trigger' or 'animation' or '$$type')
96 + $first_item = reset( $interactions );
97 + if ( is_array( $first_item ) && ( isset( $first_item['trigger'] ) || isset( $first_item['animation'] ) || isset( $first_item['$$type'] ) ) ) {
98 + // It's a direct array of items, wrap it
99 + $interactions = [ 'items' => $interactions ];
100 + }
101 + }
102 +
103 + // Register with collector if we have valid items
104 + $items = $interactions['items'] ?? [];
105 + if ( ! empty( $items ) || ! empty( $interactions ) ) {
106 + $collector->register( $element_id, $interactions );
107 + }
108 + }
109 + }
110 +
111 + // Recursively process child elements
112 + if ( ! empty( $element['elements'] ) && is_array( $element['elements'] ) ) {
113 + $this->collect_interactions_recursive( $element['elements'], $collector );
114 + }
63 115 }
64 -
65 - return $elements_data;
66 116 }
67 117
68 118 /**
69 119 * Output collected interaction data as a JSON script tag in the footer.
@@ -76,10 +126,32 @@
76 126 if ( Plugin::$instance->editor->is_edit_mode() ) {
77 127 return;
78 128 }
79 129
80 - $elements_with_interactions = $this->elements_with_interactions();
130 + $collector = Interactions_Collector::instance();
131 + $all_interactions = $collector->get_all();
81 132
133 + if ( empty( $all_interactions ) ) {
134 + return;
135 + }
136 +
137 + // Format: array of elements, each with elementId, dataId, and cleaned interactions
138 + $elements_with_interactions = [];
139 + foreach ( $all_interactions as $element_id => $interactions ) {
140 + $items = $this->extract_interaction_items( $interactions );
141 +
142 + if ( empty( $items ) ) {
143 + continue;
144 + }
145 +
146 + // Build element entry with elementId, dataId, and cleaned interactions array
147 + $elements_with_interactions[] = [
148 + 'elementId' => $element_id,
149 + 'dataId' => $element_id,
150 + 'interactions' => $items,
151 + ];
152 + }
153 +
82 154 if ( empty( $elements_with_interactions ) ) {
83 155 return;
84 156 }
85 157
@@ -91,26 +163,43 @@
91 163 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON data is already encoded
92 164 echo '<script type="application/json" id="' . Module::SCRIPT_ID_INTERACTIONS_DATA . '">' . $json_data . '</script>';
93 165 }
94 166
95 - private function elements_with_interactions() {
96 - $all_interactions = Interactions_Collector::instance()->get_all();
167 + /**
168 + * Extract interaction items from various data formats.
169 + *
170 + * Handles multiple formats:
171 + * - v1 format: { items: [...] }
172 + * - v2 format with $$type: { items: { $$type: '...', value: [...] } }
173 + * - Direct arrays: [{ trigger: ..., animation: ... }, ...]
174 + *
175 + * @param array $interactions The interactions data.
176 + * @return array The extracted items array.
177 + */
178 + private function extract_interaction_items( $interactions ) {
179 + if ( ! is_array( $interactions ) ) {
180 + return [];
181 + }
97 182
98 - $elements_with_interactions = [];
183 + // Check if it has 'items' key (standard format)
184 + if ( isset( $interactions['items'] ) ) {
185 + $items = $interactions['items'];
99 186
100 - foreach ( $all_interactions as $element_id => $interactions ) {
101 - $elements_with_interactions[] = [
102 - 'elementId' => $element_id,
103 - 'dataId' => $element_id,
104 - 'interactions' => $interactions,
105 - ];
187 + return is_array( $items ) ? $items : [];
106 188 }
107 189
108 - return $elements_with_interactions;
109 - }
190 + // Check if interactions itself is a direct array of items
191 + // (first element has interaction-related keys)
192 + $first_item = reset( $interactions );
193 + if ( is_array( $first_item ) && (
194 + isset( $first_item['trigger'] ) ||
195 + isset( $first_item['animation'] ) ||
196 + isset( $first_item['$$type'] )
197 + ) ) {
198 + return $interactions;
199 + }
110 200
111 - private function get_interactions_config() {
112 - return $this->config_provider ? call_user_func( $this->config_provider ) : [];
201 + return [];
113 202 }
114 203
115 204 private function enqueue_interactions_assets() {
116 205 wp_enqueue_script( Module::HANDLE_MOTION_JS );
@@ -115,11 +204,13 @@
115 204 private function enqueue_interactions_assets() {
116 205 wp_enqueue_script( Module::HANDLE_MOTION_JS );
117 206 wp_enqueue_script( Module::HANDLE_FRONTEND );
118 207
208 + $config = $this->config_provider ? call_user_func( $this->config_provider ) : [];
209 +
119 210 wp_localize_script(
120 211 Module::HANDLE_FRONTEND,
121 212 Module::JS_CONFIG_OBJECT,
122 - $this->get_interactions_config()
213 + $config
123 214 );
124 215 }
125 216 }