PluginProbe
Elementor Website Builder – more than just a page builder / 3.0.7
Elementor Website Builder – more than just a page builder v3.0.7
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
elementor / core / upgrade / upgrades.php

upgrades.php in Elementor Website Builder – more than just a page builder 3.0.7, at core/upgrade/upgrades.php

950 lines 24.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Core\Upgrade;
3
4 use Elementor\Core\Responsive\Responsive;
5 use Elementor\Core\Settings\Manager as SettingsManager;
6 use Elementor\Icons_Manager;
7 use Elementor\Modules\Usage\Module;
8 use Elementor\Plugin;
9 use Elementor\Utils;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14
15 /**
16 * Elementor upgrades.
17 *
18 * Elementor upgrades handler class is responsible for updating different
19 * Elementor versions.
20 *
21 * @since 1.0.0
22 */
23 class Upgrades {
24
25 /**
26 * Upgrade Elementor 0.3.2
27 *
28 * Change the image widget link URL, setting is to `custom` link.
29 *
30 * @since 2.0.0
31 * @static
32 * @access public
33 */
34 public static function _v_0_3_2() {
35 global $wpdb;
36
37 $post_ids = $wpdb->get_col(
38 'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
39 WHERE `meta_key` = \'_elementor_version\'
40 AND `meta_value` = \'0.1\';'
41 );
42
43 if ( empty( $post_ids ) ) {
44 return;
45 }
46
47 foreach ( $post_ids as $post_id ) {
48 $document = Plugin::$instance->documents->get( $post_id );
49
50 if ( $document ) {
51 $data = $document->get_elements_data();
52 }
53
54 if ( empty( $data ) ) {
55 continue;
56 }
57
58 $data = Plugin::$instance->db->iterate_data( $data, function( $element ) {
59 if ( empty( $element['widgetType'] ) || 'image' !== $element['widgetType'] ) {
60 return $element;
61 }
62
63 if ( ! empty( $element['settings']['link']['url'] ) && ! isset( $element['settings']['link_to'] ) ) {
64 $element['settings']['link_to'] = 'custom';
65 }
66
67 return $element;
68 } );
69
70 $document = Plugin::$instance->documents->get( $post_id );
71
72 $document->save( [
73 'elements' => $data,
74 ] );
75 }
76 }
77
78 /**
79 * Upgrade Elementor 0.9.2
80 *
81 * Change the icon widget, icon-box widget and the social-icons widget,
82 * setting their icon padding size to an empty string.
83 *
84 * Change the image widget, setting the image size to full image size.
85 *
86 * @since 2.0.0
87 * @static
88 * @access public
89 */
90 public static function _v_0_9_2() {
91 global $wpdb;
92
93 // Fix Icon/Icon Box Widgets padding.
94 $post_ids = $wpdb->get_col(
95 'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
96 WHERE `meta_key` = \'_elementor_version\'
97 AND `meta_value` = \'0.2\';'
98 );
99
100 if ( empty( $post_ids ) ) {
101 return;
102 }
103
104 foreach ( $post_ids as $post_id ) {
105 $document = Plugin::$instance->documents->get( $post_id );
106
107 if ( $document ) {
108 $data = $document->get_elements_data();
109 }
110
111 if ( empty( $data ) ) {
112 continue;
113 }
114
115 $data = Plugin::$instance->db->iterate_data( $data, function( $element ) {
116 if ( empty( $element['widgetType'] ) ) {
117 return $element;
118 }
119
120 if ( in_array( $element['widgetType'], [ 'icon', 'icon-box', 'social-icons' ] ) ) {
121 if ( ! empty( $element['settings']['icon_padding']['size'] ) ) {
122 $element['settings']['icon_padding']['size'] = '';
123 }
124 }
125
126 if ( 'image' === $element['widgetType'] ) {
127 if ( empty( $element['settings']['image_size'] ) ) {
128 $element['settings']['image_size'] = 'full';
129 }
130 }
131
132 return $element;
133 } );
134
135 $document = Plugin::$instance->documents->get( $post_id );
136
137 $document->save( [
138 'elements' => $data,
139 ] );
140 }
141 }
142
143 /**
144 * Upgrade Elementor 0.11.0
145 *
146 * Change the button widget sizes, setting up new button sizes.
147 *
148 * @since 2.0.0
149 * @static
150 * @access public
151 */
152 public static function _v_0_11_0() {
153 global $wpdb;
154
155 // Fix Button widget to new sizes options.
156 $post_ids = $wpdb->get_col(
157 'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
158 WHERE `meta_key` = \'_elementor_version\'
159 AND `meta_value` = \'0.3\';'
160 );
161
162 if ( empty( $post_ids ) ) {
163 return;
164 }
165
166 foreach ( $post_ids as $post_id ) {
167 $document = Plugin::$instance->documents->get( $post_id );
168
169 if ( $document ) {
170 $data = $document->get_elements_data();
171 }
172
173 if ( empty( $data ) ) {
174 continue;
175 }
176
177 $data = Plugin::$instance->db->iterate_data( $data, function( $element ) {
178 if ( empty( $element['widgetType'] ) ) {
179 return $element;
180 }
181
182 if ( 'button' === $element['widgetType'] ) {
183 $size_to_replace = [
184 'small' => 'xs',
185 'medium' => 'sm',
186 'large' => 'md',
187 'xl' => 'lg',
188 'xxl' => 'xl',
189 ];
190
191 if ( ! empty( $element['settings']['size'] ) ) {
192 $old_size = $element['settings']['size'];
193
194 if ( isset( $size_to_replace[ $old_size ] ) ) {
195 $element['settings']['size'] = $size_to_replace[ $old_size ];
196 }
197 }
198 }
199
200 return $element;
201 } );
202
203 $document = Plugin::$instance->documents->get( $post_id );
204
205 $document->save( [
206 'elements' => $data,
207 ] );
208 }
209 }
210
211 /**
212 * Upgrade Elementor 2.0.0
213 *
214 * Fix post titles for old autosave drafts that saved with the format 'Auto Save 2018-03-18 17:24'.
215 *
216 * @static
217 * @since 2.0.0
218 * @access public
219 */
220 public static function _v_2_0_0() {
221 global $wpdb;
222
223 $posts = $wpdb->get_results(
224 'SELECT `ID`, `post_title`, `post_parent`
225 FROM `' . $wpdb->posts . '` p
226 LEFT JOIN `' . $wpdb->postmeta . '` m ON p.ID = m.post_id
227 WHERE `post_status` = \'inherit\'
228 AND `post_title` = CONCAT(\'Auto Save \', DATE_FORMAT(post_date, "%Y-%m-%d %H:%i"))
229 AND m.`meta_key` = \'_elementor_data\';'
230 );
231
232 if ( empty( $posts ) ) {
233 return;
234 }
235
236 foreach ( $posts as $post ) {
237 wp_update_post( [
238 'ID' => $post->ID,
239 'post_title' => get_the_title( $post->post_parent ),
240 ] );
241 }
242 }
243
244 /**
245 * Upgrade Elementor 2.0.1
246 *
247 * Fix post titles for old autosave drafts that saved with the format 'Auto Save...'.
248 *
249 * @since 2.0.2
250 * @static
251 * @access public
252 */
253 public static function _v_2_0_1() {
254 global $wpdb;
255
256 $posts = $wpdb->get_results(
257 'SELECT `ID`, `post_title`, `post_parent`
258 FROM `' . $wpdb->posts . '` p
259 LEFT JOIN `' . $wpdb->postmeta . '` m ON p.ID = m.post_id
260 WHERE `post_status` = \'inherit\'
261 AND `post_title` REGEXP \'^Auto Save [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$\'
262 AND m.`meta_key` = \'_elementor_data\';'
263 );
264
265 if ( empty( $posts ) ) {
266 return;
267 }
268
269 foreach ( $posts as $post ) {
270 $parent = get_post( $post->post_parent );
271 $title = isset( $parent->post_title ) ? $parent->post_title : '';
272
273 wp_update_post( [
274 'ID' => $post->ID,
275 'post_title' => $title,
276 ] );
277 }
278 }
279
280 /**
281 * Upgrade Elementor 2.0.10
282 *
283 * Fix post titles for old autosave drafts that saved with the format 'Auto Save...'.
284 * Fix also Translated titles.
285 *
286 * @since 2.0.10
287 * @static
288 * @access public
289 */
290 public static function _v_2_0_10() {
291 global $wpdb;
292
293 $posts = $wpdb->get_results(
294 'SELECT `ID`, `post_title`, `post_parent`
295 FROM `' . $wpdb->posts . '` p
296 LEFT JOIN `' . $wpdb->postmeta . '` m ON p.ID = m.post_id
297 WHERE `post_status` = \'inherit\'
298 AND `post_title` REGEXP \'[[:alnum:]]+ [[:alnum:]]+ [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$\'
299 AND m.`meta_key` = \'_elementor_data\';'
300 );
301
302 if ( empty( $posts ) ) {
303 return;
304 }
305
306 foreach ( $posts as $post ) {
307 $parent = get_post( $post->post_parent );
308 $title = isset( $parent->post_title ) ? $parent->post_title : '';
309
310 wp_update_post( [
311 'ID' => $post->ID,
312 'post_title' => $title,
313 ] );
314 }
315 }
316
317 public static function _v_2_1_0() {
318 global $wpdb;
319
320 // upgrade `video` widget settings (merge providers).
321 $post_ids = $wpdb->get_col(
322 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` WHERE `meta_key` = "_elementor_data" AND `meta_value` LIKE \'%"widgetType":"video"%\';'
323 );
324
325 if ( empty( $post_ids ) ) {
326 return;
327 }
328
329 foreach ( $post_ids as $post_id ) {
330 $do_update = false;
331 $document = Plugin::$instance->documents->get( $post_id );
332
333 if ( $document ) {
334 $data = $document->get_elements_data();
335 }
336
337 if ( empty( $data ) ) {
338 continue;
339 }
340
341 $data = Plugin::$instance->db->iterate_data( $data, function( $element ) use ( &$do_update ) {
342 if ( empty( $element['widgetType'] ) || 'video' !== $element['widgetType'] ) {
343 return $element;
344 }
345
346 $replacements = [];
347
348 if ( empty( $element['settings']['video_type'] ) || 'youtube' === $element['settings']['video_type'] ) {
349 $replacements = [
350 'yt_autoplay' => 'autoplay',
351 'yt_controls' => 'controls',
352 'yt_mute' => 'mute',
353 'yt_rel' => 'rel',
354 'link' => 'youtube_url',
355 ];
356 } elseif ( 'vimeo' === $element['settings']['video_type'] ) {
357 $replacements = [
358 'vimeo_autoplay' => 'autoplay',
359 'vimeo_loop' => 'loop',
360 'vimeo_color' => 'color',
361 'vimeo_link' => 'vimeo_url',
362 ];
363 }
364
365 // cleanup old unused settings.
366 unset( $element['settings']['yt_rel_videos'] );
367
368 foreach ( $replacements as $old => $new ) {
369 if ( ! empty( $element['settings'][ $old ] ) ) {
370 $element['settings'][ $new ] = $element['settings'][ $old ];
371 $do_update = true;
372 }
373 }
374
375 return $element;
376 } );
377
378 // Only update if needed.
379 if ( ! $do_update ) {
380 continue;
381 }
382
383 // We need the `wp_slash` in order to avoid the unslashing during the `update_post_meta`
384 $json_value = wp_slash( wp_json_encode( $data ) );
385
386 update_metadata( 'post', $post_id, '_elementor_data', $json_value );
387
388 // Clear WP cache for next step.
389 wp_cache_flush();
390 } // End foreach().
391 }
392
393 /**
394 * @param Updater $updater
395 *
396 * @return bool
397 */
398 public static function _v_2_3_0_widget_image( $updater ) {
399 global $wpdb;
400
401 // upgrade `video` widget settings (merge providers).
402 $post_ids = $updater->query_col(
403 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` WHERE `meta_key` = "_elementor_data" AND (
404 `meta_value` LIKE \'%"widgetType":"image"%\'
405 OR `meta_value` LIKE \'%"widgetType":"theme-post-featured-image"%\'
406 OR `meta_value` LIKE \'%"widgetType":"theme-site-logo"%\'
407 OR `meta_value` LIKE \'%"widgetType":"woocommerce-category-image"%\'
408 );'
409 );
410
411 if ( empty( $post_ids ) ) {
412 return false;
413 }
414
415 $widgets = [
416 'image',
417 'theme-post-featured-image',
418 'theme-site-logo',
419 'woocommerce-category-image',
420 ];
421
422 foreach ( $post_ids as $post_id ) {
423 // Clear WP cache for next step.
424 wp_cache_flush();
425
426 $do_update = false;
427
428 $document = Plugin::$instance->documents->get( $post_id );
429
430 if ( ! $document ) {
431 continue;
432 }
433
434 $data = $document->get_elements_data();
435
436 if ( empty( $data ) ) {
437 continue;
438 }
439
440 $data = Plugin::$instance->db->iterate_data( $data, function( $element ) use ( &$do_update, $widgets ) {
441 if ( empty( $element['widgetType'] ) || ! in_array( $element['widgetType'], $widgets ) ) {
442 return $element;
443 }
444
445 if ( ! empty( $element['settings']['caption'] ) ) {
446 if ( ! isset( $element['settings']['caption_source'] ) ) {
447 $element['settings']['caption_source'] = 'custom';
448
449 $do_update = true;
450 }
451 }
452
453 return $element;
454 } );
455
456 // Only update if needed.
457 if ( ! $do_update ) {
458 continue;
459 }
460
461 // We need the `wp_slash` in order to avoid the unslashing during the `update_post_meta`
462 $json_value = wp_slash( wp_json_encode( $data ) );
463
464 update_metadata( 'post', $post_id, '_elementor_data', $json_value );
465 } // End foreach().
466
467 return $updater->should_run_again( $post_ids );
468 }
469
470 /**
471 * @param Updater $updater
472 *
473 * @return bool
474 */
475 public static function _v_2_3_0_template_type( $updater ) {
476 global $wpdb;
477
478 $post_ids = $updater->query_col(
479 'SELECT p.ID
480 FROM `' . $wpdb->posts . '` AS p
481 LEFT JOIN `' . $wpdb->postmeta . '` AS pm1 ON (p.ID = pm1.post_id)
482 LEFT JOIN `' . $wpdb->postmeta . '` AS pm2 ON (pm1.post_id = pm2.post_id AND pm2.meta_key = "_elementor_template_type")
483 WHERE p.post_status != "inherit" AND pm1.`meta_key` = "_elementor_data" AND pm2.post_id IS NULL;'
484 );
485
486 if ( empty( $post_ids ) ) {
487 return false;
488 }
489
490 foreach ( $post_ids as $post_id ) {
491 // Clear WP cache for next step.
492 wp_cache_flush();
493
494 $document = Plugin::$instance->documents->get( $post_id );
495
496 if ( ! $document ) {
497 continue;
498 }
499
500 $document->save_template_type();
501 } // End foreach().
502
503 return $updater->should_run_again( $post_ids );
504 }
505
506 /**
507 * Set FontAwesome Migration needed flag
508 */
509 public static function _v_2_6_0_fa4_migration_flag() {
510 add_option( 'elementor_icon_manager_needs_update', 'yes' );
511 add_option( 'elementor_load_fa4_shim', 'yes' );
512 }
513
514 /**
515 * migrate Icon control string value to Icons control array value
516 *
517 * @param array $element
518 * @param array $args
519 *
520 * @return mixed
521 */
522 public static function _migrate_icon_fa4_value( $element, $args ) {
523 $widget_id = $args['widget_id'];
524
525 if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) {
526 return $element;
527 }
528 foreach ( $args['control_ids'] as $old_name => $new_name ) {
529 // exit if new value exists
530 if ( isset( $element['settings'][ $new_name ] ) ) {
531 continue;
532 }
533
534 // exit if no value to migrate
535 if ( ! isset( $element['settings'][ $old_name ] ) ) {
536 continue;
537 }
538
539 $element['settings'][ $new_name ] = Icons_Manager::fa4_to_fa5_value_migration( $element['settings'][ $old_name ] );
540 $args['do_update'] = true;
541 }
542 return $element;
543 }
544
545 /**
546 * Set FontAwesome 5 value Migration on for button widget
547 *
548 * @param Updater $updater
549 */
550 public static function _v_2_6_6_fa4_migration_button( $updater ) {
551 $changes = [
552 [
553 'callback' => [ 'Elementor\Core\Upgrade\Upgrades', '_migrate_icon_fa4_value' ],
554 'control_ids' => [
555 'icon' => 'selected_icon',
556 ],
557 ],
558 ];
559 Upgrade_Utils::_update_widget_settings( 'button', $updater, $changes );
560 Upgrade_Utils::_update_widget_settings( 'icon-box', $updater, $changes );
561 }
562
563 /**
564 * Update database to separate page from post.
565 *
566 * @param Updater $updater
567 *
568 * @param string $type
569 *
570 * @return bool
571 */
572 public static function rename_document_base_to_wp( $updater, $type ) {
573 global $wpdb;
574
575 $post_ids = $updater->query_col( $wpdb->prepare(
576 "SELECT p1.ID FROM {$wpdb->posts} AS p
577 LEFT JOIN {$wpdb->posts} AS p1 ON (p.ID = p1.post_parent || p.ID = p1.ID)
578 WHERE p.post_type = %s;", $type ) );
579
580 if ( empty( $post_ids ) ) {
581 return false;
582 }
583
584 $sql_post_ids = implode( ',', $post_ids );
585
586 $wpdb->query( $wpdb->prepare(
587 "UPDATE $wpdb->postmeta SET meta_value = %s
588 WHERE meta_key = '_elementor_template_type' && post_id in ( %s );
589 ", 'wp-' . $type, $sql_post_ids ) );
590
591 return $updater->should_run_again( $post_ids );
592 }
593
594 /**
595 * Update database to separate page from post.
596 *
597 * @param Updater $updater
598 *
599 * @return bool
600 */
601 // Because the query is slow on large sites, temporary don't upgrade.
602 /* public static function _v_2_7_0_rename_document_types_to_wp( $updater ) {
603 return self::rename_document_base_to_wp( $updater, 'post' ) || self::rename_document_base_to_wp( $updater, 'page' );
604 }*/
605
606 // Upgrade code was fixed & moved to _v_2_7_1_remove_old_usage_data.
607 /* public static function _v_2_7_0_remove_old_usage_data() {} */
608
609 // Upgrade code moved to _v_2_7_1_recalc_usage_data.
610 /* public static function _v_2_7_0_recalc_usage_data( $updater ) {} */
611
612 /**
613 * Don't use the old data anymore.
614 * Since 2.7.1 the key was changed from `elementor_elements_usage` to `elementor_controls_usage`.
615 */
616 public static function _v_2_7_1_remove_old_usage_data() {
617 delete_option( 'elementor_elements_usage' );
618 delete_post_meta_by_key( '_elementor_elements_usage' );
619 }
620
621 /**
622 * Recalc usage.
623 *
624 * @param Updater $updater
625 *
626 * @return bool
627 */
628 public static function recalc_usage_data( $updater ) {
629 /** @var Module $module */
630 $module = Plugin::$instance->modules_manager->get_modules( 'usage' );
631
632 $post_count = $module->recalc_usage( $updater->get_limit(), $updater->get_current_offset() );
633
634 return ( $post_count === $updater->get_limit() );
635 }
636
637 public static function _v_2_7_1_recalc_usage_data( $updater ) {
638 return self::recalc_usage_data( $updater );
639 }
640
641 public static function _v_2_8_3_recalc_usage_data( $updater ) {
642 // Re-calc since older version(s) had invalid values.
643 return self::recalc_usage_data( $updater );
644 }
645
646 /**
647 * Move general & lightbox settings to active kit and all it's revisions.
648 *
649 * @param Updater $updater
650 *
651 * @return bool
652 */
653 public static function _v_3_0_0_move_general_settings_to_kit( $updater ) {
654 $callback = function( $kit_id ) {
655 $kit = Plugin::$instance->documents->get( $kit_id );
656
657 if ( ! $kit ) {
658 self::notice( 'Kit not found. nothing to do.' );
659 return;
660 }
661
662 $meta_key = \Elementor\Core\Settings\Page\Manager::META_KEY;
663 $current_settings = get_option( '_elementor_general_settings', [] );
664 $current_settings[ Responsive::BREAKPOINT_OPTION_PREFIX . 'md' ] = get_option( 'elementor_viewport_md', '' );
665 $current_settings[ Responsive::BREAKPOINT_OPTION_PREFIX . 'lg' ] = get_option( 'elementor_viewport_lg', '' );
666
667 $kit_settings = $kit->get_meta( $meta_key );
668
669 // Already exist.
670 if ( isset( $kit_settings['default_generic_fonts'] ) ) {
671 self::notice( 'General Settings already exist. nothing to do.' );
672 return;
673 }
674
675 if ( empty( $current_settings ) ) {
676 self::notice( 'Current settings are empty. nothing to do.' );
677 return;
678 }
679
680 if ( ! $kit_settings ) {
681 $kit_settings = [];
682 }
683
684 // Convert some setting to Elementor slider format.
685 $settings_to_slider = [
686 'container_width',
687 'space_between_widgets',
688 ];
689
690 foreach ( $settings_to_slider as $setting ) {
691 if ( ! empty( $current_settings[ $setting ] ) ) {
692 $current_settings[ $setting ] = [
693 'unit' => 'px',
694 'size' => $current_settings[ $setting ],
695 ];
696 }
697 }
698
699 $kit_settings = array_merge( $kit_settings, $current_settings );
700
701 $page_settings_manager = SettingsManager::get_settings_managers( 'page' );
702 $page_settings_manager->save_settings( $kit_settings, $kit_id );
703 };
704
705 return self::move_settings_to_kit( $callback, $updater );
706 }
707
708 /**
709 * Move default colors settings to active kit and all it's revisions.
710 *
711 * @param Updater $updater
712 *
713 * @return bool
714 */
715 public static function _v_3_0_0_move_default_colors_to_kit( $updater, $include_revisions = true ) {
716 $callback = function( $kit_id ) {
717 if ( ! Plugin::$instance->kits_manager->is_custom_colors_enabled() ) {
718 self::notice( 'System colors are disabled. nothing to do.' );
719 return;
720 }
721
722 $kit = Plugin::$instance->documents->get( $kit_id );
723
724 // Already exist. use raw settings that doesn't have default values.
725 $meta_key = \Elementor\Core\Settings\Page\Manager::META_KEY;
726 $kit_raw_settings = $kit->get_meta( $meta_key );
727 if ( isset( $kit_raw_settings['system_colors'] ) ) {
728 self::notice( 'System colors already exist. nothing to do.' );
729 return;
730 }
731
732 $scheme_obj = Plugin::$instance->schemes_manager->get_scheme( 'color' );
733
734 $default_colors = $scheme_obj->get_scheme();
735
736 $new_ids = [
737 'primary',
738 'secondary',
739 'text',
740 'accent',
741 ];
742
743 foreach ( $default_colors as $index => $color ) {
744 $kit->add_repeater_row( 'system_colors', [
745 '_id' => $new_ids[ $index - 1 ], // $default_colors starts from 1.
746 'title' => $color['title'],
747 'color' => strtoupper( $color['value'] ),
748 ] );
749 }
750 };
751
752 return self::move_settings_to_kit( $callback, $updater, $include_revisions );
753 }
754
755 /**
756 * Move saved colors settings to active kit and all it's revisions.
757 *
758 * @param Updater $updater
759 *
760 * @return bool
761 */
762 public static function _v_3_0_0_move_saved_colors_to_kit( $updater, $include_revisions = true ) {
763 $callback = function( $kit_id ) {
764 $kit = Plugin::$instance->documents->get( $kit_id );
765
766 // Already exist. use raw settings that doesn't have default values.
767 $meta_key = \Elementor\Core\Settings\Page\Manager::META_KEY;
768 $kit_raw_settings = $kit->get_meta( $meta_key );
769 if ( isset( $kit_raw_settings['custom_colors'] ) ) {
770 self::notice( 'Custom colors already exist. nothing to do.' );
771 return;
772 }
773
774 $system_colors_rows = $kit->get_settings( 'system_colors' );
775
776 if ( ! $system_colors_rows ) {
777 $system_colors_rows = [];
778 }
779
780 $system_colors = [];
781
782 foreach ( $system_colors_rows as $color_row ) {
783 $system_colors[] = strtoupper( $color_row['color'] );
784 }
785
786 $saved_scheme_obj = Plugin::$instance->schemes_manager->get_scheme( 'color-picker' );
787
788 $current_saved_colors_rows = $saved_scheme_obj->get_scheme();
789
790 $current_saved_colors = [];
791
792 foreach ( $current_saved_colors_rows as $color_row ) {
793 $current_saved_colors[] = strtoupper( $color_row['value'] );
794 }
795
796 $colors_to_save = array_diff( $current_saved_colors, $system_colors );
797
798 if ( empty( $colors_to_save ) ) {
799 self::notice( 'Saved colors not found. nothing to do.' );
800 return;
801 }
802
803 foreach ( $colors_to_save as $index => $color ) {
804 $kit->add_repeater_row( 'custom_colors', [
805 '_id' => Utils::generate_random_string(),
806 'title' => __( 'Saved Color', 'elementor' ) . ' #' . ( $index + 1 ),
807 'color' => $color,
808 ] );
809 }
810 };
811
812 return self::move_settings_to_kit( $callback, $updater, $include_revisions );
813 }
814
815 /**
816 * Move default typography settings to active kit and all it's revisions.
817 *
818 * @param Updater $updater
819 *
820 * @return bool
821 */
822 public static function _v_3_0_0_move_default_typography_to_kit( $updater, $include_revisions = true ) {
823 $callback = function( $kit_id ) {
824 if ( ! Plugin::$instance->kits_manager->is_custom_typography_enabled() ) {
825 self::notice( 'System typography is disabled. nothing to do.' );
826 return;
827 }
828
829 $kit = Plugin::$instance->documents->get( $kit_id );
830
831 // Already exist. use raw settings that doesn't have default values.
832 $meta_key = \Elementor\Core\Settings\Page\Manager::META_KEY;
833 $kit_raw_settings = $kit->get_meta( $meta_key );
834 if ( isset( $kit_raw_settings['system_typography'] ) ) {
835 self::notice( 'System typography already exist. nothing to do.' );
836 return;
837 }
838
839 $scheme_obj = Plugin::$instance->schemes_manager->get_scheme( 'typography' );
840
841 $default_typography = $scheme_obj->get_scheme();
842
843 $new_ids = [
844 'primary',
845 'secondary',
846 'text',
847 'accent',
848 ];
849
850 foreach ( $default_typography as $index => $typography ) {
851 $kit->add_repeater_row( 'system_typography', [
852 '_id' => $new_ids[ $index - 1 ], // $default_typography starts from 1.
853 'title' => $typography['title'],
854 'typography_typography' => 'custom',
855 'typography_font_family' => $typography['value']['font_family'],
856 'typography_font_weight' => $typography['value']['font_weight'],
857 ] );
858 }
859 };
860
861 return self::move_settings_to_kit( $callback, $updater, $include_revisions );
862 }
863
864 /**
865 * Re move `space_between_widgets` settings to kit.
866 *
867 * Due to a bug in previous upgrade, the setting `space_between_widgets` with a value `0` didn't upgraded properly.
868 * Try to re move it, if it's not already set manually in the kit.
869 *
870 * @param $updater
871 *
872 * @return false|mixed
873 */
874 public static function _v_3_0_5_re_move_space_between_widgets_to_kit( $updater ) {
875 $callback = function( $kit_id ) {
876 $kit = Plugin::$instance->documents->get( $kit_id );
877
878 if ( ! $kit ) {
879 self::notice( 'Kit not found. nothing to do.' );
880 return;
881 }
882
883 $meta_key = \Elementor\Core\Settings\Page\Manager::META_KEY;
884 $old_settings = get_option( '_elementor_general_settings', [] );
885 $kit_settings = $kit->get_meta( $meta_key );
886
887 if ( ! $kit_settings ) {
888 $kit_settings = [];
889 }
890
891 if ( isset( $old_settings['space_between_widgets'] ) && ! isset( $kit_settings['space_between_widgets'] ) ) {
892 $kit_settings['space_between_widgets'] = [
893 'unit' => 'px',
894 'size' => $old_settings['space_between_widgets'],
895 ];
896
897 $page_settings_manager = SettingsManager::get_settings_managers( 'page' );
898 $page_settings_manager->save_settings( $kit_settings, $kit_id );
899 }
900 };
901
902 return self::move_settings_to_kit( $callback, $updater );
903 }
904
905 /**
906 * @param callback $callback
907 * @param Updater $updater
908 *
909 * @param bool $include_revisions
910 *
911 * @return mixed
912 */
913 private static function move_settings_to_kit( $callback, $updater, $include_revisions = true ) {
914 $active_kit_id = Plugin::$instance->kits_manager->get_active_id();
915 if ( ! $active_kit_id ) {
916 self::notice( 'Active kit not found. nothing to do.' );
917 return false;
918 }
919
920 $offset = $updater->get_current_offset();
921
922 // On first iteration apply on active kit itself.
923 // (don't include it with revisions in order to avoid offset/iteration count wrong numbers)
924 if ( 0 === $offset ) {
925 $callback( $active_kit_id );
926 }
927
928 if ( ! $include_revisions ) {
929 return false;
930 }
931
932 $revisions_ids = wp_get_post_revisions( $active_kit_id, [
933 'fields' => 'ids',
934 'posts_per_page' => $updater->get_limit(),
935 'offset' => $offset,
936 ] );
937
938 foreach ( $revisions_ids as $revision_id ) {
939 $callback( $revision_id );
940 }
941
942 return $updater->should_run_again( $revisions_ids );
943 }
944
945 private static function notice( $message ) {
946 $logger = Plugin::$instance->logger->get_logger();
947 $logger->notice( $message );
948 }
949 }
950