merge upstream

This commit is contained in:
MichaelYick 2025-03-09 11:12:56 +00:00
commit b0cdbe2db4
160 changed files with 1177 additions and 369 deletions

View File

@ -197,10 +197,10 @@ jobs:
- run:
name: Download additional WP Plugins for tests
command: |
./do download:woo-commerce-zip 9.6.2
./do download:woo-commerce-zip 9.7.0
./do download:woo-commerce-subscriptions-zip 7.2.1
./do download:woo-commerce-memberships-zip 1.26.5
./do download:automate-woo-zip 6.1.6
./do download:automate-woo-zip 6.1.7
- run:
name: Dump tests ENV variables for acceptance tests
command: |
@ -888,6 +888,146 @@ jobs:
- store_artifacts:
path: tests/_output
qit_malware_scan:
executor: wpcli_php_latest
steps:
- attach_workspace:
at: /home/circleci
- run:
name: 'Set up environment'
command: |
# Copy built ZIP to local directory for easier access from QIT
cp /home/circleci/mailpoet/mailpoet.zip .
# Authenticate in QIT
./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}"
- run:
name: 'QIT Malware Scan'
command: ./do qa:qit-malware | tee tests/_output/qit-malware
- run:
name: 'Retrieve test results'
command: |
grep "Result Url" tests/_output/qit-malware | awk '{ print $3 }' | xargs curl -o tests/_output/report.html
when: always
- store_artifacts:
path: tests/_output
qit_php_compatibility:
executor: wpcli_php_latest
steps:
- attach_workspace:
at: /home/circleci
- run:
name: 'Set up environment'
command: |
# Copy built ZIP to local directory for easier access from QIT
cp /home/circleci/mailpoet/mailpoet.zip .
# Authenticate in QIT
./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}"
- run:
name: 'QIT PHP Compatibility Check'
command: ./do qa:qit-php-compatibility | tee tests/_output/qit-php-compatibility
- run:
name: 'Retrieve test results'
command: |
grep "Result Url" tests/_output/qit-php-compatibility | awk '{ print $3 }' | xargs curl -o tests/_output/report.html
when: always
- store_artifacts:
path: tests/_output
qit_activation_tests:
executor: wpcli_php_latest
steps:
- attach_workspace:
at: /home/circleci
- run:
name: 'Set up environment'
command: |
# Copy built ZIP to local directory for easier access from QIT
cp /home/circleci/mailpoet/mailpoet.zip .
# Authenticate in QIT
./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}"
- run:
name: 'QIT Activation Tests'
command: |
LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2)
if [ -z "$LATEST_WC_BETA" ]; then
echo "No WooCommerce Beta version found. Using stable."
./do qa:qit-activation | tee tests/_output/qit-activation
else
echo "Using WooCommerce Beta Version: $LATEST_WC_BETA"
./do qa:qit-activation --wc=$LATEST_WC_BETA | tee tests/_output/qit-activation
fi
- run:
name: 'Retrieve test results'
command: |
grep "Result Url" tests/_output/qit-activation | awk '{ print $3 }' | xargs curl -o tests/_output/report.html
when: always
- store_artifacts:
path: tests/_output
qit_woo_api_tests:
executor: wpcli_php_latest
steps:
- attach_workspace:
at: /home/circleci
- run:
name: 'Set up environment'
command: |
# Copy built ZIP to local directory for easier access from QIT
cp /home/circleci/mailpoet/mailpoet.zip .
# Authenticate in QIT
./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}"
- run:
name: 'QIT Woo API Tests'
command: |
LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2)
if [ -z "$LATEST_WC_BETA" ]; then
echo "No WooCommerce Beta version found. Using stable."
./do qa:qit-woo-api | tee tests/_output/qit-woo-api
else
echo "Using WooCommerce Beta Version: $LATEST_WC_BETA"
./do qa:qit-woo-api --wc=$LATEST_WC_BETA | tee tests/_output/qit-woo-api
fi
- run:
name: 'Retrieve test results'
command: |
grep "Result Url" tests/_output/qit-woo-api | awk '{ print $3 }' | xargs curl -o tests/_output/report.html
when: always
- store_artifacts:
path: tests/_output
qit_woo_e2e_tests:
executor: wpcli_php_latest
steps:
- attach_workspace:
at: /home/circleci
- run:
name: 'Set up environment'
command: |
# Copy built ZIP to local directory for easier access from QIT
cp /home/circleci/mailpoet/mailpoet.zip .
# Authenticate in QIT
./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}"
- run:
name: 'QIT Woo E2E Tests'
no_output_timeout: 1h # Woo E2E tests usually takes ~45m
command: |
LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2)
if [ -z "$LATEST_WC_BETA" ]; then
echo "No WooCommerce Beta version found. Using stable."
./do qa:qit-woo-e2e | tee tests/_output/qit-woo-e2e
else
echo "Using WooCommerce Beta Version: $LATEST_WC_BETA"
./do qa:qit-woo-e2e --wc=$LATEST_WC_BETA | tee tests/_output/qit-woo-e2e
fi
- run:
name: 'Retrieve test results'
command: |
grep "Result Url" tests/_output/qit-woo-e2e | awk '{ print $3 }' | xargs curl -o tests/_output/report.html
when: always
- store_artifacts:
path: tests/_output
workflows:
build_and_test:
jobs:
@ -1082,7 +1222,7 @@ workflows:
- acceptance_tests:
<<: *slack-fail-post-step
name: acceptance_oldest
woo_core_version: 9.5.2
woo_core_version: 9.6.2
woo_subscriptions_version: 7.1.0
woo_memberships_version: 1.25.2
automate_woo_version: 6.0.33
@ -1123,7 +1263,7 @@ workflows:
- integration_tests:
<<: *slack-fail-post-step
name: integration_oldest
woo_core_version: 9.5.2
woo_core_version: 9.6.2
woo_subscriptions_version: 7.1.0
woo_memberships_version: 1.25.2
automate_woo_version: 6.0.33
@ -1186,7 +1326,7 @@ workflows:
- acceptance_tests:
<<: *slack-fail-post-step
name: acceptance_with_premium_oldest
woo_core_version: 9.5.2
woo_core_version: 9.6.2
woo_subscriptions_version: 7.1.0
woo_memberships_version: 1.25.2
automate_woo_version: 6.0.33
@ -1198,7 +1338,7 @@ workflows:
- integration_tests:
<<: *slack-fail-post-step
name: integration_with_premium_oldest
woo_core_version: 9.5.2
woo_core_version: 9.6.2
woo_subscriptions_version: 7.1.0
woo_memberships_version: 1.25.2
automate_woo_version: 6.0.33
@ -1209,3 +1349,43 @@ workflows:
mysql_image: mysql:5.5
requires:
- build_premium
nightly_qit:
triggers:
- schedule:
cron: '0 2 * * 3' # Every Wednesday at 2am UTC
filters:
branches:
only:
- trunk
jobs:
- build:
<<: *slack-fail-post-step
- build_release_zip:
<<: *slack-fail-post-step
requires:
- build
- qit_security_scan:
<<: *slack-fail-post-step
requires:
- build_release_zip
- qit_activation_tests:
<<: *slack-fail-post-step
requires:
- build_release_zip
- qit_malware_scan:
<<: *slack-fail-post-step
requires:
- build_release_zip
- qit_php_compatibility:
<<: *slack-fail-post-step
requires:
- build_release_zip
- qit_woo_api_tests:
<<: *slack-fail-post-step
requires:
- build_release_zip
- qit_woo_e2e_tests:
<<: *slack-fail-post-step
requires:
- build_release_zip

View File

@ -815,6 +815,47 @@ class RoboFile extends \Robo\Tasks {
return $this->_exec('./vendor/bin/qit run:security mailpoet --zip=mailpoet.zip --wait');
}
public function qaQitMalware() {
return $this->_exec('./vendor/bin/qit run:malware mailpoet --zip=mailpoet.zip --wait');
}
public function qaQitPhpCompatibility() {
return $this->_exec('./vendor/bin/qit run:phpcompatibility mailpoet --zip=mailpoet.zip --wait');
}
public function qaQitActivation($opts = ['wp' => 'stable', 'wc' => 'stable']) {
$command = './vendor/bin/qit run:activation mailpoet --zip=mailpoet.zip --wait';
if ($opts['wp']) {
$command .= ' --wordpress_version=' . $opts['wp'];
}
if ($opts['wc']) {
$command .= ' --woocommerce_version=' . $opts['wc'];
}
return $this->_exec($command);
}
public function qaQitWooApi($opts = ['wp' => 'stable', 'wc' => 'stable']) {
$command = './vendor/bin/qit run:woo-api mailpoet --zip=mailpoet.zip --wait';
if ($opts['wp']) {
$command .= ' --wordpress_version=' . $opts['wp'];
}
if ($opts['wc']) {
$command .= ' --woocommerce_version=' . $opts['wc'];
}
return $this->_exec($command);
}
public function qaQitWooE2e($opts = ['wp' => 'stable', 'wc' => 'stable']) {
$command = './vendor/bin/qit run:woo-e2e mailpoet --zip=mailpoet.zip --wait';
if ($opts['wp']) {
$command .= ' --wordpress_version=' . $opts['wp'];
}
if ($opts['wc']) {
$command .= ' --woocommerce_version=' . $opts['wc'];
}
return $this->_exec($command);
}
public function svnCheckout() {
$svnDir = ".mp_svn";
@ -1342,7 +1383,7 @@ class RoboFile extends \Robo\Tasks {
$this->say("Release '$version[name]' info was published on Slack.");
}
public function releaseRerunCircleWorkflow(string $project = null) {
public function releaseRerunCircleWorkflow(?string $project = null) {
$circleciController = $this->createCircleCiController();
$result = $circleciController->rerunLatestWorkflow($project);
// Sometimes can be useful to know which Circle project workflow was restarted

View File

@ -34,7 +34,10 @@ class ListingComponent extends Component {
if (autoRefresh) {
jQuery(document).on('heartbeat-tick.mailpoet', () => {
this.getItems();
// Skip auto-refresh if any items are selected for bulk editing
if (this.state.selected_ids.length === 0) {
this.getItems();
}
});
}

View File

@ -19,6 +19,7 @@ Module.CouponBlockModel = base.BlockModel.extend({
return this._getDefaults(
{
isStandardEmail: App.getNewsletter().isStandardEmail(),
isAutomationEmail: App.getNewsletter().isAutomationEmail(),
productIds: [], // selected product ids,
excludedProductIds: [],
productCategoryIds: [], // selected categories id
@ -33,6 +34,10 @@ Module.CouponBlockModel = base.BlockModel.extend({
minimumAmount: '',
maximumAmount: '',
emailRestrictions: '',
restrictToSubscriber: false,
showRestrictToSubscriber:
App.getNewsletter().isAutomationEmail() ||
App.getNewsletter().isWelcomeEmail(),
styles: {
block: {
backgroundColor: '#ffffff',

View File

@ -31,6 +31,7 @@ type State = {
productCategoryIds: Post[];
excludedProductCategoryIds: Post[];
emailRestrictions: string;
restrictToSubscriber: boolean;
};
class UsageRestriction extends Component<Props, State> {
@ -62,6 +63,8 @@ class UsageRestriction extends Component<Props, State> {
'excludedProductCategoryIds',
).toJSON() as Post[],
emailRestrictions: this.getValueCallback('emailRestrictions') as string,
restrictToSubscriber:
(this.getValueCallback('restrictToSubscriber') as boolean) || false,
};
}
@ -262,6 +265,25 @@ class UsageRestriction extends Component<Props, State> {
)}
/>
</PanelRow>
{this.getValueCallback('showRestrictToSubscriber') && (
<PanelRow>
<ToggleControl
checked={this.state.restrictToSubscriber}
label={__('Restrict to subscriber email', 'mailpoet')}
onChange={(restrictToSubscriber) => {
this.setValueCallback(
'restrictToSubscriber',
restrictToSubscriber,
);
this.setState({ restrictToSubscriber });
}}
help={__(
'Restrict coupon usage to the subscriber receiving this email.',
'mailpoet',
)}
/>
</PanelRow>
)}
</PanelBody>
</Panel>
);

View File

@ -46,6 +46,18 @@ const BlockView = BaseBlock.BlockView.extend({
});
},
getTemplate() {
if (window.mailpoet_woocommerce_email_improvements_enabled) {
if (this.model.get('selected') === 'new_account') {
return window.templates.woocommerceNewAccountImproved;
}
if (this.model.get('selected') === 'processing_order') {
return window.templates.woocommerceProcessingOrderImproved;
}
if (this.model.get('selected') === 'completed_order') {
return window.templates.woocommerceCompletedOrderImproved;
}
return window.templates.woocommerceCustomerNoteImproved;
}
if (this.model.get('selected') === 'new_account') {
return window.templates.woocommerceNewAccount;
}

View File

@ -35,6 +35,9 @@ Module.NewsletterModel = SuperModel.extend({
isStandardEmail: function isStandardEmail() {
return this.get('type') === NewsletterType.Standard;
},
isWelcomeEmail: function isWelcomeEmail() {
return this.get('type') === NewsletterType.Welcome;
},
});
// Content block view and model handlers for different content types

View File

@ -1,5 +1,13 @@
== Changelog ==
= 5.8.1 - 2025-03-03 =
* Changed: minimum required WooCommerce is 9.6.
= 5.8.0 - 2025-02-24 =
* Added: allow generating coupon code in automations for a subscriber the email is sent to;
* Changed: default MailPoet pages capability changed from post to page (one of improvements is hidden previous/next post links);
* Fixed: Prevent removing the content block from the Newsletter template in the new editor.
= 5.7.1 - 2025-02-17 =
* Improved: Apply get_the_excerpt filter to MailPoets post excerpts;
* Fixed: conflict with Rank Math plugin breaking "Scheduled Actions" page.

View File

@ -158,7 +158,7 @@ class NewslettersResponseBuilder {
* @param SendingQueueEntity|null $latestQueue
* @return array<string, mixed>
*/
private function buildListingItem(NewsletterEntity $newsletter, NewsletterStatistics $statistics = null, SendingQueueEntity $latestQueue = null): array {
private function buildListingItem(NewsletterEntity $newsletter, ?NewsletterStatistics $statistics = null, ?SendingQueueEntity $latestQueue = null): array {
$couponBlockLogs = array_map(function ($item) {
return "Coupon block: $item";
}, $this->logRepository->getRawMessagesForNewsletter($newsletter, LoggerFactory::TOPIC_COUPONS));

View File

@ -6,7 +6,7 @@ use WP_REST_Response;
class Response extends WP_REST_Response {
public function __construct(
array $data = null,
?array $data = null,
int $status = 200
) {
parent::__construct(['data' => $data], $status);

View File

@ -107,7 +107,7 @@ class Help {
return $actionSchedulerData;
}
private function getLatestActionSchedulerActionDate(string $hook, string $status = null): ?string {
private function getLatestActionSchedulerActionDate(string $hook, ?string $status = null): ?string {
$query = [
'per_page' => 1,
'order' => 'DESC',

View File

@ -36,7 +36,7 @@ class FirstPurchase {
private $subscribersRepository;
public function __construct(
WCHelper $helper = null
?WCHelper $helper = null
) {
if ($helper === null) {
$helper = ContainerWrapper::getInstance()->get(WCHelper::class);

View File

@ -34,7 +34,7 @@ class PurchasedInCategory {
private $subscribersRepository;
public function __construct(
WCHelper $woocommerceHelper = null
?WCHelper $woocommerceHelper = null
) {
if ($woocommerceHelper === null) {
$woocommerceHelper = ContainerWrapper::getInstance()->get(WCHelper::class);

View File

@ -35,7 +35,7 @@ class PurchasedProduct {
private $subscribersRepository;
public function __construct(
WCHelper $helper = null
?WCHelper $helper = null
) {
if ($helper === null) {
$helper = ContainerWrapper::getInstance()->get(WCHelper::class);

View File

@ -25,15 +25,15 @@ class StepRunController {
$this->stepRunLogger = $stepRunLogger;
}
public function scheduleProgress(int $timestamp = null): int {
public function scheduleProgress(?int $timestamp = null): int {
return $this->stepScheduler->scheduleProgress($this->stepRunArgs, $timestamp);
}
public function scheduleNextStep(int $timestamp = null): int {
public function scheduleNextStep(?int $timestamp = null): int {
return $this->stepScheduler->scheduleNextStep($this->stepRunArgs, $timestamp);
}
public function scheduleNextStepByIndex(int $nextStepIndex, int $timestamp = null): int {
public function scheduleNextStepByIndex(int $nextStepIndex, ?int $timestamp = null): int {
return $this->stepScheduler->scheduleNextStepByIndex($this->stepRunArgs, $nextStepIndex, $timestamp);
}

View File

@ -42,7 +42,7 @@ class StepRunLogger {
string $stepId,
string $stepType,
int $runNumber,
bool $isWpDebug = null
?bool $isWpDebug = null
) {
$this->automationRunLogStorage = $automationRunLogStorage;
$this->hooks = $hooks;

View File

@ -23,13 +23,13 @@ class StepScheduler {
$this->automationRunStorage = $automationRunStorage;
}
public function scheduleProgress(StepRunArgs $args, int $timestamp = null): int {
public function scheduleProgress(StepRunArgs $args, ?int $timestamp = null): int {
$runId = $args->getAutomationRun()->getId();
$data = $this->getActionData($runId, $args->getStep()->getId(), $args->getRunNumber() + 1);
return $this->scheduleStepAction($data, $timestamp);
}
public function scheduleNextStep(StepRunArgs $args, int $timestamp = null): int {
public function scheduleNextStep(StepRunArgs $args, ?int $timestamp = null): int {
$step = $args->getStep();
$nextSteps = $step->getNextSteps();
@ -46,7 +46,7 @@ class StepScheduler {
return $this->scheduleNextStepByIndex($args, 0, $timestamp);
}
public function scheduleNextStepByIndex(StepRunArgs $args, int $nextStepIndex, int $timestamp = null): int {
public function scheduleNextStepByIndex(StepRunArgs $args, int $nextStepIndex, ?int $timestamp = null): int {
$step = $args->getStep();
$nextStep = $step->getNextSteps()[$nextStepIndex] ?? null;
if (!$nextStep) {
@ -95,7 +95,7 @@ class StepScheduler {
return $this->hasScheduledNextStep($args) || $this->hasScheduledProgress($args);
}
private function scheduleStepAction(array $data, int $timestamp = null): int {
private function scheduleStepAction(array $data, ?int $timestamp = null): int {
return $timestamp === null
? $this->actionScheduler->enqueue(Hooks::AUTOMATION_STEP, $data)
: $this->actionScheduler->schedule($timestamp, Hooks::AUTOMATION_STEP, $data);

View File

@ -53,8 +53,8 @@ class Automation {
string $name,
array $steps,
\WP_User $author,
int $id = null,
int $versionId = null
?int $id = null,
?int $versionId = null
) {
$this->name = $name;
$this->steps = $steps;

View File

@ -42,7 +42,7 @@ class AutomationRun {
int $versionId,
string $triggerKey,
array $subjects,
int $id = null
?int $id = null
) {
$this->automationId = $automationId;
$this->versionId = $versionId;
@ -91,7 +91,7 @@ class AutomationRun {
}
/** @return Subject[] */
public function getSubjects(string $key = null): array {
public function getSubjects(?string $key = null): array {
if ($key) {
return array_values(
array_filter($this->subjects, function (Subject $subject) use ($key) {

View File

@ -60,7 +60,7 @@ class AutomationRunLog {
int $automationRunId,
string $stepId,
string $stepType,
int $id = null
?int $id = null
) {
$this->automationRunId = $automationRunId;
$this->stepId = $stepId;

View File

@ -35,7 +35,7 @@ class Step {
string $key,
array $args,
array $nextSteps,
Filters $filters = null
?Filters $filters = null
) {
$this->id = $id;
$this->type = $type;

View File

@ -20,16 +20,16 @@ abstract class Exception extends PhpException implements RestException {
protected $errors = [];
final public function __construct(
string $message = null,
string $errorCode = null,
Throwable $previous = null
?string $message = null,
?string $errorCode = null,
?Throwable $previous = null
) {
parent::__construct($message ?? __('Unknown error.', 'mailpoet'), 0, $previous);
$this->errorCode = $errorCode ?? 'mailpoet_automation_unknown_error';
}
/** @return static */
public static function create(Throwable $previous = null) {
public static function create(?Throwable $previous = null) {
return new static(null, null, $previous);
}

View File

@ -19,7 +19,7 @@ class AutomationMapper {
$this->statisticsStorage = $statisticsStorage;
}
public function buildAutomation(Automation $automation, AutomationStatistics $statistics = null): array {
public function buildAutomation(Automation $automation, ?AutomationStatistics $statistics = null): array {
return [
'id' => $automation->getId(),

View File

@ -98,7 +98,7 @@ class Registry {
}
/** @return array<string, AutomationTemplate> */
public function getTemplates(string $category = null): array {
public function getTemplates(?string $category = null): array {
return $category
? array_filter(
$this->templates,
@ -254,7 +254,7 @@ class Registry {
$this->wordPress->addAction(Hooks::AUTOMATION_BEFORE_SAVE, $callback, $priority);
}
public function onBeforeAutomationStepSave(callable $callback, string $key = null, int $priority = 10): void {
public function onBeforeAutomationStepSave(callable $callback, ?string $key = null, int $priority = 10): void {
$keyPart = $key ? "/key=$key" : '';
$this->wordPress->addAction(Hooks::AUTOMATION_STEP_BEFORE_SAVE . $keyPart, $callback, $priority, 2);
}

View File

@ -32,7 +32,7 @@ class AutomationRunLogStorage {
}
}
public function getAutomationRunStatisticsForAutomationInTimeFrame(int $automationId, string $status, \DateTimeImmutable $after, \DateTimeImmutable $before, int $versionId = null): array {
public function getAutomationRunStatisticsForAutomationInTimeFrame(int $automationId, string $status, \DateTimeImmutable $after, \DateTimeImmutable $before, ?int $versionId = null): array {
global $wpdb;
$andWhere = $versionId ? 'AND run.version_id = %d' : '';
$results = $wpdb->get_results(

View File

@ -218,7 +218,7 @@ class AutomationRunStorage {
}
}
public function getAutomationStepStatisticForTimeFrame(int $automationId, string $status, \DateTimeImmutable $after, \DateTimeImmutable $before, int $versionId = null): array {
public function getAutomationStepStatisticForTimeFrame(int $automationId, string $status, \DateTimeImmutable $after, \DateTimeImmutable $before, ?int $versionId = null): array {
global $wpdb;
$andWhere = $versionId ? 'AND version_id = %d' : '';
$result = $wpdb->get_results(

View File

@ -39,7 +39,7 @@ class AutomationStatisticsStorage {
return $statistics;
}
public function getAutomationStats(int $automationId, int $versionId = null, \DateTimeImmutable $after = null, \DateTimeImmutable $before = null): AutomationStatistics {
public function getAutomationStats(int $automationId, ?int $versionId = null, ?\DateTimeImmutable $after = null, ?\DateTimeImmutable $before = null): AutomationStatistics {
$data = $this->getStatistics([$automationId], $versionId, $after, $before);
return new AutomationStatistics(
$automationId,
@ -53,7 +53,7 @@ class AutomationStatisticsStorage {
* @param int[] $automationIds
* @return array<int, array{id: int, total: int, running: int}>
*/
private function getStatistics(array $automationIds, int $versionId = null, \DateTimeImmutable $after = null, \DateTimeImmutable $before = null): array {
private function getStatistics(array $automationIds, ?int $versionId = null, ?\DateTimeImmutable $after = null, ?\DateTimeImmutable $before = null): array {
global $wpdb;
$totalSubquery = $this->getStatsQuery($automationIds, $versionId, $after, $before);
$runningSubquery = $this->getStatsQuery($automationIds, $versionId, $after, $before, AutomationRun::STATUS_RUNNING);
@ -71,7 +71,7 @@ class AutomationStatisticsStorage {
return array_combine(array_column($results, 'id'), $results) ?: [];
}
private function getStatsQuery(array $automationIds, int $versionId = null, \DateTimeImmutable $after = null, \DateTimeImmutable $before = null, string $status = null): string {
private function getStatsQuery(array $automationIds, ?int $versionId = null, ?\DateTimeImmutable $after = null, ?\DateTimeImmutable $before = null, ?string $status = null): string {
global $wpdb;
$versionCondition = $versionId ? 'AND version_id = %d' : '';

View File

@ -126,7 +126,7 @@ class AutomationStorage {
) : [];
}
public function getAutomation(int $automationId, int $versionId = null): ?Automation {
public function getAutomation(int $automationId, ?int $versionId = null): ?Automation {
global $wpdb;
if ($versionId) {
@ -153,7 +153,7 @@ class AutomationStorage {
}
/** @return Automation[] */
public function getAutomations(array $status = null): array {
public function getAutomations(?array $status = null): array {
global $wpdb;
$statusFilter = $status ? 'AND a.status IN (' . implode(',', array_fill(0, count($status), '%s')) . ')' : '';
@ -184,7 +184,7 @@ class AutomationStorage {
}
/** @return int[] */
public function getAutomationIdsBySubject(Subject $subject, array $runStatus = null, int $inTheLastSeconds = null): array {
public function getAutomationIdsBySubject(Subject $subject, ?array $runStatus = null, ?int $inTheLastSeconds = null): array {
global $wpdb;
$statusFilter = $runStatus ? 'AND r.status IN (' . implode(',', array_fill(0, count($runStatus), '%s')) . ')' : '';

View File

@ -68,7 +68,7 @@ class WordPress {
}
/** @return WP_Post[]|int[] */
public function getPosts(array $args = null): array {
public function getPosts(?array $args = null): array {
return get_posts($args);
}

View File

@ -423,7 +423,7 @@ class SendEmailAction implements Action {
$this->newslettersRepository->flush();
}
private function storeNewsletterOption(NewsletterEntity $newsletter, string $optionName, string $optionValue = null): void {
private function storeNewsletterOption(NewsletterEntity $newsletter, string $optionName, ?string $optionValue = null): void {
$options = $newsletter->getOptions()->toArray();
foreach ($options as $key => $option) {
if ($option->getName() === $optionName) {

View File

@ -41,7 +41,7 @@ class Query {
string $orderDirection = 'asc',
int $page = 1,
array $filter = [],
string $search = null
?string $search = null
) {
$this->primaryAfter = $primaryAfter;
$this->primaryBefore = $primaryBefore;

View File

@ -25,7 +25,7 @@ class QueryWithCompare extends Query {
string $orderDirection = 'asc',
int $page = 0,
array $filter = [],
string $search = null
?string $search = null
) {
parent::__construct($primaryAfter, $primaryBefore, $limit, $orderBy, $orderDirection, $page, $filter, $search);
$this->secondaryAfter = $secondaryAfter;

View File

@ -66,7 +66,7 @@ class SubscriberAutomationFieldsFactory {
];
}
private function getAutomationIds(SubscriberPayload $payload, array $status = null, array $params = []): array {
private function getAutomationIds(SubscriberPayload $payload, ?array $status = null, array $params = []): array {
$inTheLastSeconds = isset($params['in_the_last']) ? (int)$params['in_the_last'] : null;
$subject = new Subject(SubscriberSubject::KEY, ['subscriber_id' => $payload->getId()]);
return $this->automationStorage->getAutomationIdsBySubject($subject, $status, $inTheLastSeconds);

View File

@ -141,7 +141,7 @@ class SubscriberCustomFieldsFactory {
private function getCustomFieldValue(SubscriberPayload $payload, CustomFieldEntity $customField): ?string {
$subscriberCustomField = $payload->getSubscriber()->getSubscriberCustomFields()->filter(
function (SubscriberCustomFieldEntity $subscriberCustomField = null) use ($customField) {
function (?SubscriberCustomFieldEntity $subscriberCustomField = null) use ($customField) {
return $subscriberCustomField && $subscriberCustomField->getCustomField() === $customField;
}
)->first() ?: null;

View File

@ -332,7 +332,7 @@ class CustomerOrderFieldsFactory {
return $date ? new DateTimeImmutable($date, new DateTimeZone('GMT')) : null;
}
private function getOrderProductTermIds(WC_Customer $customer, string $taxonomy, int $inTheLastSeconds = null): array {
private function getOrderProductTermIds(WC_Customer $customer, string $taxonomy, ?int $inTheLastSeconds = null): array {
global $wpdb;
$statuses = array_map(function (string $status) {

View File

@ -53,7 +53,7 @@ class CustomerReviewFieldsFactory {
* Calculate the customer's review count excluding multiple reviews on the same product.
* Inspired by AutomateWoo implementation.
*/
private function getUniqueProductReviewCount(WC_Customer $customer, int $inTheLastSeconds = null): int {
private function getUniqueProductReviewCount(WC_Customer $customer, ?int $inTheLastSeconds = null): int {
global $wpdb;
$inTheLastFilter = isset($inTheLastSeconds) ? 'AND c.comment_date_gmt >= DATE_SUB(current_timestamp, INTERVAL %d SECOND)' : '';

View File

@ -11,8 +11,8 @@ class CustomerPayload implements Payload {
private ?WC_Order $order;
public function __construct(
WC_Customer $customer = null,
WC_Order $order = null
?WC_Customer $customer = null,
?WC_Order $order = null
) {
$this->customer = $customer;
$this->order = $order;

View File

@ -10,7 +10,7 @@ class CaptchaPhrase {
public function __construct(
CaptchaSession $session,
PhraseBuilder $phraseBuilder = null
?PhraseBuilder $phraseBuilder = null
) {
$this->session = $session;
$this->phraseBuilder = $phraseBuilder ?? new PhraseBuilder();

View File

@ -28,6 +28,7 @@ class PageRenderer {
$this->wp->removeAction('wp_head', 'noindex', 1);
$this->wp->addAction('wp_head', [$this, 'setMetaRobots'], 1);
$this->wp->addFilter('the_title', [$this, 'setPageTitle']);
$this->wp->addFilter('single_post_title', [$this, 'setPageTitle']);
$this->wp->addFilter('the_content', [$this, 'setPageContent']);
}
@ -39,18 +40,18 @@ class PageRenderer {
if ($separatorLocation === 'right') {
// first part
$titleParts[0] = $this->setPageTitle();
$titleParts[0] = $this->getPageTitle();
} else {
// last part
$lastIndex = count($titleParts) - 1;
$titleParts[$lastIndex] = $this->setPageTitle();
$titleParts[$lastIndex] = $this->getPageTitle();
}
return implode(" $separator ", $titleParts);
}
public function setWindowTitleParts($meta = []) {
$meta['title'] = $this->setPageTitle();
$meta['title'] = $this->getPageTitle();
return $meta;
}
@ -58,8 +59,11 @@ class PageRenderer {
echo '<meta name="robots" content="noindex,nofollow">';
}
public function setPageTitle() {
return __("Confirm youre not a robot", 'mailpoet');
public function setPageTitle($title = '') {
if ($title === __('MailPoet Page', 'mailpoet')) {
return $this->getPageTitle();
}
return $title;
}
public function setPageContent($pageContent) {
@ -72,4 +76,8 @@ class PageRenderer {
return str_replace('[mailpoet_page]', trim($content), $pageContent);
}
private function getPageTitle() {
return __('Confirm youre not a robot', 'mailpoet');
}
}

View File

@ -10,7 +10,7 @@ class ValidationError extends \RuntimeException {
$message = "",
array $meta = [],
$code = 0,
\Throwable $previous = null
?\Throwable $previous = null
) {
$this->meta = $meta;
$this->meta['error'] = $message;

View File

@ -16,7 +16,7 @@ class Capabilities {
public function __construct(
$renderer = null,
WPFunctions $wp = null
?WPFunctions $wp = null
) {
if ($renderer !== null) {
$this->renderer = $renderer;

View File

@ -399,7 +399,7 @@ class Hooks {
}
public function setupWooCommerceSettings() {
$this->wp->addAction('woocommerce_settings_start', [
$this->wp->addAction('woocommerce_settings_email_options_after', [
$this->hooksWooCommerce,
'disableWooCommerceSettings',
]);

View File

@ -145,7 +145,7 @@ class HooksWooCommerce {
}
}
public function onRegister($errors, string $userLogin, string $userEmail = null) {
public function onRegister($errors, string $userLogin, ?string $userEmail = null) {
try {
if (empty($errors->errors)) {
$this->subscriberRegistration->onRegister($errors, $userLogin, $userEmail);

View File

@ -711,7 +711,7 @@ class Menu {
);
}
public static function isOnMailPoetAdminPage(array $exclude = null, $screenId = null) {
public static function isOnMailPoetAdminPage(?array $exclude = null, $screenId = null) {
if (is_null($screenId)) {
if (empty($_REQUEST['page'])) {
return false;
@ -762,7 +762,7 @@ class Menu {
// Used for displaying admin notices only
}
public function checkPremiumKey(ServicesChecker $checker = null) {
public function checkPremiumKey(?ServicesChecker $checker = null) {
$showNotices = isset($_SERVER['SCRIPT_NAME'])
&& stripos(sanitize_text_field(wp_unslash($_SERVER['SCRIPT_NAME'])), 'plugins.php') !== false;
$checker = $checker ?: $this->servicesChecker;

View File

@ -14,7 +14,7 @@ class TwigEnvironment extends Environment {
* We need to produce the same class regardless of PHP_VERSION. Therefore, we
* overwrite this method.
**/
public function getTemplateClass(string $name, int $index = null): string {
public function getTemplateClass(string $name, ?int $index = null): string {
return $this->templateClassPrefix . \hash('sha256', $name) . (null === $index ? '' : '___' . $index);
}
}

View File

@ -27,7 +27,7 @@ class DaemonHttpRunner {
private $wordpressTrigger;
public function __construct(
Daemon $daemon = null,
?Daemon $daemon,
CronHelper $cronHelper,
SettingsController $settings,
WordPress $wordpressTrigger
@ -140,7 +140,7 @@ class DaemonHttpRunner {
*
* @return bool
*/
private function shouldTerminateExecution(array $settingsDaemonData = null) {
private function shouldTerminateExecution(?array $settingsDaemonData = null) {
return !$settingsDaemonData ||
$settingsDaemonData['token'] !== $this->token ||
(isset($settingsDaemonData['status']) && $settingsDaemonData['status'] !== CronHelper::DAEMON_STATUS_ACTIVE);

View File

@ -64,7 +64,7 @@ class Links {
return $this->newsletterLinks->save($links, $newsletter->getId(), $queue->getId());
}
public function getUnsubscribeUrl($queueId, SubscriberEntity $subscriber = null) {
public function getUnsubscribeUrl($queueId, ?SubscriberEntity $subscriber = null) {
if ($this->trackingConfig->isEmailTrackingEnabled() && $subscriber) {
$linkHash = $this->newsletterLinkRepository->findOneBy(
[

View File

@ -23,7 +23,7 @@ class Mailer {
$this->mailer = $this->configureMailer();
}
public function configureMailer(NewsletterEntity $newsletter = null) {
public function configureMailer(?NewsletterEntity $newsletter = null) {
$sender['address'] = ($newsletter && !empty($newsletter->getSenderAddress())) ?
$newsletter->getSenderAddress() :
null;

View File

@ -79,10 +79,10 @@ class Newsletter {
private $personalizer;
public function __construct(
WPFunctions $wp = null,
PostsTask $postsTask = null,
GATracking $gaTracking = null,
Emoji $emoji = null
?WPFunctions $wp = null,
?PostsTask $postsTask = null,
?GATracking $gaTracking = null,
?Emoji $emoji = null
) {
$trackingConfig = ContainerWrapper::getInstance()->get(TrackingConfig::class);
$this->trackingEnabled = $trackingConfig->isEmailTrackingEnabled();

View File

@ -16,7 +16,7 @@ class Shortcodes {
* @param SubscriberEntity|null $subscriber
* @param SendingQueueEntity|null $queue
*/
public static function process($content, $contentSource = null, NewsletterEntity $newsletter = null, SubscriberEntity $subscriber = null, SendingQueueEntity $queue = null) {
public static function process($content, $contentSource = null, ?NewsletterEntity $newsletter = null, ?SubscriberEntity $subscriber = null, ?SendingQueueEntity $queue = null) {
/** @var NewsletterShortcodes $shortcodes */
$shortcodes = ContainerWrapper::getInstance()->get(NewsletterShortcodes::class);

View File

@ -138,7 +138,7 @@ class Worker {
];
}
private function prepareContext(NewsletterEntity $newsletter, SendingQueueEntity $sendingQueue, NewsletterLinkEntity $link = null) {
private function prepareContext(NewsletterEntity $newsletter, SendingQueueEntity $sendingQueue, ?NewsletterLinkEntity $link = null) {
$statistics = $this->newsletterStatisticsRepository->getStatistics($newsletter);
$clicked = ($statistics->getClickCount() * 100) / $statistics->getTotalSentCount();
$opened = ($statistics->getOpenCount() * 100) / $statistics->getTotalSentCount();

View File

@ -699,7 +699,7 @@ class ContainerConfigurator implements IContainerConfigurator {
return $container;
}
public static function getPremiumService($id, ContainerInterface $container = null) {
public static function getPremiumService($id, ?ContainerInterface $container = null) {
if ($container === null) {
return null;
}

View File

@ -20,7 +20,7 @@ class ContainerWrapper implements ContainerInterface {
public function __construct(
Container $freeContainer,
Container $premiumContainer = null
?Container $premiumContainer = null
) {
$this->freeContainer = $freeContainer;
$this->premiumContainer = $premiumContainer;

View File

@ -41,7 +41,7 @@ abstract class Repository {
* @param int|null $offset
* @return T[]
*/
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) {
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null) {
return $this->doctrineRepository->findBy($criteria, $orderBy, $limit, $offset);
}
@ -62,7 +62,7 @@ abstract class Repository {
* @param array|null $orderBy
* @return T|null
*/
public function findOneBy(array $criteria, array $orderBy = null) {
public function findOneBy(array $criteria, ?array $orderBy = null) {
return $this->doctrineRepository->findOneBy($criteria, $orderBy);
}
@ -114,7 +114,7 @@ abstract class Repository {
/**
* @param callable(T): bool|null $filter
*/
public function refreshAll(callable $filter = null): void {
public function refreshAll(?callable $filter = null): void {
$entities = $this->getAllFromIdentityMap();
foreach ($entities as $entity) {
if ($filter && !$filter($entity)) {
@ -142,7 +142,7 @@ abstract class Repository {
/**
* @param callable(T): bool|null $filter
*/
public function detachAll(callable $filter = null): void {
public function detachAll(?callable $filter = null): void {
$entities = $this->getAllFromIdentityMap();
foreach ($entities as $entity) {
if ($filter && !$filter($entity)) {

View File

@ -174,7 +174,7 @@ class FormEntity {
];
}
public function getBlocksByTypes(array $types, array $blocks = null): array {
public function getBlocksByTypes(array $types, ?array $blocks = null): array {
$found = [];
if ($blocks === null) {
$blocks = $this->getBody() ?? [];

View File

@ -474,7 +474,7 @@ class NewsletterEntity {
* @return int[]
*/
public function getSegmentIds() {
return array_filter($this->newsletterSegments->map(function(NewsletterSegmentEntity $newsletterSegment = null) {
return array_filter($this->newsletterSegments->map(function(?NewsletterSegmentEntity $newsletterSegment = null) {
if (!$newsletterSegment) return null;
$segment = $newsletterSegment->getSegment();
return $segment ? (int)$segment->getId() : null;
@ -489,7 +489,7 @@ class NewsletterEntity {
}
public function getOption(string $name): ?NewsletterOptionEntity {
$option = $this->options->filter(function (NewsletterOptionEntity $option = null) use ($name): bool {
$option = $this->options->filter(function (?NewsletterOptionEntity $option = null) use ($name): bool {
if (!$option) return false;
return ($field = $option->getOptionField()) ? $field->getName() === $name : false;
})->first();

View File

@ -243,7 +243,7 @@ class ScheduledTaskEntity {
public function getSubscribersByProcessed(int $processed): array {
$criteria = Criteria::create()
->where(Criteria::expr()->eq('processed', $processed));
$subscribers = $this->subscribers->matching($criteria)->map(function (ScheduledTaskSubscriberEntity $taskSubscriber = null): ?SubscriberEntity {
$subscribers = $this->subscribers->matching($criteria)->map(function (?ScheduledTaskSubscriberEntity $taskSubscriber = null): ?SubscriberEntity {
if (!$taskSubscriber) return null;
return $taskSubscriber->getSubscriber();
});

View File

@ -61,7 +61,7 @@ class ScheduledTaskSubscriberEntity {
SubscriberEntity $subscriber,
int $processed = 0,
int $failed = 0,
string $error = null
?string $error = null
) {
$this->task = $task;
$this->subscriber = $subscriber;

View File

@ -45,7 +45,7 @@ class StatisticsNewsletterEntity {
NewsletterEntity $newsletter,
SendingQueueEntity $queue,
SubscriberEntity $subscriber,
\DateTimeInterface $sentAt = null
?\DateTimeInterface $sentAt = null
) {
$this->newsletter = $newsletter;
$this->queue = $queue;

View File

@ -67,8 +67,8 @@ class StatisticsUnsubscribeEntity {
private $method = self::METHOD_UNKNOWN;
public function __construct(
NewsletterEntity $newsletter = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter,
?SendingQueueEntity $queue,
SubscriberEntity $subscriber
) {
$this->newsletter = $newsletter;

View File

@ -504,7 +504,7 @@ class SubscriberEntity {
/** * @return Collection<int, SegmentEntity> */
public function getSegments() {
return $this->subscriberSegments->map(function (SubscriberSegmentEntity $subscriberSegment = null) {
return $this->subscriberSegments->map(function (?SubscriberSegmentEntity $subscriberSegment = null) {
if (!$subscriberSegment) return null;
return $subscriberSegment->getSegment();
})->filter(function (?SegmentEntity $segment = null) {
@ -635,7 +635,7 @@ class SubscriberEntity {
/** @ORM\PreFlush */
public function cleanupSubscriberSegments(): void {
// Delete old orphan SubscriberSegments to avoid errors on update
$this->subscriberSegments->map(function (SubscriberSegmentEntity $subscriberSegment = null) {
$this->subscriberSegments->map(function (?SubscriberSegmentEntity $subscriberSegment = null) {
if (!$subscriberSegment) return null;
if ($subscriberSegment->getSegment() === null) {
$this->subscriberSegments->removeElement($subscriberSegment);

View File

@ -41,14 +41,14 @@ class Renderer {
return $html;
}
public function renderHTML(FormEntity $form = null): string {
public function renderHTML(?FormEntity $form = null): string {
if (($form instanceof FormEntity) && !empty($form->getBody()) && is_array($form->getSettings())) {
return $this->renderBlocks($form->getBody(), $form->getSettings() ?? [], $form->getId());
}
return '';
}
public function getCustomStyles(FormEntity $form = null): string {
public function getCustomStyles(?FormEntity $form = null): string {
if (($form instanceof FormEntity) && (strlen(trim($form->getStyles() ?? '')) > 0)) {
return strip_tags($form->getStyles() ?? '');
} else {

View File

@ -31,9 +31,9 @@ class ListingDefinition {
private $selection;
public function __construct(
string $group = null,
?string $group = null,
array $filters = [],
string $search = null,
?string $search = null,
array $parameters = [],
string $sortBy = 'created_at',
string $sortOrder = 'desc',

View File

@ -50,11 +50,11 @@ class LogRepository extends Repository {
* @return LogEntity[]
*/
public function getLogs(
\DateTimeInterface $dateFrom = null,
\DateTimeInterface $dateTo = null,
string $search = null,
string $offset = null,
string $limit = null
?\DateTimeInterface $dateFrom = null,
?\DateTimeInterface $dateTo = null,
?string $search = null,
?string $offset = null,
?string $limit = null
): array {
$query = $this->doctrineRepository->createQueryBuilder('l')
->select('l');

View File

@ -45,7 +45,7 @@ class MailerFactory {
return $this->defaultMailer;
}
public function buildMailer(array $mailerConfig = null, array $sender = null, array $replyTo = null, string $returnPath = null): Mailer {
public function buildMailer(?array $mailerConfig = null, ?array $sender = null, ?array $replyTo = null, ?string $returnPath = null): Mailer {
$sender = $this->getSenderNameAndAddress($sender);
$replyTo = $this->getReplyToNameAndAddress($sender, $replyTo);
$mailerConfig = $mailerConfig ?? $this->getMailerConfig();
@ -120,7 +120,7 @@ class MailerFactory {
return $config;
}
private function getSenderNameAndAddress(array $sender = null): array {
private function getSenderNameAndAddress(?array $sender = null): array {
if (empty($sender)) {
$sender = $this->settings->get('sender', []);
if (empty($sender['address'])) throw new InvalidStateException(__('Sender name and email are not configured.', 'mailpoet'));
@ -133,7 +133,7 @@ class MailerFactory {
];
}
private function getReplyToNameAndAddress(array $sender, array $replyTo = null): array {
private function getReplyToNameAndAddress(array $sender, ?array $replyTo = null): array {
if (!$replyTo) {
$replyTo = $this->settings->get('reply_to');
$replyTo['name'] = (!empty($replyTo['name'])) ?

View File

@ -33,7 +33,7 @@ class MailerLog {
* @param MailerLogData|null $mailerLog
* @return MailerLogData
*/
public static function getMailerLog(array $mailerLog = null): array {
public static function getMailerLog(?array $mailerLog = null): array {
if ($mailerLog) return $mailerLog;
$settings = SettingsController::getInstance();
$mailerLog = $settings->get(self::SETTING_NAME);
@ -90,7 +90,7 @@ class MailerLog {
* @return null
* @throws \Exception
*/
public static function enforceExecutionRequirements(array $mailerLog = null) {
public static function enforceExecutionRequirements(?array $mailerLog = null) {
$mailerLog = self::getMailerLog($mailerLog);
if ($mailerLog['retry_attempt'] === self::RETRY_ATTEMPTS_LIMIT) {
$mailerLog = self::pauseSending($mailerLog);
@ -162,9 +162,9 @@ class MailerLog {
public static function processError(
string $operation,
string $errorMessage,
string $errorCode = null,
?string $errorCode = null,
bool $pauseSending = false,
int $throttledBatchSize = null
?int $throttledBatchSize = null
) {
$mailerLog = self::getMailerLog();
if (!isset($throttledBatchSize) || $throttledBatchSize === 1) {
@ -232,7 +232,7 @@ class MailerLog {
array $mailerLog,
string $operation,
string $errorMessage,
string $errorCode = null
?string $errorCode = null
): array {
$mailerLog['error'] = [
'operation' => $operation,
@ -248,7 +248,7 @@ class MailerLog {
* @param MailerLogData|null $mailerLog
* @return MailerLogError|null
*/
public static function getError(array $mailerLog = null): ?array {
public static function getError(?array $mailerLog = null): ?array {
$mailerLog = self::getMailerLog($mailerLog);
return isset($mailerLog['error']) ? $mailerLog['error'] : null;
}
@ -300,7 +300,7 @@ class MailerLog {
* @param MailerLogData|null $mailerLog
* @return bool
*/
public static function isSendingLimitReached(array $mailerLog = null): bool {
public static function isSendingLimitReached(?array $mailerLog = null): bool {
$settings = SettingsController::getInstance();
$mailerConfig = $settings->get(Mailer::MAILER_CONFIG_SETTING_NAME);
// do not enforce sending limit for MailPoet's sending method
@ -322,7 +322,7 @@ class MailerLog {
* @param MailerLogData|null $mailerLog
* @return int
*/
public static function sentSince(int $sinceSeconds = null, array $mailerLog = null): int {
public static function sentSince(?int $sinceSeconds = null, ?array $mailerLog = null): int {
if ($sinceSeconds === null) {
$settings = SettingsController::getInstance();
@ -353,7 +353,7 @@ class MailerLog {
* @param MailerLogData|null $mailerLog
* @return MailerLogData
*/
private static function removeOutdatedSentInformationFromMailerlog(array $mailerLog = null): array {
private static function removeOutdatedSentInformationFromMailerlog(?array $mailerLog = null): array {
$settings = SettingsController::getInstance();
$mailerConfig = $settings->get(Mailer::MAILER_CONFIG_SETTING_NAME);
@ -375,7 +375,7 @@ class MailerLog {
* @param int|null $timestamp
* @return string
*/
private static function sentEntriesDate(int $timestamp = null): string {
private static function sentEntriesDate(?int $timestamp = null): string {
return date('Y-m-d H:i:s', $timestamp ?? time());
}
@ -384,7 +384,7 @@ class MailerLog {
* @param MailerLogData|null $mailerLog
* @return bool
*/
public static function isSendingPaused(array $mailerLog = null): bool {
public static function isSendingPaused(?array $mailerLog = null): bool {
$mailerLog = self::getMailerLog($mailerLog);
return $mailerLog['status'] === self::STATUS_PAUSED;
}
@ -393,7 +393,7 @@ class MailerLog {
* @param MailerLogData|null $mailerLog
* @return bool
*/
public static function isSendingWaitingForRetry(array $mailerLog = null): bool {
public static function isSendingWaitingForRetry(?array $mailerLog = null): bool {
$mailerLog = self::getMailerLog($mailerLog);
$retryAt = $mailerLog['retry_at'] ?? null;
return $retryAt && (time() <= $retryAt);

View File

@ -18,7 +18,7 @@ class MetaInfo {
return $this->makeMetaInfo('email_stats_notification', 'unknown', 'administrator');
}
public function getWordPressTransactionalMetaInfo(SubscriberEntity $subscriber = null) {
public function getWordPressTransactionalMetaInfo(?SubscriberEntity $subscriber = null) {
return $this->makeMetaInfo(
'transactional',
$subscriber ? $subscriber->getStatus() : 'unknown',

View File

@ -9,7 +9,7 @@ class BlacklistCheck {
private $blacklist;
public function __construct(
Blacklist $blacklist = null
?Blacklist $blacklist = null
) {
if (is_null($blacklist)) {
$blacklist = new Blacklist();

View File

@ -30,7 +30,7 @@ class Migrator {
$this->store = $store;
}
public function run(Logger $logger = null): void {
public function run(?Logger $logger = null): void {
$this->store->ensureMigrationsTable();
$migrations = $this->getStatus();

View File

@ -18,7 +18,7 @@ class PostContentManager {
private $wp;
public function __construct(
WooCommerceHelper $woocommerceHelper = null
?WooCommerceHelper $woocommerceHelper = null
) {
$this->wp = new WPFunctions;
$this->maxExcerptLength = $this->wp->applyFilters('mailpoet_newsletter_post_excerpt_length', $this->maxExcerptLength);

View File

@ -15,7 +15,7 @@ class PostTransformer {
public function __construct(
$args,
PostTransformerContentsExtractor $extractor = null
?PostTransformerContentsExtractor $extractor = null
) {
$this->args = $args;
$this->withLayout = isset($args['withLayout']) ? (bool)filter_var($args['withLayout'], FILTER_VALIDATE_BOOLEAN) : false;

View File

@ -260,7 +260,7 @@ class NewsletterListingRepository extends ListingRepository {
$queryBuilder->addOrderBy("n.$sortBy", $sortOrder);
}
private function applyType(QueryBuilder $queryBuilder, string $type, string $group = null) {
private function applyType(QueryBuilder $queryBuilder, string $type, ?string $group = null) {
if (!in_array($type, self::$supportedTypes)) {
return;
}

View File

@ -22,7 +22,7 @@ class AbandonedCartContent {
NewsletterEntity $newsletter,
array $args,
bool $preview = false,
SendingQueueEntity $sendingQueue = null
?SendingQueueEntity $sendingQueue = null
): array {
if (
!in_array(
@ -38,12 +38,12 @@ class AbandonedCartContent {
// Do not display the block if not an automatic email
return [];
}
$groupOption = $newsletter->getOptions()->filter(function (NewsletterOptionEntity $newsletterOption = null) {
$groupOption = $newsletter->getOptions()->filter(function (?NewsletterOptionEntity $newsletterOption = null) {
if (!$newsletterOption) return false;
$optionField = $newsletterOption->getOptionField();
return $optionField && $optionField->getName() === 'group';
})->first();
$eventOption = $newsletter->getOptions()->filter(function (NewsletterOptionEntity $newsletterOption = null) {
$eventOption = $newsletter->getOptions()->filter(function (?NewsletterOptionEntity $newsletterOption = null) {
if (!$newsletterOption) return false;
$optionField = $newsletterOption->getOptionField();
return $optionField && $optionField->getName() === 'event';

View File

@ -48,12 +48,12 @@ class Preprocessor {
* @param NewsletterEntity $newsletter
* @return array
*/
public function process(NewsletterEntity $newsletter, $content, bool $preview = false, SendingQueueEntity $sendingQueue = null) {
public function process(NewsletterEntity $newsletter, $content, bool $preview = false, ?SendingQueueEntity $sendingQueue = null) {
if (!array_key_exists('blocks', $content)) {
return $content;
}
$contentBlocks = $content['blocks'];
$contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview);
$contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview, $sendingQueue);
$content['blocks'] = $this->processContainer($newsletter, $contentBlocks, $preview, $sendingQueue);
return $content;
}
@ -74,7 +74,7 @@ class Preprocessor {
return $containerBlocks;
}
public function processBlock(NewsletterEntity $newsletter, array $block, bool $preview = false, SendingQueueEntity $sendingQueue = null): array {
public function processBlock(NewsletterEntity $newsletter, array $block, bool $preview = false, ?SendingQueueEntity $sendingQueue = null): array {
switch ($block['type']) {
case 'abandonedCartContent':
return $this->abandonedCartContent->render($newsletter, $block, $preview, $sendingQueue);

View File

@ -68,7 +68,7 @@ class Renderer {
$this->capabilitiesManager = $capabilitiesManager;
}
public function render(NewsletterEntity $newsletter, SendingQueueEntity $sendingQueue = null, $type = false) {
public function render(NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue = null, $type = false) {
return $this->_render($newsletter, $sendingQueue, $type);
}
@ -76,7 +76,7 @@ class Renderer {
return $this->_render($newsletter, null, $type, true, $subject);
}
private function _render(NewsletterEntity $newsletter, SendingQueueEntity $sendingQueue = null, $type = false, $preview = false, $subject = null) {
private function _render(NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue = null, $type = false, $preview = false, $subject = null) {
$language = $this->wp->getBloginfo('language');
$metaRobots = $preview ? '<meta name="robots" content="noindex, nofollow" />' : '';
$subject = $subject ?: $newsletter->getSubject();

View File

@ -9,9 +9,9 @@ use MailPoet\Entities\SubscriberEntity;
interface CategoryInterface {
public function process(
array $shortcodeDetails,
NewsletterEntity $newsletter = null,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter = null,
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null,
string $content = '',
bool $wpUserPreview = false
): ?string;

View File

@ -10,9 +10,9 @@ use MailPoet\WP\Functions as WPFunctions;
class Date implements CategoryInterface {
public function process(
array $shortcodeDetails,
NewsletterEntity $newsletter = null,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter = null,
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null,
string $content = '',
bool $wpUserPreview = false
): ?string {

View File

@ -40,9 +40,9 @@ class Link implements CategoryInterface {
public function process(
array $shortcodeDetails,
NewsletterEntity $newsletter = null,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter = null,
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null,
string $content = '',
bool $wpUserPreview = false
): ?string {
@ -119,9 +119,9 @@ class Link implements CategoryInterface {
public function processShortcodeAction(
$shortcodeAction,
NewsletterEntity $newsletter = null,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter = null,
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null,
$wpUserPreview = false
): ?string {
$subscriptionUrlFactory = SubscriptionUrlFactory::getInstance();

View File

@ -25,9 +25,9 @@ class Newsletter implements CategoryInterface {
public function process(
array $shortcodeDetails,
NewsletterEntity $newsletter = null,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter = null,
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null,
string $content = '',
bool $wpUserPreview = false
): ?string {

View File

@ -19,9 +19,9 @@ class Site implements CategoryInterface {
public function process(
array $shortcodeDetails,
NewsletterEntity $newsletter = null,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter = null,
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null,
string $content = '',
bool $wpUserPreview = false
): ?string {

View File

@ -28,9 +28,9 @@ class Subscriber implements CategoryInterface {
public function process(
array $shortcodeDetails,
NewsletterEntity $newsletter = null,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null,
?NewsletterEntity $newsletter = null,
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null,
string $content = '',
bool $wpUserPreview = false
): ?string {

View File

@ -60,15 +60,15 @@ class Shortcodes {
$this->wp = $wp;
}
public function setNewsletter(NewsletterEntity $newsletter = null): void {
public function setNewsletter(?NewsletterEntity $newsletter = null): void {
$this->newsletter = $newsletter;
}
public function setSubscriber(SubscriberEntity $subscriber = null): void {
public function setSubscriber(?SubscriberEntity $subscriber = null): void {
$this->subscriber = $subscriber;
}
public function setQueue(SendingQueueEntity $queue = null): void {
public function setQueue(?SendingQueueEntity $queue = null): void {
$this->queue = $queue;
}

View File

@ -65,8 +65,8 @@ class NewsletterStatisticsRepository extends Repository {
*/
public function getBatchStatistics(
array $newsletters,
\DateTimeImmutable $from = null,
\DateTimeImmutable $to = null,
?\DateTimeImmutable $from = null,
?\DateTimeImmutable $to = null,
array $include = [
'totals',
StatisticsClickEntity::class,
@ -133,8 +133,8 @@ class NewsletterStatisticsRepository extends Repository {
*/
public function getAllForSubscriber(
SubscriberEntity $subscriber,
int $limit = null,
int $offset = null
?int $limit = null,
?int $offset = null
): array {
return $this->entityManager->createQueryBuilder()
->select('IDENTITY(statistics.newsletter) AS newsletter_id')
@ -192,7 +192,7 @@ class NewsletterStatisticsRepository extends Repository {
}
}
private function getTotalSentCounts(array $newsletters, \DateTimeImmutable $from = null, \DateTimeImmutable $to = null): array {
private function getTotalSentCounts(array $newsletters, ?\DateTimeImmutable $from = null, ?\DateTimeImmutable $to = null): array {
$query = $this->doctrineRepository
->createQueryBuilder('n')
->select('n.id, SUM(q.countProcessed) AS cnt')
@ -226,7 +226,7 @@ class NewsletterStatisticsRepository extends Repository {
return $counts;
}
private function getStatisticCounts(string $statisticsEntityName, array $newsletters, \DateTimeImmutable $from = null, \DateTimeImmutable $to = null): array {
private function getStatisticCounts(string $statisticsEntityName, array $newsletters, ?\DateTimeImmutable $from = null, ?\DateTimeImmutable $to = null): array {
$qb = $this->getStatisticsQuery($statisticsEntityName, $newsletters);
if (
$statisticsEntityName === StatisticsClickEntity::class
@ -267,7 +267,7 @@ class NewsletterStatisticsRepository extends Repository {
->setParameter('newsletters', $newsletters);
}
private function getWooCommerceRevenues(array $newsletters, \DateTimeImmutable $from = null, \DateTimeImmutable $to = null) {
private function getWooCommerceRevenues(array $newsletters, ?\DateTimeImmutable $from = null, ?\DateTimeImmutable $to = null) {
if (!$this->wcHelper->isWooCommerceActive()) {
return null;
}

View File

@ -49,8 +49,8 @@ class ViewInBrowserRenderer {
public function render(
bool $isPreview,
NewsletterEntity $newsletter,
SubscriberEntity $subscriber = null,
SendingQueueEntity $queue = null
?SubscriberEntity $subscriber = null,
?SendingQueueEntity $queue = null
) {
$wpUserPreview = $isPreview;
$isTrackingEnabled = $this->trackingConfig->isEmailTrackingEnabled();

View File

@ -191,7 +191,7 @@ class EmailAction implements Filter {
return $queryBuilder;
}
private function createNotStatsJoinCondition(string $parameterSuffix, array $linkIds = null): string {
private function createNotStatsJoinCondition(string $parameterSuffix, ?array $linkIds = null): string {
$clause = "statssent.subscriber_id = stats.subscriber_id AND stats.newsletter_id = :newsletter" . $parameterSuffix;
if ($linkIds) {
$clause .= ' AND stats.link_id IN (:links' . $parameterSuffix . ')';

View File

@ -73,7 +73,7 @@ class WooFilterHelper {
* @param array|null $allowedStatuses
* @return string - The alias of the joined order stats table
*/
public function applyOrderStatusFilter(QueryBuilder $queryBuilder, array $allowedStatuses = null): string {
public function applyOrderStatusFilter(QueryBuilder $queryBuilder, ?array $allowedStatuses = null): string {
if (is_null($allowedStatuses)) {
$allowedStatuses = $this->defaultIncludedStatuses();
}

View File

@ -38,7 +38,7 @@ class SegmentSubscribersRepository {
$this->segmentsRepository = $segmentsRepository;
}
public function findSubscribersIdsInSegment(int $segmentId, array $candidateIds = null): array {
public function findSubscribersIdsInSegment(int $segmentId, ?array $candidateIds = null): array {
return $this->loadSubscriberIdsInSegment($segmentId, $candidateIds);
}
@ -46,13 +46,13 @@ class SegmentSubscribersRepository {
return $this->loadSubscriberIdsInSegment($segmentId);
}
public function getSubscribersCount(int $segmentId, string $status = null): int {
public function getSubscribersCount(int $segmentId, ?string $status = null): int {
$segment = $this->getSegment($segmentId);
$result = $this->getSubscribersStatisticsCount($segment);
return (int)$result[$status ?: 'all'];
}
public function getSubscribersCountBySegmentIds(array $segmentIds, string $status = null, ?int $filterSegmentId = null): int {
public function getSubscribersCountBySegmentIds(array $segmentIds, ?string $status = null, ?int $filterSegmentId = null): int {
$segmentRepository = $this->entityManager->getRepository(SegmentEntity::class);
$segments = $segmentRepository->findBy(['id' => $segmentIds]);
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
@ -369,7 +369,7 @@ class SegmentSubscribersRepository {
->setParameter('statusSubscribed', SubscriberEntity::STATUS_SUBSCRIBED);
}
private function loadSubscriberIdsInSegment(int $segmentId, array $candidateIds = null): array {
private function loadSubscriberIdsInSegment(int $segmentId, ?array $candidateIds = null): array {
$segment = $this->getSegment($segmentId);
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
$queryBuilder = $this->entityManager
@ -397,7 +397,7 @@ class SegmentSubscribersRepository {
private function filterSubscribersInStaticSegment(
QueryBuilder $queryBuilder,
SegmentEntity $segment,
string $status = null
?string $status = null
): QueryBuilder {
$subscribersSegmentsTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
@ -420,7 +420,7 @@ class SegmentSubscribersRepository {
private function filterSubscribersInDynamicSegment(
QueryBuilder $queryBuilder,
SegmentEntity $segment,
string $status = null
?string $status = null
): QueryBuilder {
$filters = [];
$dynamicFilters = $segment->getDynamicFilters();

View File

@ -65,7 +65,7 @@ class SegmentsSimpleListRepository {
*/
private function getList(
array $segmentTypes = [],
string $subscriberGlobalStatus = null
?string $subscriberGlobalStatus = null
): array {
$segmentsTable = $this->entityManager->getClassMetadata(SegmentEntity::class)->getTableName();

View File

@ -161,7 +161,7 @@ class AuthorizedEmailsController {
return null;
}
public function onNewsletterSenderAddressUpdate(NewsletterEntity $newsletter, string $oldSenderAddress = null) {
public function onNewsletterSenderAddressUpdate(NewsletterEntity $newsletter, ?string $oldSenderAddress = null) {
if ($newsletter->getSenderAddress() === $oldSenderAddress) {
return;
}
@ -243,7 +243,7 @@ class AuthorizedEmailsController {
/**
* @param array|null $error
*/
private function updateMailerLog(array $error = null) {
private function updateMailerLog(?array $error = null) {
if ($error) {
return;
}

View File

@ -52,7 +52,7 @@ class Bridge {
private $settings;
public function __construct(
SettingsController $settingsController = null
?SettingsController $settingsController = null
) {
if ($settingsController === null) {
$settingsController = SettingsController::getInstance();

View File

@ -27,7 +27,18 @@ class Pages {
'can_export' => false,
'publicly_queryable' => true,
'exclude_from_search' => true,
'capability_type' => 'page',
]);
WPFunctions::get()->addFilter('next_post_link', [$this, 'disableNavigationLinks']);
WPFunctions::get()->addFilter('previous_post_link', [$this, 'disableNavigationLinks']);
}
public function disableNavigationLinks($output) {
if (is_singular('mailpoet_page')) {
return ''; // Return an empty string to remove navigation links
}
return $output;
}
public static function createMailPoetPage($postName) {

View File

@ -19,22 +19,22 @@ class TrackingConfig {
$this->settings = $settings;
}
public function isEmailTrackingEnabled(string $level = null): bool {
public function isEmailTrackingEnabled(?string $level = null): bool {
$level = $level ?? $this->settings->get('tracking.level', self::LEVEL_FULL);
return in_array($level, [self::LEVEL_PARTIAL, self::LEVEL_FULL], true);
}
public function isCookieTrackingEnabled(string $level = null): bool {
public function isCookieTrackingEnabled(?string $level = null): bool {
$level = $level ?? $this->settings->get('tracking.level', self::LEVEL_FULL);
return $level === self::LEVEL_FULL;
}
public function areOpensMerged(string $opens = null): bool {
public function areOpensMerged(?string $opens = null): bool {
$opens = $opens ?? $this->settings->get('tracking.opens', self::OPENS_MERGED);
return $opens !== self::OPENS_SEPARATED;
}
public function areOpensSeparated(string $opens = null): bool {
public function areOpensSeparated(?string $opens = null): bool {
return !$this->areOpensMerged($opens);
}

View File

@ -35,8 +35,8 @@ class Unsubscribes {
public function track(
int $subscriberId,
string $source,
int $queueId = null,
string $meta = null,
?int $queueId = null,
?string $meta = null,
string $method = StatisticsUnsubscribeEntity::METHOD_UNKNOWN
) {
$queue = null;

View File

@ -22,7 +22,7 @@ class RequiredCustomFieldValidator {
*
* @throws Exception
*/
public function validate(array $data, FormEntity $form = null) {
public function validate(array $data, ?FormEntity $form = null) {
$allCustomFields = $this->getCustomFields($form);
foreach ($allCustomFields as $customFieldId => $customFieldName) {
if ($this->isCustomFieldMissing($customFieldId, $data)) {
@ -47,7 +47,7 @@ class RequiredCustomFieldValidator {
return false;
}
private function getCustomFields(FormEntity $form = null): array {
private function getCustomFields(?FormEntity $form = null): array {
$result = [];
if ($form) {

View File

@ -20,8 +20,8 @@ class Blacklist {
];
public function __construct(
array $blacklistedEmails = null,
array $blacklistedDomains = null
?array $blacklistedEmails = null,
?array $blacklistedDomains = null
) {
if ($blacklistedEmails) {
$this->blacklistedEmails = array_fill_keys(array_map([$this, 'hash'], $blacklistedEmails), 1);

View File

@ -35,29 +35,29 @@ class SubscriptionUrlFactory {
$this->linkTokens = $linkTokens;
}
public function getConfirmationUrl(SubscriberEntity $subscriber = null) {
public function getConfirmationUrl(?SubscriberEntity $subscriber = null) {
$post = $this->getPost($this->settings->get('subscription.pages.confirmation'));
return $this->getSubscriptionUrl($post, 'confirm', $subscriber);
}
public function getConfirmUnsubscribeUrl(SubscriberEntity $subscriber = null, int $queueId = null) {
public function getConfirmUnsubscribeUrl(?SubscriberEntity $subscriber = null, ?int $queueId = null) {
$post = $this->getPost($this->settings->get('subscription.pages.confirm_unsubscribe'));
$data = $queueId && $subscriber ? ['queueId' => $queueId] : null;
return $this->getSubscriptionUrl($post, 'confirm_unsubscribe', $subscriber, $data);
}
public function getManageUrl(SubscriberEntity $subscriber = null) {
public function getManageUrl(?SubscriberEntity $subscriber = null) {
$post = $this->getPost($this->settings->get('subscription.pages.manage'));
return $this->getSubscriptionUrl($post, 'manage', $subscriber);
}
public function getUnsubscribeUrl(SubscriberEntity $subscriber = null, int $queueId = null) {
public function getUnsubscribeUrl(?SubscriberEntity $subscriber = null, ?int $queueId = null) {
$post = $this->getPost($this->settings->get('subscription.pages.unsubscribe'));
$data = $queueId && $subscriber ? ['queueId' => $queueId] : null;
return $this->getSubscriptionUrl($post, 'unsubscribe', $subscriber, $data);
}
public function getReEngagementUrl(SubscriberEntity $subscriber = null) {
public function getReEngagementUrl(?SubscriberEntity $subscriber = null) {
$reEngagementSetting = $this->settings->get('reEngagement');
$postId = $reEngagementSetting['page'] ?? null;
@ -68,7 +68,7 @@ class SubscriptionUrlFactory {
public function getSubscriptionUrl(
$post = null,
$action = null,
SubscriberEntity $subscriber = null,
?SubscriberEntity $subscriber = null,
$data = null
) {
if ($post === null || $action === null) return;

View File

@ -21,7 +21,7 @@ class Assets extends AbstractExtension {
public function __construct(
array $globals,
WPFunctions $wp,
CdnAssetUrl $cdnAssetsUrl = null
?CdnAssetUrl $cdnAssetsUrl = null
) {
$this->globals = $globals;
$this->wp = $wp;

View File

@ -167,6 +167,11 @@ class Functions extends AbstractExtension {
[$this, 'isWoocommerceActive'],
['is_safe' => ['all']]
),
new TwigFunction(
'is_woocommerce_email_improvements_enabled',
[$this, 'isWoocommerceEmailImprovementsEnabled'],
['is_safe' => ['all']]
),
new TwigFunction(
'get_woocommerce_version',
[$this, 'getWooCommerceVersion'],
@ -312,6 +317,10 @@ class Functions extends AbstractExtension {
return $this->getWooCommerceHelper()->isWooCommerceActive();
}
public function isWoocommerceEmailImprovementsEnabled() {
return $this->getWooCommerceHelper()->isWooCommerceEmailImprovementsEnabled();
}
public function getWooCommerceVersion() {
return $this->getWooCommerceHelper()->getWooCommerceVersion();
}

View File

@ -85,7 +85,7 @@ class Subscribers {
return $count;
}
public function isSubscribersCountEnoughForCache(int $count = null): bool {
public function isSubscribersCountEnoughForCache(?int $count = null): bool {
if (is_null($count) && func_num_args() === 0) {
$count = $this->getSubscribersCount();
}

View File

@ -20,7 +20,7 @@ class UnauthorizedEmailNotice {
public function __construct(
WPFunctions $wp,
SettingsController $settings = null
?SettingsController $settings = null
) {
$this->settings = $settings;
$this->wp = $wp;

Some files were not shown because too many files have changed in this diff Show More