PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.4
Elementor Website Builder – more than just a page builder v4.0.4
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 4.1.0-dev1 All 452 releases
elementor / modules / variables / utils / template-library-variables-snapshot-builder.php

template-library-variables-snapshot-builder.php in Elementor Website Builder – more than just a page builder 4.0.4, at modules/variables/utils/template-library-variables-snapshot-builder.php

239 lines 6.5 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\Variables\Utils;
4
5 use Elementor\Core\Utils\Template_Library_Element_Iterator;
6 use Elementor\Core\Utils\Template_Library_Import_Export_Utils;
7 use Elementor\Core\Utils\Template_Library_Snapshot_Processor;
8 use Elementor\Modules\Variables\Storage\Constants;
9 use Elementor\Modules\Variables\Storage\Variables_Collection;
10 use Elementor\Modules\Variables\Storage\Variables_Repository;
11 use Elementor\Plugin;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 class Template_Library_Variables_Snapshot_Builder extends Template_Library_Snapshot_Processor {
18
19 private static ?self $instance = null;
20
21 public static function make(): self {
22 if ( null === self::$instance ) {
23 self::$instance = new self();
24 }
25 return self::$instance;
26 }
27
28 public static function extract_used_variable_ids_from_elements( array $elements ): array {
29 $ids = [];
30 $variable_types = Variable_Type_Keys::get_all();
31
32 if ( empty( $elements ) ) {
33 return [];
34 }
35
36 Template_Library_Element_Iterator::iterate(
37 $elements,
38 function ( $element_data ) use ( &$ids, $variable_types ) {
39 self::collect_variable_ids_from_element( $element_data, $ids, $variable_types );
40 return $element_data;
41 }
42 );
43
44 return array_values( array_unique( $ids ) );
45 }
46
47 public static function build_snapshot_for_ids( array $ids ): ?array {
48 if ( empty( $ids ) ) {
49 return null;
50 }
51
52 $instance = self::make();
53 if ( ! $instance->can_access_repository() ) {
54 return null;
55 }
56
57 $ids = Template_Library_Import_Export_Utils::normalize_string_ids( $ids );
58 if ( empty( $ids ) ) {
59 return null;
60 }
61
62 $all_data = $instance->load_current_data();
63 $all_variables = $all_data['items'] ?? [];
64 $filtered_data = Template_Library_Import_Export_Utils::filter_items_by_ids( $all_variables, $ids );
65
66 if ( empty( $filtered_data ) ) {
67 return null;
68 }
69
70 return self::build_snapshot_from_data(
71 $filtered_data,
72 $all_data['version'] ?? Constants::FORMAT_VERSION_V1
73 );
74 }
75
76 public static function build_snapshot_for_elements( array $elements, ?array $global_classes_snapshot = null ): ?array {
77 $ids = self::extract_used_variable_ids_from_elements( $elements );
78
79 if ( ! empty( $global_classes_snapshot ) ) {
80 $ids_from_classes = self::extract_variable_ids_from_data( $global_classes_snapshot );
81 $ids = array_merge( $ids, $ids_from_classes );
82 }
83
84 $ids = array_values( array_unique( $ids ) );
85
86 if ( empty( $ids ) ) {
87 return null;
88 }
89
90 return self::build_snapshot_for_ids( $ids );
91 }
92
93 public static function extract_variable_ids_from_data( array $data ): array {
94 $ids = [];
95 $variable_types = Variable_Type_Keys::get_all();
96 self::extract_variable_ids_recursive( $data, $ids, $variable_types );
97 return array_values( array_unique( $ids ) );
98 }
99
100 public static function merge_snapshot_and_get_id_map( array $snapshot ): array {
101 return self::make()->merge_and_get_id_map( $snapshot );
102 }
103
104 public static function create_snapshot_as_new( array $snapshot ): array {
105 return self::make()->create_all_as_new( $snapshot );
106 }
107
108 protected function is_matching_item( array $existing_item, array $incoming_item ): bool {
109 // For variables, if the type and label match, we consider them the same item
110 // when merging, so we reuse the existing variable and ignore incoming values or extra fields.
111 return ( $existing_item['type'] ?? '' ) === ( $incoming_item['type'] ?? '' );
112 }
113
114 protected function get_item_prefix(): string {
115 return Template_Library_Import_Export_Utils::VARIABLE_ID_PREFIX;
116 }
117
118 protected function get_max_items(): int {
119 return Constants::TOTAL_VARIABLES_COUNT;
120 }
121
122 protected function can_access_repository(): bool {
123 return null !== $this->get_repository_or_null();
124 }
125
126 protected function load_current_data(): array {
127 $repository = $this->get_repository_or_null();
128
129 if ( ! $repository ) {
130 return [
131 'items' => [],
132 'order' => [],
133 'watermark' => 0,
134 'version' => Constants::FORMAT_VERSION_V1,
135 ];
136 }
137
138 $collection = $repository->load();
139 $serialized = $collection->serialize();
140
141 return [
142 'items' => $serialized['data'] ?? [],
143 'order' => [],
144 'watermark' => $serialized['watermark'] ?? 0,
145 'version' => $serialized['version'] ?? Constants::FORMAT_VERSION_V1,
146 ];
147 }
148
149 protected function parse_incoming_snapshot( array $snapshot ): ?array {
150 $incoming_data = $snapshot['data'] ?? [];
151 if ( empty( $incoming_data ) ) {
152 return null;
153 }
154 return $snapshot;
155 }
156
157 protected function get_incoming_items( array $parsed_snapshot ): array {
158 return $parsed_snapshot['data'] ?? [];
159 }
160
161 protected function count_current_items( array $items ): int {
162 $count = 0;
163 foreach ( $items as $item ) {
164 if ( empty( $item['deleted'] ) ) {
165 ++$count;
166 }
167 }
168 return $count;
169 }
170
171 protected function save_data( array $items, array $metadata ): array {
172 $repository = $this->get_repository_or_null();
173
174 if ( ! $repository ) {
175 return [];
176 }
177
178 $updated_collection = Variables_Collection::hydrate( [
179 'data' => $items,
180 'watermark' => $metadata['watermark'] ?? 0,
181 'version' => $metadata['version'] ?? Constants::FORMAT_VERSION_V1,
182 ] );
183
184 $repository->save( $updated_collection );
185
186 return [
187 'variables' => [
188 'data' => $items,
189 'watermark' => $updated_collection->watermark(),
190 ],
191 ];
192 }
193
194 private static function extract_variable_ids_recursive( $data, array &$ids, array $variable_types ): void {
195 if ( ! is_array( $data ) ) {
196 return;
197 }
198
199 if ( isset( $data['$$type'] ) && in_array( $data['$$type'], $variable_types, true ) ) {
200 if ( isset( $data['value'] ) && is_string( $data['value'] ) && '' !== $data['value'] ) {
201 $ids[] = $data['value'];
202 }
203 }
204
205 foreach ( $data as $value ) {
206 if ( is_array( $value ) ) {
207 self::extract_variable_ids_recursive( $value, $ids, $variable_types );
208 }
209 }
210 }
211
212 private static function collect_variable_ids_from_element( array $element_data, array &$ids, array $variable_types ): void {
213 if ( ! empty( $element_data['settings'] ) && is_array( $element_data['settings'] ) ) {
214 self::extract_variable_ids_recursive( $element_data['settings'], $ids, $variable_types );
215 }
216
217 if ( ! empty( $element_data['styles'] ) && is_array( $element_data['styles'] ) ) {
218 self::extract_variable_ids_recursive( $element_data['styles'], $ids, $variable_types );
219 }
220 }
221
222 private function get_repository_or_null(): ?Variables_Repository {
223 $kit = Plugin::instance()->kits_manager->get_active_kit();
224 if ( ! $kit ) {
225 return null;
226 }
227
228 return new Variables_Repository( $kit );
229 }
230
231 private static function build_snapshot_from_data( array $data, int $version ): array {
232 return [
233 'data' => $data,
234 'watermark' => 0,
235 'version' => $version,
236 ];
237 }
238 }
239