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

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