PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.2
Elementor Website Builder – more than just a page builder v4.3.2
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 +79 -16 4.1.1 → 4.3.2 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\Modules\GlobalClasses\Concerns\Has_Kit_Dependency;
6 +use Elementor\Core\Kits\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,12 +28,8 @@
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 - ],
36 32 ];
37 33
38 34 private ?Global_Classes $cache = null;
39 35
@@ -70,13 +66,15 @@
70 66 return $this->labels()->get_ordered_labels();
71 67 }
72 68
73 69 public function get_order(): array {
74 - return Global_Classes_Order::make( $this->get_kit() )->get_order();
70 + return Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() )->get_order();
75 71 }
76 72
77 73 public function update_order_and_labels( array $order, array $new_labels ): void {
78 - Global_Classes_Order::make( $this->get_kit() )->set_order( $order );
74 + Global_Classes_Order::make( $this->get_kit() )
75 + ->set_preview( $this->is_preview() )
76 + ->set_order( $order );
79 77
80 78 $labels = $this->labels();
81 79 $existing_labels = $labels->get_labels();
82 80
@@ -93,9 +91,9 @@
93 91 return Global_Classes_Labels::make( $this->get_kit() )->set_preview( $this->is_preview() );
94 92 }
95 93
96 94 public function get( string $class_id ): ?array {
97 - $post = Global_Class_Post::find_by_class_id( $class_id, $this->is_preview() );
95 + $post = Global_Class_Post::find_by_class_id( $class_id, $this->is_preview(), $this->get_kit() );
98 96
99 97 return $post ? $post->to_array() : null;
100 98 }
101 99
@@ -135,16 +133,19 @@
135 133 $final_label_map[ $id ] = $before[ $id ];
136 134 }
137 135 }
138 136
137 + $affected_post_ids = $this->get_posts_affected_by_deletion( $to_delete );
138 +
139 139 $this->persist_class_batch_mutations( $to_delete, $to_create, $to_update, $touched_items, $is_preview );
140 140
141 - $classes_order = Global_Classes_Order::make( $this->get_kit() );
141 + $classes_order = Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() );
142 142 $classes_order->set_order( $order );
143 143 $labels->set_labels( $final_label_map );
144 144
145 145 if ( ! $is_preview ) {
146 146 Global_Classes_Sync_Map::make( $this->get_kit() )->apply_changes( $touched_items, $to_delete );
147 + $this->propagate_order_to_preview( $order, $to_delete );
147 148
148 149 $this->bulk_clear_preview_meta( array_values( $to_update ) );
149 150 $this->clear_preview_labels_for_ids( array_merge(
150 151 array_values( $to_create ),
@@ -160,11 +161,35 @@
160 161 'added' => $to_create,
161 162 'deleted' => $to_delete,
162 163 'modified' => $to_update,
163 164 'order' => $order_changed,
165 + 'affected_post_ids' => $affected_post_ids,
164 166 ] );
167 +
168 + if ( ! empty( $to_delete ) && ! $is_preview ) {
169 + do_action(
170 + 'elementor/global_classes/cleanup',
171 + $to_delete,
172 + $affected_post_ids
173 + );
174 + }
165 175 }
166 176
177 + private function propagate_order_to_preview( array $published_order, array $deleted_ids ): void {
178 + $preview_order = Global_Classes_Order::make( $this->get_kit() )->set_preview( true );
179 + $existing_order = $preview_order->get_order();
180 + $unpublished_ids = array_flip( array_diff( $existing_order, $published_order, $deleted_ids ) );
181 + $merged_order = $published_order;
182 +
183 + foreach ( $existing_order as $position => $id ) {
184 + if ( isset( $unpublished_ids[ $id ] ) ) {
185 + array_splice( $merged_order, min( $position, count( $merged_order ) ), 0, [ $id ] );
186 + }
187 + }
188 +
189 + $preview_order->set_order( $merged_order );
190 + }
191 +
167 192 public function each_item( callable $cb, bool $skip_migration = false, int $batch_size = self::READ_BATCH_SIZE ): void {
168 193 $order = Global_Classes_Order::make( $this->get_kit() )->get_order();
169 194
170 195 if ( empty( $order ) ) {
@@ -178,31 +203,69 @@
178 203 }
179 204 }
180 205
181 206 public function put( array $items, array $order ) {
182 - $current_ids = Global_Classes_Order::make( $this->get_kit() )->get_order();
207 + $current_ids = Global_Classes_Order::make( $this->get_kit() )
208 + ->set_preview( $this->is_preview() )
209 + ->get_order();
183 210
184 211 $new_ids = array_keys( $items );
185 -
186 212 $current_order_string = implode( ';', $current_ids );
213 + $deleted_class_ids = array_values( array_diff( $current_ids, $new_ids ) );
187 214
188 215 $changes = [
189 216 'added' => array_values( array_diff( $new_ids, $current_ids ) ),
190 - 'deleted' => array_values( array_diff( $current_ids, $new_ids ) ),
217 + 'deleted' => $deleted_class_ids,
191 218 'modified' => array_values( array_intersect( $new_ids, $current_ids ) ),
192 219 'order' => implode( ';', $order ) !== $current_order_string,
193 220 ];
194 221
222 + /**
223 + * We collect all affected ids before the put_to_posts execution
224 + * as the update mechanism would handle the Global_Classes_Relations as it iterates over the update batches
225 + * So once we get to the cleanup phase - we would no longer have the relevant relations
226 + *
227 + * On top of that - by collecting all affected posts in advance, means we would iterate over each document's elements only once
228 + * (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)
229 + */
230 + $affected_post_ids = $this->get_posts_affected_by_deletion( $deleted_class_ids );
231 +
195 232 $this->put_to_posts( $items, $order, $current_ids );
196 233
197 234 $this->cache = null;
198 235
236 + $changes['affected_post_ids'] = $affected_post_ids;
237 +
199 238 do_action( 'elementor/global_classes/update', $this->get_context_key( 'event' ), $changes );
239 +
240 + if ( ! empty( $deleted_class_ids ) && ! $this->is_preview() ) {
241 + do_action(
242 + 'elementor/global_classes/cleanup',
243 + $deleted_class_ids,
244 + $affected_post_ids
245 + );
246 + }
200 247 }
201 248
249 + private function get_posts_affected_by_deletion( array $deleted_class_ids ): array {
250 + if ( empty( $deleted_class_ids ) ) {
251 + return [];
252 + }
253 +
254 + $relations = new Global_Classes_Relations();
255 + $post_ids = [];
256 +
257 + foreach ( $deleted_class_ids as $class_id ) {
258 + $post_ids[] = $relations->get_posts_by_style( $class_id );
259 + }
260 +
261 + return array_values( array_unique( array_merge( ...$post_ids ) ) );
262 + }
263 +
202 264 private function all_from_posts(): Global_Classes {
203 - $classes_order = Global_Classes_Order::make( $this->get_kit() );
204 - $order = $classes_order->get_order();
265 + $order = Global_Classes_Order::make( $this->get_kit() )
266 + ->set_preview( $this->is_preview() )
267 + ->get_order();
205 268
206 269 if ( empty( $order ) ) {
207 270 return Global_Classes::make( [], [] );
208 271 }
@@ -228,9 +291,9 @@
228 291 $to_update = array_intersect( $new_ids, $current_ids );
229 292
230 293 $this->persist_class_batch_mutations( $to_delete, $to_create, $to_update, $items, $is_preview );
231 294
232 - $classes_order = Global_Classes_Order::make( $this->get_kit() );
295 + $classes_order = Global_Classes_Order::make( $this->get_kit() )->set_preview( $this->is_preview() );
233 296 $classes_order->set_order( $order );
234 297
235 298 $label_map = [];
236 299 foreach ( $order as $id ) {
@@ -380,9 +443,9 @@
380 443 public function delete_all(): void {
381 444 $order = $this->get_order();
382 445
383 446 $this->each_class_id_batch( $order, function ( string $class_id ) {
384 - $post = Global_Class_Post::find_by_class_id( $class_id );
447 + $post = Global_Class_Post::find_by_class_id( $class_id, false, $this->get_kit() );
385 448
386 449 if ( $post ) {
387 450 $post->delete();
388 451 }