Optimize populating newsletter option fields
This commit is contained in:
@@ -78,9 +78,7 @@ class Populator {
|
|||||||
$this->wpSegment = $wpSegment;
|
$this->wpSegment = $wpSegment;
|
||||||
$this->referralDetector = $referralDetector;
|
$this->referralDetector = $referralDetector;
|
||||||
$this->prefix = Env::$dbPrefix;
|
$this->prefix = Env::$dbPrefix;
|
||||||
$this->models = [
|
$this->models = [];
|
||||||
'newsletter_option_fields',
|
|
||||||
];
|
|
||||||
$this->templates = [
|
$this->templates = [
|
||||||
'WelcomeBlank1Column',
|
'WelcomeBlank1Column',
|
||||||
'WelcomeBlank12Column',
|
'WelcomeBlank12Column',
|
||||||
@@ -169,6 +167,7 @@ class Populator {
|
|||||||
$localizer->forceLoadWebsiteLocaleText();
|
$localizer->forceLoadWebsiteLocaleText();
|
||||||
|
|
||||||
array_map([$this, 'populate'], $this->models);
|
array_map([$this, 'populate'], $this->models);
|
||||||
|
$this->populateNewsletterOptionFields();
|
||||||
$this->populateNewsletterTemplates();
|
$this->populateNewsletterTemplates();
|
||||||
|
|
||||||
$this->createDefaultSegment();
|
$this->createDefaultSegment();
|
||||||
@@ -382,7 +381,7 @@ class Populator {
|
|||||||
return $defaultSegment;
|
return $defaultSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newsletterOptionFields() {
|
private function populateNewsletterOptionFields() {
|
||||||
$optionFields = [
|
$optionFields = [
|
||||||
[
|
[
|
||||||
'name' => 'isScheduled',
|
'name' => 'isScheduled',
|
||||||
@@ -510,13 +509,33 @@ class Populator {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
return [
|
// 1. Load all existing option fields from the database.
|
||||||
'rows' => $optionFields,
|
$tableName = $this->entityManager->getClassMetadata(NewsletterOptionFieldEntity::class)->getTableName();
|
||||||
'identification_columns' => [
|
$connection = $this->entityManager->getConnection();
|
||||||
'name',
|
$existingOptionFields = $connection->createQueryBuilder()
|
||||||
'newsletter_type',
|
->select('of.name, of.newsletter_type')
|
||||||
],
|
->from($tableName, 'of')
|
||||||
];
|
->executeQuery()
|
||||||
|
->fetchAllAssociative();
|
||||||
|
|
||||||
|
// 2. Insert new option fields using a single query (good for first installs).
|
||||||
|
$inserts = array_udiff(
|
||||||
|
$optionFields,
|
||||||
|
$existingOptionFields,
|
||||||
|
fn($a, $b) => [$a['name'], $a['newsletter_type']] <=> [$b['name'], $b['newsletter_type']]
|
||||||
|
);
|
||||||
|
if ($inserts) {
|
||||||
|
$placeholders = implode(',', array_fill(0, count($inserts), '(?, ?)'));
|
||||||
|
$connection->executeStatement(
|
||||||
|
"INSERT INTO $tableName (name, newsletter_type) VALUES $placeholders",
|
||||||
|
array_merge(
|
||||||
|
...array_map(
|
||||||
|
fn($of) => [$of['name'], $of['newsletter_type']],
|
||||||
|
$inserts
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function populateNewsletterTemplates(): void {
|
private function populateNewsletterTemplates(): void {
|
||||||
|
@@ -3,13 +3,48 @@
|
|||||||
namespace MailPoet\Test\Config;
|
namespace MailPoet\Test\Config;
|
||||||
|
|
||||||
use MailPoet\Config\Populator;
|
use MailPoet\Config\Populator;
|
||||||
|
use MailPoet\Entities\NewsletterOptionFieldEntity;
|
||||||
use MailPoet\Entities\NewsletterTemplateEntity;
|
use MailPoet\Entities\NewsletterTemplateEntity;
|
||||||
use MailPoetTest;
|
use MailPoetTest;
|
||||||
use MailPoetVendor\Doctrine\ORM\Query;
|
use MailPoetVendor\Doctrine\ORM\Query;
|
||||||
|
|
||||||
class PopulatorTest extends MailPoetTest {
|
class PopulatorTest extends MailPoetTest {
|
||||||
|
private const OPTION_FIELD_COUNT = 31;
|
||||||
private const TEMPLATE_COUNT = 76;
|
private const TEMPLATE_COUNT = 76;
|
||||||
|
|
||||||
|
public function testItInsertsOptionFields(): void {
|
||||||
|
$populator = $this->diContainer->get(Populator::class);
|
||||||
|
|
||||||
|
// no option fields
|
||||||
|
$this->entityManager->createQueryBuilder()
|
||||||
|
->delete(NewsletterOptionFieldEntity::class, 'f')
|
||||||
|
->getQuery()
|
||||||
|
->execute();
|
||||||
|
$optionFields = $this->getAllOptionFields();
|
||||||
|
$this->assertSame(0, count($optionFields));
|
||||||
|
|
||||||
|
// insert all option fields
|
||||||
|
$populator->up();
|
||||||
|
$optionFields = $this->getAllOptionFields();
|
||||||
|
$this->assertSame(self::OPTION_FIELD_COUNT, count($optionFields));
|
||||||
|
|
||||||
|
// delete only some fields
|
||||||
|
$this->entityManager->createQueryBuilder()
|
||||||
|
->delete(NewsletterOptionFieldEntity::class, 'f')
|
||||||
|
->where('f.id IN (:ids)')
|
||||||
|
->setParameter('ids', array_map(fn($field) => $field->getId(), array_slice($optionFields, 0, 10)))
|
||||||
|
->getQuery()
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$optionFields = $this->getAllOptionFields();
|
||||||
|
$this->assertSame(self::OPTION_FIELD_COUNT - 10, count($optionFields));
|
||||||
|
|
||||||
|
// insert new option fields
|
||||||
|
$populator->up();
|
||||||
|
$optionFields = $this->getAllOptionFields();
|
||||||
|
$this->assertSame(self::OPTION_FIELD_COUNT, count($optionFields));
|
||||||
|
}
|
||||||
|
|
||||||
public function testItInsertsTemplates(): void {
|
public function testItInsertsTemplates(): void {
|
||||||
$populator = $this->diContainer->get(Populator::class);
|
$populator = $this->diContainer->get(Populator::class);
|
||||||
|
|
||||||
@@ -86,6 +121,15 @@ class PopulatorTest extends MailPoetTest {
|
|||||||
$this->assertSame(self::TEMPLATE_COUNT, count($templates));
|
$this->assertSame(self::TEMPLATE_COUNT, count($templates));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getAllOptionFields(): array {
|
||||||
|
return (array)$this->entityManager->createQueryBuilder()
|
||||||
|
->select('f')
|
||||||
|
->from(NewsletterOptionFieldEntity::class, 'f')
|
||||||
|
->getQuery()
|
||||||
|
->setHint(Query::HINT_REFRESH, true)
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
private function getAllTemplates(): array {
|
private function getAllTemplates(): array {
|
||||||
return (array)$this->entityManager->createQueryBuilder()
|
return (array)$this->entityManager->createQueryBuilder()
|
||||||
->select('t')
|
->select('t')
|
||||||
|
Reference in New Issue
Block a user