| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194 |
- <?php
- namespace MailPoet\Config;
- if (!defined('ABSPATH')) exit;
- use MailPoet\Entities\FormEntity;
- use MailPoet\Form\FormsRepository;
- use MailPoet\Models\CustomField;
- use MailPoet\Models\MappingToExternalEntities;
- use MailPoet\Models\Segment;
- use MailPoet\Models\Subscriber;
- use MailPoet\Models\SubscriberCustomField;
- use MailPoet\Models\SubscriberSegment;
- use MailPoet\Settings\SettingsController;
- use MailPoet\Util\Notices\AfterMigrationNotice;
- use MailPoet\Util\ProgressBar;
- use MailPoet\WP\Functions as WPFunctions;
- use MailPoetVendor\Idiorm\ORM;
- class MP2Migrator {
- const IMPORT_TIMEOUT_IN_SECONDS = 7200; // Timeout = 2 hours
- const CHUNK_SIZE = 10; // To import the data by batch
- const MIGRATION_COMPLETE_SETTING_KEY = 'mailpoet_migration_complete';
- const MIGRATION_STARTED_SETTING_KEY = 'mailpoet_migration_started';
- /** @var SettingsController */
- private $settings;
- /** @var Activator */
- private $activator;
- /** @var FormsRepository */
- private $formsRepository;
- private $logFile;
- public $logFileUrl;
- public $progressbar;
- private $segmentsMapping = []; // Mapping between old and new segment IDs
- private $wpUsersSegment;
- private $doubleOptinEnabled = true;
- private $mp2CampaignTable;
- private $mp2CustomFieldTable;
- private $mp2EmailTable;
- private $mp2FormTable;
- private $mp2ListTable;
- private $mp2UserTable;
- private $mp2UserListTable;
- public function __construct(
- SettingsController $settings,
- FormsRepository $formsRepository,
- Activator $activator
- ) {
- $this->defineMP2Tables();
- $logFilename = 'mp2migration.log';
- $this->logFile = Env::$tempPath . '/' . $logFilename;
- $this->logFileUrl = Env::$tempUrl . '/' . $logFilename;
- $this->progressbar = new ProgressBar('mp2migration');
- $this->settings = $settings;
- $this->activator = $activator;
- $this->formsRepository = $formsRepository;
- }
- private function defineMP2Tables() {
- global $wpdb;
- $this->mp2CampaignTable = defined('MP2_CAMPAIGN_TABLE')
- ? MP2_CAMPAIGN_TABLE
- : $wpdb->prefix . 'wysija_campaign';
- $this->mp2CustomFieldTable = defined('MP2_CUSTOM_FIELD_TABLE')
- ? MP2_CUSTOM_FIELD_TABLE
- : $wpdb->prefix . 'wysija_custom_field';
- $this->mp2EmailTable = defined('MP2_EMAIL_TABLE')
- ? MP2_EMAIL_TABLE
- : $wpdb->prefix . 'wysija_email';
- $this->mp2FormTable = defined('MP2_FORM_TABLE')
- ? MP2_FORM_TABLE
- : $wpdb->prefix . 'wysija_form';
- $this->mp2ListTable = defined('MP2_LIST_TABLE')
- ? MP2_LIST_TABLE
- : $wpdb->prefix . 'wysija_list';
- $this->mp2UserTable = defined('MP2_USER_TABLE')
- ? MP2_USER_TABLE
- : $wpdb->prefix . 'wysija_user';
- $this->mp2UserListTable = defined('MP2_USER_LIST_TABLE')
- ? MP2_USER_LIST_TABLE
- : $wpdb->prefix . 'wysija_user_list';
- }
- /**
- * Test if the migration is already started but is not completed
- *
- * @return bool
- */
- public function isMigrationStartedAndNotCompleted() {
- return $this->settings->get(self::MIGRATION_STARTED_SETTING_KEY, false)
- && !$this->settings->get(self::MIGRATION_COMPLETE_SETTING_KEY, false);
- }
- /**
- * Test if the migration is needed
- *
- * @return bool
- */
- public function isMigrationNeeded() {
- if ($this->settings->get(self::MIGRATION_COMPLETE_SETTING_KEY)) {
- return false;
- } else {
- return $this->tableExists($this->mp2CampaignTable); // Check if the MailPoet 2 tables exist
- }
- }
- /**
- * Store the "Skip import" choice
- *
- */
- public function skipImport() {
- $this->settings->set(self::MIGRATION_COMPLETE_SETTING_KEY, true);
- }
- /**
- * Test if a table exists
- *
- * @param string $table Table name
- * @return bool
- */
- private function tableExists($table) {
- global $wpdb;
- try {
- $sql = "SHOW TABLES LIKE '{$table}'";
- $result = $wpdb->query($sql);
- return !empty($result);
- } catch (\Exception $e) {
- // Do nothing
- }
- return false;
- }
- /**
- * Initialize the migration page
- *
- */
- public function init() {
- if (!$this->settings->get(self::MIGRATION_STARTED_SETTING_KEY, false)) {
- $this->emptyLog();
- $this->progressbar->setTotalCount(0);
- }
- $this->enqueueScripts();
- }
- /**
- * Register the JavaScript for the admin area.
- *
- */
- private function enqueueScripts() {
- WPFunctions::get()->wpEnqueueScript('jquery-ui-progressbar');
- }
- /**
- * Write a message in the log file
- *
- * @param string $message
- */
- private function log($message) {
- file_put_contents($this->logFile, "$message\n", FILE_APPEND);
- }
- /**
- * Import the data from MailPoet 2
- *
- * @return string Result
- */
- public function import() {
- if (strpos((string)@ini_get('disable_functions'), 'set_time_limit') === false) {
- @set_time_limit(3600);
- }
- ob_start();
- $datetime = new \MailPoet\WP\DateTime();
- $this->log(sprintf('=== ' . mb_strtoupper(__('Start import', 'mailpoet'), 'UTF-8') . ' %s ===', $datetime->formatTime(time(), \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT)));
- $this->settings->set('import_stopped', false); // Reset the stop import action
- if (!$this->settings->get(self::MIGRATION_STARTED_SETTING_KEY, false)) {
- $this->eraseMP3Data();
- $this->settings->set(self::MIGRATION_STARTED_SETTING_KEY, true);
- $this->displayDataToMigrate();
- }
- $this->loadDoubleOptinSettings();
- $this->importSegments();
- $this->importCustomFields();
- $this->importSubscribers();
- $this->importForms();
- $this->importSettings();
- if (!$this->importStopped()) {
- $this->settings->set(self::MIGRATION_COMPLETE_SETTING_KEY, true);
- $this->log(mb_strtoupper(__('Import complete', 'mailpoet'), 'UTF-8'));
- $afterMigrationNotice = new AfterMigrationNotice();
- $afterMigrationNotice->enable();
- }
- $this->log(sprintf('=== ' . mb_strtoupper(__('End import', 'mailpoet'), 'UTF-8') . ' %s ===', $datetime->formatTime(time(), \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT)));
- $result = ob_get_contents();
- ob_clean();
- return (string)$result;
- }
- /**
- * Empty the log file
- *
- */
- private function emptyLog() {
- file_put_contents($this->logFile, '');
- }
- /**
- * Erase all the MailPoet 3 data
- *
- */
- private function eraseMP3Data() {
- $this->activator->deactivate();
- $this->activator->activate();
- $this->deleteSegments();
- $this->resetMigrationCounters();
- $this->log(__("MailPoet data erased", 'mailpoet'));
- }
- /**
- * Reset the migration counters
- *
- */
- private function resetMigrationCounters() {
- $this->settings->set('last_imported_user_id', 0);
- $this->settings->set('last_imported_list_id', 0);
- $this->settings->set('last_imported_form_id', 0);
- }
- private function loadDoubleOptinSettings() {
- $encodedOption = WPFunctions::get()->getOption('wysija');
- $values = unserialize(base64_decode($encodedOption));
- if (isset($values['confirm_dbleoptin']) && $values['confirm_dbleoptin'] === '0') {
- $this->doubleOptinEnabled = false;
- }
- }
- /**
- * Delete the existing segments except the wp_users and woocommerce_users segments
- *
- */
- private function deleteSegments() {
- global $wpdb;
- $table = MP_SEGMENTS_TABLE;
- $wpdb->query("DELETE FROM {$table} WHERE type != '" . Segment::TYPE_WP_USERS . "' AND type != '" . Segment::TYPE_WC_USERS . "'");
- }
- /**
- * Stop the import
- *
- */
- public function stopImport() {
- $this->settings->set('import_stopped', true);
- $this->log(mb_strtoupper(__('Import stopped by user', 'mailpoet'), 'UTF-8'));
- }
- /**
- * Test if the import must stop
- *
- * @return bool Import must stop or not
- */
- private function importStopped() {
- return $this->settings->get('import_stopped', false);
- }
- /**
- * Display the number of data to migrate
- *
- */
- private function displayDataToMigrate() {
- $data = $this->getDataToMigrateAndResetProgressBar();
- $this->log($data);
- }
- /**
- * Get the data to migrate
- *
- * @return string Data to migrate
- */
- private function getDataToMigrateAndResetProgressBar() {
- $result = '';
- $totalCount = 0;
- $this->progressbar->setTotalCount(0);
- $result .= WPFunctions::get()->__('MailPoet 2 data found:', 'mailpoet') . "\n";
- // User Lists
- $usersListsCount = ORM::for_table($this->mp2ListTable)->count();
- $totalCount += $usersListsCount;
- $result .= sprintf(_n('%d subscribers list', '%d subscribers lists', $usersListsCount, 'mailpoet'), $usersListsCount) . "\n";
- // Users
- $usersCount = ORM::for_table($this->mp2UserTable)->count();
- $totalCount += $usersCount;
- $result .= sprintf(_n('%d subscriber', '%d subscribers', $usersCount, 'mailpoet'), $usersCount) . "\n";
- // Forms
- $formsCount = ORM::for_table($this->mp2FormTable)->count();
- $totalCount += $formsCount;
- $result .= sprintf(_n('%d form', '%d forms', $formsCount, 'mailpoet'), $formsCount) . "\n";
- $this->progressbar->setTotalCount($totalCount);
- return $result;
- }
- /**
- * Import the subscribers segments
- *
- */
- private function importSegments() {
- $importedSegmentsCount = 0;
- if ($this->importStopped()) {
- $this->segmentsMapping = $this->getImportedMapping('segments');
- return;
- }
- $this->log(__("Importing segments...", 'mailpoet'));
- do {
- if ($this->importStopped()) {
- break;
- }
- $lists = $this->getLists(self::CHUNK_SIZE);
- $listsCount = count($lists);
- if (is_array($lists)) {
- foreach ($lists as $list) {
- $segment = $this->importSegment($list);
- if (!empty($segment)) {
- $importedSegmentsCount++;
- }
- }
- }
- $this->progressbar->incrementCurrentCount($listsCount);
- } while (($lists != null) && ($listsCount > 0));
- $this->segmentsMapping = $this->getImportedMapping('segments');
- $this->log(sprintf(_n("%d segment imported", "%d segments imported", $importedSegmentsCount, 'mailpoet'), $importedSegmentsCount));
- }
- /**
- * Get the Mailpoet 2 users lists
- *
- * @global object $wpdb
- * @param int $limit Number of users max
- * @return array Users Lists
- */
- private function getLists($limit) {
- global $wpdb;
- $lastId = intval($this->settings->get('last_imported_list_id', 0));
- $table = $this->mp2ListTable;
- $sql = "
- SELECT l.list_id, l.name, l.description, l.is_enabled, l.created_at
- FROM `$table` l
- WHERE l.list_id > '$lastId'
- ORDER BY l.list_id
- LIMIT $limit
- ";
- $lists = $wpdb->get_results($sql, ARRAY_A);
- return $lists;
- }
- /**
- * Import a segment
- *
- * @param array $listData List data
- * @return Segment
- */
- private function importSegment($listData) {
- $datetime = new \MailPoet\WP\DateTime();
- if ($listData['is_enabled']) {
- $segment = Segment::createOrUpdate([
- 'name' => $listData['name'],
- 'type' => 'default',
- 'description' => !empty($listData['description']) ? $listData['description'] : '',
- 'created_at' => $datetime->formatTime($listData['created_at'], \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT),
- ]);
- } else {
- $segment = Segment::getWPSegment();
- }
- if (!empty($segment)) {
- // Map the segment with its old ID
- $mapping = new MappingToExternalEntities();
- $mapping->create([
- 'old_id' => $listData['list_id'],
- 'type' => 'segments',
- 'new_id' => $segment->id,
- 'created_at' => $datetime->formatTime(time(), \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT),
- ]);
- }
- $this->settings->set('last_imported_list_id', $listData['list_id']);
- return $segment;
- }
- /**
- * Import the custom fields
- *
- */
- private function importCustomFields() {
- $importedCustomFieldsCount = 0;
- if ($this->importStopped()) {
- return;
- }
- $this->log(__("Importing custom fields...", 'mailpoet'));
- $customFields = $this->getCustomFields();
- foreach ($customFields as $customField) {
- $result = $this->importCustomField($customField);
- if (!empty($result)) {
- $importedCustomFieldsCount++;
- }
- }
- $this->log(sprintf(_n("%d custom field imported", "%d custom fields imported", $importedCustomFieldsCount, 'mailpoet'), $importedCustomFieldsCount));
- }
- /**
- * Get the Mailpoet 2 custom fields
- *
- * @global object $wpdb
- * @return array Custom fields
- */
- private function getCustomFields() {
- global $wpdb;
- $customFields = [];
- $table = $this->mp2CustomFieldTable;
- $sql = "
- SELECT cf.id, cf.name, cf.type, cf.required, cf.settings
- FROM `$table` cf
- ";
- $customFields = $wpdb->get_results($sql, ARRAY_A);
- return $customFields;
- }
- /**
- * Import a custom field
- *
- * @param array $customField MP2 custom field
- * @return CustomField
- */
- private function importCustomField($customField) {
- $data = [
- 'id' => $customField['id'],
- 'name' => $customField['name'],
- 'type' => $this->mapCustomFieldType($customField['type']),
- 'params' => $this->mapCustomFieldParams($customField['name'], unserialize($customField['settings'])),
- ];
- $customField = new CustomField();
- $customField->createOrUpdate($data);
- return $customField;
- }
- /**
- * Map the MailPoet 2 custom field type with the MailPoet custom field type
- *
- * @param string $mp2Type MP2 custom field type
- * @return string MP3 custom field type
- */
- private function mapCustomFieldType($mp2Type) {
- $type = '';
- switch ($mp2Type) {
- case 'input':
- $type = 'text';
- break;
- case 'list':
- $type = 'segment';
- break;
- default:
- $type = $mp2Type;
- }
- return $type;
- }
- /**
- * Map the MailPoet 2 custom field settings with the MailPoet custom field params
- *
- * @param string $name Parameter name
- * @param array $params MP2 parameters
- * @return array serialized MP3 custom field params
- */
- private function mapCustomFieldParams($name, $params) {
- if (!isset($params['label'])) {
- $params['label'] = $name;
- }
- if (isset($params['required'])) {
- $params['required'] = (bool)$params['required'];
- }
- if (isset($params['validate'])) {
- $params['validate'] = $this->mapCustomFieldValidateValue($params['validate']);
- }
- if (isset($params['date_order'])) { // Convert the date_order field
- switch ($params['date_type']) {
- case 'year_month':
- if (preg_match('/y$/i', $params['date_order'])) {
- $params['date_format'] = 'MM/YYYY';
- } else {
- $params['date_format'] = 'YYYY/MM';
- }
- break;
- case 'month';
- $params['date_format'] = 'MM';
- break;
- case 'year';
- $params['date_format'] = 'YYYY';
- break;
- default:
- $params['date_format'] = mb_strtoupper($params['date_order'], 'UTF-8');
- }
- unset($params['date_order']);
- }
- return $params;
- }
- /**
- * Map the validate value
- *
- * @param string $mp2Value MP2 value
- * @return string MP3 value
- */
- private function mapCustomFieldValidateValue($mp2Value) {
- $value = '';
- switch ($mp2Value) {
- case 'onlyLetterSp':
- case 'onlyLetterNumber':
- $value = 'alphanum';
- break;
- case 'onlyNumberSp':
- $value = 'number';
- break;
- case 'phone':
- $value = 'phone';
- break;
- }
- return $value;
- }
- /**
- * Import the subscribers
- *
- */
- private function importSubscribers() {
- $importedSubscribersCount = 0;
- if ($this->importStopped()) {
- return;
- }
- $this->log(__("Importing subscribers...", 'mailpoet'));
- $this->wpUsersSegment = Segment::getWPSegment();
- do {
- if ($this->importStopped()) {
- break;
- }
- $users = $this->getUsers(self::CHUNK_SIZE);
- $usersCount = count($users);
- if (is_array($users)) {
- foreach ($users as $user) {
- $subscriber = $this->importSubscriber($user);
- if (!empty($subscriber)) {
- $importedSubscribersCount++;
- $this->importSubscriberSegments($subscriber, $user['user_id']);
- $this->importSubscriberCustomFields($subscriber, $user);
- }
- }
- }
- $this->progressbar->incrementCurrentCount($usersCount);
- } while (($users != null) && ($usersCount > 0));
- $this->log(sprintf(_n("%d subscriber imported", "%d subscribers imported", $importedSubscribersCount, 'mailpoet'), $importedSubscribersCount));
- }
- /**
- * Get the Mailpoet 2 users
- *
- * @global object $wpdb
- * @param int $limit Number of users max
- * @return array Users
- */
- private function getUsers($limit) {
- global $wpdb;
- $lastId = intval($this->settings->get('last_imported_user_id', 0));
- $table = $this->mp2UserTable;
- $sql = "
- SELECT u.*
- FROM `$table` u
- WHERE u.user_id > '$lastId'
- ORDER BY u.user_id
- LIMIT $limit
- ";
- $users = $wpdb->get_results($sql, ARRAY_A);
- return $users;
- }
- /**
- * Import a subscriber
- *
- * @param array $userData User data
- * @return Subscriber
- */
- private function importSubscriber($userData) {
- $datetime = new \MailPoet\WP\DateTime();
- $subscriber = Subscriber::createOrUpdate([
- 'wp_user_id' => !empty($userData['wpuser_id']) ? $userData['wpuser_id'] : null,
- 'email' => $userData['email'],
- 'first_name' => $userData['firstname'],
- 'last_name' => $userData['lastname'],
- 'status' => $this->mapUserStatus($userData['status']),
- 'created_at' => $datetime->formatTime($userData['created_at'], \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT),
- 'subscribed_ip' => !empty($userData['ip']) ? $userData['ip'] : null,
- 'confirmed_ip' => !empty($userData['confirmed_ip']) ? $userData['confirmed_ip'] : null,
- 'confirmed_at' => !empty($userData['confirmed_at']) ? $datetime->formatTime($userData['confirmed_at'], \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT) : null,
- ]);
- $this->settings->set('last_imported_user_id', $userData['user_id']);
- if (!empty($subscriber)) {
- // Map the subscriber with its old ID
- $mapping = new MappingToExternalEntities();
- $mapping->create([
- 'old_id' => $userData['user_id'],
- 'type' => 'subscribers',
- 'new_id' => $subscriber->id,
- 'created_at' => $datetime->formatTime(time(), \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT),
- ]);
- }
- return $subscriber;
- }
- /**
- * Map the MailPoet 2 user status with MailPoet 3
- *
- * @param int $mp2UserStatus MP2 user status
- * @return string MP3 user status
- */
- private function mapUserStatus($mp2UserStatus) {
- switch ($mp2UserStatus) {
- case 1:
- $status = 'subscribed';
- break;
- case -1:
- $status = 'unsubscribed';
- break;
- case 0:
- default:
- //if MP2 double-optin is disabled, we change "unconfirmed" status in MP2 to "confirmed" status in MP3.
- if (!$this->doubleOptinEnabled) {
- $status = 'subscribed';
- } else {
- $status = 'unconfirmed';
- }
- }
- return $status;
- }
- /**
- * Import the segments for a subscriber
- *
- * @param Subscriber $subscriber MP3 subscriber
- * @param int $userId MP2 user ID
- */
- private function importSubscriberSegments($subscriber, $userId) {
- $userLists = $this->getUserLists($userId);
- foreach ($userLists as $userList) {
- $this->importSubscriberSegment($subscriber->id, $userList);
- }
- }
- /**
- * Get the lists for a user
- *
- * @global object $wpdb
- * @param int $userId User ID
- * @return array Users Lists
- */
- private function getUserLists($userId) {
- global $wpdb;
- $table = $this->mp2UserListTable;
- $sql = "
- SELECT ul.list_id, ul.sub_date, ul.unsub_date
- FROM `$table` ul
- WHERE ul.user_id = '$userId'
- ";
- $userLists = $wpdb->get_results($sql, ARRAY_A);
- return $userLists;
- }
- /**
- * Import a subscriber segment
- *
- * @param int $subscriberId
- * @param array $userList
- * @return SubscriberSegment|null
- */
- private function importSubscriberSegment($subscriberId, $userList) {
- $subscriberSegment = null;
- $datetime = new \MailPoet\WP\DateTime();
- if (isset($this->segmentsMapping[$userList['list_id']])) {
- $segmentId = $this->segmentsMapping[$userList['list_id']];
- $status = (($segmentId == $this->wpUsersSegment->id) || empty($userList['unsub_date'])) ? 'subscribed' : 'unsubscribed'; // the users belonging to the wp_users segment are always subscribed
- $data = [
- 'subscriber_id' => $subscriberId,
- 'segment_id' => $segmentId,
- 'status' => $status,
- 'created_at' => $datetime->formatTime($userList['sub_date'], \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT),
- ];
- $data['updated_at'] = !empty($userList['unsub_date']) ? $datetime->formatTime($userList['unsub_date'], \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT) : $data['created_at'];
- $subscriberSegment = new SubscriberSegment();
- $subscriberSegment->createOrUpdate($data);
- }
- return $subscriberSegment;
- }
- /**
- * Import the custom fields values for a subscriber
- *
- * @param Subscriber $subscriber MP3 subscriber
- * @param array $user MP2 user
- */
- private function importSubscriberCustomFields($subscriber, $user) {
- $importedCustomFields = $this->getImportedCustomFields();
- foreach ($importedCustomFields as $customField) {
- $customFieldColumn = 'cf_' . $customField['id'];
- $this->importSubscriberCustomField($subscriber->id, $customField, $user[$customFieldColumn]);
- }
- }
- /**
- * Get the imported custom fields
- *
- * @global object $wpdb
- * @return array Imported custom fields
- *
- */
- private function getImportedCustomFields() {
- global $wpdb;
- $table = MP_CUSTOM_FIELDS_TABLE;
- $sql = "
- SELECT cf.id, cf.name, cf.type
- FROM `$table` cf
- ";
- $customFields = $wpdb->get_results($sql, ARRAY_A);
- return $customFields;
- }
- /**
- * Import a subscriber custom field
- *
- * @param int $subscriberId Subscriber ID
- * @param array $customField Custom field
- * @param string $customFieldValue Custom field value
- * @return SubscriberCustomField
- */
- private function importSubscriberCustomField($subscriberId, $customField, $customFieldValue) {
- if ($customField['type'] == 'date') {
- $datetime = new \MailPoet\WP\DateTime();
- $value = $datetime->formatTime($customFieldValue, \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT); // Convert the date field
- } else {
- $value = $customFieldValue;
- }
- $data = [
- 'subscriber_id' => $subscriberId,
- 'custom_field_id' => $customField['id'],
- 'value' => isset($value) ? $value : '',
- ];
- $subscriberCustomField = new SubscriberCustomField();
- $subscriberCustomField->createOrUpdate($data);
- return $subscriberCustomField;
- }
- /**
- * Get the mapping between the MP2 and the imported MP3 IDs
- *
- * @param string $model Model (segment,...)
- * @return array Mapping
- */
- public function getImportedMapping($model) {
- $mappings = [];
- $mappingRelations = MappingToExternalEntities::where('type', $model)->findArray();
- foreach ($mappingRelations as $relation) {
- $mappings[$relation['old_id']] = $relation['new_id'];
- }
- return $mappings;
- }
- /**
- * Import the forms
- *
- */
- private function importForms() {
- $importedFormsCount = 0;
- if ($this->importStopped()) {
- return;
- }
- $this->log(__("Importing forms...", 'mailpoet'));
- do {
- if ($this->importStopped()) {
- break;
- }
- $forms = $this->getForms(self::CHUNK_SIZE);
- $formsCount = count($forms);
- if (is_array($forms)) {
- foreach ($forms as $form) {
- $this->importForm($form);
- $importedFormsCount++;
- }
- }
- $this->formsRepository->flush();
- $this->progressbar->incrementCurrentCount($formsCount);
- } while (($forms != null) && ($formsCount > 0));
- $this->log(sprintf(_n("%d form imported", "%d forms imported", $importedFormsCount, 'mailpoet'), $importedFormsCount));
- }
- /**
- * Get the Mailpoet 2 forms
- *
- * @global object $wpdb
- * @param int $limit Number of forms max
- * @return array Forms
- */
- private function getForms($limit) {
- global $wpdb;
- $lastId = intval($this->settings->get('last_imported_form_id', 0));
- $table = $this->mp2FormTable;
- $sql = "
- SELECT f.*
- FROM `$table` f
- WHERE f.form_id > '$lastId'
- ORDER BY f.form_id
- LIMIT $limit
- ";
- $forms = $wpdb->get_results($sql, ARRAY_A);
- return $forms;
- }
- /**
- * Import a form
- *
- * @param array $formData Form data
- */
- private function importForm($formData) {
- $serializedData = base64_decode($formData['data']);
- $data = unserialize($serializedData);
- $settings = $data['settings'];
- $body = $data['body'];
- $segments = $this->getMappedSegmentIds($settings['lists']);
- $mp3FormSettings = [
- 'on_success' => $settings['on_success'],
- 'success_message' => $settings['success_message'],
- 'segments_selected_by' => $settings['lists_selected_by'],
- 'segments' => $segments,
- ];
- $mp3FormBody = [];
- foreach ($body as $field) {
- $type = $this->mapCustomFieldType($field['type']);
- if ($type == 'segment') {
- $fieldId = 'segments';
- } else {
- switch ($field['field']) {
- case 'firstname':
- $fieldId = 'first_name';
- break;
- case 'lastname':
- $fieldId = 'last_name';
- break;
- default:
- $fieldId = $field['field'];
- }
- }
- $fieldId = preg_replace('/^cf_(\d+)$/', '$1', $fieldId);
- $params = $this->mapCustomFieldParams($field['name'], $field['params']);
- if (isset($params['text'])) {
- $params['text'] = $this->replaceMP2Shortcodes(html_entity_decode($params['text']));
- }
- if (isset($params['values'])) {
- $params['values'] = $this->replaceListIds($params['values']);
- }
- $mp3FormBody[] = [
- 'type' => $type,
- 'name' => $field['name'],
- 'id' => $fieldId,
- 'unique' => !in_array($field['type'], ['html', 'divider', 'email', 'submit']) ? "1" : "0",
- 'static' => in_array($fieldId, ['email', 'submit']) ? "1" : "0",
- 'params' => $params,
- 'position' => isset($field['position']) ? $field['position'] : '',
- ];
- }
- $form = new FormEntity($formData['name']);
- $form->setBody($mp3FormBody);
- $form->setSettings($mp3FormSettings);
- $this->formsRepository->persist($form);
- $this->settings->set('last_imported_form_id', $formData['form_id']);
- }
- /**
- * Get the MP3 segments IDs of the MP2 lists IDs
- *
- * @param array $mp2ListIds
- */
- private function getMappedSegmentIds($mp2ListIds) {
- $mp3SegmentIds = [];
- foreach ($mp2ListIds as $listId) {
- if (isset($this->segmentsMapping[$listId])) {
- $mp3SegmentIds[] = $this->segmentsMapping[$listId];
- }
- }
- return $mp3SegmentIds;
- }
- /**
- * Replace the MP2 shortcodes used in the textarea fields
- *
- * @param string $text Text
- * @return string|null Text
- */
- private function replaceMP2Shortcodes($text) {
- $text = str_replace('[total_subscribers]', '[mailpoet_subscribers_count]', $text);
- $text = preg_replace_callback(
- '/\[wysija_subscribers_count list_id="(.*)" \]/',
- function ($matches) {
- return $this->replaceMP2ShortcodesCallback($matches);
- },
- $text
- );
- return $text;
- }
- /**
- * Callback function for MP2 shortcodes replacement
- *
- * @param array $matches PREG matches
- * @return string Replacement
- */
- private function replaceMP2ShortcodesCallback($matches) {
- if (!empty($matches)) {
- $mp2Lists = explode(',', $matches[1]);
- $segments = $this->getMappedSegmentIds($mp2Lists);
- $segmentsIds = implode(',', $segments);
- return '[mailpoet_subscribers_count segments=' . $segmentsIds . ']';
- }
- return '';
- }
- /**
- * Replace the MP2 list IDs by MP3 segment IDs
- *
- * @param array $values Field values
- * @return array Field values
- */
- private function replaceListIds($values) {
- $mp3Values = [];
- foreach ($values as $value) {
- $mp3Value = [];
- foreach ($value as $item => $itemValue) {
- if (($item == 'list_id') && isset($this->segmentsMapping[$itemValue])) {
- $segmentId = $this->segmentsMapping[$itemValue];
- $mp3Value['id'] = $segmentId;
- $segment = Segment::findOne($segmentId);
- if ($segment instanceof Segment) {
- $mp3Value['name'] = $segment->get('name');
- }
- } else {
- $mp3Value[$item] = $itemValue;
- }
- }
- if (!empty($mp3Value)) {
- $mp3Values[] = $mp3Value;
- }
- }
- return $mp3Values;
- }
- /**
- * Import the settings
- *
- */
- private function importSettings() {
- $encodedOptions = WPFunctions::get()->getOption('wysija');
- $options = unserialize(base64_decode($encodedOptions));
- // Sender
- $sender = $this->settings->get('sender');
- $sender['name'] = isset($options['from_name']) ? $options['from_name'] : '';
- $sender['address'] = isset($options['from_email']) ? $options['from_email'] : '';
- $this->settings->set('sender', $sender);
- // Reply To
- $replyTo = $this->settings->get('reply_to');
- $replyTo['name'] = isset($options['replyto_name']) ? $options['replyto_name'] : '';
- $replyTo['address'] = isset($options['replyto_email']) ? $options['replyto_email'] : '';
- $this->settings->set('reply_to', $replyTo);
- // Bounce
- $bounce = $this->settings->get('bounce');
- $bounce['address'] = isset($options['bounce_email']) && WPFunctions::get()->isEmail($options['bounce_email']) ? $options['bounce_email'] : '';
- $this->settings->set('bounce', $bounce);
- // Notification
- $notification = $this->settings->get('notification');
- $notification['address'] = isset($options['emails_notified']) ? $options['emails_notified'] : '';
- $this->settings->set('notification', $notification);
- // Subscribe
- $subscribe = $this->settings->get('subscribe');
- $subscribe['on_comment']['enabled'] = isset($options['commentform']) ? $options['commentform'] : '0';
- $subscribe['on_comment']['label'] = isset($options['commentform_linkname']) ? $options['commentform_linkname'] : '';
- $subscribe['on_comment']['segments'] = isset($options['commentform_lists']) ? $this->getMappedSegmentIds($options['commentform_lists']) : [];
- $subscribe['on_register']['enabled'] = isset($options['registerform']) ? $options['registerform'] : '0';
- $subscribe['on_register']['label'] = isset($options['registerform_linkname']) ? $options['registerform_linkname'] : '';
- $subscribe['on_register']['segments'] = isset($options['registerform_lists']) ? $this->getMappedSegmentIds($options['registerform_lists']) : [];
- $this->settings->set('subscribe', $subscribe);
- // Subscription
- $subscription = $this->settings->get('subscription');
- $subscription['pages']['unsubscribe'] = isset($options['unsubscribe_page']) ? $options['unsubscribe_page'] : '';
- $subscription['pages']['confirmation'] = isset($options['confirmation_page']) ? $options['confirmation_page'] : '';
- $subscription['pages']['manage'] = isset($options['subscriptions_page']) ? $options['subscriptions_page'] : '';
- $subscription['segments'] = isset($options['manage_subscriptions_lists']) ? $this->getMappedSegmentIds($options['manage_subscriptions_lists']) : [];
- $this->settings->set('subscription', $subscription);
- // Confirmation email
- $signupConfirmation = $this->settings->get('signup_confirmation');
- $signupConfirmation['enabled'] = isset($options['confirm_dbleoptin']) && ($options['confirm_dbleoptin'] == 0) ? 0 : 1;
- if (isset($options['confirm_email_id'])) {
- $confirmEmailId = $options['confirm_email_id'];
- $confirmEmail = $this->getEmail($confirmEmailId);
- if (!empty($confirmEmail)) {
- $signupConfirmation['subject'] = isset($confirmEmail['subject']) ? $confirmEmail['subject'] : '';
- $signupConfirmation['body'] = isset($confirmEmail['body']) ? $confirmEmail['body'] : '';
- }
- }
- $this->settings->set('signup_confirmation', $signupConfirmation);
- // Analytics
- $analytics = $this->settings->get('analytics');
- $analytics['enabled'] = isset($options['analytics']) ? $options['analytics'] : '';
- $this->settings->set('analytics', $analytics);
- // MTA
- $mtaGroup = isset($options['sending_method']) && ($options['sending_method'] == 'smtp') ? 'smtp' : 'website';
- $this->settings->set('mta_group', $mtaGroup);
- $mta = $this->settings->get('mta');
- $mta['method'] = (isset($options['smtp_host']) && ($options['smtp_host'] == 'smtp.sendgrid.net')) ? 'SendGrid' : (isset($options['sending_method']) && ($options['sending_method'] == 'smtp') ? 'SMTP' : 'PHPMail');
- $sendingEmailsNumber = isset($options['sending_emails_number']) ? $options['sending_emails_number'] : '';
- $sendingEmailsEach = isset($options['sending_emails_each']) ? $options['sending_emails_each'] : '';
- $mta['frequency']['emails'] = $this->mapFrequencyEmails($sendingEmailsNumber, $sendingEmailsEach);
- $mta['frequency']['interval'] = $this->mapFrequencyInterval($sendingEmailsEach);
- $mta['host'] = isset($options['smtp_host']) ? $options['smtp_host'] : '';
- $mta['port'] = isset($options['smtp_port']) ? $options['smtp_port'] : '';
- $mta['login'] = isset($options['smtp_login']) ? $options['smtp_login'] : '';
- $mta['password'] = isset($options['smtp_password']) ? $options['smtp_password'] : '';
- $mta['encryption'] = isset($options['smtp_secure']) ? $options['smtp_secure'] : '';
- $mta['authentication'] = !isset($options['smtp_auth']) ? '1' : '-1';
- $this->settings->set('mta', $mta);
- // SMTP Provider
- if ($mta['method'] == 'SendGrid') {
- $this->settings->set('smtp_provider', 'SendGrid');
- }
- // Installation date
- if (isset($options['installed_time'])) {
- $datetime = new \MailPoet\WP\DateTime();
- $installedAt = $datetime->formatTime($options['installed_time'], \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT);
- $this->settings->set('installed_at', $installedAt);
- }
- $this->log(__("Settings imported", 'mailpoet'));
- }
- /**
- * Get an email
- *
- * @global object $wpdb
- * @param int $emailId
- * @return array Email
- */
- private function getEmail($emailId) {
- global $wpdb;
- $email = [];
- $table = $this->mp2EmailTable;
- $sql = "
- SELECT e.*
- FROM `$table` e
- WHERE e.email_id = '$emailId'
- ";
- $email = $wpdb->get_row($sql, ARRAY_A);
- return $email;
- }
- /**
- * Map the Email frequency interval
- *
- * @param string $intervalStr Interval
- * @return string Interval
- */
- private function mapFrequencyInterval($intervalStr) {
- switch ($intervalStr) {
- case 'one_min':
- $interval = 1;
- break;
- case 'two_min':
- $interval = 2;
- break;
- case 'five_min':
- $interval = 5;
- break;
- case 'ten_min':
- $interval = 10;
- break;
- default:
- $interval = 15;
- }
- return (string)$interval;
- }
- /**
- * Map the Email frequency number
- *
- * @param int $emailsNumber Emails number
- * @param string $intervalStr Interval
- * @return int Emails number
- */
- private function mapFrequencyEmails($emailsNumber, $intervalStr) {
- if (empty($emailsNumber)) {
- $emailsNumber = 70;
- } else {
- switch ($intervalStr) {
- case 'thirty_min':
- $emailsNumber /= 2;
- break;
- case 'hourly':
- case '':
- $emailsNumber /= 4;
- break;
- case 'two_hours':
- $emailsNumber /= 8;
- break;
- }
- $emailsNumber = (int)round($emailsNumber);
- }
- return $emailsNumber;
- }
- }
|