Compare commits
71 Commits
update-plu
...
trunk
Author | SHA1 | Date | |
---|---|---|---|
b0cdbe2db4 | |||
0064f32cd8 | |||
0a3d49c0cd | |||
540feb6364 | |||
0508874349 | |||
fce1ac1e4a | |||
40d61001d4 | |||
a6beaa7025 | |||
370f7f83ef | |||
a57cc91438 | |||
5ac069813f | |||
a2e164a832 | |||
c424fe4b7a | |||
bf3bc6d8cb | |||
afc27fabd6 | |||
c57844cb05 | |||
83b1f90b53 | |||
355baa9a9b | |||
19abc8963a | |||
e23e4c4974 | |||
a3ec922ca5 | |||
1d28e8d7c6 | |||
0e680d50e1 | |||
c05670a860 | |||
e9baeadd6e | |||
838d896cec | |||
919a855f34 | |||
119a4f8280 | |||
336b63b43c | |||
fec3ae1239 | |||
227aab5c47 | |||
96eb805c5c | |||
40f946f25c | |||
cd44c42a1d | |||
a4d67a319a | |||
1372de1bba | |||
0b1eb4bea3 | |||
6d017c9298 | |||
fe6d4603a2 | |||
7959333fb1 | |||
1cea4342f7 | |||
a5fb8b8171 | |||
22eb47d8bc | |||
6fe58a2445 | |||
f5a4a300af | |||
d2723938aa | |||
4de580b7df | |||
642733ee0c | |||
80f354b860 | |||
25262cff80 | |||
c31795cd4d | |||
73d410eb86 | |||
b8a25410d4 | |||
85e067e7dc | |||
4afd82778a | |||
84c95293e0 | |||
f96e74cf96 | |||
ee513fd871 | |||
2adc6d23ca | |||
5023bbb6f2 | |||
b16071ee0e | |||
e5498b6baf | |||
9ad79e75b5 | |||
aa17e90365 | |||
4b917dd1b3 | |||
7c425cb04d | |||
43990d9e8b | |||
8024708c1d | |||
95a750365b | |||
2cee607749 | |||
9c9193eeed |
@ -197,10 +197,10 @@ jobs:
|
||||
- run:
|
||||
name: Download additional WP Plugins for tests
|
||||
command: |
|
||||
./do download:woo-commerce-zip 9.6.1
|
||||
./do download:woo-commerce-subscriptions-zip 7.1.0
|
||||
./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.5
|
||||
./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,8 +1222,8 @@ workflows:
|
||||
- acceptance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: acceptance_oldest
|
||||
woo_core_version: 9.5.2
|
||||
woo_subscriptions_version: 7.0.0
|
||||
woo_core_version: 9.6.2
|
||||
woo_subscriptions_version: 7.1.0
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
mysql_command: --max_allowed_packet=100M
|
||||
@ -1123,8 +1263,8 @@ workflows:
|
||||
- integration_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: integration_oldest
|
||||
woo_core_version: 9.5.2
|
||||
woo_subscriptions_version: 7.0.0
|
||||
woo_core_version: 9.6.2
|
||||
woo_subscriptions_version: 7.1.0
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
codeception_image_version: 7.4-cli_20220605.0
|
||||
@ -1186,8 +1326,8 @@ workflows:
|
||||
- acceptance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: acceptance_with_premium_oldest
|
||||
woo_core_version: 9.5.2
|
||||
woo_subscriptions_version: 7.0.0
|
||||
woo_core_version: 9.6.2
|
||||
woo_subscriptions_version: 7.1.0
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
codeception_image_version: 7.4-cli_20220605.0
|
||||
@ -1198,8 +1338,8 @@ workflows:
|
||||
- integration_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: integration_with_premium_oldest
|
||||
woo_core_version: 9.5.2
|
||||
woo_subscriptions_version: 7.0.0
|
||||
woo_core_version: 9.6.2
|
||||
woo_subscriptions_version: 7.1.0
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
codeception_image_version: 7.4-cli_20220605.0
|
||||
@ -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
|
||||
|
71
.github/workflows/codeql-analysis.yml
vendored
71
.github/workflows/codeql-analysis.yml
vendored
@ -1,71 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
name: 'CodeQL'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [trunk]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [trunk]
|
||||
schedule:
|
||||
- cron: '0 17 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['javascript']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
212
.github/workflows/email-editor-package.yml
vendored
212
.github/workflows/email-editor-package.yml
vendored
@ -1,212 +0,0 @@
|
||||
name: Email Editor Package Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.4', '8.2']
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache Composer vendor dependencies for MailPoet
|
||||
id: composer-mailpoet-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('mailpoet/composer.lock') }}-${{ hashFiles('mailpoet/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor-prefixed dependencies for MailPoet
|
||||
id: vendor-prefixed-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor-prefixed
|
||||
key: ${{ runner.os }}-vendor-prefixed-${{ matrix.php-version }}-${{ hashFiles('mailpoet/prefixer/composer.lock') }}-${{ hashFiles('mailpoet/prefixer/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor for test environment
|
||||
id: composer-tests-env-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tests_env/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('tests_env/composer.lock') }}-${{ hashFiles('tests_env/composer.json') }}
|
||||
|
||||
- name: Cache Composer dependencies for Email Editor
|
||||
id: composer-email-editor-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: packages/php/email-editor/vendor
|
||||
key: ${{ runner.os }}-composer-email-editor-${{ matrix.php-version }}-${{ hashFiles('packages/php/email-editor/composer.lock') }}-${{ hashFiles('packages/php/email-editor/composer.json') }}
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
extensions: gd
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
COMPOSER_DEV_MODE=1 php tools/install.php
|
||||
touch .env
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Test Environment dependencies only if the cache was not hit
|
||||
- name: Install test environment dependencies
|
||||
if: steps.composer-tests-env-cache.outputs.cache-hit != 'true'
|
||||
run: ../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: tests_env
|
||||
|
||||
# Install MailPoet dependencies only if the cache was not hit
|
||||
- name: Install mailpoet dependencies
|
||||
if: |
|
||||
steps.composer-mailpoet-cache.outputs.cache-hit != 'true' || steps.vendor-prefixed-cache.outputs.cache-hit != 'true'
|
||||
run: ./tools/vendor/composer.phar install
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Email Editor dependencies only if the cache was not hit
|
||||
- name: Install email-editor dependencies
|
||||
if: steps.composer-email-editor-cache.outputs.cache-hit != 'true'
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
# Dump Email Editor autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump email-editor autoload
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar dump-autoload
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
# Dump MailPoet autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump MailPoet autoload
|
||||
run: ./tools/vendor/composer.phar dump-autoload
|
||||
working-directory: mailpoet
|
||||
|
||||
# Run Email Editor unit tests
|
||||
- name: Run email-editor package unit tests
|
||||
run: ../../../tests_env/vendor/bin/codecept build && ../../../mailpoet/tools/vendor/composer.phar unit-test
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
- name: Run email-editor package integration tests
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar integration-test
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
code-style:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.2'
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
COMPOSER_DEV_MODE=1 php tools/install.php
|
||||
touch .env
|
||||
working-directory: mailpoet
|
||||
|
||||
- name: Install composer dependencies
|
||||
run: ../../tools/vendor/composer.phar install
|
||||
working-directory: mailpoet/tasks/code_sniffer
|
||||
|
||||
- name: Run code style check
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar code-style
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
phpstan-static-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.4', '8.2']
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache Composer vendor dependencies for MailPoet
|
||||
id: composer-mailpoet-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('mailpoet/composer.lock') }}-${{ hashFiles('mailpoet/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor-prefixed dependencies for MailPoet
|
||||
id: vendor-prefixed-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor-prefixed
|
||||
key: ${{ runner.os }}-vendor-prefixed-${{ matrix.php-version }}-${{ hashFiles('mailpoet/prefixer/composer.lock') }}-${{ hashFiles('mailpoet/prefixer/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor for test environment
|
||||
id: composer-tests-env-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tests_env/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('tests_env/composer.lock') }}-${{ hashFiles('tests_env/composer.json') }}
|
||||
|
||||
- name: Cache Composer dependencies for Email Editor
|
||||
id: composer-email-editor-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: packages/php/email-editor/vendor
|
||||
key: ${{ runner.os }}-composer-email-editor-${{ matrix.php-version }}-${{ hashFiles('packages/php/email-editor/composer.lock') }}-${{ hashFiles('packages/php/email-editor/composer.json') }}
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
extensions: gd
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
COMPOSER_DEV_MODE=1 php tools/install.php
|
||||
touch .env
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Test Environment dependencies only if the cache was not hit
|
||||
- name: Install test environment dependencies
|
||||
if: steps.composer-tests-env-cache.outputs.cache-hit != 'true'
|
||||
run: ../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: tests_env
|
||||
|
||||
# Install MailPoet dependencies only if the cache was not hit
|
||||
- name: Install mailpoet dependencies
|
||||
if: |
|
||||
steps.composer-mailpoet-cache.outputs.cache-hit != 'true' || steps.vendor-prefixed-cache.outputs.cache-hit != 'true'
|
||||
run: ./tools/vendor/composer.phar install
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Email Editor dependencies only if the cache was not hit
|
||||
- name: Install email-editor dependencies
|
||||
if: steps.composer-email-editor-cache.outputs.cache-hit != 'true'
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
- name: Install composer dependencies
|
||||
run: ../../tools/vendor/composer.phar install
|
||||
working-directory: mailpoet/tasks/phpstan
|
||||
|
||||
# Dump Email Editor autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump email-editor autoload
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar dump-autoload
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
# Dump MailPoet autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump MailPoet autoload
|
||||
run: ./tools/vendor/composer.phar dump-autoload
|
||||
working-directory: mailpoet
|
||||
|
||||
- name: Run code phpstan
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar phpstan -- --php-version=${{ matrix.php-version == '7.4' && '70400' || '80200' }}
|
||||
working-directory: packages/php/email-editor
|
39
.github/workflows/release.yml
vendored
Normal file
39
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
name: Make release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*' # Trigger on any tag push
|
||||
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=8192"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Pre-reqs
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y php php-symfony composer php-cli php-gd php-mysql golang npm
|
||||
npm install -g pnpm
|
||||
|
||||
- name: Build zip file
|
||||
run: |
|
||||
cd mailpoet || { echo "Directory 'mailpoet' not found"; exit 1; }
|
||||
cp .env.sample .env
|
||||
composer update
|
||||
sh build.sh
|
||||
mkdir -p ../output
|
||||
mv mailpoet.zip ../output
|
||||
|
||||
- name: Upload Release
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: |-
|
||||
output/mailpoet.zip
|
||||
api_key: '${{secrets.RELEASE_SMITH_TOKEN}}'
|
182
.github/workflows/update-wordpress-and-plugins.yml
vendored
182
.github/workflows/update-wordpress-and-plugins.yml
vendored
@ -1,182 +0,0 @@
|
||||
name: Check new versions of plugins and WordPress
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 6 * * 1' # At 06:00 on Monday
|
||||
workflow_dispatch: # Allows manual triggering
|
||||
|
||||
jobs:
|
||||
check-versions:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.3' # Specify the PHP version you want to use
|
||||
|
||||
# Updating used WordPress
|
||||
- name: Check WordPress Docker Versions
|
||||
run: php .github/workflows/scripts/check_wordpress_versions.php
|
||||
|
||||
- name: Check for WordPress changes
|
||||
id: check_wp_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "WORDPRESS_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WordPress versions from files
|
||||
id: get_wp_versions
|
||||
run: |
|
||||
echo "WORDPRESS_LATEST_VERSION=$(cat /tmp/latest_wordpress_version.txt)" >> $GITHUB_ENV
|
||||
echo "WORDPRESS_PREVIOUS_VERSION=$(cat /tmp/previous_wordpress_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WordPress changes
|
||||
if: env.WORDPRESS_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WordPress images in Circle CI\n\n - latest version: ${{ env.WORDPRESS_LATEST_VERSION }}\n - previous version: ${{ env.WORDPRESS_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used WooCommerce plugin
|
||||
- name: Check WooCommerce Versions
|
||||
run: php .github/workflows/scripts/check_woocommerce_versions.php
|
||||
|
||||
- name: Check for WooCommerce changes
|
||||
id: check_wc_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WooCommerce versions from files
|
||||
id: get_wc_versions
|
||||
run: |
|
||||
echo "WOOCOMMERCE_LATEST_VERSION=$(cat /tmp/latest_woocommerce_version.txt)" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_PREVIOUS_VERSION=$(cat /tmp/previous_woocommerce_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WooCommerce changes
|
||||
if: env.WOOCOMMERCE_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WooCommerce plugin in Circle CI\n\n - latest version: ${{ env.WOOCOMMERCE_LATEST_VERSION }}\n - previous version: ${{ env.WOOCOMMERCE_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used Automate Woo plugin
|
||||
- name: Check Automate Woo Versions
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
run: php .github/workflows/scripts/check_automate_woo_versions.php
|
||||
|
||||
- name: Check for Automate Woo changes
|
||||
id: check_aw_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "AUTOMATE_WOO_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get Automate Woo versions from files
|
||||
id: get_aw_versions
|
||||
run: |
|
||||
echo "AUTOMATE_WOO_LATEST_VERSION=$(cat /tmp/latest_automate_woo_version.txt)" >> $GITHUB_ENV
|
||||
echo "AUTOMATE_WOO_PREVIOUS_VERSION=$(cat /tmp/previous_automate_woo_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit Automate Woo changes
|
||||
if: env.AUTOMATE_WOO_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used Automate Woo plugin in Circle CI\n\n - latest version: ${{ env.AUTOMATE_WOO_LATEST_VERSION }}\n - previous version: ${{ env.AUTOMATE_WOO_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used WooCommerce Subscriptions plugin
|
||||
- name: Check WooCommerce Subscriptions Versions
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
run: php .github/workflows/scripts/check_woocommerce_subscriptions_versions.php
|
||||
|
||||
- name: Check for WooCommerce Subscriptions changes
|
||||
id: check_ws_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "SUBSCRIPTIONS_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WooCommerce Subscriptions versions from files
|
||||
id: get_ws_versions
|
||||
run: |
|
||||
echo "WOOCOMMERCE_SUBSCRIPTIONS_LATEST_VERSION=$(cat /tmp/latest_woocommerce_subscriptions_version.txt)" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_SUBSCRIPTIONS_PREVIOUS_VERSION=$(cat /tmp/previous_woocommerce_subscriptions_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WooCommerce Subscriptions changes
|
||||
if: env.SUBSCRIPTIONS_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WooCommerce Subscriptions plugin in Circle CI\n\n - latest version: ${{ env.WOOCOMMERCE_SUBSCRIPTIONS_LATEST_VERSION }}\n - previous version: ${{ env.WOOCOMMERCE_SUBSCRIPTIONS_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used WooCommerce Memberships plugin
|
||||
- name: Check WooCommerce Memberships Versions
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
run: php .github/workflows/scripts/check_woocommerce_memberships_versions.php
|
||||
|
||||
- name: Check for WooCommerce Memberships changes
|
||||
id: check_wm_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "MEMBERSHIPS_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WooCommerce Memberships versions from files
|
||||
id: get_wm_versions
|
||||
run: |
|
||||
echo "WOOCOMMERCE_MEMBERSHIPS_LATEST_VERSION=$(cat /tmp/latest_woocommerce_memberships_version.txt)" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_MEMBERSHIPS_PREVIOUS_VERSION=$(cat /tmp/previous_woocommerce_memberships_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WooCommerce Memberships changes
|
||||
if: env.MEMBERSHIPS_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WooCommerce Memberships plugin in Circle CI\n\n - latest version: ${{ env.WOOCOMMERCE_MEMBERSHIPS_LATEST_VERSION }}\n - previous version: ${{ env.WOOCOMMERCE_MEMBERSHIPS_PREVIOUS_VERSION }}'
|
||||
|
||||
# Push all changes at the end if any changes were detected
|
||||
#
|
||||
# For local testing with act tool add following:
|
||||
# env:
|
||||
# GH_PAT: ${{ secrets.GH_TOKEN }}
|
||||
# run: |
|
||||
# git remote set-url origin https://${GH_PAT}@github.com/mailpoet/mailpoet
|
||||
# git push -f origin HEAD:refs/heads/update-plugins-and-wordpress-test
|
||||
- name: Push changes
|
||||
if: env.CHANGES_DETECTED == 'true'
|
||||
run: |
|
||||
git push -f origin HEAD:refs/heads/update-plugins-and-wordpress
|
||||
|
||||
# Create a pull request if there are changes
|
||||
- name: Create Pull Request
|
||||
if: env.CHANGES_DETECTED == 'true'
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
branch: update-plugins-and-wordpress
|
||||
title: Update WordPress and plugins in CI jobs
|
||||
base: trunk
|
||||
labels: automated, check-versions
|
||||
body: |
|
||||
1. If all checks passed, you can merge this PR.
|
||||
2. If the build failed, please investigate the failure and either address the issues or delegate the job. Then, make sure these changes are merged.
|
@ -1,27 +0,0 @@
|
||||
name: Add link to WordPress Playground preview
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
add-wp-playground-link:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check and append description
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
PR_NUMBER="${{ github.event.pull_request.number }}"
|
||||
BRANCH_NAME="${{ github.head_ref }}"
|
||||
DESCRIPTION="$(gh pr view $PR_NUMBER --json body -q .body)"
|
||||
HEADING="## Preview"
|
||||
CONTENT="$(printf "${HEADING}\n\n[Preview in WordPress Playground](https://account.mailpoet.com/playground/new/branch:${BRANCH_NAME})\n\n_The latest successful build from \`${BRANCH_NAME}\` will be used. If none is available, the link won't work._")"
|
||||
|
||||
if [[ "$DESCRIPTION" != *"$HEADING"* ]]; then
|
||||
gh pr edit $PR_NUMBER --body "$(printf "${DESCRIPTION}\n\n${CONTENT}")"
|
||||
fi
|
@ -1,30 +0,0 @@
|
||||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
settings:
|
||||
depth: 1
|
||||
|
||||
steps:
|
||||
build:
|
||||
image: node:current-bookworm-slim
|
||||
commands:
|
||||
- apt update
|
||||
- apt install php php-symfony bash -y
|
||||
- npm install pnpm
|
||||
- cd mailpoet
|
||||
- bash build.sh
|
||||
- mkdir ../output
|
||||
- mv mailpoet.zip ../output
|
||||
- cd ..
|
||||
|
||||
release:
|
||||
image: woodpeckerci/plugin-gitea-release:latest
|
||||
settings:
|
||||
base_url: https://git.cavemanon.xyz
|
||||
api_key:
|
||||
from_secret: releasesmithapikey
|
||||
files: "output/"
|
||||
prerelease: false
|
||||
title: "${CI_COMMIT_TAG}"
|
||||
when:
|
||||
- event: tag
|
@ -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
|
||||
|
8
mailpoet/assets/js/src/global.d.ts
vendored
8
mailpoet/assets/js/src/global.d.ts
vendored
@ -39,13 +39,13 @@ interface JQuery {
|
||||
declare module '@woocommerce/blocks-checkout' {
|
||||
type CheckboxControlProps = {
|
||||
className?: string;
|
||||
label?: string;
|
||||
label?: string | React.ReactNode;
|
||||
id?: string;
|
||||
instanceId?: string;
|
||||
onChange?: (value: boolean) => void;
|
||||
children?: React.ReactChildren | React.ReactElement;
|
||||
onChange: (value: boolean) => void;
|
||||
children?: React.ReactChildren;
|
||||
hasError?: boolean;
|
||||
checked?: boolean;
|
||||
disabled?: string | boolean | undefined;
|
||||
};
|
||||
export const CheckboxControl: (props: CheckboxControlProps) => JSX.Element;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,142 @@
|
||||
import { ExternalLink } from '@wordpress/components';
|
||||
import { select, dispatch } from '@wordpress/data';
|
||||
import { store as coreDataStore, useEntityProp } from '@wordpress/core-data';
|
||||
import { store as editorStore } from '@wordpress/editor';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createInterpolateElement } from '@wordpress/element';
|
||||
import classnames from 'classnames';
|
||||
|
||||
const previewTextMaxLength = 150;
|
||||
const previewTextRecommendedLength = 80;
|
||||
|
||||
export function EmailSidebarExtensionBody({ RichTextWithButton }) {
|
||||
const [mailpoetEmailData] = useEntityProp(
|
||||
'postType',
|
||||
'mailpoet_email',
|
||||
'mailpoet_data',
|
||||
);
|
||||
|
||||
const updateEmailMailPoetProperty = (name: string, value: string) => {
|
||||
const postId = select(editorStore).getCurrentPostId();
|
||||
const currentPostType = 'mailpoet_email'; // only for mailpoet_email post-type
|
||||
|
||||
const editedPost = select(coreDataStore).getEditedEntityRecord(
|
||||
'postType',
|
||||
currentPostType,
|
||||
postId,
|
||||
);
|
||||
|
||||
// @ts-expect-error Property 'mailpoet_data' does not exist on type 'Updatable<Attachment<any>>'.
|
||||
const mailpoetData = editedPost?.mailpoet_data || {};
|
||||
void dispatch(coreDataStore).editEntityRecord(
|
||||
'postType',
|
||||
currentPostType,
|
||||
postId,
|
||||
{
|
||||
mailpoet_data: {
|
||||
...mailpoetData,
|
||||
[name]: value,
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const subjectHelp = createInterpolateElement(
|
||||
__(
|
||||
'Use personalization tags to personalize your email, or learn more about <bestPracticeLink>best practices</bestPracticeLink> and using <emojiLink>emoji in subject lines</emojiLink>.',
|
||||
'mailpoet',
|
||||
),
|
||||
{
|
||||
bestPracticeLink: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href="https://www.mailpoet.com/blog/17-email-subject-line-best-practices-to-boost-engagement/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
emojiLink: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href="https://www.mailpoet.com/blog/tips-using-emojis-in-subject-lines/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
const previewTextLength = mailpoetEmailData?.preheader?.length ?? 0;
|
||||
|
||||
const preheaderHelp = createInterpolateElement(
|
||||
__(
|
||||
'<link>This text</link> will appear in the inbox, underneath the subject line.',
|
||||
'mailpoet',
|
||||
),
|
||||
{
|
||||
link: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href={new URL(
|
||||
'article/418-preview-text',
|
||||
'https://kb.mailpoet.com/',
|
||||
).toString()}
|
||||
key="preview-text-kb"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<RichTextWithButton
|
||||
attributeName="subject"
|
||||
attributeValue={mailpoetEmailData?.subject}
|
||||
updateProperty={updateEmailMailPoetProperty}
|
||||
label={__('Subject', 'mailpoet')}
|
||||
labelSuffix={
|
||||
<ExternalLink href="https://kb.mailpoet.com/article/435-a-guide-to-personalisation-tags-for-tailored-newsletters#list">
|
||||
{__('Guide', 'mailpoet')}
|
||||
</ExternalLink>
|
||||
}
|
||||
help={subjectHelp}
|
||||
placeholder={__('Eg. The summer sale is here!', 'mailpoet')}
|
||||
/>
|
||||
|
||||
<br />
|
||||
|
||||
<RichTextWithButton
|
||||
attributeName="preheader"
|
||||
attributeValue={mailpoetEmailData?.preheader}
|
||||
updateProperty={updateEmailMailPoetProperty}
|
||||
label={__('Preview text', 'mailpoet')}
|
||||
labelSuffix={
|
||||
<span
|
||||
className={classnames(
|
||||
'mailpoet-settings-panel__preview-text-length',
|
||||
{
|
||||
'mailpoet-settings-panel__preview-text-length-warning':
|
||||
previewTextLength > previewTextRecommendedLength,
|
||||
'mailpoet-settings-panel__preview-text-length-error':
|
||||
previewTextLength > previewTextMaxLength,
|
||||
},
|
||||
)}
|
||||
>
|
||||
{previewTextLength}/{previewTextMaxLength}
|
||||
</span>
|
||||
}
|
||||
help={preheaderHelp}
|
||||
placeholder={__(
|
||||
"Add a preview text to capture subscribers' attention and increase open rates.",
|
||||
'mailpoet',
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function EmailSidebarExtension(RichTextWithButton: JSX.Element) {
|
||||
return <EmailSidebarExtensionBody RichTextWithButton={RichTextWithButton} />;
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
import { addFilter, addAction } from '@wordpress/hooks';
|
||||
import { MailPoet } from 'mailpoet';
|
||||
import { withSatismeterSurvey } from './satismeter-survey';
|
||||
import { EmailSidebarExtension } from './email-sidebar-extension';
|
||||
import './index.scss';
|
||||
import { useValidationRules } from './validate-email-content';
|
||||
|
||||
@ -12,10 +13,12 @@ addFilter('mailpoet_email_editor_wrap_editor_component', 'mailpoet', (editor) =>
|
||||
withSatismeterSurvey(editor),
|
||||
);
|
||||
|
||||
// validate email editor content using the defined validation rules
|
||||
// content is first validated when the "Send" button is clicked and revalidated on "Save Draft"
|
||||
addFilter(
|
||||
'mailpoet_email_editor_content_validation_rules',
|
||||
'mailpoet',
|
||||
(validationRules: []) => [...validationRules, ...useValidationRules()],
|
||||
() => useValidationRules(), // returns a memorized set of rules (array of rules)
|
||||
);
|
||||
|
||||
const EVENTS_TO_TRACK = [
|
||||
@ -53,3 +56,22 @@ addFilter(
|
||||
'mailpoet',
|
||||
() => !!window.mailpoet_analytics_enabled,
|
||||
);
|
||||
|
||||
// integration point for settings sidebar
|
||||
addFilter(
|
||||
'mailpoet_email_editor_setting_sidebar_extension_component',
|
||||
'mailpoet',
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
(RichTextWithButton) => EmailSidebarExtension.bind(null, RichTextWithButton),
|
||||
);
|
||||
|
||||
// use mailpoet data subject if available
|
||||
addFilter(
|
||||
'mailpoet_email_editor_preferred_template_title',
|
||||
'mailpoet',
|
||||
(...args) => {
|
||||
const [, post] = args;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return post?.mailpoet_data?.subject || ''; // use MailPoet subject as title
|
||||
},
|
||||
);
|
||||
|
@ -64,12 +64,14 @@ export function useValidationRules() {
|
||||
label: __('Insert link', 'mailpoet'),
|
||||
onClick: () => {
|
||||
if (!hasFooter) {
|
||||
// update the email content
|
||||
void dispatch(blockEditorStore).insertBlock(
|
||||
linksParagraphBlock,
|
||||
undefined,
|
||||
contentBlockId,
|
||||
);
|
||||
} else {
|
||||
// update the template
|
||||
void dispatch(coreDataStore).editEntityRecord(
|
||||
'postType',
|
||||
'wp_template',
|
||||
|
@ -30,8 +30,10 @@ export function FrontendBlock({
|
||||
}
|
||||
|
||||
return (
|
||||
<CheckboxControl checked={checked} onChange={setChecked}>
|
||||
<RawHTML>{text || defaultText}</RawHTML>
|
||||
</CheckboxControl>
|
||||
<CheckboxControl
|
||||
checked={checked}
|
||||
onChange={setChecked}
|
||||
label={<RawHTML>{text || defaultText}</RawHTML>}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -56,7 +56,11 @@ export function Edit({
|
||||
<div {...blockProps}>
|
||||
{optinEnabled ? (
|
||||
<div className="wc-block-checkout__marketing">
|
||||
<CheckboxControl id="mailpoet-marketing-optin" checked={false} />
|
||||
<CheckboxControl
|
||||
id="mailpoet-marketing-optin"
|
||||
checked={false}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<RichText
|
||||
value={currentText}
|
||||
onChange={(value) => setAttributes({ text: value })}
|
||||
|
@ -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',
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -57,17 +57,17 @@ echo '[BUILD] Fetching prefixed production libraries'
|
||||
|
||||
# Remove Doctrinne Annotations (no need since generated metadata are packed)
|
||||
# Should be removed before `dump-autoload` to not include the annotations classes on the autoloader.
|
||||
rm -rf vendor-prefixed/doctrine/annotations
|
||||
#rm -rf vendor-prefixed/doctrine/annotations
|
||||
|
||||
# Remove DI Container files used for container dump (no need since generated metadata are packed)
|
||||
# Should be removed before `dump-autoload` to not include these classes in the autoloader.
|
||||
echo '[BUILD] Removing DI Container development dependencies'
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Compiler
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Config
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Dumper
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Loader
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/LazyProxy
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Extension
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Compiler
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Config
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Dumper
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Loader
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/LazyProxy
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Extension
|
||||
|
||||
./tools/vendor/composer.phar dump-autoload
|
||||
|
||||
|
@ -1,5 +1,17 @@
|
||||
== 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.
|
||||
|
||||
= 5.7.0 - 2025-02-11 =
|
||||
* Improved: Rename Review Trigger in Automations;
|
||||
* Changed: minimum required WooCommerce is 9.5;
|
||||
|
@ -5,7 +5,7 @@
|
||||
"dragonmantank/cron-expression": "^3.3",
|
||||
"mailpoet/email-editor": "*",
|
||||
"mixpanel/mixpanel-php": "2.*",
|
||||
"woocommerce/action-scheduler": "^3.8.0"
|
||||
"woocommerce/action-scheduler": "3.9.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-gd": "*",
|
||||
|
18
mailpoet/composer.lock
generated
18
mailpoet/composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "51893b0f5ed38d130932b86b48e55b94",
|
||||
"content-hash": "a95263a51332277e75d7147e3dc4551e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "dragonmantank/cron-expression",
|
||||
@ -221,20 +221,20 @@
|
||||
},
|
||||
{
|
||||
"name": "woocommerce/action-scheduler",
|
||||
"version": "3.8.0",
|
||||
"version": "3.9.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/woocommerce/action-scheduler.git",
|
||||
"reference": "99cd7981f51c98883082534d4852491858d72834"
|
||||
"reference": "efbb7953f72a433086335b249292f280dd43ddfe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/99cd7981f51c98883082534d4852491858d72834",
|
||||
"reference": "99cd7981f51c98883082534d4852491858d72834",
|
||||
"url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/efbb7953f72a433086335b249292f280dd43ddfe",
|
||||
"reference": "efbb7953f72a433086335b249292f280dd43ddfe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6"
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5",
|
||||
@ -258,9 +258,9 @@
|
||||
"homepage": "https://actionscheduler.org/",
|
||||
"support": {
|
||||
"issues": "https://github.com/woocommerce/action-scheduler/issues",
|
||||
"source": "https://github.com/woocommerce/action-scheduler/tree/3.8.0"
|
||||
"source": "https://github.com/woocommerce/action-scheduler/tree/3.9.2"
|
||||
},
|
||||
"time": "2024-05-22T13:50:29+00:00"
|
||||
"time": "2025-02-03T09:09:30+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@ -8343,7 +8343,7 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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',
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ class StepRunLogger {
|
||||
string $stepId,
|
||||
string $stepType,
|
||||
int $runNumber,
|
||||
bool $isWpDebug = null
|
||||
?bool $isWpDebug = null
|
||||
) {
|
||||
$this->automationRunLogStorage = $automationRunLogStorage;
|
||||
$this->hooks = $hooks;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -60,7 +60,7 @@ class AutomationRunLog {
|
||||
int $automationRunId,
|
||||
string $stepId,
|
||||
string $stepType,
|
||||
int $id = null
|
||||
?int $id = null
|
||||
) {
|
||||
$this->automationRunId = $automationRunId;
|
||||
$this->stepId = $stepId;
|
||||
|
@ -35,7 +35,7 @@ class Step {
|
||||
string $key,
|
||||
array $args,
|
||||
array $nextSteps,
|
||||
Filters $filters = null
|
||||
?Filters $filters = null
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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' : '';
|
||||
|
@ -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')) . ')' : '';
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)' : '';
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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 you’re 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 you’re not a robot', 'mailpoet');
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -16,7 +16,7 @@ class Capabilities {
|
||||
|
||||
public function __construct(
|
||||
$renderer = null,
|
||||
WPFunctions $wp = null
|
||||
?WPFunctions $wp = null
|
||||
) {
|
||||
if ($renderer !== null) {
|
||||
$this->renderer = $renderer;
|
||||
|
@ -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',
|
||||
]);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
[
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -35,7 +35,7 @@ class EmailEditorPreviewEmail {
|
||||
}
|
||||
|
||||
private function validateData($data) {
|
||||
if (empty($data['email']) || empty($data['postId']) || empty($data['newsletterId'])) {
|
||||
if (empty($data['email']) || empty($data['postId'])) {
|
||||
throw new \InvalidArgumentException(esc_html__('Missing required data', 'mailpoet'));
|
||||
}
|
||||
|
||||
@ -50,9 +50,9 @@ class EmailEditorPreviewEmail {
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function fetchNewsletter($postData): NewsletterEntity {
|
||||
$newsletter = $this->newslettersRepository->findOneById((int)$postData['newsletterId']);
|
||||
$newsletter = $this->newslettersRepository->findOneBy(['wpPost' => (int)$postData['postId']]);
|
||||
|
||||
if (!$newsletter) {
|
||||
if (!$newsletter instanceof NewsletterEntity) {
|
||||
throw new \Exception(esc_html__('This email does not exist.', 'mailpoet'));
|
||||
}
|
||||
|
||||
|
@ -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() ?? [];
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -45,7 +45,7 @@ class StatisticsNewsletterEntity {
|
||||
NewsletterEntity $newsletter,
|
||||
SendingQueueEntity $queue,
|
||||
SubscriberEntity $subscriber,
|
||||
\DateTimeInterface $sentAt = null
|
||||
?\DateTimeInterface $sentAt = null
|
||||
) {
|
||||
$this->newsletter = $newsletter;
|
||||
$this->queue = $queue;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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',
|
||||
|
@ -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');
|
||||
|
@ -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'])) ?
|
||||
|
@ -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);
|
||||
|
@ -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',
|
||||
|
@ -9,7 +9,7 @@ class BlacklistCheck {
|
||||
private $blacklist;
|
||||
|
||||
public function __construct(
|
||||
Blacklist $blacklist = null
|
||||
?Blacklist $blacklist = null
|
||||
) {
|
||||
if (is_null($blacklist)) {
|
||||
$blacklist = new Blacklist();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user