472 lines
13 KiB
PHP
472 lines
13 KiB
PHP
<?php
|
|
namespace MailPoet\Config;
|
|
|
|
use MailPoet\Cron\CronTrigger;
|
|
use MailPoet\Mailer\MailerLog;
|
|
use MailPoet\Models\Newsletter;
|
|
use MailPoet\Models\Segment;
|
|
use MailPoet\Models\SendingQueue;
|
|
use MailPoet\Segments\WP;
|
|
use MailPoet\Models\Setting;
|
|
use MailPoet\Settings\Pages;
|
|
use MailPoet\Util\Helpers;
|
|
|
|
if(!defined('ABSPATH')) exit;
|
|
|
|
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
|
|
|
class Populator {
|
|
public $prefix;
|
|
public $models;
|
|
public $templates;
|
|
const TEMPLATES_NAMESPACE = '\MailPoet\Config\PopulatorData\Templates\\';
|
|
|
|
function __construct() {
|
|
$this->prefix = Env::$db_prefix;
|
|
$this->models = array(
|
|
'newsletter_option_fields',
|
|
'newsletter_templates',
|
|
);
|
|
$this->templates = array(
|
|
'NewsletterBlank1Column',
|
|
'NewsletterBlank12Column',
|
|
'NewsletterBlank121Column',
|
|
'NewsletterBlank13Column',
|
|
'PostNotificationsBlank1Column',
|
|
'WelcomeBlank1Column',
|
|
'WelcomeBlank12Column',
|
|
'SimpleText',
|
|
'BurgerJoint',
|
|
'AppWelcome',
|
|
'WorldCup',
|
|
'FoodBox',
|
|
'Discount',
|
|
'KickOff',
|
|
'TakeAHike',
|
|
'FestivalEvent',
|
|
'PieceOfCake',
|
|
'Shoes',
|
|
'ScienceWeekly',
|
|
'ChocolateStore',
|
|
'Faith',
|
|
'TravelNomads',
|
|
'CoffeeShop',
|
|
'NewsDay',
|
|
'YogaStudio',
|
|
);
|
|
}
|
|
|
|
function up() {
|
|
$this->convertExistingDataToUTF8();
|
|
$this->migrateSimpleScheduledTasks();
|
|
$this->populateNewsletterSentAtField();
|
|
|
|
array_map(array($this, 'populate'), $this->models);
|
|
|
|
$this->createDefaultSegments();
|
|
$this->createDefaultSettings();
|
|
$this->createMailPoetPage();
|
|
}
|
|
|
|
private function createMailPoetPage() {
|
|
$pages = get_posts(array(
|
|
'posts_per_page' => 1,
|
|
'orderby' => 'date',
|
|
'order' => 'DESC',
|
|
'post_type' => 'mailpoet_page'
|
|
));
|
|
|
|
$page = null;
|
|
if(!empty($pages)) {
|
|
$page = array_shift($pages);
|
|
if(strpos($page->post_content, '[mailpoet_page]') === false) {
|
|
$page = null;
|
|
}
|
|
}
|
|
|
|
if($page === null) {
|
|
$mailpoet_page_id = Pages::createMailPoetPage();
|
|
} else {
|
|
$mailpoet_page_id = (int)$page->ID;
|
|
}
|
|
|
|
$subscription = Setting::getValue('subscription.pages', array());
|
|
if(empty($subscription)) {
|
|
Setting::setValue('subscription.pages', array(
|
|
'unsubscribe' => $mailpoet_page_id,
|
|
'manage' => $mailpoet_page_id,
|
|
'confirmation' => $mailpoet_page_id
|
|
));
|
|
}
|
|
}
|
|
|
|
private function createDefaultSettings() {
|
|
$current_user = wp_get_current_user();
|
|
|
|
// set cron trigger option to default method
|
|
if(!Setting::getValue(CronTrigger::SETTING_NAME)) {
|
|
Setting::setValue(CronTrigger::SETTING_NAME, array(
|
|
'method' => CronTrigger::DEFAULT_METHOD
|
|
));
|
|
}
|
|
|
|
// set default sender info based on current user
|
|
$sender = array(
|
|
'name' => $current_user->display_name,
|
|
'address' => $current_user->user_email
|
|
);
|
|
|
|
// set default from name & address
|
|
if(!Setting::getValue('sender')) {
|
|
Setting::setValue('sender', $sender);
|
|
}
|
|
|
|
// enable signup confirmation by default
|
|
if(!Setting::getValue('signup_confirmation')) {
|
|
Setting::setValue('signup_confirmation', array(
|
|
'enabled' => true,
|
|
'from' => array(
|
|
'name' => get_option('blogname'),
|
|
'address' => get_option('admin_email')
|
|
),
|
|
'reply_to' => $sender
|
|
));
|
|
}
|
|
|
|
// set installation date
|
|
if(!Setting::getValue('installed_at')) {
|
|
Setting::setValue('installed_at', date("Y-m-d H:i:s"));
|
|
}
|
|
|
|
// reset mailer log
|
|
MailerLog::resetMailerLog();
|
|
}
|
|
|
|
private function createDefaultSegments() {
|
|
// WP Users segment
|
|
$wp_segment = Segment::getWPSegment();
|
|
|
|
// Synchronize WP Users
|
|
WP::synchronizeUsers();
|
|
|
|
// Default segment
|
|
if(Segment::where('type', 'default')->count() === 0) {
|
|
$default_segment = Segment::create();
|
|
$default_segment->hydrate(array(
|
|
'name' => __('My First List', 'mailpoet'),
|
|
'description' =>
|
|
__('This list is automatically created when you install MailPoet.', 'mailpoet')
|
|
));
|
|
$default_segment->save();
|
|
}
|
|
}
|
|
|
|
private function newsletterOptionFields() {
|
|
$option_fields = array(
|
|
array(
|
|
'name' => 'isScheduled',
|
|
'newsletter_type' => 'standard',
|
|
),
|
|
array(
|
|
'name' => 'scheduledAt',
|
|
'newsletter_type' => 'standard',
|
|
),
|
|
array(
|
|
'name' => 'event',
|
|
'newsletter_type' => 'welcome',
|
|
),
|
|
array(
|
|
'name' => 'segment',
|
|
'newsletter_type' => 'welcome',
|
|
),
|
|
array(
|
|
'name' => 'role',
|
|
'newsletter_type' => 'welcome',
|
|
),
|
|
array(
|
|
'name' => 'afterTimeNumber',
|
|
'newsletter_type' => 'welcome',
|
|
),
|
|
array(
|
|
'name' => 'afterTimeType',
|
|
'newsletter_type' => 'welcome',
|
|
),
|
|
|
|
array(
|
|
'name' => 'intervalType',
|
|
'newsletter_type' => 'notification',
|
|
),
|
|
array(
|
|
'name' => 'timeOfDay',
|
|
'newsletter_type' => 'notification',
|
|
),
|
|
array(
|
|
'name' => 'weekDay',
|
|
'newsletter_type' => 'notification',
|
|
),
|
|
array(
|
|
'name' => 'monthDay',
|
|
'newsletter_type' => 'notification',
|
|
),
|
|
array(
|
|
'name' => 'nthWeekDay',
|
|
'newsletter_type' => 'notification',
|
|
),
|
|
array(
|
|
'name' => 'schedule',
|
|
'newsletter_type' => 'notification',
|
|
)
|
|
);
|
|
|
|
return array(
|
|
'rows' => $option_fields,
|
|
'identification_columns' => array(
|
|
'name',
|
|
'newsletter_type'
|
|
)
|
|
);
|
|
}
|
|
|
|
private function newsletterTemplates() {
|
|
$templates = array();
|
|
foreach($this->templates as $template) {
|
|
$template = self::TEMPLATES_NAMESPACE . $template;
|
|
$template = new $template(Env::$assets_url);
|
|
$templates[] = $template->get();
|
|
}
|
|
return array(
|
|
'rows' => $templates,
|
|
'identification_columns' => array(
|
|
'name'
|
|
),
|
|
'remove_duplicates' => true
|
|
);
|
|
}
|
|
|
|
private function populate($model) {
|
|
$modelMethod = Helpers::underscoreToCamelCase($model);
|
|
$table = $this->prefix . $model;
|
|
$data_descriptor = $this->$modelMethod();
|
|
$rows = $data_descriptor['rows'];
|
|
$identification_columns = array_fill_keys(
|
|
$data_descriptor['identification_columns'],
|
|
''
|
|
);
|
|
$remove_duplicates =
|
|
isset($data_descriptor['remove_duplicates']) && $data_descriptor['remove_duplicates'];
|
|
|
|
foreach($rows as $row) {
|
|
$existence_comparison_fields = array_intersect_key(
|
|
$row,
|
|
$identification_columns
|
|
);
|
|
|
|
if(!$this->rowExists($table, $existence_comparison_fields)) {
|
|
$this->insertRow($table, $row);
|
|
} else {
|
|
if($remove_duplicates) {
|
|
$this->removeDuplicates($table, $row, $existence_comparison_fields);
|
|
}
|
|
$this->updateRow($table, $row, $existence_comparison_fields);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function rowExists($table, $columns) {
|
|
global $wpdb;
|
|
|
|
$conditions = array_map(function($key) use ($columns) {
|
|
return $key . '=%s';
|
|
}, array_keys($columns));
|
|
|
|
return $wpdb->get_var($wpdb->prepare(
|
|
"SELECT COUNT(*) FROM $table WHERE " . implode(' AND ', $conditions),
|
|
array_values($columns)
|
|
)) > 0;
|
|
}
|
|
|
|
private function insertRow($table, $row) {
|
|
global $wpdb;
|
|
|
|
return $wpdb->insert(
|
|
$table,
|
|
$row
|
|
);
|
|
}
|
|
|
|
private function updateRow($table, $row, $where) {
|
|
global $wpdb;
|
|
|
|
return $wpdb->update(
|
|
$table,
|
|
$row,
|
|
$where
|
|
);
|
|
}
|
|
|
|
private function removeDuplicates($table, $row, $where) {
|
|
global $wpdb;
|
|
|
|
$conditions = array('1=1');
|
|
$values = array();
|
|
foreach($where as $field => $value) {
|
|
$conditions[] = "`t1`.`$field` = `t2`.`$field`";
|
|
$conditions[] = "`t1`.`$field` = %s";
|
|
$values[] = $value;
|
|
}
|
|
|
|
$conditions = implode(' AND ', $conditions);
|
|
|
|
$sql = "DELETE FROM `$table` WHERE $conditions";
|
|
return $wpdb->query(
|
|
$wpdb->prepare(
|
|
"DELETE t1 FROM $table t1, $table t2 WHERE t1.id < t2.id AND $conditions",
|
|
$values
|
|
)
|
|
);
|
|
}
|
|
|
|
/*
|
|
* MailPoet versions 3.0.0-beta.32 and older used the default MySQL connection
|
|
* character set, which usually defaults to latin1, but stored UTF-8 data.
|
|
* This method converts existing incorrectly stored data that uses the
|
|
* default character set, into a new character set that is used by WordPress.
|
|
*
|
|
* TODO: remove in final release
|
|
*/
|
|
function convertExistingDataToUTF8() {
|
|
global $wpdb;
|
|
|
|
if(!version_compare(get_option('mailpoet_db_version'), '3.0.0-beta.32', '<=')) {
|
|
// Data conversion should only be performed only once, when migrating from
|
|
// older version
|
|
return false;
|
|
}
|
|
|
|
$source_charset = $wpdb->get_var('SELECT @@GLOBAL.character_set_connection');
|
|
$destination_charset = $wpdb->get_var('SELECT @@SESSION.character_set_connection');
|
|
|
|
if($source_charset === $destination_charset) return;
|
|
// UTF8MB4 is a superset of UTF8, thus a conversion is not necessary
|
|
if(substr($source_charset, 0, 4) === 'utf8' && $destination_charset === 'utf8mb4') return;
|
|
|
|
$tables = array(
|
|
'segments' => array('name', 'type', 'description'),
|
|
'settings' => array('name', 'value'),
|
|
'custom_fields' => array('name', 'type', 'params'),
|
|
'sending_queues' => array('type', 'newsletter_rendered_body', 'newsletter_rendered_subject', 'subscribers', 'status'),
|
|
'subscribers' => array('first_name', 'last_name', 'email', 'status', 'subscribed_ip', 'confirmed_ip', 'unconfirmed_data'),
|
|
'subscriber_segment' => array('status'),
|
|
'subscriber_custom_field' => array('value'),
|
|
'newsletters' => array('hash', 'subject', 'type', 'sender_address', 'sender_name', 'status', 'reply_to_address', 'reply_to_name', 'preheader', 'body'),
|
|
'newsletter_templates' => array('name', 'description', 'body', 'thumbnail'),
|
|
'newsletter_option_fields' => array('name', 'newsletter_type'),
|
|
'newsletter_option' => array('value'),
|
|
'newsletter_links' => array('url', 'hash'),
|
|
'forms' => array('name', 'body', 'settings', 'styles'),
|
|
);
|
|
|
|
foreach($tables as $table => $columns) {
|
|
$query = "UPDATE `%s` SET %s WHERE %s";
|
|
$columns_query = array();
|
|
$where_query = array();
|
|
foreach($columns as $column) {
|
|
$columns_query[] = sprintf(
|
|
'`%1$s` = @%1$s',
|
|
$column
|
|
);
|
|
$where_query[] = sprintf(
|
|
'char_length(%1$s) = length(@%1$s := convert(binary convert(%1$s using %2$s) using %3$s))',
|
|
$column,
|
|
$source_charset,
|
|
$destination_charset
|
|
);
|
|
}
|
|
$wpdb->query(sprintf(
|
|
$query,
|
|
$this->prefix . $table,
|
|
implode(', ', $columns_query),
|
|
implode(' AND ', $where_query)
|
|
));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* This migrates simple scheduled tasks from sending queues table to scheduled tasks table
|
|
*
|
|
* TODO: remove in final release
|
|
*/
|
|
public function migrateSimpleScheduledTasks() {
|
|
global $wpdb;
|
|
|
|
// perform once for versions below 3.0.0-beta.36.2.1
|
|
if(version_compare(get_option('mailpoet_db_version'), '3.0.0-beta.36.2.1', '>=')) {
|
|
return false;
|
|
}
|
|
|
|
$column_list = array(
|
|
'id',
|
|
'type',
|
|
'subscribers',
|
|
'status',
|
|
'priority',
|
|
'count_total',
|
|
'count_processed',
|
|
'count_to_process',
|
|
'scheduled_at',
|
|
'processed_at',
|
|
'created_at',
|
|
'updated_at',
|
|
'deleted_at'
|
|
);
|
|
|
|
$task_types = array(
|
|
'bounce',
|
|
'sending_service_key_check',
|
|
'premium_key_check'
|
|
);
|
|
|
|
$wpdb->query(sprintf(
|
|
'INSERT IGNORE INTO %s SELECT %s FROM %s WHERE %s',
|
|
MP_SCHEDULED_TASKS_TABLE,
|
|
'`' . join('`, `', $column_list) . '`',
|
|
MP_SENDING_QUEUES_TABLE,
|
|
'`type` IN("' . join('" , "', $task_types) . '")'
|
|
));
|
|
|
|
$wpdb->query(sprintf(
|
|
'DELETE FROM %s WHERE %s',
|
|
MP_SENDING_QUEUES_TABLE,
|
|
'`type` IN("' . join('" , "', $task_types) . '")'
|
|
));
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* This populates existing newsletters' sent_at field with processed_at field data from
|
|
* corresponding sending queue.
|
|
*
|
|
* TODO: remove in final release
|
|
*/
|
|
function populateNewsletterSentAtField() {
|
|
global $wpdb;
|
|
|
|
// perform once for versions below 3.0.0-beta.36.2.1
|
|
if(version_compare(get_option('mailpoet_db_version'), '3.0.0-beta.36.2.1', '>=')) {
|
|
return false;
|
|
}
|
|
|
|
$query = "UPDATE `%s` newsletters JOIN `%s` queues ON newsletters.id = queues.newsletter_id SET newsletters.sent_at = queues.processed_at";
|
|
$wpdb->query(sprintf(
|
|
$query,
|
|
Newsletter::$_table,
|
|
SendingQueue::$_table
|
|
));
|
|
|
|
return true;
|
|
}
|
|
}
|