This commit is contained in:
@ -197,10 +197,10 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Download additional WP Plugins for tests
|
name: Download additional WP Plugins for tests
|
||||||
command: |
|
command: |
|
||||||
./do download:woo-commerce-zip 9.8.2
|
./do download:woo-commerce-zip 9.8.3
|
||||||
./do download:woo-commerce-subscriptions-zip 7.4.0
|
./do download:woo-commerce-subscriptions-zip 7.4.0
|
||||||
./do download:woo-commerce-memberships-zip
|
./do download:woo-commerce-memberships-zip
|
||||||
./do download:automate-woo-zip 6.1.10
|
./do download:automate-woo-zip 6.1.11
|
||||||
- run:
|
- run:
|
||||||
name: Dump tests ENV variables for acceptance tests
|
name: Dump tests ENV variables for acceptance tests
|
||||||
command: |
|
command: |
|
||||||
|
@ -195,8 +195,8 @@ div.mailpoet-listing-bulk-actions-container {
|
|||||||
border-bottom: 1px solid $color-tertiary-light;
|
border-bottom: 1px solid $color-tertiary-light;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
max-width: 30vw;
|
max-width: 30vw;
|
||||||
padding: $grid-gap-medium $grid-gap-half;
|
padding: 12px $grid-gap-half;
|
||||||
vertical-align: middle;
|
vertical-align: top;
|
||||||
|
|
||||||
@include respond-to(small-screen) {
|
@include respond-to(small-screen) {
|
||||||
max-width: none;
|
max-width: none;
|
||||||
@ -310,13 +310,10 @@ a.mailpoet-listing-title {
|
|||||||
|
|
||||||
.mailpoet-listing-actions {
|
.mailpoet-listing-actions {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: none;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
left: 0;
|
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
position: absolute;
|
visibility: hidden;
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: $color-text-light;
|
color: $color-text-light;
|
||||||
@ -340,7 +337,7 @@ a.mailpoet-listing-title {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr:hover & {
|
tr:hover & {
|
||||||
display: flex;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(small-screen) {
|
@include respond-to(small-screen) {
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
import slugify from 'slugify';
|
import slugify from 'slugify';
|
||||||
|
|
||||||
export function formatCustomFieldBlockName(blockName, customField) {
|
export function formatCustomFieldBlockName(blockName, customField) {
|
||||||
const name = slugify(customField.name, { lower: true })
|
let name = slugify(customField.name, { lower: true })
|
||||||
.replace(/[^a-z0-9]+/g, '')
|
.replace(/[^a-z0-9]+/g, '')
|
||||||
.replace(/-$/, '');
|
.replace(/-$/, '');
|
||||||
|
|
||||||
|
// Ensure unique block names by appending ID if the slug is empty or too short
|
||||||
|
// (which can happen with certain character sets)
|
||||||
|
if (!name || name.length < 2) {
|
||||||
|
name = `field${customField.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
return `${blockName}-${name}`;
|
return `${blockName}-${name}`;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"apiVersion": 2,
|
"apiVersion": 3,
|
||||||
"name": "mailpoet/marketing-optin-block",
|
"name": "mailpoet/marketing-optin-block",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"title": "MailPoet Marketing Opt-in",
|
"title": "MailPoet Marketing Opt-in",
|
||||||
|
@ -18,6 +18,7 @@ const adminUrl = getSetting('adminUrl');
|
|||||||
const { optinEnabled, defaultText } = getSetting('mailpoet_data');
|
const { optinEnabled, defaultText } = getSetting('mailpoet_data');
|
||||||
|
|
||||||
function EmptyState(): JSX.Element {
|
function EmptyState(): JSX.Element {
|
||||||
|
const adminUrlToEnableOptIn = `${adminUrl}admin.php?page=mailpoet-settings#/woocommerce`;
|
||||||
return (
|
return (
|
||||||
<Placeholder
|
<Placeholder
|
||||||
icon={<Icon icon={megaphone} />}
|
icon={<Icon icon={megaphone} />}
|
||||||
@ -32,10 +33,10 @@ function EmptyState(): JSX.Element {
|
|||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
href={`${adminUrl}admin.php?page=mailpoet-settings#/woocommerce`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="wp-block-mailpoet-newsletter-block-placeholder__button"
|
className="wp-block-mailpoet-newsletter-block-placeholder__button"
|
||||||
|
onClick={() => {
|
||||||
|
window.open(adminUrlToEnableOptIn, '_blank', 'noopener noreferrer');
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{__('Enable opt-in for Checkout', 'mailpoet')}
|
{__('Enable opt-in for Checkout', 'mailpoet')}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -4,12 +4,13 @@ import { Icon } from './icon.jsx';
|
|||||||
|
|
||||||
const wp = window.wp;
|
const wp = window.wp;
|
||||||
const { Placeholder, PanelBody } = wp.components;
|
const { Placeholder, PanelBody } = wp.components;
|
||||||
const { BlockIcon, InspectorControls } = wp.blockEditor;
|
const { BlockIcon, InspectorControls, useBlockProps } = wp.blockEditor;
|
||||||
const ServerSideRender = wp.serverSideRender;
|
const ServerSideRender = wp.serverSideRender;
|
||||||
|
|
||||||
const allForms = window.mailpoet_forms;
|
const allForms = window.mailpoet_forms;
|
||||||
|
|
||||||
function Edit({ attributes, setAttributes }) {
|
function Edit({ attributes, setAttributes }) {
|
||||||
|
const blockProps = useBlockProps();
|
||||||
function displayFormsSelect() {
|
function displayFormsSelect() {
|
||||||
if (!Array.isArray(allForms)) return null;
|
if (!Array.isArray(allForms)) return null;
|
||||||
if (allForms.length === 0) return null;
|
if (allForms.length === 0) return null;
|
||||||
@ -27,7 +28,7 @@ function Edit({ attributes, setAttributes }) {
|
|||||||
{window.locale.selectForm}
|
{window.locale.selectForm}
|
||||||
</option>
|
</option>
|
||||||
{allForms.map((form) => (
|
{allForms.map((form) => (
|
||||||
<option value={form.id}>
|
<option value={form.id} key={`form-${form.id}`}>
|
||||||
{form.name +
|
{form.name +
|
||||||
(form.status === 'disabled'
|
(form.status === 'disabled'
|
||||||
? ` (${window.locale.inactive})`
|
? ` (${window.locale.inactive})`
|
||||||
@ -63,7 +64,7 @@ function Edit({ attributes, setAttributes }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div {...blockProps}>
|
||||||
<InspectorControls>
|
<InspectorControls>
|
||||||
<PanelBody title="MailPoet Subscription Form" initialOpen>
|
<PanelBody title="MailPoet Subscription Form" initialOpen>
|
||||||
{selectFormSettings()}
|
{selectFormSettings()}
|
||||||
@ -81,7 +82,7 @@ function Edit({ attributes, setAttributes }) {
|
|||||||
)}
|
)}
|
||||||
{attributes.formId !== null && renderForm()}
|
{attributes.formId !== null && renderForm()}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ const { registerBlockType } = wp.blocks;
|
|||||||
|
|
||||||
registerBlockType('mailpoet/subscription-form-block-render', {
|
registerBlockType('mailpoet/subscription-form-block-render', {
|
||||||
title: window.locale.subscriptionForm,
|
title: window.locale.subscriptionForm,
|
||||||
|
apiVersion: 3,
|
||||||
attributes: {
|
attributes: {
|
||||||
formId: {
|
formId: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@ -19,6 +20,7 @@ registerBlockType('mailpoet/subscription-form-block-render', {
|
|||||||
|
|
||||||
registerBlockType('mailpoet/subscription-form-block', {
|
registerBlockType('mailpoet/subscription-form-block', {
|
||||||
title: window.locale.subscriptionForm,
|
title: window.locale.subscriptionForm,
|
||||||
|
apiVersion: 3,
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
category: 'widgets',
|
category: 'widgets',
|
||||||
example: {},
|
example: {},
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
== Changelog ==
|
== Changelog ==
|
||||||
|
|
||||||
|
= 5.12.1 - 2025-05-06 =
|
||||||
|
* Fixed: listing action items overlaying with row border when on two lines on smaller screens;
|
||||||
|
* Fixed: Handling of Japanese characters in custom field blocks in the form editor.
|
||||||
|
|
||||||
= 5.12.0 - 2025-04-29 =
|
= 5.12.0 - 2025-04-29 =
|
||||||
* Improved: more consistent look and feel of MailPoet pages with WordPress;
|
* Improved: more consistent look and feel of MailPoet pages with WordPress;
|
||||||
* Improved: optimized email template images to decrease their file size;
|
* Improved: optimized email template images to decrease their file size;
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\Migrations\App;
|
||||||
|
|
||||||
|
use MailPoet\Entities\StatisticsClickEntity;
|
||||||
|
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||||
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Entities\SubscriberSegmentEntity;
|
||||||
|
use MailPoet\Migrator\AppMigration;
|
||||||
|
use MailPoetVendor\Doctrine\DBAL\Connection;
|
||||||
|
|
||||||
|
class Migration_20250501_114655_App extends AppMigration {
|
||||||
|
private const DB_QUERY_CHUNK_SIZE = 1000;
|
||||||
|
|
||||||
|
public function run(): void {
|
||||||
|
$clicksStatsTable = $this->entityManager->getClassMetadata(StatisticsClickEntity::class)->getTableName();
|
||||||
|
$unsubscribeStatsTable = $this->entityManager->getClassMetadata(StatisticsUnsubscribeEntity::class)->getTableName();
|
||||||
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
|
$subscribersSegmentsTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
||||||
|
|
||||||
|
// First get all subscriber IDs that were unsubscribed by a bot
|
||||||
|
$subscriberIds = $this->entityManager->getConnection()->executeQuery(
|
||||||
|
"SELECT DISTINCT mp_unsub.subscriber_id
|
||||||
|
FROM {$unsubscribeStatsTable} AS mp_unsub
|
||||||
|
LEFT JOIN {$clicksStatsTable} AS mp_click
|
||||||
|
ON mp_unsub.newsletter_id = mp_click.newsletter_id
|
||||||
|
AND mp_unsub.subscriber_id = mp_click.subscriber_id
|
||||||
|
AND ABS(TIMESTAMPDIFF(SECOND, mp_click.created_at, mp_unsub.created_at)) <= 4
|
||||||
|
WHERE mp_unsub.created_at > '2025-03-01'
|
||||||
|
GROUP BY mp_unsub.subscriber_id
|
||||||
|
HAVING COUNT(mp_click.id) >= 3"
|
||||||
|
)->fetchFirstColumn();
|
||||||
|
|
||||||
|
if (empty($subscriberIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process subscriber IDs in chunks
|
||||||
|
foreach (array_chunk($subscriberIds, self::DB_QUERY_CHUNK_SIZE) as $chunk) {
|
||||||
|
$this->processSubscriberChunk(
|
||||||
|
$chunk,
|
||||||
|
$subscribersTable,
|
||||||
|
$subscribersSegmentsTable,
|
||||||
|
$unsubscribeStatsTable
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processSubscriberChunk(
|
||||||
|
array $subscriberIds,
|
||||||
|
string $subscribersTable,
|
||||||
|
string $subscribersSegmentsTable,
|
||||||
|
string $unsubscribeStatsTable
|
||||||
|
): void {
|
||||||
|
// Switch the global subscriber status to subscribed
|
||||||
|
$this->entityManager->getConnection()->executeQuery(
|
||||||
|
"UPDATE {$subscribersTable}
|
||||||
|
SET status = :subscribedStatus
|
||||||
|
WHERE id IN (:subscriberIds)
|
||||||
|
AND status = :unsubscribedStatus",
|
||||||
|
[
|
||||||
|
'subscribedStatus' => SubscriberEntity::STATUS_SUBSCRIBED,
|
||||||
|
'unsubscribedStatus' => SubscriberEntity::STATUS_UNSUBSCRIBED,
|
||||||
|
'subscriberIds' => $subscriberIds,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'subscriberIds' => Connection::PARAM_INT_ARRAY,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update the subscriber_segment table, find rows that were unsubscribed at the same time
|
||||||
|
$this->entityManager->getConnection()->executeQuery(
|
||||||
|
"UPDATE {$subscribersSegmentsTable} AS mp_subseg
|
||||||
|
JOIN {$unsubscribeStatsTable} AS mp_unsub
|
||||||
|
ON mp_subseg.subscriber_id = mp_unsub.subscriber_id
|
||||||
|
AND ABS(TIMESTAMPDIFF(SECOND, mp_subseg.updated_at, mp_unsub.created_at)) <= 2
|
||||||
|
SET mp_subseg.status = :subscribedStatus
|
||||||
|
WHERE mp_subseg.status = :unsubscribedStatus
|
||||||
|
AND mp_subseg.subscriber_id IN (:subscriberIds)",
|
||||||
|
[
|
||||||
|
'subscribedStatus' => SubscriberEntity::STATUS_SUBSCRIBED,
|
||||||
|
'unsubscribedStatus' => SubscriberEntity::STATUS_UNSUBSCRIBED,
|
||||||
|
'subscriberIds' => $subscriberIds,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'subscriberIds' => Connection::PARAM_INT_ARRAY,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -115,7 +115,7 @@ class Migration_20230831_143755_Db extends DbMigration {
|
|||||||
$stepId = strval($item['step_id']);
|
$stepId = strval($item['step_id']);
|
||||||
$stepKey = strval($steps[$stepId]['key'] ?? 'unknown');
|
$stepKey = strval($steps[$stepId]['key'] ?? 'unknown');
|
||||||
$triggerId = $steps['root']['next_steps'][0]['id'];
|
$triggerId = $steps['root']['next_steps'][0]['id'];
|
||||||
$triggerKey = $steps['root']['next_steps'][0]['key'];
|
$triggerKey = $steps['root']['next_steps'][0]['key'] ?? 'unknown';
|
||||||
|
|
||||||
$queries[] = "UPDATE {$logsTable} SET step_key = '{$stepKey}' WHERE id = {$id}";
|
$queries[] = "UPDATE {$logsTable} SET step_key = '{$stepKey}' WHERE id = {$id}";
|
||||||
|
|
||||||
@ -132,7 +132,16 @@ class Migration_20230831_143755_Db extends DbMigration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->executeStatement(implode(';', $queries));
|
$nativeConnection = $this->connection->getNativeConnection();
|
||||||
|
// If the connection is a mysqli object, we can use the multi_query method
|
||||||
|
if (is_object($nativeConnection) && get_class($nativeConnection) === 'mysqli') {
|
||||||
|
$query = implode(';', $queries);
|
||||||
|
$nativeConnection->multi_query($query);
|
||||||
|
} else { // Otherwise, we need to execute each query individually (e.g. PDO or SQLite)
|
||||||
|
foreach ($queries as $query) {
|
||||||
|
$this->connection->executeStatement($query);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Plugin Name: MailPoet
|
* Plugin Name: MailPoet
|
||||||
* Version: 5.12.0
|
* Version: 5.12.1
|
||||||
* Plugin URI: https://www.mailpoet.com
|
* Plugin URI: https://www.mailpoet.com
|
||||||
* Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
|
* Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
|
||||||
* Author: MailPoet
|
* Author: MailPoet
|
||||||
@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$mailpoetPlugin = [
|
$mailpoetPlugin = [
|
||||||
'version' => '5.12.0',
|
'version' => '5.12.1',
|
||||||
'filename' => __FILE__,
|
'filename' => __FILE__,
|
||||||
'path' => dirname(__FILE__),
|
'path' => dirname(__FILE__),
|
||||||
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
|
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
|
||||||
|
@ -3,7 +3,7 @@ Contributors: mailpoet, woocommerce, automattic
|
|||||||
Tags: email marketing, post notification, woocommerce emails, email automation, newsletter
|
Tags: email marketing, post notification, woocommerce emails, email automation, newsletter
|
||||||
Requires at least: 6.7
|
Requires at least: 6.7
|
||||||
Tested up to: 6.8
|
Tested up to: 6.8
|
||||||
Stable tag: 5.12.0
|
Stable tag: 5.12.1
|
||||||
Requires PHP: 7.4
|
Requires PHP: 7.4
|
||||||
License: GPLv3
|
License: GPLv3
|
||||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
@ -222,11 +222,8 @@ Check our [Knowledge Base](https://kb.mailpoet.com) or contact us through our [s
|
|||||||
|
|
||||||
== Changelog ==
|
== Changelog ==
|
||||||
|
|
||||||
= 5.12.0 - 2025-04-29 =
|
= 5.12.1 - 2025-05-06 =
|
||||||
* Improved: more consistent look and feel of MailPoet pages with WordPress;
|
* Fixed: listing action items overlaying with row border when on two lines on smaller screens;
|
||||||
* Improved: optimized email template images to decrease their file size;
|
* Fixed: Handling of Japanese characters in custom field blocks in the form editor.
|
||||||
* Improved: better handling of unsubscribes via the link provided in the List-Unsubscribe header;
|
|
||||||
* Fixed: unreadable customer name in automation analytics when Gravatar fails to load;
|
|
||||||
* Fixed: "Custom HTML" block in form editor doesn't preserve "Automatically add paragraphs" setting.
|
|
||||||
|
|
||||||
[See the changelog for all versions.](https://github.com/mailpoet/mailpoet/blob/trunk/mailpoet/changelog.txt)
|
[See the changelog for all versions.](https://github.com/mailpoet/mailpoet/blob/trunk/mailpoet/changelog.txt)
|
||||||
|
51
mailpoet/tests/DataFactories/StatisticsUnsubscribes.php
Normal file
51
mailpoet/tests/DataFactories/StatisticsUnsubscribes.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\Test\DataFactories;
|
||||||
|
|
||||||
|
use MailPoet\DI\ContainerWrapper;
|
||||||
|
use MailPoet\Entities\NewsletterEntity;
|
||||||
|
use MailPoet\Entities\SendingQueueEntity;
|
||||||
|
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||||
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
|
|
||||||
|
class StatisticsUnsubscribes {
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
/** @var NewsletterEntity */
|
||||||
|
private $newsletter;
|
||||||
|
|
||||||
|
/** @var SubscriberEntity */
|
||||||
|
private $subscriber;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
NewsletterEntity $newsletter,
|
||||||
|
SubscriberEntity $subscriber
|
||||||
|
) {
|
||||||
|
$this->newsletter = $newsletter;
|
||||||
|
$this->subscriber = $subscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withCreatedAt(\DateTimeInterface $createdAt): self {
|
||||||
|
$this->data['createdAt'] = $createdAt;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(): StatisticsUnsubscribeEntity {
|
||||||
|
$entityManager = ContainerWrapper::getInstance()->get(EntityManager::class);
|
||||||
|
$queue = $this->newsletter->getLatestQueue();
|
||||||
|
Assert::assertInstanceOf(SendingQueueEntity::class, $queue);
|
||||||
|
$entity = new StatisticsUnsubscribeEntity(
|
||||||
|
$this->newsletter,
|
||||||
|
$queue,
|
||||||
|
$this->subscriber
|
||||||
|
);
|
||||||
|
if (($this->data['createdAt'] ?? null) instanceof \DateTimeInterface) {
|
||||||
|
$entity->setCreatedAt($this->data['createdAt']);
|
||||||
|
}
|
||||||
|
$entityManager->persist($entity);
|
||||||
|
$entityManager->flush();
|
||||||
|
return $entity;
|
||||||
|
}
|
||||||
|
}
|
61
mailpoet/tests/DataFactories/SubscriberSegment.php
Normal file
61
mailpoet/tests/DataFactories/SubscriberSegment.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\Test\DataFactories;
|
||||||
|
|
||||||
|
use MailPoet\DI\ContainerWrapper;
|
||||||
|
use MailPoet\Entities\SegmentEntity;
|
||||||
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Entities\SubscriberSegmentEntity;
|
||||||
|
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||||
|
|
||||||
|
class SubscriberSegment {
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
/** @var SubscriberEntity */
|
||||||
|
private $subscriber;
|
||||||
|
|
||||||
|
/** @var SegmentEntity */
|
||||||
|
private $segment;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
SubscriberEntity $subscriber,
|
||||||
|
SegmentEntity $segment,
|
||||||
|
string $status = SubscriberEntity::STATUS_SUBSCRIBED
|
||||||
|
) {
|
||||||
|
$this->subscriber = $subscriber;
|
||||||
|
$this->segment = $segment;
|
||||||
|
$this->data['status'] = $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withStatus(string $status): self {
|
||||||
|
$this->data['status'] = $status;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withUpdatedAt(\DateTimeInterface $updatedAt): self {
|
||||||
|
$this->data['updatedAt'] = $updatedAt;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(): SubscriberSegmentEntity {
|
||||||
|
$entityManager = ContainerWrapper::getInstance()->get(EntityManager::class);
|
||||||
|
$entity = new SubscriberSegmentEntity($this->segment, $this->subscriber, $this->data['status']);
|
||||||
|
|
||||||
|
if (isset($this->data['status'])) {
|
||||||
|
$entity->setStatus($this->data['status']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$entityManager->persist($entity);
|
||||||
|
$entityManager->flush();
|
||||||
|
$entityManager->refresh($entity);
|
||||||
|
if (($this->data['updatedAt'] ?? null) instanceof \DateTimeInterface) {
|
||||||
|
$subscribersSegmentsTable = $entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
||||||
|
$entityManager->getConnection()->executeQuery("UPDATE {$subscribersSegmentsTable} SET updated_at = :updatedAt WHERE id = :id", [
|
||||||
|
'updatedAt' => $this->data['updatedAt']->format('Y-m-d H:i:s'),
|
||||||
|
'id' => $entity->getId(),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
$entityManager->refresh($entity);
|
||||||
|
return $entity;
|
||||||
|
}
|
||||||
|
}
|
@ -122,22 +122,22 @@ class GutenbergFormBlockCest {
|
|||||||
$i->amEditingPostWithId($postId);
|
$i->amEditingPostWithId($postId);
|
||||||
$this->closeDialog($i);
|
$this->closeDialog($i);
|
||||||
$i->waitForText('My Gutenberg form');
|
$i->waitForText('My Gutenberg form');
|
||||||
|
$i->switchToIframe('iframe[name="editor-canvas"]');
|
||||||
$i->click('[aria-label="Add title"]');
|
$i->click('[aria-label="Add title"]');
|
||||||
$i->click('[aria-label="Add block"]');
|
$i->click('[aria-label="Add block"]');
|
||||||
|
$i->switchToIFrame();
|
||||||
$i->fillField('[placeholder="Search"]', 'MailPoet Subscription Form');
|
$i->fillField('[placeholder="Search"]', 'MailPoet Subscription Form');
|
||||||
$i->waitForElement(Locator::contains('button', 'MailPoet Subscription Form'));
|
$i->waitForElement(Locator::contains('button', 'MailPoet Subscription Form'));
|
||||||
$i->click(Locator::contains('button', 'MailPoet Subscription Form'));
|
$i->click(Locator::contains('button', 'MailPoet Subscription Form'));
|
||||||
|
$i->switchToIframe('iframe[name="editor-canvas"]');
|
||||||
$i->waitForElement('[aria-label="Block: MailPoet Subscription Form"]');
|
$i->waitForElement('[aria-label="Block: MailPoet Subscription Form"]');
|
||||||
$i->selectOption('.mailpoet-block-create-forms-list', 'Acceptance Test Block Form');
|
$i->selectOption('.mailpoet-block-create-forms-list', 'Acceptance Test Block Form');
|
||||||
$i->waitForElementVisible('[data-automation-id="form_email"]');
|
$i->waitForElementVisible('[data-automation-id="form_email"]');
|
||||||
$i->waitForElementVisible('[data-automation-id="form_first_name"]');
|
$i->waitForElementVisible('[data-automation-id="form_first_name"]');
|
||||||
$i->waitForElementVisible('[data-automation-id="form_last_name"]');
|
$i->waitForElementVisible('[data-automation-id="form_last_name"]');
|
||||||
// From WP 6.6 the button label is Save
|
$i->switchToIFrame();
|
||||||
if (version_compare($i->getWordPressVersion(), '6.6', '<')) {
|
$i->click('Save');
|
||||||
$i->click('Update');
|
|
||||||
} else {
|
|
||||||
$i->click('Save');
|
|
||||||
}
|
|
||||||
$i->waitForText('Post updated.');
|
$i->waitForText('Post updated.');
|
||||||
|
|
||||||
$i->wantTo('Verify the added form on the front-end');
|
$i->wantTo('Verify the added form on the front-end');
|
||||||
|
@ -63,7 +63,9 @@ class WooCheckoutBlocksCest {
|
|||||||
$i->wantTo('Check a message when opt-in is disabled');
|
$i->wantTo('Check a message when opt-in is disabled');
|
||||||
$i->login();
|
$i->login();
|
||||||
$i->amOnAdminPage("post.php?post={$this->checkoutPostId}&action=edit");
|
$i->amOnAdminPage("post.php?post={$this->checkoutPostId}&action=edit");
|
||||||
|
$i->switchToIframe('iframe[name="editor-canvas"]');
|
||||||
$i->canSee('MailPoet marketing opt-in would be shown here if enabled. You can enable from the settings page.');
|
$i->canSee('MailPoet marketing opt-in would be shown here if enabled. You can enable from the settings page.');
|
||||||
|
$i->switchToIframe();
|
||||||
$i->logOut();
|
$i->logOut();
|
||||||
$this->orderProduct($i, $customerEmail, true, false);
|
$this->orderProduct($i, $customerEmail, true, false);
|
||||||
$i->login();
|
$i->login();
|
||||||
@ -223,25 +225,27 @@ class WooCheckoutBlocksCest {
|
|||||||
$i->wantTo('Choose a pattern was not present, skipping action.');
|
$i->wantTo('Choose a pattern was not present, skipping action.');
|
||||||
}
|
}
|
||||||
$this->closeDialog($i);
|
$this->closeDialog($i);
|
||||||
|
$i->switchToIframe('iframe[name="editor-canvas"]');
|
||||||
$i->click('[aria-label="Add title"]'); // For block inserter to show up
|
$i->click('[aria-label="Add title"]'); // For block inserter to show up
|
||||||
$i->click('[aria-label="Add block"]');
|
$i->click('[aria-label="Add block"]');
|
||||||
|
$i->switchToIframe();
|
||||||
$i->fillField('[placeholder="Search"]', 'Checkout');
|
$i->fillField('[placeholder="Search"]', 'Checkout');
|
||||||
$i->waitForElement(Locator::contains('button > span > span', 'Checkout'));
|
$i->waitForElement(Locator::contains('button > span > span', 'Checkout'));
|
||||||
$i->click(Locator::contains('button > span > span', 'Checkout')); // Select Checkout block
|
$i->click(Locator::contains('button > span > span', 'Checkout')); // Select Checkout block
|
||||||
|
$i->switchToIframe('iframe[name="editor-canvas"]');
|
||||||
$i->waitForElement('[aria-label="Block: Checkout"]');
|
$i->waitForElement('[aria-label="Block: Checkout"]');
|
||||||
|
|
||||||
// Close dialog with Compatibility notice
|
// Close dialog with Compatibility notice
|
||||||
|
$i->switchToIframe();
|
||||||
$this->closeDialog($i);
|
$this->closeDialog($i);
|
||||||
|
|
||||||
// Enable registration during the checkout
|
// Enable registration during the checkout
|
||||||
|
$i->switchToIframe('iframe[name="editor-canvas"]');
|
||||||
$i->click('[aria-label="Block: Contact Information"]');
|
$i->click('[aria-label="Block: Contact Information"]');
|
||||||
|
|
||||||
// From WP 6.6 the button label is Save
|
$i->switchToIframe();
|
||||||
$version = (string)preg_replace('/-(RC|beta)\d*/', '', $i->getWordPressVersion());
|
$i->click('Save');
|
||||||
if (version_compare($version, '6.6', '<')) {
|
|
||||||
$i->click('Update');
|
|
||||||
} else {
|
|
||||||
$i->click('Save');
|
|
||||||
}
|
|
||||||
$i->waitForText('Page updated.');
|
$i->waitForText('Page updated.');
|
||||||
$i->logOut();
|
$i->logOut();
|
||||||
return $postId;
|
return $postId;
|
||||||
|
@ -20,7 +20,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of standard newsletters sent in last 7 days']);
|
$this->assertEquals(1, $processed['Number of standard newsletters sent in last 7 days']);
|
||||||
@ -32,7 +32,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(89), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subMonths(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of standard newsletters sent in last 7 days']);
|
$this->assertEquals(1, $processed['Number of standard newsletters sent in last 7 days']);
|
||||||
@ -47,7 +47,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of standard newsletters sent in last 7 days']);
|
$this->assertEquals(1, $processed['Number of standard newsletters sent in last 7 days']);
|
||||||
@ -65,7 +65,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of post notification campaigns sent in the last 7 days']);
|
$this->assertEquals(1, $processed['Number of post notification campaigns sent in the last 7 days']);
|
||||||
@ -77,7 +77,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(89), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subMonths(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of post notification campaigns sent in the last 7 days']);
|
$this->assertEquals(1, $processed['Number of post notification campaigns sent in the last 7 days']);
|
||||||
@ -92,7 +92,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'filterSegment' => ['not' => 'relevant']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'filterSegment' => ['not' => 'relevant']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'filterSegment' => ['not' => 'relevant']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'filterSegment' => ['not' => 'relevant']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'filterSegment' => ['not' => 'relevant']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'filterSegment' => ['not' => 'relevant']]]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of post notification campaigns sent in the last 7 days']);
|
$this->assertEquals(1, $processed['Number of post notification campaigns sent in the last 7 days']);
|
||||||
@ -110,7 +110,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of re-engagement campaigns sent in the last 7 days']);
|
$this->assertEquals(1, $processed['Number of re-engagement campaigns sent in the last 7 days']);
|
||||||
@ -122,7 +122,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(89), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subMonths(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of re-engagement campaigns sent in the last 7 days']);
|
$this->assertEquals(1, $processed['Number of re-engagement campaigns sent in the last 7 days']);
|
||||||
@ -137,7 +137,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(89), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subMonths(2), [$dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
$this->assertEquals(1, $processed['Number of re-engagement campaigns sent in the last 7 days']);
|
$this->assertEquals(1, $processed['Number of re-engagement campaigns sent in the last 7 days']);
|
||||||
@ -154,7 +154,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
public function testItWorksWithLegacyWelcomeEmails(): void {
|
public function testItWorksWithLegacyWelcomeEmails(): void {
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_WELCOME, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_WELCOME, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_WELCOME, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_WELCOME, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_WELCOME, Carbon::now()->subDays(89), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_WELCOME, Carbon::now()->subMonths(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
$this->assertSame(1, $processed['Number of legacy welcome email campaigns sent in the last 7 days']);
|
$this->assertSame(1, $processed['Number of legacy welcome email campaigns sent in the last 7 days']);
|
||||||
$this->assertSame(2, $processed['Number of legacy welcome email campaigns sent in the last 30 days']);
|
$this->assertSame(2, $processed['Number of legacy welcome email campaigns sent in the last 30 days']);
|
||||||
@ -164,7 +164,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
public function testItWorksWithLegacyAbandonedCartEmails(): void {
|
public function testItWorksWithLegacyAbandonedCartEmails(): void {
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'cart_product_ids' => ['123']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'cart_product_ids' => ['123']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'cart_product_ids' => ['1234']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'cart_product_ids' => ['1234']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(89), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'cart_product_ids' => ['1235']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subMonths(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'cart_product_ids' => ['1235']]]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
$this->assertSame(1, $processed['Number of legacy abandoned cart campaigns sent in the last 7 days']);
|
$this->assertSame(1, $processed['Number of legacy abandoned cart campaigns sent in the last 7 days']);
|
||||||
$this->assertSame(2, $processed['Number of legacy abandoned cart campaigns sent in the last 30 days']);
|
$this->assertSame(2, $processed['Number of legacy abandoned cart campaigns sent in the last 30 days']);
|
||||||
@ -174,7 +174,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
public function testItWorksWithLegacyPurchasedProductEmails(): void {
|
public function testItWorksWithLegacyPurchasedProductEmails(): void {
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'orderedProducts' => ['123']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'orderedProducts' => ['123']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'orderedProducts' => ['1234']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'orderedProducts' => ['1234']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(89), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'orderedProducts' => ['1235']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subMonths(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'orderedProducts' => ['1235']]]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
$this->assertSame(1, $processed['Number of legacy purchased product campaigns sent in the last 7 days']);
|
$this->assertSame(1, $processed['Number of legacy purchased product campaigns sent in the last 7 days']);
|
||||||
$this->assertSame(2, $processed['Number of legacy purchased product campaigns sent in the last 30 days']);
|
$this->assertSame(2, $processed['Number of legacy purchased product campaigns sent in the last 30 days']);
|
||||||
@ -184,7 +184,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
public function testItWorksWithLegacyPurchasedInCategoryEmails(): void {
|
public function testItWorksWithLegacyPurchasedInCategoryEmails(): void {
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'orderedProductCategories' => ['123']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'orderedProductCategories' => ['123']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'orderedProductCategories' => ['1234']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'orderedProductCategories' => ['1234']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(89), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'orderedProductCategories' => ['1235']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subMonths(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'orderedProductCategories' => ['1235']]]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
$this->assertSame(1, $processed['Number of legacy purchased in category campaigns sent in the last 7 days']);
|
$this->assertSame(1, $processed['Number of legacy purchased in category campaigns sent in the last 7 days']);
|
||||||
$this->assertSame(2, $processed['Number of legacy purchased in category campaigns sent in the last 30 days']);
|
$this->assertSame(2, $processed['Number of legacy purchased in category campaigns sent in the last 30 days']);
|
||||||
@ -194,7 +194,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
public function testItWorksWithLegacyFirstPurchaseEmails(): void {
|
public function testItWorksWithLegacyFirstPurchaseEmails(): void {
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'order_amount' => 123, 'order_date' => '2024-03-01', 'order_id' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'order_amount' => 123, 'order_date' => '2024-03-01', 'order_id' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'order_amount' => 123, 'order_date' => '2024-03-01', 'order_id' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'order_amount' => 123, 'order_date' => '2024-03-01', 'order_id' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subDays(89), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'order_amount' => 123, 'order_date' => '2024-03-01', 'order_id' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATIC, Carbon::now()->subMonths(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'order_amount' => 123, 'order_date' => '2024-03-01', 'order_id' => '3']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
$this->assertSame(1, $processed['Number of legacy first purchase campaigns sent in the last 7 days']);
|
$this->assertSame(1, $processed['Number of legacy first purchase campaigns sent in the last 7 days']);
|
||||||
$this->assertSame(2, $processed['Number of legacy first purchase campaigns sent in the last 30 days']);
|
$this->assertSame(2, $processed['Number of legacy first purchase campaigns sent in the last 30 days']);
|
||||||
@ -204,7 +204,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
public function testItWorksForAutomationEmails(): void {
|
public function testItWorksForAutomationEmails(): void {
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATION, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'orderedProductCategories' => ['123']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATION, Carbon::now()->subDays(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1', 'orderedProductCategories' => ['123']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATION, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'orderedProductCategories' => ['1234']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATION, Carbon::now()->subDays(8), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2', 'orderedProductCategories' => ['1234']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATION, Carbon::now()->subDays(89), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'orderedProductCategories' => ['1235']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_AUTOMATION, Carbon::now()->subMonths(2), [], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3', 'orderedProductCategories' => ['1235']]]]);
|
||||||
|
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
|
||||||
@ -218,15 +218,15 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
$dynamicSegment = (new Segment())->withType(SegmentEntity::TYPE_DYNAMIC)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '2']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '3']]]);
|
||||||
|
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$defaultSegment, $dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '4']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(2), [$defaultSegment, $dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '4']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$defaultSegment, $dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '5']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(8), [$defaultSegment, $dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '5']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subDays(89), [$defaultSegment, $dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '6']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_RE_ENGAGEMENT, Carbon::now()->subMonths(2), [$defaultSegment, $dynamicSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '6']]]);
|
||||||
|
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '7', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '7', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '8', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '8', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '9', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_STANDARD, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '9', 'filterSegment' => ['theDataDoesNot' => 'matter']]]]);
|
||||||
|
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
$this->assertEquals(3, $processed['Number of campaigns sent in the last 7 days']);
|
$this->assertEquals(3, $processed['Number of campaigns sent in the last 7 days']);
|
||||||
@ -244,7 +244,7 @@ class ReporterTest extends \MailPoetTest {
|
|||||||
|
|
||||||
public function testItDoesNotDoubleCountDuplicateCampaignIds(): void {
|
public function testItDoesNotDoubleCountDuplicateCampaignIds(): void {
|
||||||
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
$defaultSegment = (new Segment())->withType(SegmentEntity::TYPE_DEFAULT)->create();
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(89), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subMonths(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(8), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
$this->createSentNewsletter(NewsletterEntity::TYPE_NOTIFICATION_HISTORY, Carbon::now()->subDays(2), [$defaultSegment], ['sendingQueueOptions' => ['meta' => ['campaignId' => '1']]]);
|
||||||
$processed = $this->reporter->getData();
|
$processed = $this->reporter->getData();
|
||||||
|
@ -0,0 +1,150 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace integration\Migrations\App;
|
||||||
|
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use MailPoet\Entities\NewsletterEntity;
|
||||||
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Migrations\App\Migration_20250501_114655_App;
|
||||||
|
use MailPoet\Test\DataFactories\Newsletter as NewsletterFactory;
|
||||||
|
use MailPoet\Test\DataFactories\NewsletterLink as NewsletterLinkFactory;
|
||||||
|
use MailPoet\Test\DataFactories\Segment as SegmentFactory;
|
||||||
|
use MailPoet\Test\DataFactories\StatisticsClicks;
|
||||||
|
use MailPoet\Test\DataFactories\StatisticsUnsubscribes;
|
||||||
|
use MailPoet\Test\DataFactories\Subscriber;
|
||||||
|
use MailPoet\Test\DataFactories\SubscriberSegment as SubscriberSegmentFactory;
|
||||||
|
|
||||||
|
// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
|
||||||
|
class Migration_20250501_114655_App_Test extends \MailPoetTest {
|
||||||
|
/** @var Migration_20250501_114655_App */
|
||||||
|
private $migration;
|
||||||
|
|
||||||
|
public function _before() {
|
||||||
|
parent::_before();
|
||||||
|
$this->migration = new Migration_20250501_114655_App($this->diContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItPausesInvalidTasksWithUnprocessedSubscribers(): void {
|
||||||
|
$subscriberFactory = new Subscriber();
|
||||||
|
$subscriberUnsubscribedBefore = $subscriberFactory->withEmail('subscriber1@example.com')
|
||||||
|
->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->create();
|
||||||
|
$subscriberUnsubscribedByBot = $subscriberFactory->withEmail('subscriber2@example.com')
|
||||||
|
->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->create();
|
||||||
|
$subscriberUnsubscribedByUserManyClicks = $subscriberFactory->withEmail('subscriber3@example.com')
|
||||||
|
->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->create();
|
||||||
|
$subscriberUnsubscribedByUserSingleClick = $subscriberFactory->withEmail('subscriber4@example.com')
|
||||||
|
->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$newsletterFactory = new NewsletterFactory();
|
||||||
|
$newsletter = $newsletterFactory->withType(NewsletterEntity::TYPE_STANDARD)
|
||||||
|
->withSubject('Test Newsletter')
|
||||||
|
->withSendingQueue()
|
||||||
|
->withStatus(NewsletterEntity::STATUS_SENT)
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$newsletterLinkFactory = new NewsletterLinkFactory($newsletter);
|
||||||
|
$newsletterLink = $newsletterLinkFactory
|
||||||
|
->withUrl('https://example.com/test')
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$newsletterLink2 = $newsletterLinkFactory
|
||||||
|
->withUrl('https://example.com/test2')
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$newsletterLink3 = $newsletterLinkFactory
|
||||||
|
->withUrl('https://example.com/test3')
|
||||||
|
->create();
|
||||||
|
|
||||||
|
// Create a test segment
|
||||||
|
$segment = (new SegmentFactory())->create();
|
||||||
|
|
||||||
|
// Create subscriber segments for each subscriber
|
||||||
|
$subscriberSegmentFactory = new SubscriberSegmentFactory($subscriberUnsubscribedBefore, $segment);
|
||||||
|
$subscriberSegmentBefore = $subscriberSegmentFactory
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->withUpdatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$subscriberSegmentFactory = new SubscriberSegmentFactory($subscriberUnsubscribedByBot, $segment);
|
||||||
|
$subscriberSegmentByBot = $subscriberSegmentFactory
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->withUpdatedAt(new DateTimeImmutable('2025-04-01 10:00:03'))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$subscriberSegmentFactory = new SubscriberSegmentFactory($subscriberUnsubscribedByUserManyClicks, $segment);
|
||||||
|
$subscriberSegmentByUserManyClicks = $subscriberSegmentFactory
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->withUpdatedAt(new DateTimeImmutable('2025-04-01 10:00:55'))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$subscriberSegmentFactory = new SubscriberSegmentFactory($subscriberUnsubscribedByUserSingleClick, $segment);
|
||||||
|
$subscriberSegmentByUserSingleClick = $subscriberSegmentFactory
|
||||||
|
->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->withUpdatedAt(new DateTimeImmutable('2025-04-01 10:00:00'))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
// $subscriberUnsubscribedBefore Has many suspicious clicks but unsubscribed before the issue
|
||||||
|
$subscriber1ClickFactory = new StatisticsClicks($newsletterLink, $subscriberUnsubscribedBefore);
|
||||||
|
$subscriber1ClickFactory->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))->create();
|
||||||
|
$subscriber1ClickFactory = new StatisticsClicks($newsletterLink2, $subscriberUnsubscribedBefore);
|
||||||
|
$subscriber1ClickFactory->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))->create();
|
||||||
|
$subscriber1ClickFactory = new StatisticsClicks($newsletterLink3, $subscriberUnsubscribedBefore);
|
||||||
|
$subscriber1ClickFactory->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))->create();
|
||||||
|
$subscriber1UnsubscribeFactory = new StatisticsUnsubscribes($newsletter, $subscriberUnsubscribedBefore);
|
||||||
|
$subscriber1UnsubscribeFactory->withCreatedAt(new DateTimeImmutable('2024-12-01 10:00:00'))->create();
|
||||||
|
|
||||||
|
// $subscriberUnsubscribedByBot Has many suspicious clicks but and unsubscribed after the issue
|
||||||
|
$subscriber2ClickFactory = new StatisticsClicks($newsletterLink, $subscriberUnsubscribedByBot);
|
||||||
|
$subscriber2ClickFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:00'))->create();
|
||||||
|
$subscriber2ClickFactory = new StatisticsClicks($newsletterLink2, $subscriberUnsubscribedByBot);
|
||||||
|
$subscriber2ClickFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:02'))->create();
|
||||||
|
$subscriber2ClickFactory = new StatisticsClicks($newsletterLink3, $subscriberUnsubscribedByBot);
|
||||||
|
$subscriber2ClickFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:05'))->create();
|
||||||
|
$subscriber2UnsubscribeFactory = new StatisticsUnsubscribes($newsletter, $subscriberUnsubscribedByBot);
|
||||||
|
$subscriber2UnsubscribeFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:03'))->create();
|
||||||
|
|
||||||
|
// $subscriberUnsubscribedByUserManyClicks Has many clicks but they are spread in time so it's not suspicious
|
||||||
|
$subscriber3ClickFactory = new StatisticsClicks($newsletterLink, $subscriberUnsubscribedByUserManyClicks);
|
||||||
|
$subscriber3ClickFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:00'))->create();
|
||||||
|
$subscriber3ClickFactory = new StatisticsClicks($newsletterLink2, $subscriberUnsubscribedByUserManyClicks);
|
||||||
|
$subscriber3ClickFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:30'))->create();
|
||||||
|
$subscriber3ClickFactory = new StatisticsClicks($newsletterLink3, $subscriberUnsubscribedByUserManyClicks);
|
||||||
|
$subscriber3ClickFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:50'))->create();
|
||||||
|
$subscriber3UnsubscribeFactory = new StatisticsUnsubscribes($newsletter, $subscriberUnsubscribedByUserManyClicks);
|
||||||
|
$subscriber3UnsubscribeFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:55'))->create();
|
||||||
|
|
||||||
|
// $subscriberUnsubscribedByUserSingleClick Has one click and unsubscribed after the issue
|
||||||
|
$subscriber4ClickFactory = new StatisticsClicks($newsletterLink, $subscriberUnsubscribedByUserSingleClick);
|
||||||
|
$subscriber4ClickFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:00'))->create();
|
||||||
|
$subscriber4UnsubscribeFactory = new StatisticsUnsubscribes($newsletter, $subscriberUnsubscribedByUserSingleClick);
|
||||||
|
$subscriber4UnsubscribeFactory->withCreatedAt(new DateTimeImmutable('2025-04-01 10:00:00'))->create();
|
||||||
|
$this->migration->run();
|
||||||
|
|
||||||
|
$this->entityManager->refresh($subscriberUnsubscribedBefore);
|
||||||
|
$this->entityManager->refresh($subscriberUnsubscribedByBot);
|
||||||
|
$this->entityManager->refresh($subscriberUnsubscribedByUserManyClicks);
|
||||||
|
$this->entityManager->refresh($subscriberUnsubscribedByUserSingleClick);
|
||||||
|
$this->entityManager->refresh($subscriberSegmentBefore);
|
||||||
|
$this->entityManager->refresh($subscriberSegmentByBot);
|
||||||
|
$this->entityManager->refresh($subscriberSegmentByUserManyClicks);
|
||||||
|
$this->entityManager->refresh($subscriberSegmentByUserSingleClick);
|
||||||
|
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_UNSUBSCRIBED, $subscriberUnsubscribedBefore->getStatus());
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_SUBSCRIBED, $subscriberUnsubscribedByBot->getStatus());
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_UNSUBSCRIBED, $subscriberUnsubscribedByUserManyClicks->getStatus());
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_UNSUBSCRIBED, $subscriberUnsubscribedByUserSingleClick->getStatus());
|
||||||
|
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_UNSUBSCRIBED, $subscriberSegmentBefore->getStatus());
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_SUBSCRIBED, $subscriberSegmentByBot->getStatus());
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_UNSUBSCRIBED, $subscriberSegmentByUserManyClicks->getStatus());
|
||||||
|
$this->assertEquals(SubscriberEntity::STATUS_UNSUBSCRIBED, $subscriberSegmentByUserSingleClick->getStatus());
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@
|
|||||||
"d3-color@<3.1.0": ">=3.1.0",
|
"d3-color@<3.1.0": ">=3.1.0",
|
||||||
"debug@>=4.0.0 <4.3.1": ">=4.3.1",
|
"debug@>=4.0.0 <4.3.1": ">=4.3.1",
|
||||||
"decode-uri-component@<0.2.1": ">=0.2.1",
|
"decode-uri-component@<0.2.1": ">=0.2.1",
|
||||||
|
"http-proxy-middleware": ">=2.0.9",
|
||||||
"json5@<1.0.2": ">=1.0.2",
|
"json5@<1.0.2": ">=1.0.2",
|
||||||
"path-to-regexp@<0.1.12": "0.1.12",
|
"path-to-regexp@<0.1.12": "0.1.12",
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
|
43
pnpm-lock.yaml
generated
43
pnpm-lock.yaml
generated
@ -13,6 +13,7 @@ overrides:
|
|||||||
d3-color@<3.1.0: '>=3.1.0'
|
d3-color@<3.1.0: '>=3.1.0'
|
||||||
debug@>=4.0.0 <4.3.1: '>=4.3.1'
|
debug@>=4.0.0 <4.3.1: '>=4.3.1'
|
||||||
decode-uri-component@<0.2.1: '>=0.2.1'
|
decode-uri-component@<0.2.1: '>=0.2.1'
|
||||||
|
http-proxy-middleware: '>=2.0.9'
|
||||||
json5@<1.0.2: '>=1.0.2'
|
json5@<1.0.2: '>=1.0.2'
|
||||||
path-to-regexp@<0.1.12: 0.1.12
|
path-to-regexp@<0.1.12: 0.1.12
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@ -8287,7 +8288,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||||
engines: {node: '>= 6.0.0'}
|
engines: {node: '>= 6.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.4
|
debug: 4.4.0(supports-color@8.1.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
@ -8684,7 +8685,7 @@ packages:
|
|||||||
/axios@1.7.4:
|
/axios@1.7.4:
|
||||||
resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==}
|
resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: 1.15.6
|
follow-redirects: 1.15.6(debug@4.4.0)
|
||||||
form-data: 4.0.0
|
form-data: 4.0.0
|
||||||
proxy-from-env: 1.1.0
|
proxy-from-env: 1.1.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -12095,7 +12096,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/follow-redirects@1.15.6:
|
/follow-redirects@1.15.6(debug@4.4.0):
|
||||||
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
|
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
|
||||||
engines: {node: '>=4.0'}
|
engines: {node: '>=4.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -12103,6 +12104,8 @@ packages:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
debug:
|
debug:
|
||||||
optional: true
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
debug: 4.4.0(supports-color@8.1.1)
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/for-each@0.3.3:
|
/for-each@0.3.3:
|
||||||
@ -12380,7 +12383,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
basic-ftp: 5.0.5
|
basic-ftp: 5.0.5
|
||||||
data-uri-to-buffer: 6.0.2
|
data-uri-to-buffer: 6.0.2
|
||||||
debug: 4.3.4
|
debug: 4.4.0(supports-color@8.1.1)
|
||||||
fs-extra: 11.2.0
|
fs-extra: 11.2.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@ -12910,31 +12913,26 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/http-proxy-middleware@2.0.6(@types/express@4.17.21):
|
/http-proxy-middleware@3.0.5:
|
||||||
resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==}
|
resolution: {integrity: sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||||
peerDependencies:
|
|
||||||
'@types/express': ^4.17.13
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@types/express':
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/express': 4.17.21
|
|
||||||
'@types/http-proxy': 1.17.15
|
'@types/http-proxy': 1.17.15
|
||||||
http-proxy: 1.18.1
|
debug: 4.4.0(supports-color@8.1.1)
|
||||||
|
http-proxy: 1.18.1(debug@4.4.0)
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
is-plain-obj: 3.0.0
|
is-plain-object: 5.0.0
|
||||||
micromatch: 4.0.8
|
micromatch: 4.0.8
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/http-proxy@1.18.1:
|
/http-proxy@1.18.1(debug@4.4.0):
|
||||||
resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
|
resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
eventemitter3: 4.0.7
|
eventemitter3: 4.0.7
|
||||||
follow-redirects: 1.15.6
|
follow-redirects: 1.15.6(debug@4.4.0)
|
||||||
requires-port: 1.0.0
|
requires-port: 1.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
@ -15567,7 +15565,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@tootallnate/quickjs-emscripten': 0.23.0
|
'@tootallnate/quickjs-emscripten': 0.23.0
|
||||||
agent-base: 7.1.1
|
agent-base: 7.1.1
|
||||||
debug: 4.3.4
|
debug: 4.4.0(supports-color@8.1.1)
|
||||||
get-uri: 6.0.3
|
get-uri: 6.0.3
|
||||||
http-proxy-agent: 7.0.2
|
http-proxy-agent: 7.0.2
|
||||||
https-proxy-agent: 7.0.5
|
https-proxy-agent: 7.0.5
|
||||||
@ -16443,7 +16441,7 @@ packages:
|
|||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 7.1.1
|
agent-base: 7.1.1
|
||||||
debug: 4.3.4
|
debug: 4.4.0(supports-color@8.1.1)
|
||||||
http-proxy-agent: 7.0.2
|
http-proxy-agent: 7.0.2
|
||||||
https-proxy-agent: 7.0.5
|
https-proxy-agent: 7.0.5
|
||||||
lru-cache: 7.18.3
|
lru-cache: 7.18.3
|
||||||
@ -17920,7 +17918,7 @@ packages:
|
|||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 7.1.1
|
agent-base: 7.1.1
|
||||||
debug: 4.3.4
|
debug: 4.4.0(supports-color@8.1.1)
|
||||||
socks: 2.8.3
|
socks: 2.8.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@ -19503,7 +19501,7 @@ packages:
|
|||||||
express: 4.21.0
|
express: 4.21.0
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
html-entities: 2.5.2
|
html-entities: 2.5.2
|
||||||
http-proxy-middleware: 2.0.6(@types/express@4.17.21)
|
http-proxy-middleware: 3.0.5
|
||||||
ipaddr.js: 2.2.0
|
ipaddr.js: 2.2.0
|
||||||
launch-editor: 2.8.1
|
launch-editor: 2.8.1
|
||||||
open: 8.4.2
|
open: 8.4.2
|
||||||
@ -19520,7 +19518,6 @@ packages:
|
|||||||
ws: 8.18.0
|
ws: 8.18.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- debug
|
|
||||||
- supports-color
|
- supports-color
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -75,7 +75,7 @@ services:
|
|||||||
- mailhog-data:/mailhog-data
|
- mailhog-data:/mailhog-data
|
||||||
|
|
||||||
wordpress:
|
wordpress:
|
||||||
image: wordpress:${WORDPRESS_IMAGE_VERSION:-6.8.0-php8.3}
|
image: wordpress:${WORDPRESS_IMAGE_VERSION:-6.8.1-php8.3}
|
||||||
container_name: wordpress_${CIRCLE_NODE_INDEX:-default}
|
container_name: wordpress_${CIRCLE_NODE_INDEX:-default}
|
||||||
depends_on:
|
depends_on:
|
||||||
smtp:
|
smtp:
|
||||||
|
Reference in New Issue
Block a user