PluginProbe
Elementor Website Builder – more than just a page builder / 3.4.0
Elementor Website Builder – more than just a page builder v3.4.0
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.4.0, at core/upgrade/upgrades.php

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