PluginProbe
Elementor Website Builder – more than just a page builder / 4.1.0-beta3
Elementor Website Builder – more than just a page builder v4.1.0-beta3
4.3.3 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 All 456 releases
← All changes | modules/global-classes/global-classes-repository.php +77 -193 4.1.5 → 4.1.0-beta3 View file →
@@ -70,15 +70,13 @@
70 70 return $this->labels()->get_ordered_labels();
71 71 }
72 72
73 73 public function get_order(): array {
74 - 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();
75 75 }
76 76
77 77 public function update_order_and_labels( array $order, array $new_labels ): void {
78 - Global_Classes_Order::make( $this->get_kit() )
79 - ->set_preview( $this->is_preview() )
80 - ->set_order( $order );
78 + Global_Classes_Order::make( $this->get_kit() )->set_order( $order );
81 79
82 80 $labels = $this->labels();
83 81 $existing_labels = $labels->get_labels();
84 82
@@ -87,16 +85,8 @@
87 85 }
88 86
89 87 $labels->set_labels( $existing_labels );
90 88
91 - if ( ! $this->is_preview() ) {
92 - Global_Classes_Order::make( $this->get_kit() )
93 - ->set_preview( true )
94 - ->set_order( $order );
95 -
96 - $this->clear_preview_labels_for_ids( array_keys( $new_labels ) );
97 - }
98 -
99 89 $this->cache = null;
100 90 }
101 91
102 92 private function labels(): Global_Classes_Labels {
@@ -113,17 +103,13 @@
113 103 if ( empty( $class_ids ) ) {
114 104 return [];
115 105 }
116 106
117 - $post_ids = Global_Classes_Post_IDs::make( $this->get_kit() )->get_post_ids( $class_ids );
118 107 $items = [];
119 108
120 - foreach ( $post_ids as $class_id => $post_id ) {
121 - $post = Global_Class_Post::from_post_id( $post_id, $this->is_preview() );
122 -
123 - if ( $post ) {
124 - $items[ $class_id ] = $post->to_array();
125 - }
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;
126 112 }
127 113
128 114 return $items;
129 115 }
@@ -145,28 +131,24 @@
145 131 $final_label_map[ $id ] = $before[ $id ];
146 132 }
147 133 }
148 134
149 - $affected_post_ids = $this->get_posts_affected_by_deletion( $to_delete );
150 -
151 135 $this->persist_class_batch_mutations( $to_delete, $to_create, $to_update, $touched_items, $is_preview );
152 136
153 - $classes_order = Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() );
137 + $classes_order = Global_Classes_Order::make( $this->get_kit() );
154 138 $classes_order->set_order( $order );
155 139 $labels->set_labels( $final_label_map );
156 140
157 141 if ( ! $is_preview ) {
158 142 Global_Classes_Sync_Map::make( $this->get_kit() )->apply_changes( $touched_items, $to_delete );
159 - Global_Classes_Order::make( $this->get_kit() )
160 - ->set_preview( true )
161 - ->set_order( $order );
162 143
163 - $this->bulk_clear_preview_meta( array_values( $to_update ) );
164 - $this->clear_preview_labels_for_ids( array_merge(
165 - array_values( $to_create ),
166 - array_values( $to_update ),
167 - array_values( $to_delete )
168 - ) );
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 + } );
169 151 }
170 152
171 153 $this->cache = null;
172 154 $this->flush_runtime_cache();
@@ -175,18 +157,9 @@
175 157 'added' => $to_create,
176 158 'deleted' => $to_delete,
177 159 'modified' => $to_update,
178 160 'order' => $order_changed,
179 - 'affected_post_ids' => $affected_post_ids,
180 161 ] );
181 -
182 - if ( ! empty( $to_delete ) && ! $is_preview ) {
183 - do_action(
184 - 'elementor/global_classes/cleanup',
185 - $to_delete,
186 - $affected_post_ids
187 - );
188 - }
189 162 }
190 163
191 164 public function each_item( callable $cb, bool $skip_migration = false, int $batch_size = self::READ_BATCH_SIZE ): void {
192 165 $order = Global_Classes_Order::make( $this->get_kit() )->get_order();
@@ -202,69 +175,31 @@
202 175 }
203 176 }
204 177
205 178 public function put( array $items, array $order ) {
206 - $current_ids = Global_Classes_Order::make( $this->get_kit() )
207 - ->set_preview( $this->is_preview() )
208 - ->get_order();
179 + $current_ids = Global_Classes_Order::make( $this->get_kit() )->get_order();
209 180
210 181 $new_ids = array_keys( $items );
182 +
211 183 $current_order_string = implode( ';', $current_ids );
212 - $deleted_class_ids = array_values( array_diff( $current_ids, $new_ids ) );
213 184
214 185 $changes = [
215 186 'added' => array_values( array_diff( $new_ids, $current_ids ) ),
216 - 'deleted' => $deleted_class_ids,
187 + 'deleted' => array_values( array_diff( $current_ids, $new_ids ) ),
217 188 'modified' => array_values( array_intersect( $new_ids, $current_ids ) ),
218 189 'order' => implode( ';', $order ) !== $current_order_string,
219 190 ];
220 191
221 - /**
222 - * We collect all affected ids before the put_to_posts execution
223 - * as the update mechanism would handle the Global_Classes_Relations as it iterates over the update batches
224 - * So once we get to the cleanup phase - we would no longer have the relevant relations
225 - *
226 - * On top of that - by collecting all affected posts in advance, means we would iterate over each document's elements only once
227 - * (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)
228 - */
229 - $affected_post_ids = $this->get_posts_affected_by_deletion( $deleted_class_ids );
230 -
231 192 $this->put_to_posts( $items, $order, $current_ids );
232 193
233 194 $this->cache = null;
234 195
235 - $changes['affected_post_ids'] = $affected_post_ids;
236 -
237 196 do_action( 'elementor/global_classes/update', $this->get_context_key( 'event' ), $changes );
238 -
239 - if ( ! empty( $deleted_class_ids ) && ! $this->is_preview() ) {
240 - do_action(
241 - 'elementor/global_classes/cleanup',
242 - $deleted_class_ids,
243 - $affected_post_ids
244 - );
245 - }
246 197 }
247 198
248 - private function get_posts_affected_by_deletion( array $deleted_class_ids ): array {
249 - if ( empty( $deleted_class_ids ) ) {
250 - return [];
251 - }
252 -
253 - $relations = new Global_Classes_Relations();
254 - $post_ids = [];
255 -
256 - foreach ( $deleted_class_ids as $class_id ) {
257 - $post_ids[] = $relations->get_posts_by_style( $class_id );
258 - }
259 -
260 - return array_values( array_unique( array_merge( ...$post_ids ) ) );
261 - }
262 -
263 199 private function all_from_posts(): Global_Classes {
264 - $order = Global_Classes_Order::make( $this->get_kit() )
265 - ->set_preview( $this->is_preview() )
266 - ->get_order();
200 + $classes_order = Global_Classes_Order::make( $this->get_kit() );
201 + $order = $classes_order->get_order();
267 202
268 203 if ( empty( $order ) ) {
269 204 return Global_Classes::make( [], [] );
270 205 }
@@ -290,9 +225,9 @@
290 225 $to_update = array_intersect( $new_ids, $current_ids );
291 226
292 227 $this->persist_class_batch_mutations( $to_delete, $to_create, $to_update, $items, $is_preview );
293 228
294 - $classes_order = Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() );
229 + $classes_order = Global_Classes_Order::make( $this->get_kit() );
295 230 $classes_order->set_order( $order );
296 231
297 232 $label_map = [];
298 233 foreach ( $order as $id ) {
@@ -309,14 +244,15 @@
309 244 array_flip( $touched_ids )
310 245 );
311 246 Global_Classes_Sync_Map::make( $this->get_kit() )->apply_changes( $touched_items, array_values( $to_delete ) );
312 247
313 - $this->bulk_clear_preview_meta( array_values( $to_update ) );
314 - $this->clear_preview_labels_for_ids( array_merge(
315 - array_values( $to_create ),
316 - array_values( $to_update ),
317 - array_values( $to_delete )
318 - ) );
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 + } );
319 255 }
320 256 }
321 257
322 258 private function iterate_class_posts_for_ids( array $class_ids ): \Generator {
@@ -333,13 +269,28 @@
333 269 ],
334 270 ],
335 271 ] );
336 272
273 + $seen_class_ids = [];
274 +
337 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 +
338 289 yield Global_Class_Post::from_post( $post, $this->is_preview() );
339 290 clean_post_cache( $post->ID );
340 291 }
341 - unset( $posts );
292 + unset( $posts, $seen_class_ids );
342 293 $this->flush_runtime_cache();
343 294 }
344 295 }
345 296
@@ -350,28 +301,13 @@
350 301 array $items_by_id,
351 302 bool $is_preview
352 303 ): void {
353 304 $relations = new Global_Classes_Relations();
354 - $post_ids_map = Global_Classes_Post_IDs::make( $this->get_kit() );
355 305
356 - $ids_to_resolve = array_values( array_merge(
357 - array_values( $to_delete ),
358 - array_values( $to_update ),
359 - array_values( $to_create )
360 - ) );
361 - $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 );
362 308
363 - $this->each_class_id_batch(
364 - array_values( $to_delete ),
365 - function ( string $class_id ) use ( $is_preview, $relations, $post_ids ) {
366 - $post = isset( $post_ids[ $class_id ] )
367 - ? Global_Class_Post::from_post_id( $post_ids[ $class_id ], false )
368 - : null;
369 -
370 - if ( ! $post ) {
371 - return;
372 - }
373 -
309 + if ( $post ) {
374 310 if ( $is_preview ) {
375 311 $post->set_preview( true );
376 312 $post->update_data( [] );
377 313 clean_post_cache( $post->get_post_id() );
@@ -379,11 +315,11 @@
379 315 $relations->clear_class_relations( $class_id );
380 316 $post->delete();
381 317 }
382 318 }
383 - );
319 + } );
384 320
385 - $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 ) {
386 322 if ( ! isset( $items_by_id[ $class_id ] ) ) {
387 323 return;
388 324 }
389 325
@@ -388,56 +324,48 @@
388 324 }
389 325
390 326 $item = $items_by_id[ $class_id ];
391 327 $data = Global_Class_Data_Normalizer::normalize_style_fields( $item );
392 - $kit = $this->get_kit();
393 - $existing_post_id = $post_ids[ $class_id ] ?? null;
394 - $existing_post = $existing_post_id ? Global_Class_Post::from_post_id( $existing_post_id, $is_preview ) : null;
395 328
396 - if ( $existing_post ) {
397 - $existing_post->update_data( $data );
329 + if ( $is_preview ) {
330 + $post = Global_Class_Post::find_by_class_id( $class_id, true );
398 331
399 - if ( ! $is_preview ) {
400 - $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 + }
401 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 + } );
402 350
403 - clean_post_cache( $existing_post->get_post_id() );
404 -
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 ] ) ) {
405 353 return;
406 354 }
407 355
408 - $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 );
409 358
410 - if ( $created ) {
411 - $post_ids_map->set( $class_id, $created->get_post_id() );
412 - clean_post_cache( $created->get_post_id() );
359 + if ( ! $post ) {
360 + return;
413 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() );
414 367 } );
415 -
416 - $this->each_class_id_batch(
417 - $to_update,
418 - function ( string $class_id ) use ( $items_by_id, $is_preview, $post_ids ) {
419 - if ( ! isset( $items_by_id[ $class_id ] ) || ! isset( $post_ids[ $class_id ] ) ) {
420 - return;
421 - }
422 -
423 - $item = $items_by_id[ $class_id ];
424 - $post = Global_Class_Post::from_post_id( $post_ids[ $class_id ], $is_preview );
425 -
426 - if ( ! $post ) {
427 - return;
428 - }
429 -
430 - $data = Global_Class_Data_Normalizer::normalize_style_fields( $item );
431 - $post->update_data( $data );
432 -
433 - if ( ! $is_preview ) {
434 - $post->update_label( $item['label'] );
435 - }
436 -
437 - clean_post_cache( $post->get_post_id() );
438 - }
439 - );
440 368 }
441 369
442 370 public function delete_all(): void {
443 371 $order = $this->get_order();
@@ -451,52 +379,8 @@
451 379 } );
452 380
453 381 Global_Classes_Order::make( $this->get_kit() )->set_order( [] );
454 382 $this->labels()->set_labels( [] );
455 - }
456 -
457 - private function clear_preview_labels_for_ids( array $class_ids ): void {
458 - if ( empty( $class_ids ) ) {
459 - return;
460 - }
461 -
462 - $preview_labels = Global_Classes_Labels::make( $this->get_kit() )->set_preview( true );
463 - $labels_map = $preview_labels->get_labels();
464 -
465 - if ( empty( $labels_map ) ) {
466 - return;
467 - }
468 -
469 - $ids_to_remove = array_intersect( array_unique( $class_ids ), array_keys( $labels_map ) );
470 -
471 - if ( empty( $ids_to_remove ) ) {
472 - return;
473 - }
474 -
475 - foreach ( $ids_to_remove as $id ) {
476 - unset( $labels_map[ $id ] );
477 - }
478 -
479 - $preview_labels->set_labels( $labels_map );
480 - }
481 -
482 - private function bulk_clear_preview_meta( array $class_ids ): void {
483 - if ( empty( $class_ids ) ) {
484 - return;
485 - }
486 -
487 - $post_ids_map = Global_Classes_Post_IDs::make( $this->get_kit() );
488 -
489 - foreach ( array_chunk( $class_ids, self::PERSIST_BATCH_SIZE ) as $chunk ) {
490 - $post_ids = $post_ids_map->get_post_ids( $chunk );
491 -
492 - foreach ( $post_ids as $post_id ) {
493 - delete_post_meta( $post_id, Global_Class_Post::META_KEY_DATA_PREVIEW );
494 - clean_post_cache( $post_id );
495 - }
496 -
497 - $this->flush_runtime_cache();
498 - }
499 383 }
500 384
501 385 private function each_class_id_batch( $class_ids, callable $callback, int $batch_size = self::PERSIST_BATCH_SIZE ): void {
502 386 $class_ids = is_array( $class_ids ) ? $class_ids : iterator_to_array( $class_ids, false );