Compare commits
1 Commits
update-plu
...
4.57.0
Author | SHA1 | Date | |
---|---|---|---|
b9058b4ad5 |
@ -99,12 +99,12 @@ executors:
|
||||
wpcli_php_max_wporg:
|
||||
<<: *default_job_config
|
||||
docker:
|
||||
- image: mailpoet/wordpress:8.1_20230307.1 # We need to use 8.1 to emulate the WP.org environment
|
||||
- image: mailpoet/wordpress:8.1_20230307.1
|
||||
|
||||
wpcli_php_latest:
|
||||
<<: *default_job_config
|
||||
docker:
|
||||
- image: mailpoet/wordpress:8.2_20241126.1
|
||||
- image: mailpoet/wordpress:8.1_20230307.1
|
||||
|
||||
wpcli_php_mysql_oldest:
|
||||
<<: *default_job_config
|
||||
@ -115,7 +115,7 @@ executors:
|
||||
wpcli_php_mysql_latest:
|
||||
<<: *default_job_config
|
||||
docker:
|
||||
- image: mailpoet/wordpress:8.2_20241126.1
|
||||
- image: mailpoet/wordpress:8.1_20230307.1
|
||||
- image: cimg/mysql:8.0
|
||||
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_520_ci
|
||||
|
||||
@ -141,8 +141,6 @@ jobs:
|
||||
key: composer-{{ checksum "tasks/code_sniffer/composer.json" }}-{{ checksum "tasks/code_sniffer/composer.lock" }}
|
||||
- restore_cache:
|
||||
key: composer-{{ checksum "composer.json" }}-{{ checksum "composer.lock" }}
|
||||
- restore_cache:
|
||||
key: composer-{{ checksum "../tests_env/composer.json" }}-{{ checksum "../tests_env/composer.lock" }}
|
||||
- restore_cache:
|
||||
key: composer-prefixed-{{ checksum "prefixer-checksum" }}
|
||||
- restore_cache:
|
||||
@ -157,9 +155,9 @@ jobs:
|
||||
./tools/vendor/composer.phar validate --no-check-all --no-check-publish --working-dir=prefixer
|
||||
touch .env
|
||||
./do install
|
||||
./do compile:all --env production --skip-tests
|
||||
./do compile:all --env production
|
||||
./do doctrine:generate-cache
|
||||
../tests_env/vendor/bin/codecept build
|
||||
vendor/bin/codecept build
|
||||
./do twig:generate-cache
|
||||
- run:
|
||||
name: 'Check Prettier formatting'
|
||||
@ -180,10 +178,6 @@ jobs:
|
||||
key: composer-{{ checksum "composer.json" }}-{{ checksum "composer.lock" }}
|
||||
paths:
|
||||
- vendor
|
||||
- save_cache:
|
||||
key: composer-{{ checksum "../tests_env/composer.json" }}-{{ checksum "../tests_env/composer.lock" }}
|
||||
paths:
|
||||
- ../tests_env/vendor
|
||||
- save_cache:
|
||||
key: composer-prefixed-{{ checksum "prefixer-checksum" }}
|
||||
paths:
|
||||
@ -197,10 +191,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.1.2
|
||||
./do download:woo-commerce-subscriptions-zip 6.5.0
|
||||
./do download:woo-commerce-memberships-zip 1.26.5
|
||||
./do download:automate-woo-zip 6.1.5
|
||||
./do download:automate-woo-zip 6.0.29
|
||||
- run:
|
||||
name: Dump tests ENV variables for acceptance tests
|
||||
command: |
|
||||
@ -336,7 +330,6 @@ jobs:
|
||||
name: 'JS Newsletter Editor Tests'
|
||||
command: |
|
||||
mkdir test-results/mocha
|
||||
./do compile:js --env production --only-tests
|
||||
./do t:newsletter-editor test-results/mocha/newsletter_editor_junit.xml
|
||||
- run:
|
||||
name: 'JS Tests'
|
||||
@ -402,15 +395,11 @@ jobs:
|
||||
use_woocommerce_beta:
|
||||
type: boolean
|
||||
default: false
|
||||
wordpress_version:
|
||||
type: string
|
||||
default: ''
|
||||
environment:
|
||||
MYSQL_COMMAND: << parameters.mysql_command >>
|
||||
MYSQL_IMAGE: << parameters.mysql_image >>
|
||||
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
|
||||
WORDPRESS_IMAGE_VERSION: << parameters.wordpress_image_version >>
|
||||
WORDPRESS_VERSION: << parameters.wordpress_version >>
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /home/circleci
|
||||
@ -426,7 +415,7 @@ jobs:
|
||||
echo "No latest beta version found. Ending job early."
|
||||
circleci-agent step halt
|
||||
else
|
||||
echo "export WORDPRESS_VERSION=$LATEST_WP_BETA" >> $BASH_ENV
|
||||
echo "export LATEST_WP_BETA=$LATEST_WP_BETA" >> $BASH_ENV
|
||||
echo "Using WordPress Beta Version: $LATEST_WP_BETA"
|
||||
fi
|
||||
else
|
||||
@ -451,51 +440,51 @@ jobs:
|
||||
- run:
|
||||
name: 'Pull test docker images'
|
||||
# Pull docker images with 3 retries
|
||||
command: i='0';while ! docker compose -f ../tests_env/docker/docker-compose.yml pull && ((i < 3)); do sleep 3 && i=$[$i+1]; done
|
||||
command: i='0';while ! docker-compose -f tests/docker/docker-compose.yml pull && ((i < 3)); do sleep 3 && i=$[$i+1]; done
|
||||
- run:
|
||||
name: Create docker containers for test
|
||||
# We experienced some failures when creating containers so we do it explicitly with one retry
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose create || docker compose create
|
||||
cd tests/docker
|
||||
docker-compose create || docker-compose create
|
||||
- run:
|
||||
# Some tools we use may need different version based on PHP version used in docker
|
||||
name: Ensure correct versions of tools
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project -e COMPOSER_DEV_MODE=1 --entrypoint "php tools/install.php" codeception_acceptance
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project -e COMPOSER_DEV_MODE=1 --entrypoint "php tools/install.php" codeception_acceptance
|
||||
- when:
|
||||
condition: ${WOOCOMMERCE_VERSION}
|
||||
steps:
|
||||
- run:
|
||||
name: Download WooCommerce Core
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:woo-commerce-zip ${WOOCOMMERCE_VERSION}" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-zip ${WOOCOMMERCE_VERSION}" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
- when:
|
||||
condition: << parameters.woo_subscriptions_version >>
|
||||
steps:
|
||||
- run:
|
||||
name: Download WooCommerce Subscriptions
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:woo-commerce-subscriptions-zip << parameters.woo_subscriptions_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-subscriptions-zip << parameters.woo_subscriptions_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
- when:
|
||||
condition: << parameters.woo_memberships_version >>
|
||||
steps:
|
||||
- run:
|
||||
name: Download WooCommerce Memberships
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:woo-commerce-memberships-zip << parameters.woo_memberships_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-memberships-zip << parameters.woo_memberships_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
- when:
|
||||
condition: << parameters.automate_woo_version >>
|
||||
steps:
|
||||
- run:
|
||||
name: Download AutomateWoo
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:automate-woo-zip << parameters.automate_woo_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:automate-woo-zip << parameters.automate_woo_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance
|
||||
- run:
|
||||
name: Group acceptance tests
|
||||
command: |
|
||||
@ -515,7 +504,7 @@ jobs:
|
||||
name: Run acceptance tests
|
||||
command: |
|
||||
mkdir -m 777 -p tests/_output/exceptions
|
||||
cd ../tests_env/docker
|
||||
cd tests/docker
|
||||
args=(
|
||||
--steps
|
||||
--debug
|
||||
@ -524,7 +513,7 @@ jobs:
|
||||
--xml
|
||||
-g circleci_split_group
|
||||
)
|
||||
docker compose run -e SKIP_DEPS=1 \
|
||||
docker-compose run -e SKIP_DEPS=1 \
|
||||
-e CIRCLE_BRANCH=${CIRCLE_BRANCH} \
|
||||
-e CIRCLE_JOB=${CIRCLE_JOB} \
|
||||
-e MULTISITE=<< parameters.multisite >> \
|
||||
@ -532,7 +521,7 @@ jobs:
|
||||
-e ENABLE_HPOS=<< parameters.enable_hpos >> \
|
||||
-e ENABLE_HPOS_SYNC=<< parameters.enable_hpos_sync >> \
|
||||
-e DISABLE_HPOS=<< parameters.disable_hpos >> \
|
||||
-e WORDPRESS_VERSION=${WORDPRESS_VERSION} \
|
||||
-e LATEST_BETA=${LATEST_WP_BETA} \
|
||||
codeception_acceptance "${args[@]}"
|
||||
- run:
|
||||
name: Check exceptions
|
||||
@ -583,13 +572,13 @@ jobs:
|
||||
- run:
|
||||
name: 'Pull test docker images'
|
||||
# Pull docker images with 3 retries
|
||||
command: i='0';while ! docker compose -f tests/performance/docker-compose.yml pull && ((i < 3)); do sleep 3 && i=$[$i+1]; done
|
||||
command: i='0';while ! docker-compose -f tests/performance/docker-compose.yml pull && ((i < 3)); do sleep 3 && i=$[$i+1]; done
|
||||
- run:
|
||||
name: Create docker containers for test
|
||||
# We experienced some failures when creating containers so we do it explicitly with one retry
|
||||
command: |
|
||||
cd tests/performance
|
||||
docker compose create || docker compose create
|
||||
docker-compose create || docker-compose create
|
||||
- run:
|
||||
name: Run performance tests
|
||||
command: |
|
||||
@ -653,15 +642,10 @@ jobs:
|
||||
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
|
||||
MYSQL_COMMAND: << parameters.mysql_command >>
|
||||
MYSQL_IMAGE: << parameters.mysql_image >>
|
||||
WORDPRESS_IMAGE_VERSION: << parameters.wordpress_image_version >>
|
||||
WORDPRESS_VERSION: << parameters.wordpress_version >>
|
||||
parameters:
|
||||
codeception_image_version:
|
||||
type: string
|
||||
default: ''
|
||||
wordpress_image_version:
|
||||
type: string
|
||||
default: ''
|
||||
group:
|
||||
type: string
|
||||
default: ''
|
||||
@ -707,9 +691,6 @@ jobs:
|
||||
use_woocommerce_beta:
|
||||
type: boolean
|
||||
default: false
|
||||
wordpress_version:
|
||||
type: string
|
||||
default: ''
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /home/circleci
|
||||
@ -722,7 +703,7 @@ jobs:
|
||||
echo "No latest beta version found. Ending job early."
|
||||
circleci-agent step halt
|
||||
else
|
||||
echo "export WORDPRESS_VERSION=$LATEST_WP_BETA" >> $BASH_ENV
|
||||
echo "export LATEST_WP_BETA=$LATEST_WP_BETA" >> $BASH_ENV
|
||||
echo "Using WordPress Beta Version: $LATEST_WP_BETA"
|
||||
fi
|
||||
else
|
||||
@ -747,56 +728,56 @@ jobs:
|
||||
- run:
|
||||
name: 'Pull test docker images'
|
||||
# Pull docker images with 3 retries
|
||||
command: i='0';while ! docker compose -f ../tests_env/docker/docker-compose.yml pull && ((i < 3)); do sleep 3 && i=$[$i+1]; done
|
||||
command: i='0';while ! docker-compose -f tests/docker/docker-compose.yml pull && ((i < 3)); do sleep 3 && i=$[$i+1]; done
|
||||
- run:
|
||||
name: Create docker containers for test
|
||||
# We experienced some failures when creating containers so we do it explicitly with one retry
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose create || docker compose create
|
||||
cd tests/docker
|
||||
docker-compose create || docker-compose create
|
||||
- run:
|
||||
# Some tools we use may need different version based on PHP version used in docker
|
||||
name: Ensure correct versions of tools
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project -e COMPOSER_DEV_MODE=1 --entrypoint "php tools/install.php" codeception_integration
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project -e COMPOSER_DEV_MODE=1 --entrypoint "php tools/install.php" codeception_integration
|
||||
- when:
|
||||
condition: ${WOOCOMMERCE_VERSION}
|
||||
steps:
|
||||
- run:
|
||||
name: Download WooCommerce Core
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:woo-commerce-zip ${WOOCOMMERCE_VERSION}" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-zip ${WOOCOMMERCE_VERSION}" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
- when:
|
||||
condition: << parameters.woo_subscriptions_version >>
|
||||
steps:
|
||||
- run:
|
||||
name: Download WooCommerce Subscriptions
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:woo-commerce-subscriptions-zip << parameters.woo_subscriptions_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-subscriptions-zip << parameters.woo_subscriptions_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
- when:
|
||||
condition: << parameters.woo_memberships_version >>
|
||||
steps:
|
||||
- run:
|
||||
name: Download WooCommerce Memberships
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:woo-commerce-memberships-zip << parameters.woo_memberships_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-memberships-zip << parameters.woo_memberships_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
- when:
|
||||
condition: << parameters.automate_woo_version >>
|
||||
steps:
|
||||
- run:
|
||||
name: Download AutomateWoo
|
||||
command: |
|
||||
cd ../tests_env/docker
|
||||
docker compose run --rm -w /project --entrypoint "./do download:automate-woo-zip << parameters.automate_woo_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
cd tests/docker
|
||||
docker-compose run --rm -w /project --entrypoint "./do download:automate-woo-zip << parameters.automate_woo_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration
|
||||
- run:
|
||||
name: 'PHP Integration tests'
|
||||
command: |
|
||||
mkdir -m 777 -p tests/_output/exceptions
|
||||
cd ../tests_env/docker
|
||||
cd tests/docker
|
||||
args=(
|
||||
--steps
|
||||
--debug
|
||||
@ -810,7 +791,7 @@ jobs:
|
||||
if [[ -n '<< parameters.skip_group >>' ]]; then
|
||||
args+=(--skip-group << parameters.skip_group >>)
|
||||
fi
|
||||
docker compose run -e SKIP_DEPS=1 \
|
||||
docker-compose run -e SKIP_DEPS=1 \
|
||||
-e CIRCLE_BRANCH=${CIRCLE_BRANCH} \
|
||||
-e CIRCLE_JOB=${CIRCLE_JOB} \
|
||||
-e SKIP_PLUGINS=<< parameters.skip_plugins >> \
|
||||
@ -830,7 +811,7 @@ jobs:
|
||||
-e ENABLE_HPOS=<< parameters.enable_hpos >> \
|
||||
-e ENABLE_HPOS_SYNC=<< parameters.enable_hpos_sync >> \
|
||||
-e DISABLE_HPOS=<< parameters.disable_hpos >> \
|
||||
-e WORDPRESS_VERSION=${WORDPRESS_VERSION} \
|
||||
-e LATEST_BETA=${LATEST_WP_BETA} \
|
||||
codeception_integration "${args[@]}"
|
||||
- store_test_results:
|
||||
path: tests/_output
|
||||
@ -863,30 +844,6 @@ jobs:
|
||||
root: /home/circleci/mailpoet
|
||||
paths:
|
||||
- mailpoet/release_zip_build_number.txt
|
||||
- mailpoet/mailpoet.zip
|
||||
qit_security_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 Security Test'
|
||||
command: ./do qa:qit-security | tee tests/_output/qit-security
|
||||
- run:
|
||||
name: 'Retrieve test results'
|
||||
command: |
|
||||
# Download HTML report from QIT servers
|
||||
grep "Result Url" tests/_output/qit-security | awk '{ print $3 }' | xargs curl -o tests/_output/report.html
|
||||
when: always
|
||||
- store_artifacts:
|
||||
path: tests/_output
|
||||
|
||||
workflows:
|
||||
build_and_test:
|
||||
@ -940,28 +897,48 @@ workflows:
|
||||
name: acceptance_tests_base_and_woo
|
||||
enable_hpos: 1
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- acceptance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: acceptance_tests_woo_hpos_sync_on
|
||||
group: woo
|
||||
enable_hpos_sync: 1
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- acceptance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: acceptance_tests_woo_hpos_off
|
||||
group: woo
|
||||
disable_hpos: 1
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- acceptance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: acceptance_tests_blockbased_theme
|
||||
group: frontend
|
||||
blockbased_theme: 1
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- performance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
name: performance_tests
|
||||
requires:
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- js_tests:
|
||||
<<: *slack-fail-post-step
|
||||
requires:
|
||||
@ -972,41 +949,55 @@ workflows:
|
||||
enable_hpos_sync: 1
|
||||
name: integration_test_woo_hpos_sync_on
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- integration_tests:
|
||||
<<: *slack-fail-post-step
|
||||
group: woo
|
||||
name: integration_test_woo_hpos_on
|
||||
enable_hpos: 1
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- integration_tests:
|
||||
<<: *slack-fail-post-step
|
||||
group: woo
|
||||
disable_hpos: 1
|
||||
name: integration_test_woo_hpos_off
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- integration_tests:
|
||||
<<: *slack-fail-post-step
|
||||
skip_group: woo
|
||||
skip_plugins: 1
|
||||
name: integration_test_base
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- acceptance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
<<: *multisite_acceptance_config
|
||||
name: acceptance_tests_multisite
|
||||
requires:
|
||||
- build
|
||||
- integration_tests:
|
||||
<<: *slack-fail-post-step
|
||||
<<: *only_trunk_and_release
|
||||
multisite: 1
|
||||
name: integration_tests_multisite
|
||||
requires:
|
||||
- build
|
||||
- unit_tests
|
||||
- static_analysis_php7
|
||||
- static_analysis_php8
|
||||
- qa_js
|
||||
- qa_php
|
||||
- acceptance_tests:
|
||||
<<: *slack-fail-post-step
|
||||
<<: *only_release
|
||||
@ -1035,22 +1026,10 @@ workflows:
|
||||
- integration_test_woo_hpos_on
|
||||
- integration_test_woo_hpos_off
|
||||
- integration_test_woo_hpos_sync_on
|
||||
- integration_with_premium_latest
|
||||
- acceptance_tests_woo_hpos_sync_on
|
||||
- acceptance_tests_woo_hpos_off
|
||||
- acceptance_tests_blockbased_theme
|
||||
- static_analysis_php8
|
||||
- static_analysis_php7
|
||||
- unit_tests
|
||||
- qa_js
|
||||
- qa_php
|
||||
- qa_php_oldest
|
||||
- security_analysis
|
||||
- qa_php_max_wporg
|
||||
- qit_security_scan:
|
||||
<<: *slack-fail-post-step
|
||||
requires:
|
||||
- build_release_zip
|
||||
- performance_tests
|
||||
|
||||
nightly:
|
||||
triggers:
|
||||
@ -1082,15 +1061,14 @@ 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.0.2
|
||||
woo_subscriptions_version: 6.4.1
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
mysql_command: --max_allowed_packet=100M
|
||||
automate_woo_version: 5.8.5
|
||||
mysql_command: --max_allowed_packet=100M --default-storage-engine=MYISAM
|
||||
mysql_image: mysql:5.5
|
||||
codeception_image_version: 7.4-cli_20220605.0
|
||||
wordpress_image_version: 6.1.1-php7.4 # We use image with PHP 7.4 and install required WordPress version via CLI
|
||||
wordpress_version: 6.6.2
|
||||
wordpress_image_version: 6.5.5-php8.1
|
||||
requires:
|
||||
- build
|
||||
- performance_tests:
|
||||
@ -1123,14 +1101,12 @@ 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.0.2
|
||||
woo_subscriptions_version: 6.4.1
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
automate_woo_version: 5.8.5
|
||||
codeception_image_version: 7.4-cli_20220605.0
|
||||
wordpress_image_version: 6.1.1-php7.4 # We use image with PHP 7.4 and install required WordPress version via CLI # We use image with PHP 7.4 and install required WordPress version via CLI
|
||||
wordpress_version: 6.6.2
|
||||
mysql_command: --max_allowed_packet=100M
|
||||
mysql_command: --max_allowed_packet=100M --default-storage-engine=MYISAM
|
||||
mysql_image: mysql:5.5
|
||||
requires:
|
||||
- build
|
||||
@ -1186,26 +1162,23 @@ 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.0.2
|
||||
woo_subscriptions_version: 6.4.1
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
automate_woo_version: 5.8.5
|
||||
codeception_image_version: 7.4-cli_20220605.0
|
||||
wordpress_image_version: 6.1.1-php7.4 # We use image with PHP 7.4 and install required WordPress version via CLI
|
||||
wordpress_version: 6.6.2
|
||||
wordpress_image_version: 6.5.5-php8.1
|
||||
requires:
|
||||
- build_premium
|
||||
- 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.0.2
|
||||
woo_subscriptions_version: 6.4.1
|
||||
woo_memberships_version: 1.25.2
|
||||
automate_woo_version: 6.0.33
|
||||
automate_woo_version: 5.8.5
|
||||
codeception_image_version: 7.4-cli_20220605.0
|
||||
wordpress_image_version: 6.1.1-php7.4 # We use image with PHP 7.4 and install required WordPress version via CLI
|
||||
wordpress_version: 6.6.2
|
||||
mysql_command: --max_allowed_packet=100M
|
||||
mysql_command: --max_allowed_packet=100M --default-storage-engine=MYISAM
|
||||
mysql_image: mysql:5.5
|
||||
requires:
|
||||
- build_premium
|
||||
|
@ -10,12 +10,6 @@ indent_size = 2
|
||||
ij_smart_tabs = false
|
||||
max_line_length = off
|
||||
|
||||
[packages/php/email-editor/**]
|
||||
indent_style = tab
|
||||
|
||||
[packages/js/email-editor/**.{js,jsx,ts,tsx,scss}]
|
||||
indent_style = tab
|
||||
|
||||
[*.php]
|
||||
ij_php_align_key_value_pairs = false
|
||||
ij_php_align_multiline_chained_methods = false
|
||||
@ -61,5 +55,3 @@ ij_php_space_after_for_semicolon = true
|
||||
ij_php_space_after_colon_in_return_type = true
|
||||
ij_php_space_before_else_keyword = true
|
||||
ij_php_for_statement_new_line_after_left_paren = true
|
||||
ij_php_class_brace_style = end_of_line
|
||||
ij_php_comma_after_last_array_element = true
|
||||
|
@ -39,15 +39,3 @@ e66c76133ec3ef667e382203426d91a4b4aa5174
|
||||
|
||||
# Prettier autoformatting
|
||||
ab27eaee2df740c0add4331a7f8c115a87ecfa2b
|
||||
|
||||
# Move email editor to JS packages folder
|
||||
912282f57ccc839491ff951ec5cf7aa10c14f429
|
||||
|
||||
# Switch email editor js packages to WP coding style
|
||||
b2fb96f8793b63db629d5237010d87332330c51e
|
||||
|
||||
# Email editor Prettier autoformatting
|
||||
8c604453b1d82e3a2c731241e1c96ea8b32ec716
|
||||
|
||||
# Move email editor components out of the engine folder
|
||||
1c3ea9cd0a5fc8848a64d840e2fa16a6c7d8c1fe
|
||||
|
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
|
@ -65,7 +65,7 @@ function getLatestAndPreviousVersions(array $sortedVersions): array {
|
||||
*/
|
||||
function replaceLatestWordPressVersion(string $latestVersion): void {
|
||||
replaceVersionInFile(
|
||||
__DIR__ . './../../../tests_env/docker/docker-compose.yml',
|
||||
__DIR__ . './../../../mailpoet/tests/docker/docker-compose.yml',
|
||||
'/(wordpress:\${WORDPRESS_IMAGE_VERSION:-\s*)\d+\.\d+\.?\d*-php\d+\.\d+(})/',
|
||||
'${1}' . $latestVersion . '${2}'
|
||||
);
|
||||
@ -77,7 +77,7 @@ function replaceLatestWordPressVersion(string $latestVersion): void {
|
||||
function replacePreviousWordPressVersion(string $previousVersion): void {
|
||||
replaceVersionInFile(
|
||||
__DIR__ . './../../../.circleci/config.yml',
|
||||
'/(wordpress_version: )\d+\.\d+\.?\d*/',
|
||||
'/(wordpress_image_version: )\d+\.\d+\.?\d*-php\d+\.\d+/',
|
||||
'${1}' . $previousVersion
|
||||
);
|
||||
}
|
||||
@ -113,8 +113,6 @@ if ($latestVersion) {
|
||||
|
||||
if ($previousVersion) {
|
||||
echo "Replacing the previous version in the config file...\n";
|
||||
// We install previous WordPress version via CLI so we need a version without PHP in the name.
|
||||
$previousVersion = preg_replace('/-php\d+\.\d+$/', '', $previousVersion);
|
||||
replacePreviousWordPressVersion($previousVersion);
|
||||
} else {
|
||||
echo "No previous version found.\n";
|
||||
|
@ -155,17 +155,10 @@ jobs:
|
||||
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
|
||||
git push origin HEAD:refs/heads/update-plugins-and-wordpress
|
||||
|
||||
# Create a pull request if there are changes
|
||||
- name: Create Pull Request
|
||||
@ -174,9 +167,5 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
branch: update-plugins-and-wordpress
|
||||
title: Update WordPress and plugins in CI jobs
|
||||
title: 'Update used WordPress Docker image and used plugin versions in Circle 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
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,5 +9,3 @@ npm-debug.log
|
||||
mailpoet-premium
|
||||
tsconfig.tsbuildinfo
|
||||
/wordpress
|
||||
packages/php/*/vendor
|
||||
tests_env/vendor
|
||||
|
@ -7,6 +7,7 @@ export MP_GIT_HOOKS_ESLINT="${MP_GIT_HOOKS_ESLINT:-true}"
|
||||
export MP_GIT_HOOKS_STYLELINT="${MP_GIT_HOOKS_STYLELINT:-true}"
|
||||
export MP_GIT_HOOKS_PHPLINT="${MP_GIT_HOOKS_PHPLINT:-true}"
|
||||
export MP_GIT_HOOKS_CODE_SNIFFER="${MP_GIT_HOOKS_CODE_SNIFFER:-true}"
|
||||
export MP_GIT_HOOKS_MINIMAL_PLUGIN_STANDARDS="${MP_GIT_HOOKS_MINIMAL_PLUGIN_STANDARDS:-true}"
|
||||
export MP_GIT_HOOKS_PHPSTAN="${MP_GIT_HOOKS_PHPSTAN:-true}"
|
||||
export MP_GIT_HOOKS_INSTALL_JS="${MP_GIT_HOOKS_INSTALL_JS:-false}"
|
||||
export MP_GIT_HOOKS_INSTALL_PHP="${MP_GIT_HOOKS_INSTALL_PHP:-false}"
|
||||
|
@ -4,5 +4,3 @@
|
||||
[ "$MP_GIT_HOOKS_ENABLE" != "true" ] && exit 0
|
||||
|
||||
installIfUpdates
|
||||
|
||||
./do cleanup:cached-files
|
||||
|
@ -1,8 +1,7 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
. "$(dirname "$0")/common.sh"
|
||||
[ "$MP_GIT_HOOKS_ENABLE" != "true" ] && exit 0
|
||||
|
||||
npx lint-staged -c mailpoet/package.json --cwd mailpoet
|
||||
npx lint-staged -c package.json
|
||||
npx lint-staged -c packages/js/email-editor/package.json --cwd packages/js/email-editor
|
||||
npx lint-staged -c packages/php/email-editor/.lintstagedrc.json --cwd packages/php/email-editor
|
||||
|
@ -25,5 +25,3 @@ vendor-prefixed
|
||||
/mailpoet/views
|
||||
/mailpoet-premium
|
||||
/wordpress
|
||||
/packages/php/email-editor
|
||||
/packages/js/email-editor
|
||||
|
@ -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
|
10
README.md
10
README.md
@ -85,7 +85,7 @@ mailpoet/vendor/bin/codecept -> /project/vendor/bin/codecept
|
||||
mailpoet/vendor/bin/wp -> /usr/local/bin/wp
|
||||
```
|
||||
|
||||
- Add `XDEBUG_TRIGGER: 1` environment to `tests_env/docker/docker-compose.yml` -> codeception service to start triggering Xdebug
|
||||
- Add `XDEBUG_TRIGGER: 1` environment to `mailpoet/tests/docker/docker-compose.yml` -> codeception service to start triggering Xdebug
|
||||
- Make PHPStorm listen to connections by clicking on the phone icon
|
||||
|
||||
## Local development
|
||||
@ -103,8 +103,8 @@ Then create a Docker Compose override file with NFS settings and restart contain
|
||||
```shell
|
||||
cp docker-compose.override.macos-sample.yml docker-compose.override.yml
|
||||
|
||||
docker compose down -v --remove-orphans
|
||||
docker compose up -d
|
||||
docker-compose down -v --remove-orphans
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
**NOTE:** If you are on MacOS Catalina or newer, make sure to put the repository
|
||||
@ -163,10 +163,10 @@ To switch the environment to a different PHP version:
|
||||
dockerfile: dev/{PHP_VERSION}/Dockerfile
|
||||
```
|
||||
|
||||
3. Run `docker compose build wordpress`.
|
||||
3. Run `docker-compose build wordpress`.
|
||||
4. Start the stack with `./do start`.
|
||||
|
||||
To switch back to the default PHP version remove what was added in 2) and, run `docker compose build wordpress` for application container and `docker compose build test_wordpress` for tests container,
|
||||
To switch back to the default PHP version remove what was added in 2) and, run `docker-compose build wordpress` for application container and `docker-compose build test_wordpress` for tests container,
|
||||
and start the stack using `./do start`.
|
||||
|
||||
### Disabling the Tracy panel
|
||||
|
@ -21,7 +21,7 @@ mkdir -p wordpress/wp-content/plugins/mailpoet-premium
|
||||
mkdir -p dev/data/mailhog
|
||||
|
||||
for plugin in "mailpoet" "mailpoet-premium"; do
|
||||
docker compose run --rm wordpress /bin/sh -c "
|
||||
docker-compose run --rm wordpress /bin/sh -c "
|
||||
[ -d /var/www/html/wp-content/plugins/$plugin ] &&
|
||||
cd /var/www/html/wp-content/plugins/$plugin &&
|
||||
./do install &&
|
||||
@ -29,7 +29,7 @@ for plugin in "mailpoet" "mailpoet-premium"; do
|
||||
"
|
||||
done
|
||||
|
||||
docker compose run --rm wordpress /bin/sh -c "
|
||||
docker-compose run --rm wordpress /bin/sh -c "
|
||||
cd /var/www/templates &&
|
||||
mkdir assets classes exported
|
||||
"
|
||||
|
@ -29,6 +29,6 @@ cat <<EOT
|
||||
NFS volume sharing is set up. Recreate your containers and volumes using:
|
||||
cp docker-compose.override.macos-sample.yml docker-compose.override.yml
|
||||
|
||||
docker compose down -v --remove-orphans
|
||||
docker compose up -d
|
||||
docker-compose down -v --remove-orphans
|
||||
docker-compose up -d
|
||||
EOT
|
||||
|
16
do
16
do
@ -3,8 +3,8 @@
|
||||
function syntax {
|
||||
cat << EOF
|
||||
./do setup Setup the dev environment.
|
||||
./do start Start the docker containers (docker compose up -d).
|
||||
./do stop Stop the docker containers (docker compose stop).
|
||||
./do start Start the docker containers (docker-compose up -d).
|
||||
./do stop Stop the docker containers (docker-compose stop).
|
||||
./do ssh [--test] Run an interactive bash shell inside the plugin directory.
|
||||
./do run [--test] <command> Run a custom bash command in the wordpress container.
|
||||
./do acceptance [--premium] Run acceptance tests.
|
||||
@ -21,7 +21,7 @@ EOF
|
||||
function ssh_and_run {
|
||||
params=("$@")
|
||||
params=("${params[@]:1}")
|
||||
docker compose exec $1 bash -c "${params[@]}"
|
||||
docker-compose exec $1 bash -c "${params[@]}"
|
||||
}
|
||||
|
||||
if [ "$1" = "" -o "$1" = "--help" ]; then
|
||||
@ -31,10 +31,10 @@ elif [ "$1" = "setup" ]; then
|
||||
./dev/initial-setup.sh
|
||||
|
||||
elif [ "$1" = "start" ]; then
|
||||
docker compose up -d
|
||||
docker-compose up -d
|
||||
|
||||
elif [ "$1" = "stop" ]; then
|
||||
docker compose stop
|
||||
docker-compose stop
|
||||
|
||||
elif [ "$1" = "run" ]; then
|
||||
params=("$@")
|
||||
@ -54,9 +54,9 @@ elif [ "$1" = "ssh" ]; then
|
||||
fi
|
||||
|
||||
if [ "$2" = "--test" ] || [ "$3" = "--test" ]; then
|
||||
docker compose exec --workdir $dir test_wordpress bash
|
||||
docker-compose exec --workdir $dir test_wordpress bash
|
||||
else
|
||||
docker compose exec --workdir $dir wordpress bash
|
||||
docker-compose exec --workdir $dir wordpress bash
|
||||
fi
|
||||
|
||||
elif [ "$1" = "acceptance" ]; then
|
||||
@ -65,7 +65,7 @@ elif [ "$1" = "acceptance" ]; then
|
||||
else
|
||||
cd mailpoet
|
||||
fi
|
||||
COMPOSE_HTTP_TIMEOUT=200 docker compose run codeception_acceptance -e KEEP_DEPS=1 --steps --debug -vvv
|
||||
COMPOSE_HTTP_TIMEOUT=200 docker-compose run codeception_acceptance -e KEEP_DEPS=1 --steps --debug -vvv
|
||||
cd ..
|
||||
|
||||
elif [ "$1" = "build" ]; then
|
||||
|
@ -27,7 +27,6 @@ Class `\MailPoet\API\API` becomes available once MailPoet plugin is loaded by Wo
|
||||
|
||||
- [Add List (addList)](api_methods/AddList.md)
|
||||
- [Add Subscriber (addSubscriber)](api_methods/AddSubscriber.md)
|
||||
- [Update Subscriber (updateSubscriber)](api_methods/UpdateSubscriber.md)
|
||||
- [Add Subscriber Field (addSubscriberField)](api_methods/AddSubscriberField.md)
|
||||
- [Delete List (deleteList)](api_methods/DeleteList.md)
|
||||
- [Get Lists (getLists)](api_methods/GetLists.md)
|
||||
|
@ -1,33 +0,0 @@
|
||||
[back to list](../Readme.md)
|
||||
|
||||
# Update Subscriber
|
||||
|
||||
## `array updateSubscriber($subscriberIdOrEmail, array $subscriber): array`
|
||||
|
||||
This method allows a subscriber to be updated.
|
||||
The argument `$subscriber` is similar to [Add Subscriber](AddSubscriber.md) method, but the subscriber is updated instead of created.
|
||||
|
||||
It returns the updated subscriber. See [Get Subscriber](GetSubscriber.md) for a subscriber data structure.
|
||||
|
||||
If the subscriber is a WordPress user, the method does not allow updating `email`, `first_name` and `last_name`. It needs to be updated in the `wp_users` and MailPoet will synchronise the new values.
|
||||
|
||||
## Arguments
|
||||
|
||||
| Argument | Type | Description |
|
||||
| -------------------- | ------------- | ----------------------------------------- |
|
||||
| $subscriberIdOrEmail | string or int | An id or email of an existing subscriber. |
|
||||
| $subscriber | array | Subscriber data that will be updated |
|
||||
|
||||
## Error handling
|
||||
|
||||
All expected errors from the API are exceptions of class `\MailPoet\API\MP\v1\APIException`.
|
||||
Code of the exception is populated to distinguish between different errors.
|
||||
|
||||
An exception of base class `\Exception` can be thrown when something unexpected happens.
|
||||
|
||||
Codes description:
|
||||
|
||||
| Code | Description |
|
||||
| ---- | -------------------------------------------------- |
|
||||
| 4 | Updating a subscriber that does not exist. |
|
||||
| 13 | The subscriber couldn’t be updated in the database |
|
@ -1,3 +1,5 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# for M1 Macs
|
||||
db:
|
||||
|
@ -25,7 +25,7 @@ services:
|
||||
container_name: mp-wp
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dev/php82/Dockerfile
|
||||
dockerfile: dev/php81/Dockerfile
|
||||
args:
|
||||
UID: ${UID:-1000}
|
||||
GID: ${GID:-1000}
|
||||
@ -49,12 +49,10 @@ services:
|
||||
volumes:
|
||||
- './wordpress:/var/www/html'
|
||||
- './tsconfig.base.json:/var/www/html/wp-content/plugins/tsconfig.base.json:ro'
|
||||
- './.npmrc:/var/www/html/wp-content/plugins/.npmrc'
|
||||
- './package.json:/var/www/html/wp-content/plugins/package.json'
|
||||
- './pnpm-lock.yaml:/var/www/html/wp-content/plugins/pnpm-lock.yaml'
|
||||
- './pnpm-workspace.yaml:/var/www/html/wp-content/plugins/pnpm-workspace.yaml'
|
||||
- './patches:/var/www/html/wp-content/plugins/patches'
|
||||
- './tests_env:/var/www/html/wp-content/plugins/tests_env'
|
||||
- './mailpoet:/var/www/html/wp-content/plugins/mailpoet'
|
||||
- './mailpoet-premium:/var/www/html/wp-content/plugins/mailpoet-premium'
|
||||
- './packages:/var/www/html/wp-content/plugins/packages'
|
||||
|
@ -51,6 +51,7 @@ MP_GIT_HOOKS_ESLINT=true
|
||||
MP_GIT_HOOKS_STYLELINT=true
|
||||
MP_GIT_HOOKS_PHPLINT=true
|
||||
MP_GIT_HOOKS_CODE_SNIFFER=true
|
||||
MP_GIT_HOOKS_MINIMAL_PLUGIN_STANDARDS=true
|
||||
MP_GIT_HOOKS_PHPSTAN=true
|
||||
MP_GIT_HOOKS_INSTALL_JS=false
|
||||
MP_GIT_HOOKS_INSTALL_PHP=false
|
||||
|
2616
mailpoet/CHANGELOG.md
Normal file
2616
mailpoet/CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
return $this->taskExecStack()
|
||||
->stopOnFail()
|
||||
->exec('./tools/vendor/composer.phar install')
|
||||
->exec('cd ../packages/php/email-editor && ../../../mailpoet/tools/vendor/composer.phar install && cd -')
|
||||
->exec('cd .. && pnpm install --frozen-lockfile --prefer-offline')
|
||||
->addCode([$this, 'cleanupCachedFiles'])
|
||||
->run();
|
||||
@ -33,7 +32,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
return $this->taskExecStack()
|
||||
->stopOnFail()
|
||||
->exec('./tools/vendor/composer.phar install')
|
||||
->exec('cd ../packages/php/email-editor && ../../../mailpoet/tools/vendor/composer.phar install && cd -')
|
||||
->addCode([$this, 'cleanupCachedFiles'])
|
||||
->run();
|
||||
}
|
||||
@ -189,7 +187,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
$this->_exec('./node_modules/webpack/bin/webpack.js --watch');
|
||||
}
|
||||
|
||||
public function compileAll($opts = ['env' => null, 'skip-tests' => false, 'only-tests' => false]) {
|
||||
public function compileAll($opts = ['env' => null, 'skip-tests' => false]) {
|
||||
$collection = $this->collectionBuilder();
|
||||
$collection->addCode(function() use ($opts) {
|
||||
return call_user_func([$this, 'compileJs'], $opts);
|
||||
@ -200,17 +198,15 @@ class RoboFile extends \Robo\Tasks {
|
||||
return $collection->run();
|
||||
}
|
||||
|
||||
public function compileJs($opts = ['env' => null, 'skip-tests' => false, 'only-tests' => false]) {
|
||||
public function compileJs($opts = ['env' => null, 'skip-tests' => false]) {
|
||||
if (!is_dir('assets/dist/js')) {
|
||||
mkdir('assets/dist/js', 0777, true);
|
||||
}
|
||||
if (!$opts['only-tests']) {
|
||||
$this->_exec('rm -rf ' . __DIR__ . '/assets/dist/js/*');
|
||||
}
|
||||
$this->_exec('rm -rf ' . __DIR__ . '/assets/dist/js/*');
|
||||
$env = ($opts['env']) ?
|
||||
sprintf('./node_modules/.bin/cross-env NODE_ENV="%s"', $opts['env']) :
|
||||
null;
|
||||
return $this->_exec($env . ' ./node_modules/webpack/bin/webpack.js --env BUILD_TESTS=' . ($opts['skip-tests'] ? 'skip' : 'build') . ' --env BUILD_ONLY_TESTS=' . ($opts['only-tests'] ? 'true' : 'false'));
|
||||
return $this->_exec($env . ' ./node_modules/webpack/bin/webpack.js --env BUILD_TESTS=' . ($opts['skip-tests'] ? 'skip' : 'build'));
|
||||
}
|
||||
|
||||
public function compileCss($opts = ['env' => null]) {
|
||||
@ -222,7 +218,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
|
||||
$compilationResult = $this->taskExecStack()
|
||||
->exec('pnpm run stylelint-check -- "assets/css/src/**/*.scss"')
|
||||
->exec('pnpm run scss' . ($opts['env'] === 'production' ? ' --no-source-map' : ''))
|
||||
->exec('pnpm run scss')
|
||||
->exec('pnpm run autoprefixer')
|
||||
->run();
|
||||
|
||||
@ -332,7 +328,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
}
|
||||
|
||||
public function testUnit(array $opts = ['file' => null, 'xml' => false, 'multisite' => false, 'debug' => false]) {
|
||||
$command = '../tests_env/vendor/bin/codecept run unit';
|
||||
$command = 'vendor/bin/codecept run unit';
|
||||
|
||||
if ($opts['file']) {
|
||||
$command .= ' -f ' . $opts['file'];
|
||||
@ -349,7 +345,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
return $this->_exec($command);
|
||||
}
|
||||
|
||||
public function testIntegration(array $opts = ['file' => null, 'group' => null, 'skip-group' => null, 'xml' => false, 'multisite' => false, 'debug' => false, 'skip-deps' => false, 'skip-plugins' => false, 'disable-hpos' => false, 'enable-hpos-sync' => false, 'enable-hpos' => false, 'stop-on-fail' => false, 'wordpress-version' => null]) {
|
||||
public function testIntegration(array $opts = ['file' => null, 'group' => null, 'skip-group' => null, 'xml' => false, 'multisite' => false, 'debug' => false, 'skip-deps' => false, 'skip-plugins' => false, 'disable-hpos' => false, 'enable-hpos-sync' => false, 'enable-hpos' => false, 'stop-on-fail' => false, 'beta-version' => null]) {
|
||||
return $this->runTestsInContainer(array_merge($opts, ['test_type' => 'integration']));
|
||||
}
|
||||
|
||||
@ -406,7 +402,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
return $this->testIntegration($opts);
|
||||
}
|
||||
|
||||
public function testAcceptance($opts = ['file' => null, 'skip-deps' => false, 'group' => null, 'timeout' => null, 'disable-hpos' => false, 'enable-hpos-sync' => false, 'enable-hpos' => false, 'wordpress-version' => null, 'skip-plugins' => false]) {
|
||||
public function testAcceptance($opts = ['file' => null, 'skip-deps' => false, 'group' => null, 'timeout' => null, 'disable-hpos' => false, 'enable-hpos-sync' => false, 'enable-hpos' => false, 'beta-version' => null]) {
|
||||
return $this->runTestsInContainer($opts);
|
||||
}
|
||||
|
||||
@ -422,7 +418,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
->option('env', 'US=' . $opts['us'])
|
||||
->option('env', 'PW=' . $opts['pw'])
|
||||
->option('env', 'K6_BROWSER_HEADLESS=' . ($opts['head'] ? 'false' : 'true'))
|
||||
->option('env', 'K6_BROWSER_TIMEOUT=' . getenv('K6_BROWSER_TIMEOUT'))
|
||||
->option('env', 'K6_BROWSER_TIMEOUT=120s')
|
||||
->option('env', 'SCENARIO=' . $opts['scenario'])
|
||||
->arg($path ?? "$dir/tests/performance/scenarios.js")
|
||||
->dir($dir)->run();
|
||||
@ -439,7 +435,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
->option('env', 'SCENARIO=' . $opts['scenario'])
|
||||
->option('env', 'K6_CLOUD_TOKEN=' . getenv('K6_CLOUD_TOKEN'))
|
||||
->option('env', 'K6_CLOUD_ID=' . getenv('K6_CLOUD_ID'))
|
||||
->option('env', 'K6_BROWSER_TIMEOUT=' . getenv('K6_BROWSER_TIMEOUT'))
|
||||
->option('env', 'K6_PROJECT_NAME=' . $opts['scenario'])
|
||||
->option('out', 'cloud')
|
||||
->arg($path ?? "$dir/tests/performance/scenarios.js")
|
||||
@ -476,14 +471,14 @@ class RoboFile extends \Robo\Tasks {
|
||||
|
||||
// import data & run WordPress setup
|
||||
$this->say('Importing data and running a WordPress setup...');
|
||||
$this->taskExec('COMPOSE_HTTP_TIMEOUT=200 docker compose run --rm -it setup')
|
||||
$this->taskExec('COMPOSE_HTTP_TIMEOUT=200 docker-compose run --rm -it setup')
|
||||
->dir(__DIR__ . '/tests/performance')
|
||||
->run();
|
||||
$this->say('Data imported, WordPress set up.');
|
||||
}
|
||||
|
||||
public function testPerformanceClean() {
|
||||
$this->taskExec('COMPOSE_HTTP_TIMEOUT=200 docker compose down --remove-orphans -v')
|
||||
$this->taskExec('COMPOSE_HTTP_TIMEOUT=200 docker-compose down --remove-orphans -v')
|
||||
->dir(__DIR__ . '/tests/performance')
|
||||
->run();
|
||||
}
|
||||
@ -497,8 +492,8 @@ class RoboFile extends \Robo\Tasks {
|
||||
*/
|
||||
public function deleteDocker() {
|
||||
return $this->taskExec(
|
||||
'docker compose down -v --remove-orphans --rmi all'
|
||||
)->dir(__DIR__ . '/../tests_env/docker')->run();
|
||||
'docker-compose down -v --remove-orphans --rmi all'
|
||||
)->dir(__DIR__ . '/tests/docker')->run();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -507,20 +502,20 @@ class RoboFile extends \Robo\Tasks {
|
||||
public function resetTestDocker() {
|
||||
return $this
|
||||
->taskExec(
|
||||
'docker compose down -v --remove-orphans'
|
||||
)->dir(__DIR__ . '/../tests_env/docker')
|
||||
'docker-compose down -v --remove-orphans'
|
||||
)->dir(__DIR__ . '/tests/docker')
|
||||
->addCode([$this, 'cleanupCachedFiles'])
|
||||
->run();
|
||||
}
|
||||
|
||||
public function testFailedUnit() {
|
||||
$this->_exec('../tests_env/vendor/bin/codecept build');
|
||||
return $this->_exec('../tests_env/vendor/bin/codecept run unit -g failed');
|
||||
$this->_exec('vendor/bin/codecept build');
|
||||
return $this->_exec('vendor/bin/codecept run unit -g failed');
|
||||
}
|
||||
|
||||
public function testFailedIntegration() {
|
||||
$this->_exec('../tests_env/vendor/bin/codecept build');
|
||||
return $this->_exec('../tests_env/vendor/bin/codecept run integration -g failed');
|
||||
$this->_exec('vendor/bin/codecept build');
|
||||
return $this->_exec('vendor/bin/codecept run integration -g failed');
|
||||
}
|
||||
|
||||
public function containerDump() {
|
||||
@ -624,6 +619,9 @@ class RoboFile extends \Robo\Tasks {
|
||||
$collection->addCode(function() {
|
||||
return $this->qaCodeSniffer([]);
|
||||
});
|
||||
$collection->addCode(function() {
|
||||
return $this->qaMinimalPluginStandard([]);
|
||||
});
|
||||
return $collection->run();
|
||||
}
|
||||
|
||||
@ -650,7 +648,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
'lib/',
|
||||
'lib-3rd-party/',
|
||||
'vendor/composer',
|
||||
'vendor/dragonmantank',
|
||||
'vendor/mtdowling',
|
||||
'vendor-prefixed/',
|
||||
'vendor-prefixed/soundasleep',
|
||||
'mailpoet.php',
|
||||
@ -666,7 +664,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
'vendor-prefixed/cerdic/css-tidy/COPYING',
|
||||
'vendor-prefixed/cerdic/css-tidy/NEWS',
|
||||
'vendor-prefixed/cerdic/css-tidy/testing',
|
||||
'vendor/dragonmantank/cron-expression/tests',
|
||||
'vendor/mtdowling/cron-expression/tests',
|
||||
'vendor/phpmailer/phpmailer/test',
|
||||
'vendor-prefixed/psr/log/Psr/Log/Test',
|
||||
'vendor-prefixed/sabberworm/php-css-parser/tests',
|
||||
@ -686,21 +684,11 @@ class RoboFile extends \Robo\Tasks {
|
||||
}
|
||||
|
||||
public function qaLintJavascript() {
|
||||
$collection = $this->collectionBuilder();
|
||||
return $collection->taskExecStack()
|
||||
->stopOnFail()
|
||||
->exec('pnpm run check-types && pnpm run lint')
|
||||
->exec('cd .. && cd packages/js/email-editor && pnpm run check-types && pnpm run lint:js')
|
||||
->run();
|
||||
return $this->_exec('pnpm run check-types && pnpm run lint');
|
||||
}
|
||||
|
||||
public function qaLintCss() {
|
||||
$collection = $this->collectionBuilder();
|
||||
return $collection->taskExecStack()
|
||||
->stopOnFail()
|
||||
->exec('pnpm run stylelint-check -- "assets/css/src/**/*.scss"')
|
||||
->exec('cd .. && cd packages/js/email-editor && pnpm run lint:css')
|
||||
->run();
|
||||
return $this->_exec('pnpm run stylelint-check -- "assets/css/src/**/*.scss"');
|
||||
}
|
||||
|
||||
public function qaCodeSniffer(array $filesToCheck, $opts = ['severity' => 'all']) {
|
||||
@ -729,7 +717,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
'tasks/code_sniffer/vendor',
|
||||
'tasks/phpstan/vendor',
|
||||
'tasks/makepot',
|
||||
'tasks/minimal-plugin-standard/vendor',
|
||||
'tools/vendor',
|
||||
'tools/wpscan-semgrep-rules',
|
||||
'temp',
|
||||
@ -754,6 +741,58 @@ class RoboFile extends \Robo\Tasks {
|
||||
->run();
|
||||
}
|
||||
|
||||
public function qaMinimalPluginStandard(array $filesToCheck, $opts = ['severity' => 'all']) {
|
||||
$severityFlag = $opts['severity'] === 'all' ? '-w' : '-n';
|
||||
|
||||
$task = implode(' ', [
|
||||
'php -d memory_limit=-1',
|
||||
'./tasks/code_sniffer/vendor/bin/phpcs',
|
||||
'--parallel=' . $this->getParallelism(),
|
||||
'--extensions=php',
|
||||
$severityFlag,
|
||||
'--standard=tasks/code_sniffer/vendor/wporg/plugin-directory/MinimalPluginStandard',
|
||||
'-s',
|
||||
]);
|
||||
|
||||
$ignorePaths = [
|
||||
'.mp_svn',
|
||||
'assets',
|
||||
'doc',
|
||||
'generated',
|
||||
'lib/Config/PopulatorData/Templates',
|
||||
'lib-3rd-party',
|
||||
'node_modules',
|
||||
'plugin_repository',
|
||||
'prefixer/build',
|
||||
'prefixer/vendor',
|
||||
'tasks/code_sniffer/vendor',
|
||||
'tasks/phpstan/vendor',
|
||||
'tasks/makepot',
|
||||
'tools/vendor',
|
||||
'tools/wpscan-semgrep-rules',
|
||||
'temp',
|
||||
'tests/_data',
|
||||
'tests/_output',
|
||||
'tests/_support/_generated',
|
||||
'vendor',
|
||||
'vendor-prefixed',
|
||||
'views',
|
||||
];
|
||||
|
||||
// the "--ignore" arg takes a list of regexes, we need to anchor and escape them
|
||||
$ignorePatterns = array_map(function (string $path): string {
|
||||
return '^' . preg_quote(__DIR__ . DIRECTORY_SEPARATOR . $path);
|
||||
}, $ignorePaths);
|
||||
|
||||
$stringFilesToCheck = !empty($filesToCheck) ? implode(' ', $filesToCheck) : '.';
|
||||
|
||||
return $this
|
||||
->taskExec($task)
|
||||
->arg('--ignore=' . implode(',', $ignorePatterns))
|
||||
->rawArg($stringFilesToCheck)
|
||||
->run();
|
||||
}
|
||||
|
||||
public function qaFixFile($filePath) {
|
||||
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
|
||||
if ($extension === 'php') {
|
||||
@ -761,7 +800,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
return $this->collectionBuilder()
|
||||
->taskExec(
|
||||
'./tasks/code_sniffer/vendor/bin/phpcbf ' .
|
||||
'--standard=tasks/code_sniffer/MailPoet/free-ruleset.xml ' .
|
||||
'--standard=./tasks/code_sniffer/MailPoet ' .
|
||||
'--runtime-set testVersion 7.4-8.2 ' .
|
||||
$filePath . ' -n'
|
||||
)
|
||||
@ -787,7 +826,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
}
|
||||
|
||||
// make sure Codeception support files are present to avoid invalid errors when running PHPStan
|
||||
$this->_exec('../tests_env/vendor/bin/codecept build');
|
||||
$this->_exec('vendor/bin/codecept build');
|
||||
|
||||
// PHPStan must be run out of main plugin directory to avoid its autoloading
|
||||
// from vendor/autoload.php where some dev dependencies cause conflicts.
|
||||
@ -811,10 +850,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
return $this->_exec('./tools/semgrep.sh lib/ lib-3rd-party/');
|
||||
}
|
||||
|
||||
public function qaQitSecurity() {
|
||||
return $this->_exec('./vendor/bin/qit run:security mailpoet --zip=mailpoet.zip --wait');
|
||||
}
|
||||
|
||||
public function svnCheckout() {
|
||||
$svnDir = ".mp_svn";
|
||||
|
||||
@ -1091,9 +1126,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
->addCode(function () {
|
||||
return $this->releaseDownloadZip();
|
||||
})
|
||||
->addCode(function () use ($version) {
|
||||
return $this->releaseVerifyDownloadedZip($version);
|
||||
})
|
||||
->addCode(function () {
|
||||
return $this->translationsGetPotFileFromBuild();
|
||||
})
|
||||
@ -1118,9 +1150,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
->addCode(function () {
|
||||
return $this->releaseMergePullRequest(\MailPoetTasks\Release\GitHubController::RELEASE_SOURCE_BRANCH);
|
||||
})
|
||||
->addCode(function () {
|
||||
return $this->releaseDeleteDownloadedZip();
|
||||
})
|
||||
->run();
|
||||
}
|
||||
|
||||
@ -1279,29 +1308,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
$this->say("IMPORTANT NOTES \n" . ($outputs[2] ?: 'none'));
|
||||
}
|
||||
|
||||
public function releaseVerifyDownloadedZip($version) {
|
||||
$this->say('Verifying ZIP file');
|
||||
$zip = new ZipArchive();
|
||||
|
||||
$versionFound = false;
|
||||
if ($zip->open(self::ZIP_BUILD_PATH) === true) {
|
||||
$fileContent = $zip->getFromName('mailpoet/readme.txt');
|
||||
if ($fileContent !== false) {
|
||||
$versionFound = strpos($fileContent, 'Stable tag: ' . $version);
|
||||
}
|
||||
$zip->close();
|
||||
} else {
|
||||
$this->yell('ZIP file could not be opened!', 40, 'red');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!$versionFound) {
|
||||
$this->yell('ZIP file does not contain required version: "' . $version . '" in readme.txt! ', 40, 'red');
|
||||
exit(1);
|
||||
}
|
||||
$this->say('ZIP file contains required version: "' . $version . '" in readme.txt.');
|
||||
}
|
||||
|
||||
public function releaseDownloadZip() {
|
||||
$circleciController = $this->createCircleCiController();
|
||||
$path = $circleciController->downloadLatestBuild(self::ZIP_BUILD_PATH);
|
||||
@ -1309,12 +1315,6 @@ class RoboFile extends \Robo\Tasks {
|
||||
$this->say(sprintf('Release ZIP file size: %.2F MB', filesize($path) / pow(1024, 2)));
|
||||
}
|
||||
|
||||
public function releaseDeleteDownloadedZip() {
|
||||
$this->say('Delete downloaded ZIP: ' . self::ZIP_BUILD_PATH);
|
||||
$this->taskExec('rm -f ' . self::ZIP_BUILD_PATH)->run();
|
||||
$this->say('ZIP file was deleted');
|
||||
}
|
||||
|
||||
public function releasePublishGithub($version = null) {
|
||||
$jiraController = $this->createJiraController();
|
||||
$version = $jiraController->getVersion($version);
|
||||
@ -1611,9 +1611,9 @@ class RoboFile extends \Robo\Tasks {
|
||||
}
|
||||
$annotationReaderProvider = new \MailPoet\Doctrine\Annotations\AnnotationReaderProvider();
|
||||
$configuration = (new \MailPoet\Doctrine\ConfigurationFactory($annotationReaderProvider, true))->createConfiguration();
|
||||
$platformClass = \MailPoetVendor\Doctrine\DBAL\Platforms\MySQLPlatform::class;
|
||||
$platformClass = \MailPoet\Doctrine\ConnectionFactory::PLATFORM_CLASS;
|
||||
return \MailPoetVendor\Doctrine\ORM\EntityManager::create([
|
||||
'driverClass' => \MailPoet\Doctrine\ConnectionFactory::DRIVER_CLASS,
|
||||
'driver' => \MailPoet\Doctrine\ConnectionFactory::DRIVER,
|
||||
'platform' => new $platformClass,
|
||||
], $configuration);
|
||||
}
|
||||
@ -1622,8 +1622,8 @@ class RoboFile extends \Robo\Tasks {
|
||||
$testType = $opts['test_type'] ?? 'acceptance';
|
||||
$this->doctrineGenerateCache();
|
||||
return $this->taskExec(
|
||||
'COMPOSE_HTTP_TIMEOUT=200 docker compose run ' .
|
||||
(isset($opts['wordpress-version']) && $opts['wordpress-version'] ? '-e WORDPRESS_VERSION=' . $opts['wordpress-version'] . ' ' : '') .
|
||||
'COMPOSE_HTTP_TIMEOUT=200 docker-compose run ' .
|
||||
(isset($opts['beta-version']) && $opts['beta-version'] ? '-e LATEST_BETA=' . $opts['beta-version'] . ' ' : '') .
|
||||
(isset($opts['skip-deps']) && $opts['skip-deps'] ? '-e SKIP_DEPS=1 ' : '') .
|
||||
(isset($opts['disable-hpos']) && $opts['disable-hpos'] ? '-e DISABLE_HPOS=1 ' : '') .
|
||||
(isset($opts['enable-hpos-sync']) && $opts['enable-hpos-sync'] ? '-e ENABLE_HPOS_SYNC=1 ' : '') .
|
||||
@ -1637,7 +1637,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
(isset($opts['skip-group']) && $opts['skip-group'] ? '--skip-group ' . $opts['skip-group'] . ' ' : '') .
|
||||
(isset($opts['stop-on-fail']) && $opts['stop-on-fail'] ? '-f ' : '') .
|
||||
(isset($opts['file']) && $opts['file'] ? $opts['file'] : '')
|
||||
)->dir(__DIR__ . '/../tests_env/docker')->run();
|
||||
)->dir(__DIR__ . '/tests/docker')->run();
|
||||
}
|
||||
|
||||
private function getParallelism(int $multiplier = 1, int $min = 4, int $max = 32): int {
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -9,11 +9,6 @@
|
||||
|
||||
.mailpoet-automation-editor-automation-wrapper {
|
||||
padding: 0 20px 50px;
|
||||
|
||||
// Fix for action selector popup on small devices
|
||||
.components-popover__content {
|
||||
min-width: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-automation-editor-automation-flow {
|
||||
|
@ -1,16 +1,11 @@
|
||||
.mailpoet_history_wrapper {
|
||||
display: grid;
|
||||
grid-gap: $grid-gap;
|
||||
grid-template-columns: 26px 26px auto;
|
||||
display: flex;
|
||||
padding: 12px 20px;
|
||||
|
||||
.mailpoet_reset_template {
|
||||
justify-self: end;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_history_arrow {
|
||||
cursor: pointer;
|
||||
margin-right: 20px;
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
|
@ -155,8 +155,3 @@
|
||||
.mailpoet_popup .mailpoet_browser_preview_toggle {
|
||||
top: -30px;
|
||||
}
|
||||
|
||||
.mailpoet_newsletter_styles label {
|
||||
display: block;
|
||||
margin-bottom: $grid-gap-half;
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
.mailpoet_feature_announcement {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.button.mailpoet_feature_announcement_button {
|
||||
height: 28px;
|
||||
min-height: auto;
|
||||
padding: 0 5px 1px;
|
||||
position: relative;
|
||||
|
||||
@include respond-to(small-screen) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_feature_announcement_icon {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.mailpoet_feature_announcement_dot:before {
|
||||
background: #d54e21;
|
||||
border-radius: 10px;
|
||||
content: '';
|
||||
display: block;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
right: -4px;
|
||||
top: -4px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.mailpoet_in_beamer_update_notice {
|
||||
background: #f00;
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
margin: 0;
|
||||
padding: 20px 10px;
|
||||
position: fixed;
|
||||
right: -400px;
|
||||
text-align: center;
|
||||
transition: right 0.2s ease-in;
|
||||
width: 400px;
|
||||
z-index: 10000000000; // really has to be this high
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.beamer_show & {
|
||||
right: 0;
|
||||
}
|
||||
}
|
@ -95,6 +95,10 @@ h1.title.mailpoet-newsletter-listing-heading {
|
||||
#mailpoet_editor_steps_heading {
|
||||
.mailpoet-top-bar {
|
||||
left: 0;
|
||||
|
||||
.mailpoet-top-bar-beamer {
|
||||
top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,7 @@
|
||||
.mailpoet-logs-message {
|
||||
.mailpoet-logs-full-message {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mailpoet-logs-message-full {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.mailpoet-logs-min-width {
|
||||
white-space: nowrap;
|
||||
width: 1px;
|
||||
height: 120px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mailpoet-logs {
|
||||
|
@ -30,11 +30,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-template-preview-image {
|
||||
max-width: 100%;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
.mailpoet-template-info {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
@ -90,19 +90,14 @@
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.mailpoet-re-engagement-scheduling {
|
||||
display: grid;
|
||||
grid-template-columns: 5fr 2fr 3fr;
|
||||
|
||||
.mailpoet-form-input {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-re-engagement-scheduling-note {
|
||||
color: $color-input-error;
|
||||
}
|
||||
|
||||
.mailpoet-re-engagement-scheduling .mailpoet-form-input-small {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
[data-type='re_engagement'] .mailpoet-newsletter-type-image {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 178.78 177.29'%3E%3Cpath fill='%23fb8959' d='M147 35.1a.15.15 0 00-.05-.28l-2.28-.5a4.12 4.12 0 00-.68-1 4.34 4.34 0 00-.72-.62c-.1-.08-.2-.14-.29-.2l-.11-.07a4.3 4.3 0 00-.57-.28 3.82 3.82 0 00-2-.16c1.76-6.91-1.65-14.3-1.65-14.3L130 33l-14.63-11.19a21 21 0 00-.57 7v.38a14.93 14.93 0 003.95 8.81s.22.22.59.56a16 16 0 001.58 1.28 13.83 13.83 0 002.56 1.55c-1.16.86-2 1.55-2.51 1.92l-1.56 1.17-3 2.3-4.37 3.3s2.22.4 3.28-.51c0 0-1.36 1.45-1 2.86l4.17-3.37 4.55-3.67a20.58 20.58 0 002.85 1.67q.39.2.78.36h.1c.51.21 1 .39 1.49.54h.09a13.41 13.41 0 001.43.34h.08a9.48 9.48 0 001.36.16h.08a10.9 10.9 0 001.28 0h.08a9.77 9.77 0 001.21-.16h.07c.39-.08.77-.17 1.14-.28h.07a11.07 11.07 0 001.06-.4h.07q.53-.22 1-.48h.07l.47-.27.43-.28h.07l.43-.3.39-.3.06-.05c.14-.1.27-.21.4-.32l.35-.32.37-.34c.12-.1.22-.21.33-.32l.33-.35.29-.33.3-.35.43-.61.27-.34c.57-.74 1-1.4 1.34-1.9a8.91 8.91 0 001.39-3.58 2.47 2.47 0 00.07-.61 1.09 1.09 0 000-.18z'/%3E%3Cpath fill='%23a73e27' d='M76.9 67.52l23.39-41.74s22.9 49.52-21.93 65.53z'/%3E%3Cpath fill='%23fb8959' d='M86.34 74.31l-49-37.48S25.82 76.07 61.74 90.9z'/%3E%3Cpath fill='%23f86937' d='M84 73.17s-21.38 11.94-37.62 7.58c0 0 7.81 7.81 15.36 10.15z'/%3E%3Cpath fill='%23fb8959' d='M51.39 95.92s45.69-36.64 58.83-31c9.41 4 9.37 14.38 3.64 23.23s-26.35 38.28-62.47 7.77z'/%3E%3Cpath fill='%23fb8959' d='M55.52 92.76L28 113.55s6 1.09 8.88-1.4c0 0-3.68 3.95-2.66 7.77l26.83-21.69z'/%3E%3Cpath fill='%23a73e27' d='M115.62 70.48l7.19 1.6a.42.42 0 01.15.76l-5.57 3.78a5.27 5.27 0 00-1.77-6.14z'/%3E%3Cpath fill='%237e9ffc' d='M117.7 78.41s-10.67 10-18.61 5.21c-3.67-2.23-4.47-10.94 2.09-10.81 8.17.17 9-7.87 9-7.87s9.22 3.45 7.52 13.47z'/%3E%3Ccircle fill='%230a0851' cx='111.39' cy='72.88' r='1.46'/%3E%3Cpath fill='%23f86937' d='M57.78 100.81s-6-4.2-6.39-4.89l-3.32 2.47z'/%3E%3Cpath fill='%23f5a278' opacity='.55' d='M114.54 134.69l-2.43-1.4a1.73 1.73 0 000-.68 3 3 0 00-1.61-1.67 13.58 13.58 0 00-4.09-1.21 26.84 26.84 0 00-4.4-.23c4-3.54 7.92-7.83 0-10.86-5.93 2.78-13.18 5.3-16.88 8.58l-3.35 2.26-1.34.91-30.95-9s-8.56 11 17.13 15.62c-2.5.7-4.4 1.26-5.4 1.55l-19 5.43s4.69.32 6.92-.41c0 0-2.87 1.17-2.07 2.29l18.38-5.62c25 6.5 39.47-1.28 43.66-3.73a10.79 10.79 0 001.78-1.28z'/%3E%3Cpath fill='%23a73e27' d='M35.76 55.86s6.46 6 14.46 5.21c0 0-7.75 1.91-14.17-3.09zM37.16 63.77s7.24 5.67 15.37 3.14a17 17 0 01-14.68-1z'/%3E%3Cpath fill='%23f86937' d='M94.88 95.61c-4.4 8.61-22.37 9.68-29.33 9.77 24.07 11.66 39.33-4.57 46-13.85-1.29-4.35-11.76-5.53-16.67 4.08z'/%3E%3Cpath fill='%23a73e27' d='M45.51 110.79l-11.29 9.13c-1-3.82 2.66-7.77 2.66-7.77-2.86 2.49-8.88 1.4-8.88 1.4l11.83-8.94s-1.08 5.94 5.68 6.18z'/%3E%3Cpath fill='%230a0851' d='M117.89 76.75S107 87 99.09 82.14a6.8 6.8 0 01-2.76-5.07c-.26 2.51.86 5.39 2.76 6.55 7.94 4.81 18.61-5.21 18.61-5.21a7.87 7.87 0 00.19-1.66z'/%3E%3Cpath fill='%23fb8959' d='M73 34.31c.25-.08.49-.17.73-.27.24-.11.47-.22.69-.34l.33-.19.3-.19.3-.21.27-.21.28-.22.24-.22.2-.19c5.15 3.35 12.35.38 12.35.38l-9.08-5.59v-.15a2.19 2.19 0 000-.43v-.13l1.32-.9a.11.11 0 000-.19l-1.6-.36A3.14 3.14 0 0078 23.28c-1.3-.56-3.84.5-6.48 2a2.46 2.46 0 00-3.08.88l-1.29 1.94C64.76 29.76 63 31.2 63 31.2h.05l-6.55 1.16a3.29 3.29 0 002.19.73s-1.3.46-1.52 1.45l6.59-1.37-2.65 4s6.66 2.16 11.15-2.66l.68-.17zm6.92-8.44a3.82 3.82 0 00-.12-.66 1.43 1.43 0 01.12.66z'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
|
@ -161,12 +161,3 @@ ul.sending-method-benefits {
|
||||
.mailpoet_install_premium_message {
|
||||
margin-bottom: $grid-gap-medium;
|
||||
}
|
||||
|
||||
.mailpoet-verify-key-button {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.mailpoet-premium-key-toggle {
|
||||
height: 34px;
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
|
@ -559,3 +559,38 @@ h2.mailpoet-heading {
|
||||
font-size: 85%;
|
||||
}
|
||||
}
|
||||
|
||||
// screen-reader-text CSS class only exists within the WordPress environment
|
||||
// the class does not exist when using iFrame forms due to these being used outside WordPress
|
||||
// prefixing with mailpoet-* to not interfere with the default WordPress screen-reader-text class
|
||||
.mailpoet-screen-reader-text {
|
||||
border: 0;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
-webkit-clip-path: inset(50%);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
word-wrap: normal !important;
|
||||
}
|
||||
|
||||
.mailpoet-screen-reader-text:focus {
|
||||
background-color: #ddd;
|
||||
clip: auto !important;
|
||||
-webkit-clip-path: none;
|
||||
clip-path: none;
|
||||
color: #444;
|
||||
display: block;
|
||||
font-size: 1em;
|
||||
height: auto;
|
||||
line-height: normal;
|
||||
padding: 15px 23px 14px;
|
||||
right: 5px;
|
||||
text-decoration: none;
|
||||
top: 5px;
|
||||
width: auto;
|
||||
z-index: 100000;
|
||||
}
|
||||
|
@ -10,15 +10,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WP registration form
|
||||
form#registerform .g-recaptcha:not([data-size='invisible']) {
|
||||
scale: 0.9;
|
||||
-webkit-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
// WC registration form
|
||||
form.woocommerce-form-register .g-recaptcha {
|
||||
padding-inline-start: 3px;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ textarea.parsley-error {
|
||||
|
||||
.parsley-errors-list {
|
||||
color: #900;
|
||||
font-size: 0.8rem;
|
||||
font-size: 13px;
|
||||
line-height: 1em;
|
||||
list-style-type: none;
|
||||
margin: 8px 0 3px;
|
||||
|
@ -1,3 +1,5 @@
|
||||
$beamer-dot-size: 8px;
|
||||
|
||||
.mailpoet-top-bar {
|
||||
align-items: center;
|
||||
background-color: $color-white;
|
||||
@ -81,7 +83,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-top-bar-tutorial {
|
||||
.mailpoet-top-bar-beamer {
|
||||
align-items: center;
|
||||
background-color: $color-white;
|
||||
border: none;
|
||||
@ -94,7 +96,6 @@
|
||||
position: relative;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
top: 4px;
|
||||
width: 75px;
|
||||
|
||||
svg {
|
||||
@ -102,3 +103,15 @@
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-top-bar-beamer-dot:before {
|
||||
background: $color-editor-warning;
|
||||
border-radius: $beamer-dot-size;
|
||||
content: '';
|
||||
display: block;
|
||||
height: $beamer-dot-size;
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
top: 2px;
|
||||
width: $beamer-dot-size;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
&:focus {
|
||||
~ .mailpoet-form-checkbox-control {
|
||||
border-color: $color-input-border-focus;
|
||||
border: 2px solid $color-input-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,7 @@
|
||||
input,
|
||||
select {
|
||||
font-size: $font-size-small;
|
||||
line-height: $form-control-line-height-small;
|
||||
}
|
||||
|
||||
svg {
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
&:focus {
|
||||
~ .mailpoet-form-radio-control {
|
||||
border-color: $color-input-border-focus;
|
||||
border: 2px solid $color-input-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,9 @@
|
||||
|
||||
input {
|
||||
height: 1px;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
width: 1px;
|
||||
|
||||
&:focus {
|
||||
~ .mailpoet-form-toggle-control {
|
||||
border-color: $color-input-border-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,16 +22,9 @@
|
||||
|
||||
input {
|
||||
height: 1px;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
width: 1px;
|
||||
|
||||
&:focus {
|
||||
~ .mailpoet-form-yesno-control {
|
||||
box-shadow: 0 0 0 1px $color-input-border-focus;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,3 +110,10 @@ span.mailpoet-gap-half {
|
||||
height: 6px;
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.mailpoet-is-dragging {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
@ -4,36 +4,6 @@
|
||||
line-height: $line-height;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
caption,
|
||||
figcaption {
|
||||
// https://developer.chrome.com/docs/css-ui/css-text-wrap-balance
|
||||
text-wrap: balance;
|
||||
|
||||
// Skip in email editor to preserve WYSIWYG functionality
|
||||
.mailpoet_newsletter_wrapper & {
|
||||
text-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
blockquote {
|
||||
// https://developer.chrome.com/blog/css-text-wrap-pretty/
|
||||
text-wrap: pretty;
|
||||
|
||||
// Skip in email editor to preserve WYSIWYG functionality
|
||||
.mailpoet_newsletter_wrapper & {
|
||||
text-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.admin_page_mailpoet-form-editor #wpbody {
|
||||
color: inherit;
|
||||
}
|
||||
|
@ -87,6 +87,7 @@
|
||||
@import 'components-plugin/newsletter-types';
|
||||
@import 'components-plugin/newsletter-template-styles';
|
||||
@import 'components-plugin/welcome-wizard';
|
||||
@import 'components-plugin/feature-announcement';
|
||||
@import 'components-plugin/newsletter-congratulate';
|
||||
@import 'components-plugin/discounts';
|
||||
@import 'components-plugin/review-request';
|
||||
|
@ -31,7 +31,6 @@ $color-tertiary-hover: darken($color-tertiary, 10%);
|
||||
$color-tertiary-light: #dcdcde;
|
||||
$color-grey-0: #f6f7f7;
|
||||
$color-tertiary-light-hover: darken($color-tertiary-light, 10%);
|
||||
$color-tertiary-light-focus: #777;
|
||||
$color-tertiary-light-background: rgba($color-tertiary-light, 0.3);
|
||||
$color-destructive: #b52727;
|
||||
$color-destructive-hover: #a02222;
|
||||
@ -47,7 +46,6 @@ $color-text-dark: #2c3338;
|
||||
// Form colors
|
||||
$color-input-background: #fdfdff;
|
||||
$color-input-border: $color-tertiary-light-hover;
|
||||
$color-input-border-focus: $color-tertiary-light-focus;
|
||||
$color-input-error: #f00;
|
||||
$color-input-success: #7ed321;
|
||||
|
||||
|
@ -53,7 +53,7 @@ function exportMixpanel() {
|
||||
|
||||
if (
|
||||
window.mailpoet_analytics_enabled &&
|
||||
window.mailpoet_3rd_party_libs_enabled
|
||||
window.MailPoet.libs3rdPartyEnabled
|
||||
) {
|
||||
window.MailPoet.trackEvent = track;
|
||||
} else {
|
||||
@ -104,30 +104,11 @@ function cacheEvent(forced, name, data, options, callback) {
|
||||
}
|
||||
|
||||
export function initializeMixpanelWhenLoaded() {
|
||||
const MAX_RETRY = 5;
|
||||
let intervalId;
|
||||
let retryCount = 0;
|
||||
|
||||
const setupMixpanel = () => {
|
||||
if (typeof window.mixpanel === 'object') {
|
||||
exportMixpanel();
|
||||
trackCachedEvents();
|
||||
};
|
||||
|
||||
if (typeof window.mixpanel === 'object') {
|
||||
setupMixpanel();
|
||||
} else {
|
||||
intervalId = setInterval(() => {
|
||||
if (typeof window.mixpanel === 'object') {
|
||||
clearInterval(intervalId);
|
||||
setupMixpanel();
|
||||
} else {
|
||||
retryCount += 1;
|
||||
}
|
||||
|
||||
if (retryCount > MAX_RETRY) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
}, 100);
|
||||
setTimeout(initializeMixpanelWhenLoaded, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
import classnames from 'classnames';
|
||||
import { MailPoet } from 'mailpoet';
|
||||
import { withFeatureAnnouncement } from './with-feature-announcement';
|
||||
|
||||
type Props = {
|
||||
hasNews: boolean;
|
||||
onBeamerClick: () => void;
|
||||
};
|
||||
|
||||
function FeatureAnnouncementComponent({ hasNews, onBeamerClick }: Props) {
|
||||
const buttonClasses = classnames(
|
||||
'button mailpoet_feature_announcement_button',
|
||||
hasNews ? 'mailpoet_feature_announcement_dot' : '',
|
||||
);
|
||||
return (
|
||||
<div className="mailpoet_feature_announcement">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onBeamerClick}
|
||||
className={buttonClasses}
|
||||
title={MailPoet.I18n.t('whatsNew')}
|
||||
>
|
||||
<span className="mailpoet_feature_announcement_icon dashicons dashicons-carrot" />
|
||||
</button>
|
||||
<span id="beamer-empty-element" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const FeatureAnnouncement = withFeatureAnnouncement(
|
||||
FeatureAnnouncementComponent,
|
||||
);
|
||||
export { FeatureAnnouncement };
|
@ -0,0 +1,111 @@
|
||||
import { ComponentType, FC } from 'react';
|
||||
import { MailPoet } from 'mailpoet';
|
||||
import ReactStringReplace from 'react-string-replace';
|
||||
import jQuery from 'jquery';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
interface FeatureAnnouncementWindow extends Window {
|
||||
Beamer: {
|
||||
show: () => void;
|
||||
};
|
||||
mailpoet_feature_announcement_has_news: boolean;
|
||||
mailpoet_update_available: boolean;
|
||||
beamer_config: {
|
||||
product_id: string;
|
||||
selector: string;
|
||||
language: string;
|
||||
callback: () => void;
|
||||
filter?: string;
|
||||
};
|
||||
mailpoet_user_locale: string;
|
||||
}
|
||||
|
||||
declare let window: FeatureAnnouncementWindow;
|
||||
|
||||
export const withFeatureAnnouncement = <P extends Record<string, unknown>>(
|
||||
Component: ComponentType<P>,
|
||||
): FC<Omit<P, 'hasNews' | 'onBeamerClick'>> => {
|
||||
const isBeamerInitialized = () => typeof window.Beamer !== 'undefined';
|
||||
let showDot = window.mailpoet_feature_announcement_has_news;
|
||||
let beamerCallback;
|
||||
|
||||
function showPluginUpdateNotice() {
|
||||
if (
|
||||
!window.mailpoet_update_available ||
|
||||
document.getElementById('mailpoet_update_notice')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const updateMailPoetNotice = ReactStringReplace(
|
||||
MailPoet.I18n.t('updateMailPoetNotice'),
|
||||
/\[link\](.*?)\[\/link\]/,
|
||||
(match) => `<a href="update-core.php">${match}</a>`,
|
||||
).join('');
|
||||
jQuery('#beamerOverlay').append(
|
||||
`<p id="mailpoet_update_notice" class="mailpoet_in_beamer_update_notice">${updateMailPoetNotice}</p>`,
|
||||
);
|
||||
}
|
||||
|
||||
function updateLastAnnouncementSeenValue() {
|
||||
const data = { last_announcement_seen: Math.floor(Date.now() / 1000) };
|
||||
void MailPoet.Ajax.post({
|
||||
api_version: MailPoet.apiVersion,
|
||||
endpoint: 'user_flags',
|
||||
action: 'set',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
function loadBeamer() {
|
||||
window.beamer_config = {
|
||||
product_id: 'VvHbhYWy7118',
|
||||
selector: '#beamer-empty-element',
|
||||
language: window.mailpoet_user_locale,
|
||||
callback: beamerCallback,
|
||||
};
|
||||
if (MailPoet.isWoocommerceActive) {
|
||||
window.beamer_config.filter = 'woocommerce';
|
||||
}
|
||||
MailPoet.Modal.loading(true);
|
||||
window.mailpoet_feature_announcement_has_news = false;
|
||||
const s = document.createElement('script');
|
||||
s.type = 'text/javascript';
|
||||
s.src = 'https://app.getbeamer.com/js/beamer-embed.js';
|
||||
document.getElementsByTagName('body')[0].appendChild(s);
|
||||
}
|
||||
|
||||
function showBeamer(event = null) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (!isBeamerInitialized()) {
|
||||
loadBeamer();
|
||||
return;
|
||||
}
|
||||
showDot = false;
|
||||
beamerCallback = noop; // We show Beamer panel only on first callback after initialization
|
||||
MailPoet.Modal.loading(false);
|
||||
window.Beamer.show();
|
||||
updateLastAnnouncementSeenValue();
|
||||
showPluginUpdateNotice();
|
||||
}
|
||||
|
||||
beamerCallback = () => {
|
||||
if (!isBeamerInitialized()) {
|
||||
return;
|
||||
}
|
||||
showBeamer();
|
||||
};
|
||||
|
||||
return function withFeatureAnnouncementRenderer({
|
||||
...props
|
||||
}: Omit<P, 'hasNews' | 'onBeamerClick'>) {
|
||||
return (
|
||||
<Component
|
||||
{...(props as P)}
|
||||
onBeamerClick={(e) => showBeamer(e)}
|
||||
hasNews={showDot}
|
||||
/>
|
||||
);
|
||||
};
|
||||
};
|
@ -16,11 +16,7 @@ export type ApiError = {
|
||||
|
||||
export const initializeApi = () => {
|
||||
apiFetch.use((options, next) => {
|
||||
if (
|
||||
options.path &&
|
||||
(options.path.startsWith('/wc-analytics/') ||
|
||||
options.path.startsWith('/wp/v2/'))
|
||||
) {
|
||||
if (options.path && options.path.startsWith('/wc-analytics/')) {
|
||||
return apiFetch.createRootURLMiddleware(`${api.root}/`)(options, next);
|
||||
}
|
||||
return apiFetch.createRootURLMiddleware(apiUrl)(options, next);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { TopBarWithBoundary } from 'common/top-bar/top-bar';
|
||||
import { TopBarWithBeamer } from 'common/top-bar/top-bar';
|
||||
import { SlotFillProvider } from '@wordpress/components';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { registerTranslations } from 'common';
|
||||
@ -72,7 +72,7 @@ function Automations(): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
<TopBarWithBoundary />
|
||||
<TopBarWithBeamer />
|
||||
<GlobalNotices />
|
||||
<Notices />
|
||||
<MssAccessNotices />
|
||||
|
@ -3,23 +3,14 @@ import { FlowSeparator } from './flow-separator';
|
||||
import { Step as StepData } from './types';
|
||||
|
||||
type Props = {
|
||||
previousStepData: StepData;
|
||||
stepData: StepData;
|
||||
index: number;
|
||||
nextStepData?: StepData;
|
||||
};
|
||||
|
||||
export function FlowEnding({
|
||||
previousStepData,
|
||||
index,
|
||||
nextStepData,
|
||||
}: Props): JSX.Element {
|
||||
export function FlowEnding({ stepData, index }: Props): JSX.Element {
|
||||
return (
|
||||
<div className="mailpoet-automation-editor-step-wrapper">
|
||||
<FlowSeparator
|
||||
previousStepData={previousStepData}
|
||||
nextStepData={nextStepData}
|
||||
index={index}
|
||||
/>
|
||||
<FlowSeparator stepData={stepData} index={index} />
|
||||
<Icon
|
||||
className="mailpoet-automation-editor-automation-end"
|
||||
icon={check}
|
||||
|
@ -6,9 +6,8 @@ import { Step as StepData } from './types';
|
||||
import { RenderStepSeparatorType } from '../../../types/filters';
|
||||
|
||||
type Props = {
|
||||
previousStepData: StepData;
|
||||
stepData: StepData;
|
||||
index: number;
|
||||
nextStepData?: StepData;
|
||||
};
|
||||
|
||||
export function FlowSeparator(props: Props): JSX.Element {
|
||||
@ -36,9 +35,5 @@ export function FlowSeparator(props: Props): JSX.Element {
|
||||
),
|
||||
[context],
|
||||
);
|
||||
return renderSeparator(
|
||||
props.previousStepData,
|
||||
props.index,
|
||||
props.nextStepData,
|
||||
);
|
||||
return renderSeparator(props.stepData, props.index);
|
||||
}
|
||||
|
@ -40,24 +40,13 @@ export function Flow({ stepData, row }: Props): JSX.Element {
|
||||
|
||||
return nextStepData ? (
|
||||
<div key={id}>
|
||||
{row > 0 && (
|
||||
<FlowSeparator
|
||||
previousStepData={stepData}
|
||||
index={i}
|
||||
nextStepData={nextStepData}
|
||||
/>
|
||||
)}
|
||||
{row > 0 && <FlowSeparator stepData={stepData} index={i} />}
|
||||
<FlowStep stepData={nextStepData} index={i} />
|
||||
<Flow stepData={nextStepData} row={row + 1} />
|
||||
</div>
|
||||
) : (
|
||||
<FlowEnding
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
key={i}
|
||||
previousStepData={stepData}
|
||||
index={i}
|
||||
nextStepData={nextStepData}
|
||||
/>
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<FlowEnding key={i} stepData={stepData} index={i} />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
@ -37,9 +37,8 @@ export function InserterPopover(): JSX.Element | null {
|
||||
return (
|
||||
<>
|
||||
<Popover
|
||||
placement="bottom"
|
||||
ref={popoverRef}
|
||||
anchor={inserterPopover.anchor}
|
||||
anchorRect={inserterPopover.anchor.getBoundingClientRect()}
|
||||
onClose={() => {
|
||||
if (!showModal) {
|
||||
void setInserterPopover(undefined);
|
||||
|
@ -143,7 +143,6 @@ export function* activate() {
|
||||
return {
|
||||
type: 'ACTIVATE',
|
||||
automation: data?.data ?? automation,
|
||||
saved: !!data?.data,
|
||||
} as const;
|
||||
}
|
||||
|
||||
|
@ -41,15 +41,11 @@ export function reducer(state: State, action): State {
|
||||
savedState: 'saved',
|
||||
};
|
||||
case 'ACTIVATE':
|
||||
return action.saved
|
||||
? {
|
||||
...state,
|
||||
automationData: action.automation,
|
||||
savedState: 'saved',
|
||||
}
|
||||
: {
|
||||
...state,
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
automationData: action.automation,
|
||||
savedState: 'saved',
|
||||
};
|
||||
case 'DEACTIVATE':
|
||||
return {
|
||||
...state,
|
||||
|
@ -50,7 +50,6 @@ export function initHooks() {
|
||||
return function StatisticSeparatorWrapper(
|
||||
previousStepData: StepData,
|
||||
index: number,
|
||||
nextStepData: StepData,
|
||||
) {
|
||||
return (
|
||||
<>
|
||||
@ -63,11 +62,7 @@ export function initHooks() {
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<StatisticSeparator
|
||||
previousStep={previousStepData}
|
||||
nextStep={nextStepData}
|
||||
index={index}
|
||||
/>
|
||||
<StatisticSeparator previousStep={previousStepData} index={index} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -8,13 +8,11 @@ import { Step } from '../../../../../../editor/components/automation/types';
|
||||
type Props = {
|
||||
previousStep: Step;
|
||||
index: number;
|
||||
nextStep?: Step;
|
||||
};
|
||||
|
||||
export function StatisticSeparator({
|
||||
previousStep,
|
||||
index,
|
||||
nextStep,
|
||||
}: Props): JSX.Element | null {
|
||||
const { section, stepType } = useSelect(
|
||||
(s) => ({
|
||||
@ -54,34 +52,15 @@ export function StatisticSeparator({
|
||||
);
|
||||
}
|
||||
|
||||
const completed = data.step_data?.completed || {};
|
||||
const failed = data.step_data?.failed || {};
|
||||
const waiting = data.step_data?.waiting || {};
|
||||
const calculateTotals = (id) =>
|
||||
(completed[id] ?? 0) + (failed[id] ?? 0) + (waiting[id] ?? 0);
|
||||
let totalEntered = 0;
|
||||
if (nextStep) {
|
||||
totalEntered = calculateTotals(nextStep.id);
|
||||
} else if (previousStep.next_steps.length === 2) {
|
||||
// When there is no next step and the previous step has 2+ next steps we are
|
||||
// in an empty if/else branch. To calculate the total we need to subtract
|
||||
// totalEntered of the sibling step from totalEntered of previousStep
|
||||
const siblingStep = previousStep.next_steps.find((step) => step.id);
|
||||
const totalEnteredSibling = siblingStep
|
||||
? calculateTotals(siblingStep.id)
|
||||
: 0;
|
||||
const totalEnteredPrevious = completed[previousStep.id] ?? 0;
|
||||
totalEntered = totalEnteredPrevious - totalEnteredSibling;
|
||||
} else {
|
||||
totalEntered = completed[previousStep.id] ?? 0;
|
||||
}
|
||||
const flow = data.step_data?.flow;
|
||||
const value = flow !== undefined ? flow[previousStep.id] ?? 0 : 0;
|
||||
const percent =
|
||||
data.step_data.total > 0
|
||||
? Math.round((totalEntered / data.step_data.total) * 100)
|
||||
? Math.round((value / data.step_data.total) * 100)
|
||||
: 0;
|
||||
const formattedValue = Intl.NumberFormat(locale.toString(), {
|
||||
notation: 'compact',
|
||||
}).format(totalEntered);
|
||||
}).format(value);
|
||||
const formattedPercent = Intl.NumberFormat(locale.toString(), {
|
||||
style: 'percent',
|
||||
}).format(percent / 100);
|
||||
|
@ -29,20 +29,6 @@ export function Tabs(): JSX.Element {
|
||||
className: 'mailpoet-analytics-tab-flow',
|
||||
title: __('Automation flow', 'mailpoet'),
|
||||
},
|
||||
{
|
||||
name: 'automation-subscribers',
|
||||
className: classNames(
|
||||
'mailpoet-analytics-tab-subscribers',
|
||||
!MailPoet.capabilities.detailedAnalytics.isRestricted
|
||||
? 'is-unlocked'
|
||||
: '',
|
||||
),
|
||||
title: (
|
||||
<>
|
||||
{__('Subscribers', 'mailpoet')} <Icon icon={lockSmall} />
|
||||
</>
|
||||
) as unknown as string,
|
||||
},
|
||||
];
|
||||
if (hasEmails) {
|
||||
tabs.push({
|
||||
@ -68,6 +54,20 @@ export function Tabs(): JSX.Element {
|
||||
) as unknown as string,
|
||||
});
|
||||
}
|
||||
tabs.push({
|
||||
name: 'automation-subscribers',
|
||||
className: classNames(
|
||||
'mailpoet-analytics-tab-subscribers',
|
||||
!MailPoet.capabilities.detailedAnalytics.isRestricted
|
||||
? 'is-unlocked'
|
||||
: '',
|
||||
),
|
||||
title: (
|
||||
<>
|
||||
{__('Subscribers', 'mailpoet')} <Icon icon={lockSmall} />
|
||||
</>
|
||||
) as unknown as string,
|
||||
});
|
||||
}
|
||||
|
||||
const updateUrlSearchString = useCallback(
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Modal, Spinner } from '@wordpress/components';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Table } from '@woocommerce/components';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
import { addQueryArgs } from '@wordpress/url';
|
||||
@ -32,12 +32,12 @@ export function ActivityModal(): JSX.Element {
|
||||
const [state, setState] = useState<ActivityModalState>('hidden');
|
||||
const [run, setRun] = useState<RunData | null>(null);
|
||||
|
||||
const closeModal = useCallback(() => {
|
||||
const closeModal = () => {
|
||||
setState('hidden');
|
||||
setRun(null);
|
||||
pageParams.delete('runId');
|
||||
navigate({ search: pageParams.toString() });
|
||||
}, [navigate, pageParams]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
@ -64,7 +64,7 @@ export function ActivityModal(): JSX.Element {
|
||||
setState('loaded');
|
||||
} catch (error) {
|
||||
if (!controller.signal?.aborted) {
|
||||
closeModal();
|
||||
setState('hidden');
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -75,7 +75,7 @@ export function ActivityModal(): JSX.Element {
|
||||
setState('hidden');
|
||||
controller.abort();
|
||||
};
|
||||
}, [runId, closeModal]);
|
||||
}, [runId]);
|
||||
|
||||
if (state === 'hidden') {
|
||||
return null;
|
||||
@ -104,10 +104,14 @@ export function ActivityModal(): JSX.Element {
|
||||
<Table
|
||||
className="mailpoet-analytics-activity-modal-table"
|
||||
headers={headers}
|
||||
rows={transformLogsToRows(run.logs, run.automation.steps)}
|
||||
rows={transformLogsToRows(
|
||||
run.logs,
|
||||
run.automation.steps,
|
||||
run.next_step,
|
||||
)}
|
||||
/>
|
||||
|
||||
<Footer run={run.run} />
|
||||
<Footer runStatus={run.run.status} />
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
@ -1,39 +1,8 @@
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createInterpolateElement } from '@wordpress/element';
|
||||
import { AutomationEndedIcon, AutomationInProgressIcon } from './icons';
|
||||
import { Run } from '../../../../store';
|
||||
|
||||
export function Footer({ run }: { run: Run }) {
|
||||
if (run.is_past_due) {
|
||||
const automationRunFilterValue = encodeURIComponent(
|
||||
`"automation_run_id":${run.id}`,
|
||||
);
|
||||
const pastDueActionsUrl = `/wp-admin/tools.php?page=action-scheduler&status=past-due&s=${automationRunFilterValue}`;
|
||||
return (
|
||||
<div className="mailpoet-analytics-activity-modal-footer">
|
||||
<AutomationInProgressIcon />
|
||||
<span>
|
||||
{createInterpolateElement(
|
||||
__(
|
||||
'Automation stuck. Run <link>past due actions</link> manually.',
|
||||
'mailpoet',
|
||||
),
|
||||
{
|
||||
link: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href={pastDueActionsUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
},
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (run.status === 'running') {
|
||||
export function Footer({ runStatus }: { runStatus: string }) {
|
||||
if (runStatus === 'running') {
|
||||
return (
|
||||
<div className="mailpoet-analytics-activity-modal-footer">
|
||||
<AutomationInProgressIcon />
|
||||
|
@ -3,7 +3,7 @@ import { Steps } from '../../../../../../../editor/components/automation/types';
|
||||
import { MailPoet } from '../../../../../../../../mailpoet';
|
||||
import { StepCell } from '../cells/step';
|
||||
import { AutomationRunStatus } from '../../../../../../../components/status';
|
||||
import { Log } from '../../../../store';
|
||||
import { Log, NextStep } from '../../../../store';
|
||||
|
||||
export const headers = [
|
||||
{
|
||||
@ -37,43 +37,64 @@ function StatusInfo({ info }: { info: string | null }): JSX.Element {
|
||||
);
|
||||
}
|
||||
|
||||
export function transformLogsToRows(logs: Log[], steps: Steps) {
|
||||
return logs.map((log) => {
|
||||
const timeLeft = log.time_left
|
||||
? // translators: "Time left: 1 hour" or "Time left: 1 minute", uses WordPress' human_time_diff() to get the value
|
||||
sprintf(__('Time left: %s', 'mailpoet'), log.time_left)
|
||||
: null;
|
||||
let statusInfo = null;
|
||||
if (log.error) {
|
||||
statusInfo = log.error.message ? log.error.message : null;
|
||||
} else {
|
||||
statusInfo = timeLeft;
|
||||
}
|
||||
|
||||
return [
|
||||
export function transformLogsToRows(
|
||||
logs: Log[],
|
||||
steps: Steps,
|
||||
nextStep: NextStep,
|
||||
) {
|
||||
const items = logs.map((log) => [
|
||||
{
|
||||
display: <StepCell name={log.step_name} data={steps[log.step_id]} />,
|
||||
value: log.step_name,
|
||||
},
|
||||
{
|
||||
display: MailPoet.Date.format(new Date(log.started_at)),
|
||||
value: log.started_at,
|
||||
},
|
||||
{
|
||||
display:
|
||||
log.status === 'complete'
|
||||
? MailPoet.Date.format(new Date(log.updated_at))
|
||||
: '-',
|
||||
value: log.updated_at,
|
||||
},
|
||||
{
|
||||
display: (
|
||||
<>
|
||||
<AutomationRunStatus status={log.status} />
|
||||
<StatusInfo info={log.error && log.error.message} />
|
||||
</>
|
||||
),
|
||||
},
|
||||
]);
|
||||
if (nextStep) {
|
||||
// translators: "Time left: 1 hour" or "Time left: 1 minute", uses WordPress' human_time_diff() to get the value
|
||||
const timeLeft = sprintf(
|
||||
__('Time left: %s', 'mailpoet'),
|
||||
nextStep.time_left,
|
||||
);
|
||||
items.push([
|
||||
{
|
||||
display: <StepCell name={log.step_name} data={steps[log.step_id]} />,
|
||||
value: log.step_name,
|
||||
display: <StepCell name={nextStep.name} data={nextStep.step} />,
|
||||
value: nextStep.name,
|
||||
},
|
||||
{
|
||||
display: MailPoet.Date.format(new Date(log.started_at)),
|
||||
value: log.started_at,
|
||||
display: MailPoet.Date.format(new Date(logs.at(-1).updated_at)),
|
||||
value: logs.at(-1).updated_at,
|
||||
},
|
||||
{
|
||||
display:
|
||||
log.status === 'complete'
|
||||
? MailPoet.Date.format(new Date(log.updated_at))
|
||||
: '-',
|
||||
value: log.updated_at,
|
||||
display: '-',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
display: (
|
||||
<>
|
||||
<AutomationRunStatus status={log.status} />
|
||||
<StatusInfo info={statusInfo} />
|
||||
<AutomationRunStatus status="running" />
|
||||
<StatusInfo info={timeLeft} />
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
});
|
||||
]);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { createRoot } from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { dispatch, select, useSelect } from '@wordpress/data';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { TopBarWithBoundary } from '../../../../common/top-bar/top-bar';
|
||||
import { TopBarWithBeamer } from '../../../../common/top-bar/top-bar';
|
||||
import { Notices } from '../../../listing/components/notices';
|
||||
import { Header } from './components/header';
|
||||
import { Overview } from './components/overview';
|
||||
@ -49,7 +49,7 @@ function TopBarWithBreadcrumb(): JSX.Element {
|
||||
}));
|
||||
|
||||
return (
|
||||
<TopBarWithBoundary>
|
||||
<TopBarWithBeamer>
|
||||
<p className="mailpoet-automation-analytics-title">
|
||||
<a href={MailPoet.urls.automationListing}>
|
||||
{__('Automations', 'mailpoet')}
|
||||
@ -57,7 +57,7 @@ function TopBarWithBreadcrumb(): JSX.Element {
|
||||
› <strong>{automation.name}</strong>
|
||||
<AutomationStatus status={automation.status} />
|
||||
</p>
|
||||
</TopBarWithBoundary>
|
||||
</TopBarWithBeamer>
|
||||
);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user