Move temporary automation migrator to a new migration

[MAILPOET-4788]
This commit is contained in:
Jan Jakes
2022-11-10 18:25:22 +03:00
committed by David Remer
parent 8489e63d34
commit 2e328b6d7f
11 changed files with 79 additions and 177 deletions

View File

@@ -4,7 +4,6 @@ namespace MailPoet\AdminPages\Pages;
use MailPoet\AdminPages\PageRenderer;
use MailPoet\Automation\Engine\Data\AutomationTemplate;
use MailPoet\Automation\Engine\Migrations\Migrator;
use MailPoet\Automation\Engine\Storage\AutomationStorage;
use MailPoet\Automation\Engine\Storage\AutomationTemplateStorage;
use MailPoet\Form\AssetsController;
@@ -14,9 +13,6 @@ class Automation {
/** @var AssetsController */
private $assetsController;
/** @var Migrator */
private $migrator;
/** @var PageRenderer */
private $pageRenderer;
@@ -31,14 +27,12 @@ class Automation {
public function __construct(
AssetsController $assetsController,
Migrator $migrator,
PageRenderer $pageRenderer,
WPFunctions $wp,
AutomationStorage $automationStorage,
AutomationTemplateStorage $templateStorage
) {
$this->assetsController = $assetsController;
$this->migrator = $migrator;
$this->pageRenderer = $pageRenderer;
$this->wp = $wp;
$this->automationStorage = $automationStorage;
@@ -47,10 +41,6 @@ class Automation {
public function render() {
$this->assetsController->setupAutomationListingDependencies();
if (!$this->migrator->hasSchema()) {
$this->migrator->createSchema();
}
$this->pageRenderer->displayPage('automation.html', [
'api' => [
'root' => rtrim($this->wp->escUrlRaw($this->wp->restUrl()), '/'),

View File

@@ -1,136 +0,0 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Engine\Migrations;
use MailPoet\Automation\Engine\Exceptions;
use wpdb;
class Migrator {
/** @var string */
private $prefix;
/** @var wpdb */
private $wpdb;
public function __construct() {
global $wpdb;
$this->prefix = $wpdb->prefix . 'mailpoet_';
$this->wpdb = $wpdb;
}
public function createSchema(): void {
$this->removeOldSchema();
$this->runQuery("
CREATE TABLE {$this->prefix}automations (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author bigint NOT NULL,
status varchar(255) NOT NULL,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
activated_at timestamp NULL,
deleted_at timestamp NULL,
PRIMARY KEY (id)
);
");
$this->runQuery("
CREATE TABLE {$this->prefix}automation_versions (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
automation_id int(11) unsigned NOT NULL,
steps longtext,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
PRIMARY KEY (id),
INDEX (automation_id)
);
");
$this->runQuery("
CREATE TABLE {$this->prefix}automation_triggers (
automation_id int(11) unsigned NOT NULL,
trigger_key varchar(255),
PRIMARY KEY (automation_id, trigger_key)
);
");
$this->runQuery("
CREATE TABLE {$this->prefix}automation_runs (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
automation_id int(11) unsigned NOT NULL,
version_id int(11) unsigned NOT NULL,
trigger_key varchar(255) NOT NULL,
status varchar(255) NOT NULL,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
subjects longtext,
next_step_id varchar(255),
PRIMARY KEY (id),
INDEX (automation_id),
INDEX (status)
);
");
$this->runQuery("
CREATE TABLE {$this->prefix}automation_run_logs (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
automation_run_id int(11) unsigned NOT NULL,
step_id varchar(255) NOT NULL,
status varchar(255) NOT NULL,
started_at timestamp NOT NULL,
completed_at timestamp NULL DEFAULT NULL,
error longtext,
data longtext,
PRIMARY KEY (id),
INDEX (automation_run_id)
);
");
}
public function deleteSchema(): void {
$this->removeOldSchema();
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}automations");
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}automation_runs");
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}automation_run_logs");
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}automation_versions");
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}automation_triggers");
// clean Action Scheduler data
$this->runQuery("
DELETE FROM {$this->wpdb->prefix}actionscheduler_claims WHERE claim_id IN (
SELECT claim_id FROM {$this->wpdb->prefix}actionscheduler_actions WHERE hook LIKE '%mailpoet/automation%'
)
");
$this->runQuery("
DELETE FROM {$this->wpdb->prefix}actionscheduler_logs WHERE action_id IN (
SELECT action_id FROM {$this->wpdb->prefix}actionscheduler_actions WHERE hook LIKE '%mailpoet/automation%'
)
");
$this->runQuery("DELETE FROM {$this->wpdb->prefix}actionscheduler_actions WHERE hook LIKE '%mailpoet/automation%'");
$this->runQuery("DELETE FROM {$this->wpdb->prefix}actionscheduler_groups WHERE slug = 'mailpoet-automation'");
}
public function hasSchema(): bool {
$pattern = $this->wpdb->esc_like("{$this->prefix}automations") . '%';
return $this->runQuery("SHOW TABLES LIKE '$pattern'") > 0;
}
private function removeOldSchema(): void {
$oldPrefix = $this->wpdb->prefix . 'mailpoet_automation_';
$this->runQuery("DROP TABLE IF EXISTS {$oldPrefix}automations");
$this->runQuery("DROP TABLE IF EXISTS {$oldPrefix}automation_runs");
}
private function runQuery(string $query): int {
$this->wpdb->hide_errors();
// It's a private method and all Queries in this class are safe
// phpcs:ignore WordPressDotOrg.sniffs.DirectDB.UnescapedDBParameter
$result = $this->wpdb->query($query);
if ($result === false) {
throw Exceptions::migrationFailed($this->wpdb->last_error ?: 'Unknown error');
}
return $result === true ? 0 : (int)$result;
}
}

View File

@@ -125,7 +125,6 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\Automation\Engine\Engine::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\Hooks::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\Mappers\AutomationMapper::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\Migrations\Migrator::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\Registry::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\Storage\AutomationRunStorage::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\Storage\AutomationRunLogStorage::class)->setPublic(true);

View File

@@ -0,0 +1,79 @@
<?php declare(strict_types = 1);
namespace MailPoet\Migrations;
use MailPoet\Config\Env;
use MailPoet\Migrator\Migration;
class Migration_20221110_151621 extends Migration {
public function run(): void {
$prefix = Env::$dbPrefix;
$charsetCollate = Env::$dbCharsetCollate;
$this->connection->executeStatement("
CREATE TABLE {$prefix}automations (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author bigint NOT NULL,
status varchar(255) NOT NULL,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
activated_at timestamp NULL,
deleted_at timestamp NULL,
PRIMARY KEY (id)
) {$charsetCollate};
");
$this->connection->executeStatement("
CREATE TABLE {$prefix}automation_versions (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
automation_id int(11) unsigned NOT NULL,
steps longtext,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
PRIMARY KEY (id),
INDEX (automation_id)
) {$charsetCollate};
");
$this->connection->executeStatement("
CREATE TABLE {$prefix}automation_triggers (
automation_id int(11) unsigned NOT NULL,
trigger_key varchar(255),
PRIMARY KEY (automation_id, trigger_key)
);
");
$this->connection->executeStatement("
CREATE TABLE {$prefix}automation_runs (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
automation_id int(11) unsigned NOT NULL,
version_id int(11) unsigned NOT NULL,
trigger_key varchar(255) NOT NULL,
status varchar(255) NOT NULL,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
subjects longtext,
next_step_id varchar(255),
PRIMARY KEY (id),
INDEX (automation_id),
INDEX (status)
) {$charsetCollate};
");
$this->connection->executeStatement("
CREATE TABLE {$prefix}automation_run_logs (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
automation_run_id int(11) unsigned NOT NULL,
step_id varchar(255) NOT NULL,
status varchar(255) NOT NULL,
started_at timestamp NOT NULL,
completed_at timestamp NULL DEFAULT NULL,
error longtext,
data longtext,
PRIMARY KEY (id),
INDEX (automation_run_id)
) {$charsetCollate};
");
}
}

View File

@@ -2,7 +2,6 @@
namespace MailPoet\Test\Acceptance;
use MailPoet\Automation\Engine\Migrations\Migrator;
use MailPoet\DI\ContainerWrapper;
use MailPoet\Features\FeaturesController;
use MailPoet\Test\DataFactories\Features;
@@ -14,9 +13,6 @@ class ConfirmLeaveWhenUnsavedChangesCest
$features = new Features();
$features->withFeatureEnabled(FeaturesController::AUTOMATION);
$container = ContainerWrapper::getInstance();
$migrator = $container->get(Migrator::class);
$migrator->deleteSchema();
$migrator->createSchema();
}
public function confirmationIsRequiredIfAutomationNotSaved(\AcceptanceTester $i) {

View File

@@ -3,7 +3,6 @@
namespace MailPoet\Test\Acceptance;
use Facebook\WebDriver\WebDriverKeys;
use MailPoet\Automation\Engine\Migrations\Migrator;
use MailPoet\DI\ContainerWrapper;
use MailPoet\Features\FeaturesController;
use MailPoet\Test\DataFactories\Features;
@@ -16,9 +15,6 @@ class CreateEmailAutomationAndWalkThroughCest
$features = new Features();
$features->withFeatureEnabled(FeaturesController::AUTOMATION);
$container = ContainerWrapper::getInstance();
$migrator = $container->get(Migrator::class);
$migrator->deleteSchema();
$migrator->createSchema();
$settings = new Settings();
$settings->withCronTriggerMethod('Action Scheduler');

View File

@@ -5,7 +5,6 @@ namespace MailPoet\Test\Acceptance;
use MailPoet\Automation\Engine\Data\NextStep;
use MailPoet\Automation\Engine\Data\Step;
use MailPoet\Automation\Engine\Data\Automation;
use MailPoet\Automation\Engine\Migrations\Migrator;
use MailPoet\Automation\Engine\Storage\AutomationRunLogStorage;
use MailPoet\Automation\Engine\Storage\AutomationRunStorage;
use MailPoet\Automation\Engine\Storage\AutomationStatisticsStorage;
@@ -47,9 +46,6 @@ class SomeoneSubscribesAutomationTriggeredByCheckoutCest
$features = new Features();
$features->withFeatureEnabled(FeaturesController::AUTOMATION);
$this->container = ContainerWrapper::getInstance();
$migrator = $this->container->get(Migrator::class);
$migrator->deleteSchema();
$migrator->createSchema();
$this->settingsFactory = new Settings();

View File

@@ -6,7 +6,6 @@ use Codeception\Util\Locator;
use MailPoet\Automation\Engine\Data\NextStep;
use MailPoet\Automation\Engine\Data\Step;
use MailPoet\Automation\Engine\Data\Automation;
use MailPoet\Automation\Engine\Migrations\Migrator;
use MailPoet\Automation\Engine\Storage\AutomationRunLogStorage;
use MailPoet\Automation\Engine\Storage\AutomationRunStorage;
use MailPoet\Automation\Engine\Storage\AutomationStorage;
@@ -39,9 +38,6 @@ class UserRegistrationTriggerCest
$features = new Features();
$features->withFeatureEnabled(FeaturesController::AUTOMATION);
$this->container = ContainerWrapper::getInstance();
$migrator = $this->container->get(Migrator::class);
$migrator->deleteSchema();
$migrator->createSchema();
$this->settingsFactory = new Settings();

View File

@@ -6,7 +6,6 @@ use Codeception\Stub;
use Helper\WordPressHooks as WPHooksHelper;
use MailPoet\API\JSON\Response as APIResponse;
use MailPoet\API\JSON\v1\Setup;
use MailPoet\Automation\Engine\Migrations\Migrator as AutomationMigrator;
use MailPoet\Config\Activator;
use MailPoet\Config\Populator;
use MailPoet\Cron\ActionScheduler\ActionScheduler;
@@ -66,6 +65,5 @@ class SetupTest extends \MailPoetTest {
// Temporarily hotfix a side effect of this test, that is, removing automation feature flag
// and tables and not setting them back. This will be removed very soon, before MVP release.
$this->diContainer->get(FeatureFlagsController::class)->set(FeaturesController::AUTOMATION, true);
$this->diContainer->get(AutomationMigrator::class)->createSchema();
}
}

View File

@@ -4,17 +4,11 @@ namespace MailPoet\REST\Automation;
require_once __DIR__ . '/../Test.php';
use MailPoet\Automation\Engine\Migrations\Migrator;
use MailPoet\REST\Test;
abstract class AutomationTest extends Test {
public function _before() {
parent::_before();
$migrator = $this->diContainer->get(Migrator::class);
if ($migrator->hasSchema()) {
$migrator->deleteSchema();
}
$migrator->createSchema();
wp_set_current_user(1);
}

View File

@@ -3,7 +3,6 @@
use Codeception\Stub;
use MailPoet\Automation\Engine\Engine;
use MailPoet\Automation\Engine\Hooks;
use MailPoet\Automation\Engine\Migrations\Migrator;
use MailPoet\Automation\Integrations\MailPoet\MailPoetIntegration;
use MailPoet\Cache\TransientCache;
use MailPoet\Cron\CronTrigger;
@@ -63,12 +62,7 @@ remove_filter('admin_print_styles', 'wp_resource_hints', 1);
// enable & initialize automation (this is needed only when behind a feature flag)
$_SERVER['SERVER_NAME'] = '';
$container = ContainerWrapper::getInstance();
$migrator = $container->get(Migrator::class);
$container->get(FeatureFlagsController::class)->set(FeaturesController::AUTOMATION, true);
if ($migrator->hasSchema()) {
$migrator->deleteSchema();
}
$migrator->createSchema();
$action = [$container->get(MailPoetIntegration::class), 'register'];
if (!has_action(Hooks::INITIALIZE, $action) && is_callable($action)) {
add_action(Hooks::INITIALIZE, $action);