Builders at construction site

Create Elementor migration/upgrade scripts

Every now and then, you may need to migrate something on existing Elementor widgets. One solution would be to go through every single template and change it by hand, but we’re not savages.

Note that migration in this context means that we have the widget in place but we update some of its values.

So we use code! Since I didn’t found any resource on how this could be accomplished, here is a short how to.

You can use this with either Elementor Pro or the free version (although the Pro version have some goodies built in).

In your plugin file, you add this:

// if you're using the free version:
add_action('elementor/init', 'MyUpgradeManager::instance', 99);

// if you're using the Pro version:
add_action('elementor_pro/init', 'MyUpgradeManager::instance', 99);

Next up, you need to create two classes: MyUpgradeManager and MyUpgrades. It’s recommended that you set up an autoloader for your classes, but that’s a story for another time (or you can head to Composer documentation and do your thing).

First class is the MyUpgradeManager, which only register the actions. Nothing fancy here:

<?php

!defined('ABSPATH') && die();

use Elementor\Core\Upgrade\Manager as ElementorUpgradeManager;

class MyUpgradeManager extends ElementorUpgradeManager
{
    public function get_action()
    {
        return 'elementor-my-upgrade-manager';
    }

    public function get_plugin_name()
    {
        return 'my-elementor-widgets';
    }

    public function get_plugin_label()
    {
        return esc_html__('My Elementor Widgets');
    }

    public function get_updater_label()
    {
        return esc_html__('My Elementor Widgets Data Updater');
    }

    public function get_new_version()
    {
        return '1.0.0'; 
    }

    public function get_version_option_name()
    {
        return 'elementor_my_widgets_version';
    }

    public function get_upgrades_class()
    {
        // if you're using namespaces, you need to add the full path: my\namespace\MyUpgrades
        return 'MyUpgrades'; 
    }
}

Next up, the class that actually do the changes:

<?php

use Elementor\Core\Upgrade\Upgrade_Utils;

!defined('ABSPATH') && die();

class MyUpgrades
{
    public static function do_my_changes($element, $args)
    {
        if (empty($element['widgetType']) || $args['widget_id'] !== $element['widgetType']) {
            return $element;
        }

        $element['settings']['components_to_show'] ??= [];
        $element['settings']['layout_type'] ??= $element['settings']['type'] ?? 'three_wide';

        return $element;
    }

    /**
     * Remember `get_new_version()` method from the previous class?
     * We convert that version from dots to underscore, we prefix it with `_v_` and we add the changes.
     * Note that `_v_0_0_1_changes_will_not_be_applied()` will NOT execute, as the version 0.0.1 is 
     * lower than Manager version (1.0.0)
     */
    public static function _v_0_0_1_changes_will_not_be_applied($updater)
    {
        // do nothing
    }

    public static function _v_1_0_0_my_changes($updater)
    {
        $changes = [
            [
                'callback' => ['ElementorPro\Core\Upgrade\Upgrades', '_rename_widget_settings'],
                'control_ids' => [
                    'type' => 'layout_type',
                ],
            ],

            [
                'callback' => ['MyUpgrades', 'do_my_changes'],
                'control_ids' => [],
            ],
        ];

        return Upgrade_Utils::_update_widget_settings('my-widget-name', $updater, $changes);
    }

    // this will run on each version
    public static function _on_each_version( $updater ) {}
}

What does this class do?

Inside _v_1_0_0_my_changes method, it takes a custom widget, called my-widget-name and do a couple of changes, as you can see in the $changes variable:

  1. Firstly, it will rename an existing control called type to layout_type, as it’s more suggestive on what that will do;
  2. Secondly, it will do some custom changes, as you can see inside do_my_changes method (in this case, it will set some default values)

You need to make sure that the first param of Upgrade_Utils::_update_widget_settings('my-widget-name', $updater, $changes); will match your widget name.

You can add as many methods as you want and you can get inspired by the Elementor upgrades class on what can be done.

WP CLI

In order to make it work on WP-CLI, you need to add an extra class:

class UpdateCliCommand extends UpdateBase {
    protected function get_update_db_manager_class() {
        return 'MyUpgradeManager'; // you use the same class name as above **including** namespace, if that's the case
    }
}

You also need to add the following after the initialization:

add_action('elementor/init', 'MyUpgradeManager::instance', 99);
+ if (class_exists('\WP_CLI')) {
+     \WP_CLI::add_command('my-plugin elementor update', 'UpdateCliCommand');
+ }

After you do this, you can run wp my-plugin elementor update db to… well, update the db.


Publicat

în

de către

Etichete:

Comentarii

0 răspunsuri la „Create Elementor migration/upgrade scripts”

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

Acest site folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.

windows apple dropbox facebook twitter