PluginProbe
Elementor Website Builder – more than just a page builder / 4.1.0-dev3
Elementor Website Builder – more than just a page builder v4.1.0-dev3
4.3.2 4.3.1 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 All 455 releases
← All changes | modules/global-classes/global-classes-repository.php +84 -188 4.3.0-beta2 → 4.1.0-dev3 View file →
@@ -2,9 +2,9 @@
2 2 namespace Elementor\Modules\GlobalClasses;
3 3
4 4 use Elementor\Core\Kits\Documents\Kit;
5 5 use Elementor\Modules\DesignSystemSync\Classes\Global_Classes_Sync_Map;
6 -use Elementor\Core\Kits\Concerns\Has_Kit_Dependency;
6 +use Elementor\Modules\GlobalClasses\Concerns\Has_Kit_Dependency;
7 7 use Elementor\Modules\GlobalClasses\Concerns\Has_Preview_Context;
8 8 use Elementor\Modules\GlobalClasses\Utils\Global_Class_Data_Normalizer;
9 9
10 10 if ( ! defined( 'ABSPATH' ) ) {
@@ -28,8 +28,12 @@
28 28 'event' => [
29 29 'frontend' => self::CONTEXT_FRONTEND,
30 30 'preview' => self::CONTEXT_PREVIEW,
31 31 ],
32 + 'meta_key' => [
33 + 'frontend' => self::META_KEY_FRONTEND,
34 + 'preview' => self::META_KEY_PREVIEW,
35 + ],
32 36 ];
33 37
34 38 private ?Global_Classes $cache = null;
35 39
@@ -66,15 +70,13 @@
66 70 return $this->labels()->get_ordered_labels();
67 71 }
68 72
69 73 public function get_order(): array {
70 - return Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() )->get_order();
74 + return Global_Classes_Order::make( $this->get_kit() )->get_order();
71 75 }
72 76
73 77 public function update_order_and_labels( array $order, array $new_labels ): void {
74 - Global_Classes_Order::make( $this->get_kit() )
75 - ->set_preview( $this->is_preview() )
76 - ->set_order( $order );
78 + Global_Classes_Order::make( $this->get_kit() )->set_order( $order );
77 79
78 80 $labels = $this->labels();
79 81 $existing_labels = $labels->get_labels();
80 82
@@ -91,9 +93,9 @@
91 93 return Global_Classes_Labels::make( $this->get_kit() )->set_preview( $this->is_preview() );
92 94 }
93 95
94 96 public function get( string $class_id ): ?array {
95 - $post = Global_Class_Post::find_by_class_id( $class_id, $this->is_preview(), $this->get_kit() );
97 + $post = Global_Class_Post::find_by_class_id( $class_id, $this->is_preview() );
96 98
97 99 return $post ? $post->to_array() : null;
98 100 }
99 101
@@ -101,17 +103,13 @@
101 103 if ( empty( $class_ids ) ) {
102 104 return [];
103 105 }
104 106
105 - $post_ids = Global_Classes_Post_IDs::make( $this->get_kit() )->get_post_ids( $class_ids );
106 107 $items = [];
107 108
108 - foreach ( $post_ids as $class_id => $post_id ) {
109 - $post = Global_Class_Post::from_post_id( $post_id, $this->is_preview() );
110 -
111 - if ( $post ) {
112 - $items[ $class_id ] = $post->to_array();
113 - }
109 + foreach ( $this->iterate_class_posts_for_ids( $class_ids ) as $class_post ) {
110 + $class_data = $class_post->to_array();
111 + $items[ $class_data['id'] ] = $class_data;
114 112 }
115 113
116 114 return $items;
117 115 }
@@ -133,28 +131,24 @@
133 131 $final_label_map[ $id ] = $before[ $id ];
134 132 }
135 133 }
136 134
137 - $affected_post_ids = $this->get_posts_affected_by_deletion( $to_delete );
138 -
139 135 $this->persist_class_batch_mutations( $to_delete, $to_create, $to_update, $touched_items, $is_preview );
140 136
141 - $classes_order = Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() );
137 + $classes_order = Global_Classes_Order::make( $this->get_kit() );
142 138 $classes_order->set_order( $order );
143 139 $labels->set_labels( $final_label_map );
144 140
145 141 if ( ! $is_preview ) {
146 142 Global_Classes_Sync_Map::make( $this->get_kit() )->apply_changes( $touched_items, $to_delete );
147 - Global_Classes_Order::make( $this->get_kit() )
148 - ->set_preview( true )
149 - ->set_order( $order );
150 143
151 - $this->bulk_clear_preview_meta( array_values( $to_update ) );
152 - $this->clear_preview_labels_for_ids( array_merge(
153 - array_values( $to_create ),
154 - array_values( $to_update ),
155 - array_values( $to_delete )
156 - ) );
144 + $this->each_class_id_batch( array_values( $to_update ), function ( string $class_id ) {
145 + $post = Global_Class_Post::find_by_class_id( $class_id, false );
146 + if ( $post ) {
147 + delete_post_meta( $post->get_post_id(), Global_Class_Post::META_KEY_DATA_PREVIEW );
148 + clean_post_cache( $post->get_post_id() );
149 + }
150 + } );
157 151 }
158 152
159 153 $this->cache = null;
160 154 $this->flush_runtime_cache();
@@ -163,18 +157,9 @@
163 157 'added' => $to_create,
164 158 'deleted' => $to_delete,
165 159 'modified' => $to_update,
166 160 'order' => $order_changed,
167 - 'affected_post_ids' => $affected_post_ids,
168 161 ] );
169 -
170 - if ( ! empty( $to_delete ) && ! $is_preview ) {
171 - do_action(
172 - 'elementor/global_classes/cleanup',
173 - $to_delete,
174 - $affected_post_ids
175 - );
176 - }
177 162 }
178 163
179 164 public function each_item( callable $cb, bool $skip_migration = false, int $batch_size = self::READ_BATCH_SIZE ): void {
180 165 $order = Global_Classes_Order::make( $this->get_kit() )->get_order();
@@ -190,69 +175,31 @@
190 175 }
191 176 }
192 177
193 178 public function put( array $items, array $order ) {
194 - $current_ids = Global_Classes_Order::make( $this->get_kit() )
195 - ->set_preview( $this->is_preview() )
196 - ->get_order();
179 + $current_ids = Global_Classes_Order::make( $this->get_kit() )->get_order();
197 180
198 181 $new_ids = array_keys( $items );
182 +
199 183 $current_order_string = implode( ';', $current_ids );
200 - $deleted_class_ids = array_values( array_diff( $current_ids, $new_ids ) );
201 184
202 185 $changes = [
203 186 'added' => array_values( array_diff( $new_ids, $current_ids ) ),
204 - 'deleted' => $deleted_class_ids,
187 + 'deleted' => array_values( array_diff( $current_ids, $new_ids ) ),
205 188 'modified' => array_values( array_intersect( $new_ids, $current_ids ) ),
206 189 'order' => implode( ';', $order ) !== $current_order_string,
207 190 ];
208 191
209 - /**
210 - * We collect all affected ids before the put_to_posts execution
211 - * as the update mechanism would handle the Global_Classes_Relations as it iterates over the update batches
212 - * So once we get to the cleanup phase - we would no longer have the relevant relations
213 - *
214 - * On top of that - by collecting all affected posts in advance, means we would iterate over each document's elements only once
215 - * (as the alternative would be to trigger the cleanup per removed class, but that means we may end up iterating over the same document N times, if all N styles are used in it)
216 - */
217 - $affected_post_ids = $this->get_posts_affected_by_deletion( $deleted_class_ids );
218 -
219 192 $this->put_to_posts( $items, $order, $current_ids );
220 193
221 194 $this->cache = null;
222 195
223 - $changes['affected_post_ids'] = $affected_post_ids;
224 -
225 196 do_action( 'elementor/global_classes/update', $this->get_context_key( 'event' ), $changes );
226 -
227 - if ( ! empty( $deleted_class_ids ) && ! $this->is_preview() ) {
228 - do_action(
229 - 'elementor/global_classes/cleanup',
230 - $deleted_class_ids,
231 - $affected_post_ids
232 - );
233 - }
234 197 }
235 198
236 - private function get_posts_affected_by_deletion( array $deleted_class_ids ): array {
237 - if ( empty( $deleted_class_ids ) ) {
238 - return [];
239 - }
240 -
241 - $relations = new Global_Classes_Relations();
242 - $post_ids = [];
243 -
244 - foreach ( $deleted_class_ids as $class_id ) {
245 - $post_ids[] = $relations->get_posts_by_style( $class_id );
246 - }
247 -
248 - return array_values( array_unique( array_merge( ...$post_ids ) ) );
249 - }
250 -
251 199 private function all_from_posts(): Global_Classes {
252 - $order = Global_Classes_Order::make( $this->get_kit() )
253 - ->set_preview( $this->is_preview() )
254 - ->get_order();
200 + $classes_order = Global_Classes_Order::make( $this->get_kit() );
201 + $order = $classes_order->get_order();
255 202
256 203 if ( empty( $order ) ) {
257 204 return Global_Classes::make( [], [] );
258 205 }
@@ -278,9 +225,9 @@
278 225 $to_update = array_intersect( $new_ids, $current_ids );
279 226
280 227 $this->persist_class_batch_mutations( $to_delete, $to_create, $to_update, $items, $is_preview );
281 228
282 - $classes_order = Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() );
229 + $classes_order = Global_Classes_Order::make( $this->get_kit() );
283 230 $classes_order->set_order( $order );
284 231
285 232 $label_map = [];
286 233 foreach ( $order as $id ) {
@@ -297,14 +244,15 @@
297 244 array_flip( $touched_ids )
298 245 );
299 246 Global_Classes_Sync_Map::make( $this->get_kit() )->apply_changes( $touched_items, array_values( $to_delete ) );
300 247
301 - $this->bulk_clear_preview_meta( array_values( $to_update ) );
302 - $this->clear_preview_labels_for_ids( array_merge(
303 - array_values( $to_create ),
304 - array_values( $to_update ),
305 - array_values( $to_delete )
306 - ) );
248 + $this->each_class_id_batch( array_values( $to_update ), function ( string $class_id ) {
249 + $post = Global_Class_Post::find_by_class_id( $class_id, false );
250 + if ( $post ) {
251 + delete_post_meta( $post->get_post_id(), Global_Class_Post::META_KEY_DATA_PREVIEW );
252 + clean_post_cache( $post->get_post_id() );
253 + }
254 + } );
307 255 }
308 256 }
309 257
310 258 private function iterate_class_posts_for_ids( array $class_ids ): \Generator {
@@ -321,13 +269,28 @@
321 269 ],
322 270 ],
323 271 ] );
324 272
273 + $seen_class_ids = [];
274 +
325 275 foreach ( $posts as $post ) {
276 + $class_id = get_post_meta( $post->ID, Global_Class_Post::META_KEY_ID, true );
277 +
278 + if ( $class_id && isset( $seen_class_ids[ $class_id ] ) ) {
279 + // if for some reason there's already a post meta to that class - delete any other ones
280 + // otherwise we may end up updating a stale post meta
281 + wp_delete_post( $post->ID, true );
282 + continue;
283 + }
284 +
285 + if ( $class_id ) {
286 + $seen_class_ids[ $class_id ] = true;
287 + }
288 +
326 289 yield Global_Class_Post::from_post( $post, $this->is_preview() );
327 290 clean_post_cache( $post->ID );
328 291 }
329 - unset( $posts );
292 + unset( $posts, $seen_class_ids );
330 293 $this->flush_runtime_cache();
331 294 }
332 295 }
333 296
@@ -338,28 +301,13 @@
338 301 array $items_by_id,
339 302 bool $is_preview
340 303 ): void {
341 304 $relations = new Global_Classes_Relations();
342 - $post_ids_map = Global_Classes_Post_IDs::make( $this->get_kit() );
343 305
344 - $ids_to_resolve = array_values( array_merge(
345 - array_values( $to_delete ),
346 - array_values( $to_update ),
347 - array_values( $to_create )
348 - ) );
349 - $post_ids = $post_ids_map->get_post_ids( $ids_to_resolve );
306 + $this->each_class_id_batch( array_values( $to_delete ), function ( string $class_id ) use ( $is_preview, $relations ) {
307 + $post = Global_Class_Post::find_by_class_id( $class_id, false );
350 308
351 - $this->each_class_id_batch(
352 - array_values( $to_delete ),
353 - function ( string $class_id ) use ( $is_preview, $relations, $post_ids ) {
354 - $post = isset( $post_ids[ $class_id ] )
355 - ? Global_Class_Post::from_post_id( $post_ids[ $class_id ], false )
356 - : null;
357 -
358 - if ( ! $post ) {
359 - return;
360 - }
361 -
309 + if ( $post ) {
362 310 if ( $is_preview ) {
363 311 $post->set_preview( true );
364 312 $post->update_data( [] );
365 313 clean_post_cache( $post->get_post_id() );
@@ -367,11 +315,11 @@
367 315 $relations->clear_class_relations( $class_id );
368 316 $post->delete();
369 317 }
370 318 }
371 - );
319 + } );
372 320
373 - $this->each_class_id_batch( $to_create, function ( string $class_id ) use ( $items_by_id, $is_preview, $post_ids, $post_ids_map ) {
321 + $this->each_class_id_batch( $to_create, function ( string $class_id ) use ( $items_by_id, $is_preview ) {
374 322 if ( ! isset( $items_by_id[ $class_id ] ) ) {
375 323 return;
376 324 }
377 325
@@ -376,56 +324,48 @@
376 324 }
377 325
378 326 $item = $items_by_id[ $class_id ];
379 327 $data = Global_Class_Data_Normalizer::normalize_style_fields( $item );
380 - $kit = $this->get_kit();
381 - $existing_post_id = $post_ids[ $class_id ] ?? null;
382 - $existing_post = $existing_post_id ? Global_Class_Post::from_post_id( $existing_post_id, $is_preview ) : null;
383 328
384 - if ( $existing_post ) {
385 - $existing_post->update_data( $data );
329 + if ( $is_preview ) {
330 + $post = Global_Class_Post::find_by_class_id( $class_id, true );
386 331
387 - if ( ! $is_preview ) {
388 - $existing_post->update_label( $item['label'] );
332 + if ( $post ) {
333 + $post->set_preview( true );
334 + $post->update_data( $data );
335 + $post->update_label( $item['label'] );
336 + clean_post_cache( $post->get_post_id() );
337 + } else {
338 + $created = Global_Class_Post::create( $class_id, $item['label'], $data );
339 + if ( $created ) {
340 + clean_post_cache( $created->get_post_id() );
341 + }
389 342 }
343 + } else {
344 + $created = Global_Class_Post::create( $class_id, $item['label'], $data );
345 + if ( $created ) {
346 + clean_post_cache( $created->get_post_id() );
347 + }
348 + }
349 + } );
390 350
391 - clean_post_cache( $existing_post->get_post_id() );
392 -
351 + $this->each_class_id_batch( $to_update, function ( string $class_id ) use ( $items_by_id, $is_preview ) {
352 + if ( ! isset( $items_by_id[ $class_id ] ) ) {
393 353 return;
394 354 }
395 355
396 - $created = Global_Class_Post::create( $class_id, $item['label'], $data, $kit );
356 + $item = $items_by_id[ $class_id ];
357 + $post = Global_Class_Post::find_by_class_id( $class_id, $is_preview );
397 358
398 - if ( $created ) {
399 - $post_ids_map->set( $class_id, $created->get_post_id() );
400 - clean_post_cache( $created->get_post_id() );
359 + if ( ! $post ) {
360 + return;
401 361 }
362 +
363 + $data = Global_Class_Data_Normalizer::normalize_style_fields( $item );
364 + $post->update_data( $data );
365 + $post->update_label( $item['label'] );
366 + clean_post_cache( $post->get_post_id() );
402 367 } );
403 -
404 - $this->each_class_id_batch(
405 - $to_update,
406 - function ( string $class_id ) use ( $items_by_id, $is_preview, $post_ids ) {
407 - if ( ! isset( $items_by_id[ $class_id ] ) || ! isset( $post_ids[ $class_id ] ) ) {
408 - return;
409 - }
410 -
411 - $item = $items_by_id[ $class_id ];
412 - $post = Global_Class_Post::from_post_id( $post_ids[ $class_id ], $is_preview );
413 -
414 - if ( ! $post ) {
415 - return;
416 - }
417 -
418 - $data = Global_Class_Data_Normalizer::normalize_style_fields( $item );
419 - $post->update_data( $data );
420 -
421 - if ( ! $is_preview ) {
422 - $post->update_label( $item['label'] );
423 - }
424 -
425 - clean_post_cache( $post->get_post_id() );
426 - }
427 - );
428 368 }
429 369
430 370 public function delete_all(): void {
431 371 $order = $this->get_order();
@@ -430,9 +370,9 @@
430 370 public function delete_all(): void {
431 371 $order = $this->get_order();
432 372
433 373 $this->each_class_id_batch( $order, function ( string $class_id ) {
434 - $post = Global_Class_Post::find_by_class_id( $class_id, false, $this->get_kit() );
374 + $post = Global_Class_Post::find_by_class_id( $class_id );
435 375
436 376 if ( $post ) {
437 377 $post->delete();
438 378 }
@@ -439,52 +379,8 @@
439 379 } );
440 380
441 381 Global_Classes_Order::make( $this->get_kit() )->set_order( [] );
442 382 $this->labels()->set_labels( [] );
443 - }
444 -
445 - private function clear_preview_labels_for_ids( array $class_ids ): void {
446 - if ( empty( $class_ids ) ) {
447 - return;
448 - }
449 -
450 - $preview_labels = Global_Classes_Labels::make( $this->get_kit() )->set_preview( true );
451 - $labels_map = $preview_labels->get_labels();
452 -
453 - if ( empty( $labels_map ) ) {
454 - return;
455 - }
456 -
457 - $ids_to_remove = array_intersect( array_unique( $class_ids ), array_keys( $labels_map ) );
458 -
459 - if ( empty( $ids_to_remove ) ) {
460 - return;
461 - }
462 -
463 - foreach ( $ids_to_remove as $id ) {
464 - unset( $labels_map[ $id ] );
465 - }
466 -
467 - $preview_labels->set_labels( $labels_map );
468 - }
469 -
470 - private function bulk_clear_preview_meta( array $class_ids ): void {
471 - if ( empty( $class_ids ) ) {
472 - return;
473 - }
474 -
475 - $post_ids_map = Global_Classes_Post_IDs::make( $this->get_kit() );
476 -
477 - foreach ( array_chunk( $class_ids, self::PERSIST_BATCH_SIZE ) as $chunk ) {
478 - $post_ids = $post_ids_map->get_post_ids( $chunk );
479 -
480 - foreach ( $post_ids as $post_id ) {
481 - delete_post_meta( $post_id, Global_Class_Post::META_KEY_DATA_PREVIEW );
482 - clean_post_cache( $post_id );
483 - }
484 -
485 - $this->flush_runtime_cache();
486 - }
487 383 }
488 384
489 385 private function each_class_id_batch( $class_ids, callable $callback, int $batch_size = self::PERSIST_BATCH_SIZE ): void {
490 386 $class_ids = is_array( $class_ids ) ? $class_ids : iterator_to_array( $class_ids, false );