Optimize populating newsletter option fields
This commit is contained in:
@@ -78,9 +78,7 @@ class Populator {
|
||||
$this->wpSegment = $wpSegment;
|
||||
$this->referralDetector = $referralDetector;
|
||||
$this->prefix = Env::$dbPrefix;
|
||||
$this->models = [
|
||||
'newsletter_option_fields',
|
||||
];
|
||||
$this->models = [];
|
||||
$this->templates = [
|
||||
'WelcomeBlank1Column',
|
||||
'WelcomeBlank12Column',
|
||||
@@ -169,6 +167,7 @@ class Populator {
|
||||
$localizer->forceLoadWebsiteLocaleText();
|
||||
|
||||
array_map([$this, 'populate'], $this->models);
|
||||
$this->populateNewsletterOptionFields();
|
||||
$this->populateNewsletterTemplates();
|
||||
|
||||
$this->createDefaultSegment();
|
||||
@@ -382,7 +381,7 @@ class Populator {
|
||||
return $defaultSegment;
|
||||
}
|
||||
|
||||
protected function newsletterOptionFields() {
|
||||
private function populateNewsletterOptionFields() {
|
||||
$optionFields = [
|
||||
[
|
||||
'name' => 'isScheduled',
|
||||
@@ -510,13 +509,33 @@ class Populator {
|
||||
],
|
||||
];
|
||||
|
||||
return [
|
||||
'rows' => $optionFields,
|
||||
'identification_columns' => [
|
||||
'name',
|
||||
'newsletter_type',
|
||||
],
|
||||
];
|
||||
// 1. Load all existing option fields from the database.
|
||||
$tableName = $this->entityManager->getClassMetadata(NewsletterOptionFieldEntity::class)->getTableName();
|
||||
$connection = $this->entityManager->getConnection();
|
||||
$existingOptionFields = $connection->createQueryBuilder()
|
||||
->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 {
|
||||
|
@@ -3,13 +3,48 @@
|
||||
namespace MailPoet\Test\Config;
|
||||
|
||||
use MailPoet\Config\Populator;
|
||||
use MailPoet\Entities\NewsletterOptionFieldEntity;
|
||||
use MailPoet\Entities\NewsletterTemplateEntity;
|
||||
use MailPoetTest;
|
||||
use MailPoetVendor\Doctrine\ORM\Query;
|
||||
|
||||
class PopulatorTest extends MailPoetTest {
|
||||
private const OPTION_FIELD_COUNT = 31;
|
||||
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 {
|
||||
$populator = $this->diContainer->get(Populator::class);
|
||||
|
||||
@@ -86,6 +121,15 @@ class PopulatorTest extends MailPoetTest {
|
||||
$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 {
|
||||
return (array)$this->entityManager->createQueryBuilder()
|
||||
->select('t')
|
||||
|
Reference in New Issue
Block a user