Compare commits

..

1 Commits

Author SHA1 Message Date
f0b779d724 Release 4.0.0 2022-11-15 15:06:53 +01:00
3246 changed files with 49147 additions and 118609 deletions

View File

@ -71,12 +71,6 @@ anchors:
- trunk - trunk
- release - release
only_release: &only_release
filters:
branches:
only:
- release
multisite_acceptance_config: &multisite_acceptance_config multisite_acceptance_config: &multisite_acceptance_config
multisite: 1 multisite: 1
requires: requires:
@ -84,16 +78,11 @@ anchors:
- static_analysis_php8 - static_analysis_php8
<<: *only_trunk_and_release <<: *only_trunk_and_release
command_add_github_key: &command_add_github_key
command: |
# Add GitHub to known_hosts (for jobs without a checkout step that need to clone repos)
echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> ~/.ssh/known_hosts
executors: executors:
wpcli_php_oldest: wpcli_php_oldest:
<<: *default_job_config <<: *default_job_config
docker: docker:
- image: mailpoet/wordpress:7.4_20231129.1 - image: mailpoet/wordpress:7.2_20220309.1
wpcli_php_max_wporg: wpcli_php_max_wporg:
<<: *default_job_config <<: *default_job_config
@ -103,18 +92,18 @@ executors:
wpcli_php_latest: wpcli_php_latest:
<<: *default_job_config <<: *default_job_config
docker: docker:
- image: mailpoet/wordpress:8.1_20230307.1 - image: mailpoet/wordpress:8.1_20220718.1
wpcli_php_mysql_oldest: wpcli_php_mysql_oldest:
<<: *default_job_config <<: *default_job_config
docker: docker:
- image: mailpoet/wordpress:7.4_20231129.1 - image: mailpoet/wordpress:7.2_20220309.1
- image: cimg/mysql:5.7 - image: cimg/mysql:5.7
wpcli_php_mysql_latest: wpcli_php_mysql_latest:
<<: *default_job_config <<: *default_job_config
docker: docker:
- image: mailpoet/wordpress:8.1_20230307.1 - image: mailpoet/wordpress:8.1_20220718.1
- image: cimg/mysql:8.0 - image: cimg/mysql:8.0
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_520_ci command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_520_ci
@ -190,11 +179,10 @@ jobs:
- run: - run:
name: Download additional WP Plugins for tests name: Download additional WP Plugins for tests
command: | command: |
./do download:woo-commerce-zip latest ./do download:woo-commerce-zip 7.0.1
./do download:woo-commerce-subscriptions-zip 5.7.0 ./do download:woo-commerce-subscriptions-zip 4.6.0
./do download:woo-commerce-memberships-zip 1.25.2 ./do download:woo-commerce-memberships-zip 1.23.1
./do download:woo-commerce-blocks-zip 11.7.0 ./do download:woo-commerce-blocks-zip 8.8.2
./do download:automate-woo-zip 6.0.10
- run: - run:
name: Dump tests ENV variables for acceptance tests name: Dump tests ENV variables for acceptance tests
command: | command: |
@ -212,12 +200,11 @@ jobs:
- attach_workspace: - attach_workspace:
at: /home/circleci at: /home/circleci
- add_ssh_keys - add_ssh_keys
- run:
name: 'Add GitHub to known_hosts'
<<: *command_add_github_key
- run: - run:
name: 'Install Premium plugin' name: 'Install Premium plugin'
command: | command: |
# Add GitHub to known_hosts because there is no checkout step in this job
echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
git clone ${MAILPOET_PREMIUM_REPO_URL} mailpoet-premium git clone ${MAILPOET_PREMIUM_REPO_URL} mailpoet-premium
- restore_cache: - restore_cache:
key: premium-tools-{{ checksum "mailpoet-premium/tools/install.php" }} key: premium-tools-{{ checksum "mailpoet-premium/tools/install.php" }}
@ -250,38 +237,18 @@ jobs:
static_analysis: static_analysis:
executor: wpcli_php_latest executor: wpcli_php_latest
resource_class: medium+ resource_class: medium
working_directory: /home/circleci/mailpoet/mailpoet working_directory: /home/circleci/mailpoet/mailpoet
parameters: parameters:
php_version: php_version:
type: integer type: integer
default: 70400 default: 70200
steps: steps:
- attach_workspace: - attach_workspace:
at: /home/circleci at: /home/circleci
- run: - run:
name: 'Static analysis' name: 'Static analysis'
command: ./do qa:phpstan --php-version=<< parameters.php_version >> command: ./do qa:phpstan --php-version=<< parameters.php_version >>
security_analysis:
working_directory: /home/circleci/mailpoet/mailpoet
machine:
image: ubuntu-2204:2022.10.2
docker_layer_caching: false
steps:
- attach_workspace:
at: /home/circleci
- add_ssh_keys
- run:
name: 'Add GitHub to known_hosts'
<<: *command_add_github_key
- run:
name: 'Set up PHP'
command: |
sudo apt update
sudo apt install -y php8.1-cli
- run:
name: 'QA Security'
command: ./do qa:semgrep
qa_js: qa_js:
executor: wpcli_php_latest executor: wpcli_php_latest
working_directory: /home/circleci/mailpoet/mailpoet working_directory: /home/circleci/mailpoet/mailpoet
@ -344,8 +311,7 @@ jobs:
parallelism: 20 parallelism: 20
working_directory: /home/circleci/mailpoet/mailpoet working_directory: /home/circleci/mailpoet/mailpoet
machine: machine:
image: ubuntu-2204:2022.10.2 image: ubuntu-2204:2022.07.1
docker_layer_caching: false
parameters: parameters:
multisite: multisite:
type: integer type: integer
@ -356,7 +322,7 @@ jobs:
mysql_command: mysql_command:
type: string type: string
default: '' default: ''
mysql_image: mysql_image_version:
type: string type: string
default: '' default: ''
codeception_image_version: codeception_image_version:
@ -377,9 +343,6 @@ jobs:
woo_blocks_version: woo_blocks_version:
type: string type: string
default: '' default: ''
automate_woo_version:
type: string
default: ''
enable_cot: enable_cot:
type: integer type: integer
default: 0 default: 0
@ -388,7 +351,7 @@ jobs:
default: 0 default: 0
environment: environment:
MYSQL_COMMAND: << parameters.mysql_command >> MYSQL_COMMAND: << parameters.mysql_command >>
MYSQL_IMAGE: << parameters.mysql_image >> MYSQL_IMAGE_VERSION: << parameters.mysql_image_version >>
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >> CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
WORDPRESS_IMAGE_VERSION: << parameters.wordpress_image_version >> WORDPRESS_IMAGE_VERSION: << parameters.wordpress_image_version >>
steps: steps:
@ -401,18 +364,6 @@ jobs:
name: 'Pull test docker images' name: 'Pull test docker images'
# Pull docker images with 3 retries # Pull docker images with 3 retries
command: i='0';while ! docker-compose -f tests/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/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/docker
docker-compose run --rm -w /project -e COMPOSER_DEV_MODE=1 --entrypoint "php tools/install.php" codeception_acceptance
- when: - when:
condition: << parameters.woo_core_version >> condition: << parameters.woo_core_version >>
steps: steps:
@ -445,14 +396,6 @@ jobs:
command: | command: |
cd tests/docker cd tests/docker
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-blocks-zip << parameters.woo_blocks_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_acceptance docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-blocks-zip << parameters.woo_blocks_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/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: - run:
name: Group acceptance tests name: Group acceptance tests
command: | command: |
@ -499,67 +442,6 @@ jobs:
path: tests/_output path: tests/_output
- store_test_results: - store_test_results:
path: tests/_output path: tests/_output
performance_tests:
working_directory: /home/circleci/mailpoet/mailpoet
machine:
image: ubuntu-2204:2022.10.2
docker_layer_caching: false
parameters:
mysql_command:
type: string
default: ''
mysql_image:
type: string
default: ''
wordpress_image_version:
type: string
default: ''
url:
type: string
default: 'http://localhost:9500'
pw:
type: string
default: 'password'
scenario:
type: string
default: 'pullrequests'
steps:
- attach_workspace:
at: /home/circleci
- run:
name: 'Set up PHP'
command: |
sudo apt update
sudo apt install -y php8.1-cli
- 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
- 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
- run:
name: Run performance tests
command: |
mkdir -p tests/performance/_output
mkdir -p tests/performance/_screenshots
./do test:performance --url=<< parameters.url >> --pw=<< parameters.pw >> --scenario=<< parameters.scenario >>
- run:
name: Check exceptions
command: |
if [ "$(ls tests/performance/_output/exceptions/*.html)" ]; then
echo "There were some exceptions during the tests run"
exit 1
fi
- store_artifacts:
path: tests/performance/_output
- store_artifacts:
path: tests/performance/_screenshots
- store_test_results:
path: tests/performance/_output
unit_tests: unit_tests:
working_directory: /home/circleci/mailpoet/mailpoet working_directory: /home/circleci/mailpoet/mailpoet
parameters: parameters:
@ -576,10 +458,6 @@ jobs:
- run: - run:
name: 'Prepare example.com for testing' name: 'Prepare example.com for testing'
command: echo 127.0.0.1 example.com | sudo tee -a /etc/hosts command: echo 127.0.0.1 example.com | sudo tee -a /etc/hosts
- run:
# Some tools we use may need different version based on PHP version used in docker
name: Ensure correct versions of tools
command: COMPOSER_DEV_MODE=1 php tools/install.php
- run: - run:
name: 'Set up test environment' name: 'Set up test environment'
command: source ../.circleci/setup.bash && setup php7 command: source ../.circleci/setup.bash && setup php7
@ -598,12 +476,9 @@ jobs:
integration_tests: integration_tests:
working_directory: /home/circleci/mailpoet/mailpoet working_directory: /home/circleci/mailpoet/mailpoet
machine: machine:
image: ubuntu-2204:2022.10.2 image: ubuntu-2204:2022.07.1
docker_layer_caching: false
environment: environment:
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >> CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
MYSQL_COMMAND: << parameters.mysql_command >>
MYSQL_IMAGE: << parameters.mysql_image >>
parameters: parameters:
codeception_image_version: codeception_image_version:
type: string type: string
@ -626,27 +501,9 @@ jobs:
multisite: multisite:
type: integer type: integer
default: 0 default: 0
mysql_command:
type: string
default: ''
mysql_image:
type: string
default: ''
woo_core_version: woo_core_version:
type: string type: string
default: '' default: ''
woo_subscriptions_version:
type: string
default: ''
woo_memberships_version:
type: string
default: ''
woo_blocks_version:
type: string
default: ''
automate_woo_version:
type: string
default: ''
steps: steps:
- attach_workspace: - attach_workspace:
at: /home/circleci at: /home/circleci
@ -654,18 +511,6 @@ jobs:
name: 'Pull test docker images' name: 'Pull test docker images'
# Pull docker images with 3 retries # Pull docker images with 3 retries
command: i='0';while ! docker-compose -f tests/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/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/docker
docker-compose run --rm -w /project -e COMPOSER_DEV_MODE=1 --entrypoint "php tools/install.php" codeception_integration
- when: - when:
condition: << parameters.woo_core_version >> condition: << parameters.woo_core_version >>
steps: steps:
@ -673,39 +518,7 @@ jobs:
name: Download WooCommerce Core name: Download WooCommerce Core
command: | command: |
cd tests/docker cd tests/docker
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-zip << parameters.woo_core_version >>" --no-deps -e WP_GITHUB_USERNAME=${WP_GITHUB_USERNAME} -e WP_GITHUB_TOKEN=${WP_GITHUB_TOKEN} codeception_integration docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-zip << parameters.woo_core_version >>" --no-deps codeception_integration
- when:
condition: << parameters.woo_subscriptions_version >>
steps:
- run:
name: Download WooCommerce Subscriptions
command: |
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/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.woo_blocks_version >>
steps:
- run:
name: Download WooCommerce Blocks
command: |
cd tests/docker
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-blocks-zip << parameters.woo_blocks_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/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: - run:
name: 'PHP Integration tests' name: 'PHP Integration tests'
command: | command: |
@ -781,11 +594,6 @@ workflows:
jobs: jobs:
- build: - build:
<<: *slack-fail-post-step <<: *slack-fail-post-step
- build_premium:
<<: *slack-fail-post-step
<<: *only_release
requires:
- build
- unit_tests: - unit_tests:
<<: *slack-fail-post-step <<: *slack-fail-post-step
name: unit_tests name: unit_tests
@ -794,17 +602,13 @@ workflows:
- static_analysis: - static_analysis:
<<: *slack-fail-post-step <<: *slack-fail-post-step
name: static_analysis_php7 name: static_analysis_php7
php_version: 70400 php_version: 70200
requires: requires:
- build - build
- static_analysis: - static_analysis:
<<: *slack-fail-post-step <<: *slack-fail-post-step
name: static_analysis_php8 name: static_analysis_php8
php_version: 80200 php_version: 80000
requires:
- build
- security_analysis:
<<: *slack-fail-post-step
requires: requires:
- build - build
- qa_js: - qa_js:
@ -825,7 +629,7 @@ workflows:
- build - build
- acceptance_tests: - acceptance_tests:
<<: *slack-fail-post-step <<: *slack-fail-post-step
name: acceptance_tests_base_and_woo_cot_off name: acceptance_tests
requires: requires:
- unit_tests - unit_tests
- static_analysis_php8 - static_analysis_php8
@ -837,6 +641,7 @@ workflows:
group: woo group: woo
enable_cot: 1 enable_cot: 1
enable_cot_sync: 1 enable_cot_sync: 1
woo_core_version: 7.1.0-rc.2 # Temporarily force COT beta version
requires: requires:
- unit_tests - unit_tests
- static_analysis_php8 - static_analysis_php8
@ -848,14 +653,17 @@ workflows:
group: woo group: woo
enable_cot: 1 enable_cot: 1
enable_cot_sync: 0 enable_cot_sync: 0
woo_core_version: 7.1.0-rc.2 # Temporarily force COT beta version
requires: requires:
- unit_tests - unit_tests
- static_analysis_php8 - static_analysis_php8
- qa_js - qa_js
- qa_php - qa_php
- performance_tests: - acceptance_tests:
<<: *slack-fail-post-step <<: *slack-fail-post-step
name: performance_tests name: acceptance_tests_woo_cot_off
group: woo
woo_core_version: 7.1.0-rc.2 # Temporarily force COT beta version
requires: requires:
- unit_tests - unit_tests
- static_analysis_php8 - static_analysis_php8
@ -865,11 +673,21 @@ workflows:
<<: *slack-fail-post-step <<: *slack-fail-post-step
requires: requires:
- build - build
- integration_tests:
<<: *slack-fail-post-step
group: woo
name: integration_test_woocommerce
requires:
- unit_tests
- static_analysis_php8
- qa_js
- qa_php
- integration_tests: - integration_tests:
<<: *slack-fail-post-step <<: *slack-fail-post-step
group: woo group: woo
enable_cot: 1 enable_cot: 1
enable_cot_sync: 1 enable_cot_sync: 1
woo_core_version: 7.1.0-rc.2 # Temporarily force COT beta version
name: integration_test_woo_cot_sync name: integration_test_woo_cot_sync
requires: requires:
- unit_tests - unit_tests
@ -881,6 +699,7 @@ workflows:
group: woo group: woo
enable_cot: 1 enable_cot: 1
enable_cot_sync: 0 enable_cot_sync: 0
woo_core_version: 7.1.0-rc.2 # Temporarily force COT beta version
name: integration_test_woo_cot_no_sync name: integration_test_woo_cot_no_sync
requires: requires:
- unit_tests - unit_tests
@ -890,6 +709,7 @@ workflows:
- integration_tests: - integration_tests:
<<: *slack-fail-post-step <<: *slack-fail-post-step
group: woo group: woo
woo_core_version: 7.1.0-rc.2 # Temporarily force COT beta version
name: integration_test_woo_cot_off name: integration_test_woo_cot_off
requires: requires:
- unit_tests - unit_tests
@ -921,37 +741,20 @@ workflows:
- static_analysis_php8 - static_analysis_php8
- qa_js - qa_js
- qa_php - qa_php
- acceptance_tests:
<<: *slack-fail-post-step
<<: *only_release
name: acceptance_with_premium_latest
requires:
- build_premium
- unit_tests:
<<: *slack-fail-post-step
<<: *only_release
name: unit_with_premium_latest
requires:
- build_premium
- integration_tests:
<<: *slack-fail-post-step
<<: *only_release
name: integration_with_premium_latest
requires:
- build_premium
- build_release_zip: - build_release_zip:
<<: *slack-fail-post-step <<: *slack-fail-post-step
requires: requires:
- build - build
- acceptance_tests_base_and_woo_cot_off - acceptance_tests
- js_tests - js_tests
- integration_test_woocommerce
- integration_test_base - integration_test_base
- integration_test_woo_cot_no_sync - integration_test_woo_cot_no_sync
- integration_test_woo_cot_off - integration_test_woo_cot_off
- integration_test_woo_cot_sync - integration_test_woo_cot_sync
- acceptance_tests_woo_cot_sync - acceptance_tests_woo_cot_sync
- acceptance_tests_woo_cot_off
- acceptance_tests_woo_cot_no_sync - acceptance_tests_woo_cot_no_sync
- performance_tests
nightly: nightly:
triggers: triggers:
@ -971,29 +774,19 @@ workflows:
woo_subscriptions_version: latest woo_subscriptions_version: latest
woo_memberships_version: latest woo_memberships_version: latest
woo_blocks_version: latest woo_blocks_version: latest
automate_woo_version: latest
requires: requires:
- build - build
- acceptance_tests: - acceptance_tests:
<<: *slack-fail-post-step <<: *slack-fail-post-step
name: acceptance_oldest name: acceptance_oldest
woo_core_version: 8.3.0 woo_core_version: 6.8.0
woo_subscriptions_version: 5.6.0 woo_subscriptions_version: 4.3.0
woo_memberships_version: 1.23.1 woo_memberships_version: 1.21.0
woo_blocks_version: 11.6.0 woo_blocks_version: 6.8.0
automate_woo_version: 5.8.5 mysql_command: --max_allowed_packet=100M
mysql_command: --max_allowed_packet=100M --default-storage-engine=MYISAM mysql_image_version: 5.7.36
mysql_image: mysql:5.5
codeception_image_version: 7.4-cli_20220605.0 codeception_image_version: 7.4-cli_20220605.0
wordpress_image_version: wp-6.3_php8.0_20230811.1 wordpress_image_version: wp-5.8_php7.3_20221104.1
requires:
- build
- performance_tests:
<<: *slack-fail-post-step
name: performance_latest
url: https://mpperftesting.mystagingwebsite.com
pw: $WP_TEST_PERFORMANCE_PW
scenario: nightlytests
requires: requires:
- build - build
- unit_tests: - unit_tests:
@ -1015,14 +808,7 @@ workflows:
- integration_tests: - integration_tests:
<<: *slack-fail-post-step <<: *slack-fail-post-step
name: integration_oldest name: integration_oldest
woo_core_version: 8.3.0 codeception_image_version: 7.2-cli_20220605.0
woo_subscriptions_version: 5.6.0
woo_memberships_version: 1.24.0
woo_blocks_version: 11.6.0
automate_woo_version: 5.8.5
codeception_image_version: 7.4-cli_20220605.0
mysql_command: --max_allowed_packet=100M --default-storage-engine=MYISAM
mysql_image: mysql:5.5
requires: requires:
- build - build
- build_premium: - build_premium:

View File

@ -1,23 +0,0 @@
import * as fs from 'fs/promises';
import * as os from 'os';
// Get logical CPU count for a container on CircleCI. Adapted from:
// https://circleci.canny.io/cloud-feature-requests/p/have-nproc-accurately-reporter-number-of-cpus-available-to-container
async function cgroupCpuCount() {
const quotaS = await fs.readFile('/sys/fs/cgroup/cpu/cpu.cfs_quota_us');
const periodS = await fs.readFile('/sys/fs/cgroup/cpu/cpu.cfs_period_us');
const quota = parseInt(quotaS);
const period = parseInt(periodS);
return quota / period;
}
async function cpuCount() {
try {
return await cgroupCpuCount();
} catch {
return os.cpus().length;
}
}
cpuCount().then(console.log);

View File

@ -21,9 +21,3 @@ _N/A_
## After-merge notes ## After-merge notes
_N/A_ _N/A_
## Tasks
- [ ] I followed [best practices](https://codex.wordpress.org/I18n_for_WordPress_Developers) for translations
- [ ] I added sufficient test coverage
- [ ] I embraced TypeScript by either creating new files in TypeScript or converting existing JavaScript files when making changes

View File

@ -1,18 +0,0 @@
name: Pull Request Stats
on:
pull_request:
types: [opened]
branches-ignore:
- 'dependabot/**'
jobs:
stats:
runs-on: ubuntu-latest
steps:
- name: Run pull request stats
uses: flowwer-dev/pull-request-stats@master
with:
period: 90
charts: true
sort-by: 'TIME'

3
.gitignore vendored
View File

@ -7,5 +7,4 @@ docker-compose.override.yml
node_modules node_modules
npm-debug.log npm-debug.log
mailpoet-premium mailpoet-premium
tsconfig.tsbuildinfo wordpress
/wordpress

2
.npmrc
View File

@ -1,2 +1,2 @@
auto-install-peers=false save-workspace-protocol=rolling
strict-peer-dependencies=false strict-peer-dependencies=false

2
.nvmrc
View File

@ -1 +1 @@
v19.7.0 v17.9.1

View File

@ -1,22 +0,0 @@
function readPackage(pkg) {
// Resolve @wordpress/* dependencies of @woocommerce packages to those used by MailPoet.
// This avoids their duplication and downgrading due to @woocommerce pinning them to wp-6.0.
// This should be removed once we adopt similar pinning strategy and use dependency extraction.
// See: https://github.com/woocommerce/woocommerce/pull/37034
if (pkg.name?.startsWith('@woocommerce/')) {
pkg.dependencies = Object.fromEntries(
Object.entries(pkg.dependencies).map(([name, version]) =>
name.startsWith('@wordpress/') || name.startsWith('@types/wordpress__')
? [name, '*']
: [name, version],
),
);
}
return pkg;
}
module.exports = {
hooks: {
readPackage,
},
};

View File

@ -1,4 +1,5 @@
*.hbs *.hbs
*.scss
.mp_svn .mp_svn
_generated _generated
_output _output
@ -12,16 +13,15 @@ vendor-prefixed
/dev/data /dev/data
/mailpoet/assets/dist /mailpoet/assets/dist
/mailpoet/assets/js/lib /mailpoet/assets/js/lib
/mailpoet/assets/js/src/newsletter-editor/behaviors/tinymce-icons.js /mailpoet/assets/js/src/newsletter_editor/behaviors/tinymce_icons.js
/mailpoet/generated /mailpoet/generated
/mailpoet/lang /mailpoet/lang
/mailpoet/lib/Newsletter/Renderer/Template.html /mailpoet/lib/Newsletter/Renderer/Template.html
/mailpoet/lib-3rd-party /mailpoet/lib-3rd-party
/mailpoet/plugin_repository /mailpoet/plugin_repository
/mailpoet/temp /mailpoet/temp
/mailpoet/tests/javascript-newsletter-editor/testBundles /mailpoet/tests/javascript_newsletter_editor/testBundles
/mailpoet/tests/plugins /mailpoet/tests/plugins
/mailpoet/tools/wpscan-semgrep-rules
/mailpoet/views /mailpoet/views
/mailpoet-premium /mailpoet-premium
/wordpress /wordpress

View File

@ -126,37 +126,25 @@ You can access this help in your command line running `./do` without parameters.
[Read the article.](https://mailpoet.atlassian.net/wiki/spaces/MAILPOET/pages/629374977/Adding+new+templates+to+the+plugin) [Read the article.](https://mailpoet.atlassian.net/wiki/spaces/MAILPOET/pages/629374977/Adding+new+templates+to+the+plugin)
## 🚥 Testing with different PHP versions ## 🚥 Testing with PHP 7.4 or PHP 8.0
To switch the environment to a different PHP version: To switch the environment to PHP 7.4/8.0:
1. Check https://github.com/mailpoet/mailpoet/tree/trunk/dev for a list of available PHP versions. Each directory starting with `php` corresponds to a available version. 1. Configure the `wordpress` service in `docker-compose.override.yml` to build from the php74 Dockerfile:
2. Configure the `wordpress` service in `docker-compose.override.yml` to build from the desired PHP version Dockerfile (replace {PHP_VERSION} with the name of the directory that corresponds to the version that you want to use):
```yaml ```yaml
wordpress: wordpress:
build: build:
context: . context: .
dockerfile: dev/{PHP_VERSION}/Dockerfile dockerfile: dev/php74/Dockerfile # OR dev/php80/Dockerfile
``` ```
3. Run `docker-compose build wordpress`. 2. Run `docker-compose build wordpress`.
4. Start the stack with `./do start`. 3. 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 PHP 8.1 remove what was added in 1) 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`. and start the stack using `./do start`.
## Disabling the Tracy panel
To disable the Tracy panel, add the following to `docker-compose.override.yml`:
```yaml
services:
wordpress:
environment:
MAILPOET_DISABLE_TRACY_PANEL: 1
```
## ✅ TODO ## ✅ TODO
- install woo commerce, members and other useful plugins by default - install woo commerce, members and other useful plugins by default

View File

@ -1,8 +0,0 @@
export default {
presets: [
['@babel/preset-react', { runtime: 'automatic' }],
'@babel/preset-env',
'@babel/preset-typescript',
],
plugins: [['@babel/plugin-transform-runtime']],
};

View File

@ -10,7 +10,7 @@ RUN apt-get update \
&& pecl install xdebug-2.9.8 && \ && pecl install xdebug-2.9.8 && \
\ \
# Install NodeJS, enable Corepack # Install NodeJS, enable Corepack
curl -sL https://deb.nodesource.com/setup_19.x | bash - && \ curl -sL https://deb.nodesource.com/setup_17.x | bash - && \
apt-get install -y nodejs build-essential && \ apt-get install -y nodejs build-essential && \
corepack enable && \ corepack enable && \
\ \

View File

@ -8,7 +8,7 @@ RUN apt-get update \
&& apt-get install -y git zlib1g-dev libzip-dev zip wget gnupg msmtp libpng-dev gettext subversion \ && apt-get install -y git zlib1g-dev libzip-dev zip wget gnupg msmtp libpng-dev gettext subversion \
&& \ && \
# Install NodeJS, enable Corepack # Install NodeJS, enable Corepack
curl -sL https://deb.nodesource.com/setup_19.x | bash - && \ curl -sL https://deb.nodesource.com/setup_17.x | bash - && \
apt-get install -y nodejs build-essential && \ apt-get install -y nodejs build-essential && \
corepack enable && \ corepack enable && \
\ \

View File

@ -8,7 +8,7 @@ RUN apt-get update \
&& apt-get install -y git zlib1g-dev libzip-dev zip wget gnupg msmtp libpng-dev gettext subversion \ && apt-get install -y git zlib1g-dev libzip-dev zip wget gnupg msmtp libpng-dev gettext subversion \
&& \ && \
# Install NodeJS, enable Corepack # Install NodeJS, enable Corepack
curl -sL https://deb.nodesource.com/setup_19.x | bash - && \ curl -sL https://deb.nodesource.com/setup_17.x | bash - && \
apt-get install -y nodejs build-essential && \ apt-get install -y nodejs build-essential && \
corepack enable && \ corepack enable && \
\ \

View File

@ -1,46 +0,0 @@
FROM php:8.2.0RC6-apache
ARG UID=1000
ARG GID=1000
# additinal extensions
RUN apt-get update \
&& apt-get install -y git zlib1g-dev libzip-dev zip wget gnupg msmtp libpng-dev gettext subversion \
&& \
# Install NodeJS, enable Corepack
curl -sL https://deb.nodesource.com/setup_19.x | bash - && \
apt-get install -y nodejs build-essential && \
corepack enable && \
\
# Install WP-CLI
curl -o /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \
chmod +x /usr/local/bin/wp && \
\
# Clean up
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
COPY dev/php.ini /usr/local/etc/php/conf.d/php_user.ini
# msmtp config
RUN printf "account default\nhost smtp\nport 1025" > /etc/msmtprc
# xdebug build an config
ENV XDEBUGINI_PATH=/usr/local/etc/php/conf.d/xdebug.ini
RUN git clone -b "3.2.0RC2" --depth 1 https://github.com/xdebug/xdebug.git /usr/src/php/ext/xdebug \
&& docker-php-ext-configure xdebug --enable-xdebug-dev \
&& docker-php-ext-install xdebug \
&& mkdir /tmp/debug
COPY dev/xdebug.ini /tmp/xdebug.ini
RUN cat /tmp/xdebug.ini >> $XDEBUGINI_PATH
# php extensions
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli
# allow .htaccess files (between <Directory /var/www/> and </Directory>, which is WordPress installation)
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
# ensure existing content in /var/www/html respects UID and GID, give Node permissions for Corepack
RUN chown -R ${UID}:${GID} /var/www/html && \
mkdir -p /.node && chown -R ${UID}:${GID} /.node

View File

@ -37,7 +37,6 @@ Class `\MailPoet\API\API` becomes available once MailPoet plugin is loaded by Wo
- [Is Setup Complete (isSetupComplete)](api_methods/IsSetupComplete.md) - [Is Setup Complete (isSetupComplete)](api_methods/IsSetupComplete.md)
- [Subscribe to List (subscribeToList)](api_methods/SubscribeToList.md) - [Subscribe to List (subscribeToList)](api_methods/SubscribeToList.md)
- [Subscribe to Lists (subscribeToLists)](api_methods/SubscribeToLists.md) - [Subscribe to Lists (subscribeToLists)](api_methods/SubscribeToLists.md)
- [Unsubscribe globally](api_methods/UnsubscribeGlobally.md)
- [Unsubscribe from List (unsubscribeFromList)](api_methods/UnsubscribeFromList.md) - [Unsubscribe from List (unsubscribeFromList)](api_methods/UnsubscribeFromList.md)
- [Unsubscribe from Lists (unsubscribeFromLists)](api_methods/UnsubscribeFromLists.md) - [Unsubscribe from Lists (unsubscribeFromLists)](api_methods/UnsubscribeFromLists.md)
- [Update List (updateList)](api_methods/UpdateList.md) - [Update List (updateList)](api_methods/UpdateList.md)

View File

@ -1,29 +0,0 @@
[back to list](../Readme.md)
# Unsubscribe from all lists and change subscriber status
## `array unsubscribe(string $subscriber_id)`
This method removes a subscriber from all lists and updates its status to 'unsubscribed'.
It returns a subscriber. See [Get Subscriber](GetSubscriber.md) for returned data structure.
## Arguments
### string `$subscriber_id` (required)
An id or email of an existing subscriber. An `\Exception` is thrown when an id or email doesn't match any subscriber.
## 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 | Invalid subscriber that does not exist |
| 24 | Subscriber already has 'unsubscribed' status |

View File

@ -15,7 +15,6 @@ services:
volumes: volumes:
- my-datavolume:/var/lib/mysql - my-datavolume:/var/lib/mysql
- ./dev/database/create_test_db.sh:/docker-entrypoint-initdb.d/10-create_test_db.sh - ./dev/database/create_test_db.sh:/docker-entrypoint-initdb.d/10-create_test_db.sh
command: --sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ANSI,ONLY_FULL_GROUP_BY
environment: environment:
MYSQL_ROOT_PASSWORD: somewordpress MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress MYSQL_DATABASE: wordpress
@ -47,7 +46,6 @@ services:
PHP_IDE_CONFIG: 'serverName=Mailpoet' PHP_IDE_CONFIG: 'serverName=Mailpoet'
COMPOSER_HOME: '/tmp/.composer' COMPOSER_HOME: '/tmp/.composer'
NPM_CONFIG_CACHE: '/tmp/.npm' NPM_CONFIG_CACHE: '/tmp/.npm'
XDG_CACHE_HOME: '/tmp/.cache'
MAILPOET_DEV_SITE: 1 MAILPOET_DEV_SITE: 1
volumes: volumes:
- './wordpress:/var/www/html' - './wordpress:/var/www/html'

View File

@ -1,8 +1,8 @@
{ {
"presets": [ "presets": [
"@babel/preset-typescript",
["@babel/preset-react", { "runtime": "automatic" }], ["@babel/preset-react", { "runtime": "automatic" }],
"@babel/preset-env", "@babel/preset-env"
["@babel/preset-typescript", { "allowDeclareFields": true }]
], ],
"plugins": [ "plugins": [
[ [

View File

@ -37,10 +37,3 @@ WP_GITHUB_TOKEN=
# Jira username/email and a token from https://id.atlassian.com/manage/api-tokens: # Jira username/email and a token from https://id.atlassian.com/manage/api-tokens:
WP_JIRA_USER= WP_JIRA_USER=
WP_JIRA_TOKEN= WP_JIRA_TOKEN=
# k6 performance test suite
# Get following secrets from the Secret Store, look for "MailPoet: plugin .env":
WP_TEST_PERFORMANCE_DATA_URL=
WP_TEST_PERFORMANCE_PW=
K6_CLOUD_TOKEN=
K6_CLOUD_ID=

3
mailpoet/.eslintignore Normal file
View File

@ -0,0 +1,3 @@
**/vendor/**
**/vendor-prefixed/**
**/testBundles/**

4
mailpoet/.gitignore vendored
View File

@ -11,7 +11,7 @@ tests/plugins
/views/cache/** /views/cache/**
temp temp
mailpoet.zip mailpoet.zip
tests/javascript-newsletter-editor/testBundles tests/javascript_newsletter_editor/testBundles
assets/dist assets/dist
.vagrant .vagrant
lang lang
@ -27,4 +27,4 @@ tasks/phpstan/vendor
tasks/phpstan/_phpstan-wp-source.neon tasks/phpstan/_phpstan-wp-source.neon
/tools/vendor /tools/vendor
/storybook-static /storybook-static
assets/js/src/newsletter-editor/behaviors/tinymce-icons.js assets/js/src/newsletter_editor/behaviors/tinymce_icons.js

View File

@ -1,2 +1 @@
# we can set this back to "true" once @woocommerce/components have less restrictive definitions engine-strict=true
engine-strict=false

1
mailpoet/.nvmrc Normal file
View File

@ -0,0 +1 @@
v17.9.1

View File

@ -3,39 +3,104 @@
'customSyntax': 'postcss-scss', 'customSyntax': 'postcss-scss',
'rules': 'rules':
{ {
'at-rule-empty-line-before':
['always', { except: ['first-nested', 'blockless-after-blockless'] }],
'at-rule-name-case': 'lower',
'at-rule-semicolon-newline-after': 'always',
'block-closing-brace-empty-line-before': 'never',
'block-closing-brace-newline-after': 'always',
'block-closing-brace-newline-before': 'always-multi-line',
'block-closing-brace-space-before': 'always-single-line',
'block-no-empty': true, 'block-no-empty': true,
'block-opening-brace-newline-after': 'always-multi-line',
'block-opening-brace-space-after': 'always-single-line',
'block-opening-brace-space-before': 'always',
'color-hex-case': 'lower',
'color-hex-length': 'short', 'color-hex-length': 'short',
'color-no-invalid-hex': true, 'color-no-invalid-hex': true,
'comment-no-empty': true, 'comment-no-empty': true,
'comment-whitespace-inside': 'always', 'comment-whitespace-inside': 'always',
'declaration-bang-space-after': 'never',
'declaration-bang-space-before': 'always',
'declaration-block-no-duplicate-properties': 'declaration-block-no-duplicate-properties':
[true, { ignore: ['consecutive-duplicates-with-different-values'] }], [true, { ignore: ['consecutive-duplicates-with-different-values'] }],
'declaration-block-no-redundant-longhand-properties': 'declaration-block-no-redundant-longhand-properties':
[true, { ignoreShorthands: [/flex/, /grid/] }], [true, { ignoreShorthands: [/flex/, /grid/] }],
'declaration-block-semicolon-newline-after': 'always-multi-line',
'declaration-block-semicolon-space-after': 'always-single-line',
'declaration-block-semicolon-space-before': 'never',
'declaration-block-single-line-max-declarations': 1, 'declaration-block-single-line-max-declarations': 1,
'declaration-colon-newline-after': 'always-multi-line',
'declaration-colon-space-after': 'always-single-line',
'declaration-colon-space-before': 'never',
'declaration-empty-line-before': 'never', 'declaration-empty-line-before': 'never',
'font-family-no-duplicate-names': true, 'font-family-no-duplicate-names': true,
'function-comma-space-after': 'always-single-line',
'function-comma-space-before': 'never',
'function-max-empty-lines': 0,
'function-name-case': 'lower', 'function-name-case': 'lower',
'function-parentheses-newline-inside': 'always-multi-line',
'function-parentheses-space-inside': 'never-single-line',
'function-url-quotes': 'always', 'function-url-quotes': 'always',
'function-whitespace-after': 'always',
'indentation': 2,
'keyframe-declaration-no-important': true, 'keyframe-declaration-no-important': true,
'length-zero-no-unit': true, 'length-zero-no-unit': true,
'max-empty-lines': 1,
'media-feature-colon-space-after': 'always',
'media-feature-colon-space-before': 'never',
'media-feature-name-case': 'lower',
'media-feature-name-no-unknown': true, 'media-feature-name-no-unknown': true,
'media-feature-parentheses-space-inside': 'never',
'media-feature-range-operator-space-after': 'always',
'media-query-list-comma-newline-after': 'always-multi-line',
'media-query-list-comma-space-after': 'always-single-line',
'media-query-list-comma-space-before': 'never',
'no-duplicate-selectors': true, 'no-duplicate-selectors': true,
'no-eol-whitespace': true,
'no-extra-semicolons': true,
'no-missing-end-of-source-newline': true,
'number-leading-zero': 'never',
'number-no-trailing-zeros': true,
'order/properties-alphabetical-order': true, 'order/properties-alphabetical-order': true,
'property-case': 'lower',
'property-no-unknown': true, 'property-no-unknown': true,
'rule-empty-line-before':
[
'always-multi-line',
{ except: ['first-nested'], ignore: ['after-comment'] },
],
'scss/at-rule-no-unknown': true, 'scss/at-rule-no-unknown': true,
'scss/dollar-variable-colon-space-after': 'always', 'scss/dollar-variable-colon-space-after': 'always',
'scss/dollar-variable-colon-space-before': 'never', 'scss/dollar-variable-colon-space-before': 'never',
'scss/operator-no-newline-after': true,
'scss/operator-no-newline-before': true, 'scss/operator-no-newline-before': true,
'scss/operator-no-unspaced': true, 'scss/operator-no-unspaced': true,
'scss/selector-no-redundant-nesting-selector': true, 'scss/selector-no-redundant-nesting-selector': true,
'selector-attribute-brackets-space-inside': 'never',
'selector-attribute-operator-space-after': 'never',
'selector-attribute-operator-space-before': 'never',
'selector-combinator-space-after': 'always',
'selector-combinator-space-before': 'always',
'selector-list-comma-newline-after': 'always',
'selector-list-comma-space-before': 'never',
'selector-max-empty-lines': 0,
'selector-nested-pattern': '^(?!&-|&_).*', 'selector-nested-pattern': '^(?!&-|&_).*',
'selector-pseudo-class-case': 'lower',
'selector-pseudo-class-no-unknown': true, 'selector-pseudo-class-no-unknown': true,
'selector-pseudo-class-parentheses-space-inside': 'never',
'selector-pseudo-element-case': 'lower',
'selector-pseudo-element-colon-notation': 'single', 'selector-pseudo-element-colon-notation': 'single',
'selector-pseudo-element-no-unknown': true, 'selector-pseudo-element-no-unknown': true,
'selector-type-case': 'lower', 'selector-type-case': 'lower',
'shorthand-property-no-redundant-values': true, 'shorthand-property-no-redundant-values': true,
'string-no-newline': true, 'string-no-newline': true,
'string-quotes': 'single',
'unit-case': 'lower',
'unit-no-unknown': true, 'unit-no-unknown': true,
'value-list-comma-newline-after': 'always-multi-line',
'value-list-comma-space-after': 'always-single-line',
'value-list-comma-space-before': 'never',
'value-list-max-empty-lines': 0,
}, },
} }

View File

@ -90,6 +90,7 @@ $ ./do test:debug-unit # alias for ./do test:unit --debug
$ ./do test:debug-integration # alias for ./do test:integration --debug $ ./do test:debug-integration # alias for ./do test:integration --debug
$ ./do test:failed-unit # run the last failing unit test. $ ./do test:failed-unit # run the last failing unit test.
$ ./do test:failed-integration # run the last failing integration test. $ ./do test:failed-integration # run the last failing integration test.
$ ./do test:coverage # run tests and output coverage information.
$ ./do test:javascript # run the JS tests. $ ./do test:javascript # run the JS tests.
$ ./do test:acceptance [--file=...] [--skip-deps] $ ./do test:acceptance [--file=...] [--skip-deps]
# run acceptances tests into a docker environment. # run acceptances tests into a docker environment.
@ -160,58 +161,35 @@ Dependencies handled by PHP-Scoper are configured in extra configuration files `
### i18n ### i18n
We use functions `__()`, `_n()`, `_x()`, and `_nx()` with domain `mailpoet` to translate strings. We use functions `__()`, `_n()` and `_x()` with domain `mailpoet` to translate strings.
**in PHP code** **in PHP code**
```php ```php
__('text to translate', 'mailpoet'); __('text to translate', 'mailpoet');
_n('single text', 'plural text', $number, 'mailpoet'); _n('single text', 'plural text', $number, 'mailpoet');
_x('text to translate', 'context', 'mailpoet'); _x('text to translate', 'context for translators', 'mailpoet');
_xn('single text', 'plural text', $number, 'context', 'mailpoet');
``` ```
**in JavaScript/TypeScript code** **in Twig views**
```ts ```html
import { __, _n, _x, _xn } from '@wordpress/i18n'; <%= __('text to translate') %> <%= _n('single text', 'plural text', $number) %>
<%= _x('text to translate', 'context for translators') %>
__('text to translate', 'mailpoet');
_n('single text', 'plural text', number, 'mailpoet');
_x('text to translate', 'context', 'mailpoet');
_nx('single text', 'plural text', number, 'context', 'mailpoet');
``` ```
To replace placeholders in translated strings, use `sprintf`: The domain `mailpoet` will be added automatically by the Twig functions.
```ts **in Javascript code**
import { sprintf } from '@wordpress/i18n';
sprintf(__('Hello %s', 'mailpoet'), 'John'); First add the string to the translations block in the Twig view:
```html
<% block translations %> <%= localize({ 'key': __('string to translate'), ... })
%> <% endblock %>
``` ```
To replace React elements use `createInterpolateElement`: Then use `MailPoet.I18n.t('key')` to get the translated string on your Javascript code.
```tsx
import { __ } from '@wordpress/i18n';
import { createInterpolateElement } from '@wordpress/element';
import { CustomComponent } from '../custom-component.js';
const translatedString = createInterpolateElement(
__(
'This is a <span>string</span> with a <a>link</a> and a self-closing <custom_component/>.',
),
{
span: <span class="special-text" />,
a: <a href="https://make.wordpress.org" />,
custom_component: <CustomComponent />,
},
);
```
For more information, see the [@wordpress/i18n](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/)
and the [createInterpolateElement](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-element/#createinterpolateelement)
guides.
### Acceptance testing ### Acceptance testing

View File

@ -1,4 +1,4 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing <?php
// phpcs:disable PSR1.Classes.ClassDeclaration // phpcs:disable PSR1.Classes.ClassDeclaration
// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace // phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
@ -28,20 +28,11 @@ class RoboFile extends \Robo\Tasks {
->run(); ->run();
} }
public function installJs() {
return $this->taskExecStack()
->stopOnFail()
->exec('cd .. && pnpm install --frozen-lockfile --prefer-offline')
->run();
}
public function cleanupCachedFiles() { public function cleanupCachedFiles() {
$this->say('Cleaning up generated folder.'); $this->say('Cleaning up generated folder.');
$this->_exec('rm -rf ' . __DIR__ . '/generated/*'); $this->_exec('rm -rf ' . __DIR__ . '/generated/*');
$this->say('Cleaning up PHPStan cache.'); $this->say('Cleaning up PHPStan cache.');
$this->_exec('rm -rf ' . __DIR__ . '/temp/*'); $this->_exec('rm -rf ' . __DIR__ . '/temp/*');
$this->say('Cleaning up old testing plugins.');
$this->_exec('rm -rf ' . __DIR__ . '/tests/plugins/*');
} }
public function update() { public function update() {
@ -52,119 +43,6 @@ class RoboFile extends \Robo\Tasks {
->run(); ->run();
} }
public function updateJsPackages($opts = ['ticket' => '', 'latest' => true, 'checks' => false, 'dedupe' => false]) {
$ticket = $opts['ticket'];
$latest = $opts['latest'];
$runChecks = $opts['checks'];
$runDedupe = $opts['dedupe'];
if (empty($ticket)) {
$this->say('Please specify a ticket with --ticket=<ticket>');
exit(1);
}
$outdatedPackagesOutput = $this->taskExec('pnpm outdated --no-table')
->printOutput(false)
->run()
->getMessage();
$lines = explode("\n", $outdatedPackagesOutput);
// The package names themselves are every third line
$outdatedPackages = array_filter($lines, function($key) {
return $key % 3 === 0;
}, ARRAY_FILTER_USE_KEY);
$excludePackages = [
'tinymce',
'react-router-dom', // MAILPOET-3911
'react-tooltip', // MAILPOET-5482
'codemirror', // MAILPOET-5483
'@babel/preset-env', // MAILPOET-5489
'react-string-replace', // MAILPOET-5490
'babel-loader', // MAILPOET-5491
'stylelint', // MAILPOET-5462
'backbone', // Will remove with new email editor
'backbone.marionette', // Will remove with new email editor
'history',
'fork-ts-checker-webpack-plugin',
];
$majorVersionChanges = [];
foreach ($outdatedPackages as $packageName) {
// @wordpress packages should be handled all together
if (strpos($packageName, '@wordpress') !== false) {
continue;
}
// @types should be kept in sync with the major version of the dependency and will be easiest to update after
if (strpos($packageName, '@types') !== false) {
continue;
}
$packageName = str_replace(' (dev)', '', $packageName);
if (in_array($packageName, $excludePackages)) {
$this->say("Skipping $packageName");
continue;
}
$this->say("Updating $packageName");
$oldVersion = $this->getCurrentJsPackageVersion($packageName);
$oldMajorVersion = explode('.', $oldVersion)[0];
if ($latest) {
$this->taskExec("pnpm up -L $packageName")->run();
} else {
$this->taskExec("pnpm up $packageName")->run();
}
if ($this->taskExec("pnpm list $packageName")->run()->wasSuccessful()) {
$newVersion = $this->getCurrentJsPackageVersion($packageName);
if ($newVersion === $oldVersion) {
continue;
}
if ($runChecks) {
$collection = $this->collectionBuilder();
$collection
->addCode([$this, 'installJs'])
->addCode([$this, 'compileJs'])
->addCode([$this, 'compileCss'])
->addCode([$this, 'qaFrontendAssets'])
->run();
}
$newMajorVersion = explode('.', $newVersion)[0];
$this->taskExecStack()
->exec("git add ./package.json")
->exec('git add ../pnpm-lock.yaml')
->exec("git commit --no-verify -m \"Update $packageName from $oldVersion to $newVersion\" -m \"\" -m \"$ticket\"")
->run();
if ($oldMajorVersion !== $newMajorVersion) {
$majorVersionChanges[] = $packageName;
}
} else {
$this->say("Update of $packageName failed. Exiting.");
exit(1);
}
}
if ($runDedupe) {
$this->taskExecStack()
->exec('pnpm dedupe')
->exec('git add ../pnpm-lock.yaml')
->exec("git commit --no-verify -m \"Update lock file after pnpm dedupe\" -m \"\" -m \"$ticket\"")
->run();
}
if (count($majorVersionChanges) > 0) {
$this->say(sprintf("The following packages changed major version: %s. Check to see if any of them need to have their @types updated.", implode(', ', $majorVersionChanges)));
}
}
public function watchCss() { public function watchCss() {
$cssFiles = $this->rsearch('assets/css/src/', ['scss']); $cssFiles = $this->rsearch('assets/css/src/', ['scss']);
$this->taskWatch() $this->taskWatch()
@ -257,9 +135,6 @@ class RoboFile extends \Robo\Tasks {
'tools', 'tools',
'vendor', 'vendor',
'vendor-prefixed', 'vendor-prefixed',
'RoboFile.php',
'.storybook',
'storybook-static',
]); ]);
$headers = escapeshellarg( $headers = escapeshellarg(
@ -278,7 +153,7 @@ class RoboFile extends \Robo\Tasks {
->taskExec("php -d memory_limit=-1 tasks/makepot/makepot-views.php . > lang/mailpoet.pot") ->taskExec("php -d memory_limit=-1 tasks/makepot/makepot-views.php . > lang/mailpoet.pot")
// PHP, JS/TS // PHP, JS/TS
->taskExec("php -d memory_limit=-1 vendor/wp-cli/wp-cli/php/boot-fs.php i18n make-pot --merge --slug=mailpoet --domain=mailpoet --exclude=$exclude --headers=$headers . lang/mailpoet.pot") ->taskExec("vendor/bin/wp i18n make-pot --merge --slug=mailpoet --domain=mailpoet --exclude=$exclude --headers=$headers . lang/mailpoet.pot")
->run(); ->run();
} }
@ -343,7 +218,7 @@ class RoboFile extends \Robo\Tasks {
return $this->_exec($command); 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, 'enable-cot' => false, 'enable-cot-sync' => false, 'stop-on-fail' => false]) { public function testIntegration(array $opts = ['file' => null, 'group' => null, 'skip-group' => null, 'xml' => false, 'multisite' => false, 'debug' => false, 'skip-deps' => false, 'skip-plugins' => false, 'enable-cot' => false, 'enable-cot-sync' => false]) {
return $this->runTestsInContainer(array_merge($opts, ['test_type' => 'integration'])); return $this->runTestsInContainer(array_merge($opts, ['test_type' => 'integration']));
} }
@ -359,11 +234,26 @@ class RoboFile extends \Robo\Tasks {
return $this->runTestsInContainer(array_merge($opts, ['test_type' => 'integration', 'skip-group' => 'woo', 'skip-deps' => true, 'skip-plugins' => true])); return $this->runTestsInContainer(array_merge($opts, ['test_type' => 'integration', 'skip-group' => 'woo', 'skip-deps' => true, 'skip-plugins' => true]));
} }
public function testCoverage($opts = ['file' => null, 'xml' => false]) {
$command = join(' ', [
'vendor/bin/codecept run -s acceptance',
(($opts['file']) ? $opts['file'] : ''),
'--coverage',
($opts['xml']) ? '--coverage-xml' : '--coverage-html',
]);
if ($opts['xml']) {
$command .= ' --xml';
}
return $this->execWithXDebug($command);
}
public function testNewsletterEditor($xmlOutputFile = null) { public function testNewsletterEditor($xmlOutputFile = null) {
$command = join(' ', [ $command = join(' ', [
'./node_modules/.bin/mocha', './node_modules/.bin/mocha',
'-r tests/javascript-newsletter-editor/mocha-test-helper.js', '-r tests/javascript_newsletter_editor/mochaTestHelper.js',
'tests/javascript-newsletter-editor/testBundles/**/*.js', 'tests/javascript_newsletter_editor/testBundles/**/*.js',
'--exit', '--exit',
]); ]);
@ -374,12 +264,16 @@ class RoboFile extends \Robo\Tasks {
); );
} }
return $this->taskExec($command) return $this->collectionBuilder()
->addCode(function () {
$this->compileJs();
})
->taskExec($command)
->run(); ->run();
} }
public function testJavascript($xmlOutputFile = null) { public function testJavascript($xmlOutputFile = null) {
$command = './node_modules/.bin/mocha --recursive --require tests/javascript/babel-register.js tests/javascript --extension spec.js --extension spec.ts'; $command = './node_modules/.bin/mocha --recursive --require tests/javascript/babel_register.js tests/javascript --extension spec.js --extension spec.ts';
if (!empty($xmlOutputFile)) { if (!empty($xmlOutputFile)) {
$command .= sprintf( $command .= sprintf(
@ -403,81 +297,6 @@ class RoboFile extends \Robo\Tasks {
return $this->runTestsInContainer($opts); return $this->runTestsInContainer($opts);
} }
public function testPerformance($path = null, $opts = ['url' => null, 'pw' => null, 'head' => false, 'scenario' => null]) {
$dir = __DIR__;
if ((getenv('K6_CLOUD_TOKEN')) === false) {
return $this->collectionBuilder()
->addCode([$this, 'testPerformanceSetup'])
->taskExec("php $dir/tools/k6.php")
->arg('run')
->option('env', 'K6_BROWSER_ENABLED=1')
->option('env', 'URL=' . $opts['url'])
->option('env', 'PW=' . $opts['pw'])
->option('env', 'K6_BROWSER_HEADLESS=' . ($opts['head'] ? 'false' : 'true'))
->option('env', 'K6_BROWSER_TIMEOUT=120s')
->option('env', 'SCENARIO=' . $opts['scenario'])
->arg($path ?? "$dir/tests/performance/scenarios.js")
->dir($dir)->run();
} else {
return $this->collectionBuilder()
->addCode([$this, 'testPerformanceSetup'])
->taskExec("php $dir/tools/k6.php")
->arg('run')
->option('env', 'K6_BROWSER_ENABLED=1')
->option('env', 'URL=' . $opts['url'])
->option('env', 'PW=' . $opts['pw'])
->option('env', 'HEADLESS=' . ($opts['head'] ? 'false' : 'true'))
->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_PROJECT_NAME=' . $opts['scenario'])
->option('out', 'cloud')
->arg($path ?? "$dir/tests/performance/scenarios.js")
->dir($dir)->run();
}
}
public function testPerformanceSetup() {
// get data file URL
$url = getenv('WP_TEST_PERFORMANCE_DATA_URL');
if (!$url) {
$this->yell("Please set 'WP_TEST_PERFORMANCE_DATA_URL'. You'll find it in the secret store.", 40, 'red');
exit(1);
}
// download data
$dataFile = __DIR__ . '/tests/performance/_data/data.sql';
if (!file_exists($dataFile)) {
$this->say('Downloading data file...');
if (!is_dir(dirname($dataFile))) {
mkdir(dirname($dataFile), 0777, true);
}
$source = gzopen($url, 'rb');
$destination = fopen($dataFile, 'wb');
while (!gzeof($source)) {
fwrite($destination, gzread($source, 4096));
}
fclose($destination);
gzclose($source);
$this->say("Data file downloaded to: $dataFile");
} else {
$this->say("Data file already exists: $dataFile");
}
// 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')
->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')
->dir(__DIR__ . '/tests/performance')
->run();
}
public function testAcceptanceMultisite($opts = ['file' => null, 'skip-deps' => false, 'group' => null, 'timeout' => null, 'enable-cot' => false, 'enable-cot-sync' => false]) { public function testAcceptanceMultisite($opts = ['file' => null, 'skip-deps' => false, 'group' => null, 'timeout' => null, 'enable-cot' => false, 'enable-cot-sync' => false]) {
return $this->runTestsInContainer(array_merge($opts, ['multisite' => true])); return $this->runTestsInContainer(array_merge($opts, ['multisite' => true]));
} }
@ -495,12 +314,9 @@ class RoboFile extends \Robo\Tasks {
* Deletes docker containers and volumes used in tests * Deletes docker containers and volumes used in tests
*/ */
public function resetTestDocker() { public function resetTestDocker() {
return $this return $this->taskExec(
->taskExec(
'docker-compose down -v --remove-orphans' 'docker-compose down -v --remove-orphans'
)->dir(__DIR__ . '/tests/docker') )->dir(__DIR__ . '/tests/docker')->run();
->addCode([$this, 'cleanupCachedFiles'])
->run();
} }
public function testFailedUnit() { public function testFailedUnit() {
@ -569,14 +385,9 @@ class RoboFile extends \Robo\Tasks {
$this->say("Validator metadata generated to: $validatorMetadataDir"); $this->say("Validator metadata generated to: $validatorMetadataDir");
} }
/** public function migrationsNew() {
* Creates a new migration file. Use `migrations:new db` for a db level migration or `migrations:new app` for app level migration.
* @param $level string - db or app
*/
public function migrationsNew($level) {
$generator = new \MailPoet\Migrator\Repository(); $generator = new \MailPoet\Migrator\Repository();
$level = strtolower($level); $result = $generator->create();
$result = $generator->create($level);
$path = realpath($result['path']); $path = realpath($result['path']);
$this->output->writeln('MAILPOET DATABASE MIGRATIONS'); $this->output->writeln('MAILPOET DATABASE MIGRATIONS');
$this->output->writeln("============================\n"); $this->output->writeln("============================\n");
@ -614,9 +425,6 @@ class RoboFile extends \Robo\Tasks {
$collection->addCode(function() { $collection->addCode(function() {
return $this->qaCodeSniffer([]); return $this->qaCodeSniffer([]);
}); });
$collection->addCode(function() {
return $this->qaMinimalPluginStandard([]);
});
return $collection->run(); return $collection->run();
} }
@ -644,8 +452,8 @@ class RoboFile extends \Robo\Tasks {
'lib-3rd-party/', 'lib-3rd-party/',
'vendor/composer', 'vendor/composer',
'vendor/mtdowling', 'vendor/mtdowling',
'vendor/soundasleep',
'vendor-prefixed/', 'vendor-prefixed/',
'vendor-prefixed/soundasleep',
'mailpoet.php', 'mailpoet.php',
]); ]);
// The list of files and folders to exclude is coming from build.sh // The list of files and folders to exclude is coming from build.sh
@ -663,7 +471,7 @@ class RoboFile extends \Robo\Tasks {
'vendor/phpmailer/phpmailer/test', 'vendor/phpmailer/phpmailer/test',
'vendor-prefixed/psr/log/Psr/Log/Test', 'vendor-prefixed/psr/log/Psr/Log/Test',
'vendor-prefixed/sabberworm/php-css-parser/tests', 'vendor-prefixed/sabberworm/php-css-parser/tests',
'vendor-prefixed/soundasleep/html2text/tests', 'vendor/soundasleep/html2text/tests',
'vendor-prefixed/swiftmailer/swiftmailer/tests', 'vendor-prefixed/swiftmailer/swiftmailer/tests',
'vendor-prefixed/symfony/service-contracts/Tests', 'vendor-prefixed/symfony/service-contracts/Tests',
'vendor-prefixed/symfony/translation/Tests', 'vendor-prefixed/symfony/translation/Tests',
@ -691,60 +499,9 @@ class RoboFile extends \Robo\Tasks {
$task = implode(' ', [ $task = implode(' ', [
'php -d memory_limit=-1', 'php -d memory_limit=-1',
'./tasks/code_sniffer/vendor/bin/phpcs', './tasks/code_sniffer/vendor/bin/phpcs',
"--parallel=" . $this->getParallelism(),
'--extensions=php', '--extensions=php',
$severityFlag, $severityFlag,
'--standard=tasks/code_sniffer/MailPoet/free-ruleset.xml', '--standard=tasks/code_sniffer/MailPoet',
'-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',
'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 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', '-s',
]); ]);
@ -787,22 +544,59 @@ class RoboFile extends \Robo\Tasks {
} }
public function qaFixFile($filePath) { public function qaFixFile($filePath) {
$extension = pathinfo($filePath, PATHINFO_EXTENSION); if (substr($filePath, -4) === '.php') {
if ($extension === 'php') {
// fix PHPCS rules // fix PHPCS rules
return $this->collectionBuilder() return $this->collectionBuilder()
->taskExec( ->taskExec(
'./tasks/code_sniffer/vendor/bin/phpcbf ' . './tasks/code_sniffer/vendor/bin/phpcbf ' .
'--standard=./tasks/code_sniffer/MailPoet ' . '--standard=./tasks/code_sniffer/MailPoet ' .
'--runtime-set testVersion 7.4-8.2 ' . '--runtime-set testVersion 7.2-8.0 ' .
$filePath . ' -n' $filePath . ' -n'
) )
->run(); ->run();
} }
if (in_array($extension, ['js', 'jsx', 'ts', 'tsx'], true)) { if (substr($filePath, -4) === '.jsx') {
// fix ESLint rules // fix ESLint using ES6 rules
return $this->collectionBuilder() return $this->collectionBuilder()
->taskExec("pnpm eslint --max-warnings 0 --fix $filePath") ->taskExec(
'npx ../eslint-config/node_modules/.bin/eslint -c ../eslint-config/.eslintrc.es6.json ' .
'--max-warnings 0 ' .
'--fix ' .
$filePath
)
->run();
}
if (substr($filePath, -4) === '.tsx' || substr($filePath, -3) === '.ts') {
// fix ESLint using TS rules
return $this->collectionBuilder()
->taskExec(
'npx ../eslint-config/node_modules/.bin/eslint -c ../eslint-config/.eslintrc.ts.json ' .
'--max-warnings 0 ' .
'--fix ' .
$filePath
)
->run();
}
if (substr($filePath, -8) === '.spec.js') {
// fix ESLint using tests rules
return $this->collectionBuilder()
->taskExec(
'npx ../eslint-config/node_modules/.bin/eslint -c ../eslint-config/.eslintrc.tests_newsletter_editor.json ' .
'--max-warnings 0 ' .
'--fix ' .
$filePath
)
->run();
}
if (substr($filePath, -3) === '.js') {
// fix ESLint using ES5 rules
return $this->collectionBuilder()
->taskExec(
'npx ../eslint-config/node_modules/.bin/eslint -c ../eslint-config/.eslintrc.es5.json ' .
'--max-warnings 0 ' .
'--fix ' .
$filePath
)
->run(); ->run();
} }
} }
@ -839,10 +633,6 @@ class RoboFile extends \Robo\Tasks {
->run(); ->run();
} }
public function qaSemgrep() {
return $this->_exec('./tools/semgrep.sh lib/ lib-3rd-party/');
}
public function storybookBuild() { public function storybookBuild() {
return $this->_exec('pnpm run build-storybook'); return $this->_exec('pnpm run build-storybook');
} }
@ -1009,9 +799,6 @@ class RoboFile extends \Robo\Tasks {
->addCode(function () use ($version) { ->addCode(function () use ($version) {
$this->releaseCreatePullRequest($version); $this->releaseCreatePullRequest($version);
}) })
->addCode(function () use ($version) {
$this->releaseRerunCircleWorkflow(\MailPoetTasks\Release\CircleCiController::PROJECT_PREMIUM);
})
->addCode(function () use ($version) { ->addCode(function () use ($version) {
$this->translationsPrepareLanguagePacks($version); $this->translationsPrepareLanguagePacks($version);
}) })
@ -1148,23 +935,9 @@ class RoboFile extends \Robo\Tasks {
->addCode(function () use ($version) { ->addCode(function () use ($version) {
return $this->releasePublishSlack($version); return $this->releasePublishSlack($version);
}) })
->addCode(function () {
return $this->releaseMergePullRequest(\MailPoetTasks\Release\GitHubController::RELEASE_SOURCE_BRANCH);
})
->run(); ->run();
} }
public function releaseMergePullRequest(string $branch) {
try {
$this->createGitHubController()
->mergePullRequest(\MailPoetTasks\Release\CircleCiController::PROJECT_MAILPOET, $branch);
} catch (\Exception $e) {
$this->yell($e->getMessage(), 40, 'red');
exit(1);
}
$this->say("Pull request for branch: '{$branch}' was successfully merged");
}
/** /**
* This command displays how many pull request each person did recently * This command displays how many pull request each person did recently
*/ */
@ -1343,18 +1116,6 @@ class RoboFile extends \Robo\Tasks {
$this->say("Release '$version[name]' info was published on Slack."); $this->say("Release '$version[name]' info was published on Slack.");
} }
public function releaseRerunCircleWorkflow(string $project = null) {
$circleciController = $this->createCircleCiController();
$result = $circleciController->rerunLatestWorkflow($project);
// Sometimes can be useful to know which Circle project workflow was restarted
$project = $project ? " for the project '{$project}'" : '';
if (!$result) {
$this->yell("Circle Workflow{$project} was not restarted", 40, 'red');
} else {
$this->say("Circle Workflow{$project} was started from the beginning");
}
}
public function downloadWooCommerceBlocksZip($tag = null) { public function downloadWooCommerceBlocksZip($tag = null) {
$this->createWpOrgDownloader('woo-gutenberg-products-block') $this->createWpOrgDownloader('woo-gutenberg-products-block')
->downloadPluginZip('woo-gutenberg-products-block.zip', __DIR__ . '/tests/plugins/', $tag); ->downloadPluginZip('woo-gutenberg-products-block.zip', __DIR__ . '/tests/plugins/', $tag);
@ -1378,15 +1139,6 @@ class RoboFile extends \Robo\Tasks {
->downloadReleaseZip('woocommerce-subscriptions.zip', __DIR__ . '/tests/plugins/', $tag); ->downloadReleaseZip('woocommerce-subscriptions.zip', __DIR__ . '/tests/plugins/', $tag);
} }
public function downloadAutomateWooZip($tag = null) {
if (!getenv('WP_GITHUB_USERNAME') && !getenv('WP_GITHUB_TOKEN')) {
$this->yell("Skipping download of Automate Woo", 40, 'red');
exit(0); // Exit with 0 since it is a valid state for some environments
}
$this->createGithubClient('woocommerce/automatewoo')
->downloadReleaseZip('automatewoo.zip', __DIR__ . '/tests/plugins/', $tag);
}
public function downloadWooCommerceZip($tag = null) { public function downloadWooCommerceZip($tag = null) {
$this->createWpOrgDownloader('woocommerce') $this->createWpOrgDownloader('woocommerce')
->downloadPluginZip('woocommerce.zip', __DIR__ . '/tests/plugins/', $tag); ->downloadPluginZip('woocommerce.zip', __DIR__ . '/tests/plugins/', $tag);
@ -1418,60 +1170,6 @@ class RoboFile extends \Robo\Tasks {
$generator->run($generatorName); $generator->run($generatorName);
} }
public function automationAddStep() {
require_once __DIR__ . '/tasks/automation/AddStep.php';
$yes = ['y', 'yes', 'Y', 'Yes', 'YES'];
$type = in_array($this->ask("Is this step a trigger? [y]"), $yes) ? 'trigger' : 'action';
$isPremium = in_array($this->ask("Is this $type a premium feature? [y]"), $yes);
$vendor = $this->ask("Who is the vendor of the $type? (default: mailpoet)") ?? 'mailpoet';
do {
$id = $this->ask("What is the id of the $type?");
} while (!$id);
do {
$name = $this->ask("What is the name of the $type?");
} while (!$name);
do {
$description = $this->ask("Describe the $type?");
} while (!$description);
do {
$keywords = array_map(
function(string $keyword): string {
return trim($keyword);
},
explode(',', $this->ask("Add some keywords (commaseparated)"))
);
} while (!$keywords);
$subtitle = 'Trigger';
if ($type === 'action') {
do {
$subtitle = $this->ask("What is the subtitle?");
} while (!$subtitle);
}
$premiumNotice = '';
if ($isPremium) {
do {
$premiumNotice = $this->ask("What is the text message for the premium modal?");
} while (!$premiumNotice);
}
$generator = new \MailPoetTasks\Automation\AddStep(
$type,
$isPremium,
$vendor,
$id,
$name,
$description,
$subtitle,
$keywords,
$premiumNotice
);
$generator->create();
$this->yell(ucfirst("$type created."));
}
public function twigGenerateCache() { public function twigGenerateCache() {
$templatePath = __DIR__ . '/views/'; // \MailPoet\Config\Env::$viewsPath . '/' $templatePath = __DIR__ . '/views/'; // \MailPoet\Config\Env::$viewsPath . '/'
@ -1635,21 +1333,7 @@ class RoboFile extends \Robo\Tasks {
(isset($opts['xml']) && $opts['xml'] ? '--xml ' : '') . (isset($opts['xml']) && $opts['xml'] ? '--xml ' : '') .
(isset($opts['group']) && $opts['group'] ? '--group ' . $opts['group'] . ' ' : '') . (isset($opts['group']) && $opts['group'] ? '--group ' . $opts['group'] . ' ' : '') .
(isset($opts['skip-group']) && $opts['skip-group'] ? '--skip-group ' . $opts['skip-group'] . ' ' : '') . (isset($opts['skip-group']) && $opts['skip-group'] ? '--skip-group ' . $opts['skip-group'] . ' ' : '') .
(isset($opts['stop-on-fail']) && $opts['stop-on-fail'] ? '-f ' : '') . '-f ' . (isset($opts['file']) && $opts['file'] ? $opts['file'] : '')
(isset($opts['file']) && $opts['file'] ? $opts['file'] : '')
)->dir(__DIR__ . '/tests/docker')->run(); )->dir(__DIR__ . '/tests/docker')->run();
} }
private function getParallelism(int $multiplier = 1, int $min = 4, int $max = 32): int {
$path = __DIR__ . '/../.circleci/nproc.js';
$nproc = (int)$this->taskExec("node $path")->printOutput(false)->run()->stopOnFail()->getMessage();
return max(min($nproc * $multiplier, $max), $min);
}
private function getCurrentJsPackageVersion(string $packageName) {
$versionInfo = $this->taskExec("pnpm list $packageName")->printOutput(false)->run()->getMessage();
$lines = explode("\n", $versionInfo);
$lastLine = end($lines);
return explode(' ', $lastLine)[1];
}
} }

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.

View File

@ -3,8 +3,7 @@ Style for Members plugin
*/ */
.members-tab-title { .members-tab-title {
.mailpoet-icon-logo { .mailpoet-icon-logo {
background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTIuMDIgMTU2LjQiPjxwYXRoIGQ9Ik0zNy43MSw4OS4xYzMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFYzNS43bDE3LDQ1LjFhMTIuNjgsMTIuNjgsMCwwLDAsMy43LDUuNGMxLjYsMS4zLDQsMiw3LjIsMmExMi41NCwxMi41NCwwLDAsMCw1LjktMS40LDguNDEsOC40MSwwLDAsMCwzLjktNWwxOC4xLTUwVjgxYTguNTMsOC41MywwLDAsMCwyLjEsNi4xYzEuNCwxLjQsMy43LDIuMiw2LjksMi4yLDMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFY4LjdhNy40OCw3LjQ4LDAsMCwwLTMuMy02LjZjLTIuMS0xLjQtNS0yLjEtOC42LTIuMWExOS4zLDE5LjMsMCwwLDAtOS40LDIsMTEuNjMsMTEuNjMsMCwwLDAtNS4xLDYuOEw3NC45MSw2Ny4xLDU0LjQxLDguNGExMi40LDEyLjQsMCwwLDAtNC41LTYuMmMtMi4xLTEuNS01LTIuMi04LjgtMi4yYTE2LjUxLDE2LjUxLDAsMCwwLTguOSwyLjFjLTIuMywxLjUtMy41LDMuOS0zLjUsNy4yVjgwLjhjMCwyLjguNyw0LjgsMiw2LjJDMzIuMjEsODguNCwzNC40MSw4OS4xLDM3LjcxLDg5LjFaIiAvPjxwYXRoIGQ9Ik0xNDksMTE2LjZsLTIuNC0xLjlhNy40LDcuNCwwLDAsMC05LjQuMywxOS42NSwxOS42NSwwLDAsMS0xMi41LDQuNmgtMjEuNEEzNy4wOCwzNy4wOCwwLDAsMCw3NywxMzAuNWwtMS4xLDEuMi0xLjEtMS4xYTM3LjI1LDM3LjI1LDAsMCwwLTI2LjMtMTAuOUgyN2ExOS41OSwxOS41OSwwLDAsMS0xMi40LTQuNiw3LjI4LDcuMjgsMCwwLDAtOS40LS4zbC0yLjQsMS45QTcuNDMsNy40MywwLDAsMCwwLDEyMi4yYTcuMTQsNy4xNCwwLDAsMCwyLjQsNS43QTM3LjI4LDM3LjI4LDAsMCwwLDI3LDEzNy40aDIxLjZhMTkuNTksMTkuNTksMCwwLDEsMTguOSwxNC40di4yYy4xLjcsMS4yLDQuNCw4LjUsNC40czguNC0zLjcsOC41LTQuNHYtLjJhMTkuNTksMTkuNTksMCwwLDEsMTguOS0xNC40SDEyNWEzNy4yOCwzNy4yOCwwLDAsMCwyNC42LTkuNSw3LjQyLDcuNDIsMCwwLDAsMi40LTUuN0E3Ljg2LDcuODYsMCwwLDAsMTQ5LDExNi42WiIgLz48L3N2Zz4=') background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTIuMDIgMTU2LjQiPjxwYXRoIGQ9Ik0zNy43MSw4OS4xYzMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFYzNS43bDE3LDQ1LjFhMTIuNjgsMTIuNjgsMCwwLDAsMy43LDUuNGMxLjYsMS4zLDQsMiw3LjIsMmExMi41NCwxMi41NCwwLDAsMCw1LjktMS40LDguNDEsOC40MSwwLDAsMCwzLjktNWwxOC4xLTUwVjgxYTguNTMsOC41MywwLDAsMCwyLjEsNi4xYzEuNCwxLjQsMy43LDIuMiw2LjksMi4yLDMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFY4LjdhNy40OCw3LjQ4LDAsMCwwLTMuMy02LjZjLTIuMS0xLjQtNS0yLjEtOC42LTIuMWExOS4zLDE5LjMsMCwwLDAtOS40LDIsMTEuNjMsMTEuNjMsMCwwLDAtNS4xLDYuOEw3NC45MSw2Ny4xLDU0LjQxLDguNGExMi40LDEyLjQsMCwwLDAtNC41LTYuMmMtMi4xLTEuNS01LTIuMi04LjgtMi4yYTE2LjUxLDE2LjUxLDAsMCwwLTguOSwyLjFjLTIuMywxLjUtMy41LDMuOS0zLjUsNy4yVjgwLjhjMCwyLjguNyw0LjgsMiw2LjJDMzIuMjEsODguNCwzNC40MSw4OS4xLDM3LjcxLDg5LjFaIiAvPjxwYXRoIGQ9Ik0xNDksMTE2LjZsLTIuNC0xLjlhNy40LDcuNCwwLDAsMC05LjQuMywxOS42NSwxOS42NSwwLDAsMS0xMi41LDQuNmgtMjEuNEEzNy4wOCwzNy4wOCwwLDAsMCw3NywxMzAuNWwtMS4xLDEuMi0xLjEtMS4xYTM3LjI1LDM3LjI1LDAsMCwwLTI2LjMtMTAuOUgyN2ExOS41OSwxOS41OSwwLDAsMS0xMi40LTQuNiw3LjI4LDcuMjgsMCwwLDAtOS40LS4zbC0yLjQsMS45QTcuNDMsNy40MywwLDAsMCwwLDEyMi4yYTcuMTQsNy4xNCwwLDAsMCwyLjQsNS43QTM3LjI4LDM3LjI4LDAsMCwwLDI3LDEzNy40aDIxLjZhMTkuNTksMTkuNTksMCwwLDEsMTguOSwxNC40di4yYy4xLjcsMS4yLDQuNCw4LjUsNC40czguNC0zLjcsOC41LTQuNHYtLjJhMTkuNTksMTkuNTksMCwwLDEsMTguOS0xNC40SDEyNWEzNy4yOCwzNy4yOCwwLDAsMCwyNC42LTkuNSw3LjQyLDcuNDIsMCwwLDAsMi40LTUuN0E3Ljg2LDcuODYsMCwwLDAsMTQ5LDExNi42WiIgLz48L3N2Zz4=') no-repeat center;
no-repeat center;
background-size: contain; background-size: contain;
display: inline-block; display: inline-block;
height: 20px; height: 20px;
@ -14,18 +13,15 @@ Style for Members plugin
} }
&:not([aria-selected='true']) .mailpoet-icon-logo { &:not([aria-selected='true']) .mailpoet-icon-logo {
filter: invert(24%) sepia(95%) saturate(1872%) hue-rotate(179deg) filter: invert(24%) sepia(95%) saturate(1872%) hue-rotate(179deg) brightness(93%) contrast(101%);
brightness(93%) contrast(101%);
} }
> a:hover .mailpoet-icon-logo, > a:hover .mailpoet-icon-logo,
> a:active .mailpoet-icon-logo { > a:active .mailpoet-icon-logo {
filter: invert(49%) sepia(50%) saturate(3683%) hue-rotate(163deg) filter: invert(49%) sepia(50%) saturate(3683%) hue-rotate(163deg) brightness(94%) contrast(101%);
brightness(94%) contrast(101%);
} }
&[aria-selected='true'] a .mailpoet-icon-logo { &[aria-selected='true'] a .mailpoet-icon-logo {
filter: invert(33%) sepia(0%) saturate(7%) hue-rotate(205deg) filter: invert(33%) sepia(0%) saturate(7%) hue-rotate(205deg) brightness(94%) contrast(87%);
brightness(94%) contrast(87%);
} }
} }

View File

@ -1,20 +0,0 @@
$color-grey: #ddd;
$color-wp-gray-0: #fbfbfb;
$color-poet-gray-dividers: #dcdcde;
$color-gutenberg-blue: #007cba;
$color-gutenberg-grey-100: #f0f0f0;
$color-gutenberg-grey-600: #949494;
$color-gutenberg-grey-700: #757575;
$color-gutenberg-grey-800: #2f2f2f;
$color-gutenberg-grey-900: #1e1e1e;
$color-white: #fff;
$color-black: #1e1e1e;
$color-primary: #007cba;
$color-gutenberg-alert-green: #4ab866;
$color-wp-green-0: #edfaef;
$color-wp-green-60: #007017;
$color-wp-yellow-0: #fcf9e8;
$color-wp-yellow-50: #996800;
$color-wp-yellow-60: #755100;
$color-wp-red-0: #fcf0f1;
$color-wp-red-60: #b32d2e;

View File

@ -1,44 +0,0 @@
@import 'colors';
.mailpoet-automation-analytics-title {
color: $color-gutenberg-grey-700;
font-size: 16px;
a {
color: inherit;
text-decoration: none;
}
strong {
color: $color-gutenberg-grey-900;
}
.mailpoet-analytics-badge {
display: inline-block;
margin-left: 8px;
}
}
.mailpoet-analytics-header {
align-items: end;
display: flex;
justify-content: space-between;
margin-bottom: 24px;
.woocommerce-filters-filter {
width: 100%;
.components-dropdown__content .components-popover__content {
padding: 0;
}
* {
box-sizing: border-box;
}
}
.components-dropdown {
.components-button.is-primary {
box-shadow: none;
}
}
}

View File

@ -1,21 +0,0 @@
@import './colors';
.mailpoet-automation-analytics-overview {
background: $color-white;
margin-bottom: 24px;
h1 {
border: 1px solid $color-grey;
border-bottom: none;
padding: 16px 24px;
}
.woocommerce-summary {
background: $color-white;
margin: 0;
}
.woocommerce-summary__item {
background: $color-white;
}
}

View File

@ -1,29 +0,0 @@
.mailpoet-automation-analytics {
.woocommerce-table__header,
.woocommerce-table__item,
.woocommerce-table__empty-item {
text-wrap: balance;
@include respond-to(medium-screen) {
padding: 8px 12px;
}
}
.woocommerce-table__header.is-sortable {
padding: 2px;
button {
padding: 4px 20px;
width: 100%;
@include respond-to(medium-screen) {
padding: 4px 8px;
}
}
}
.woocommerce-table__header,
.woocommerce-table__header button {
font-weight: bold;
}
}

View File

@ -1,162 +0,0 @@
@import '../colors';
.mailpoet-automation-editor-stats-placeholder {
.mailpoet-automation-stats-label {
background: $color-gutenberg-grey-100;
color: $color-gutenberg-grey-100;
margin-bottom: 3px;
}
.mailpoet-automation-stats-value {
background: $color-gutenberg-grey-100;
color: $color-gutenberg-grey-100;
display: block;
margin: auto;
width: 10px;
}
}
.mailpoet-automation-editor-step-wrapper-placeholder {
.mailpoet-automation-editor-step-icon {
background: $color-gutenberg-grey-100;
border-radius: 50%;
height: 49px;
width: 49px;
}
.mailpoet-automation-editor-step-title {
background: $color-gutenberg-grey-100;
height: 20px;
margin-bottom: 3px;
width: 50%;
}
.mailpoet-automation-editor-step-subtitle {
background: $color-gutenberg-grey-100;
height: 20px;
width: 90%;
}
}
.mailpoet-automation-analytics-step-failed {
bottom: 0;
display: none;
grid-column: 1 / -1;
justify-content: center;
left: -100px;
position: absolute;
&:after {
border-top: 1px dashed $color-gutenberg-grey-600;
content: '';
height: 0;
left: 100%;
position: absolute;
top: 15px;
width: 100px;
}
span {
display: block;
}
p {
padding: 0 8px;
}
}
@media screen and (min-width: 600px) {
.mailpoet-automation-analytics-step-failed {
display: block;
}
}
.mailpoet-automation-analytics-step-footer {
background: $color-wp-gray-0;
border-top: 1px solid $color-poet-gray-dividers;
display: flex;
grid-column: 1 / -1;
justify-content: center;
margin-bottom: -12px;
margin-left: -12px;
width: calc(100% + 24px);
z-index: 1;
p {
padding: 6px 0;
}
}
.mailpoet-automation-analytics-step-footer,
.mailpoet-automation-analytics-step-failed {
p {
margin: 0;
a {
color: $color-gutenberg-grey-800;
text-decoration: none;
&:hover {
color: $color-gutenberg-blue;
}
}
}
span {
color: $color-gutenberg-grey-600;
}
a:hover span {
color: $color-gutenberg-blue;
}
}
.mailpoet-automation-analytics-separator {
p {
background: $color-wp-gray-0;
text-align: center;
}
span {
display: block;
}
.mailpoet-automation-analytics-separator-text {
color: $color-gutenberg-grey-600;
}
}
// Send Email Panel
.mailpoet-automation-analytics-send-email-panel {
grid-column: 1 / -1;
}
.mailpoet-automation-analytics-send-email-panel-section {
display: flex;
justify-content: space-between;
margin: 1em 0;
&.is-loading {
background: $color-gutenberg-grey-100;
height: 20px;
}
}
.mailpoet-automation-analytics-send-email-panel-label {
color: $color-gutenberg-grey-700;
}
.mailpoet-automation-analytics-send-email-panel-value {
text-align: end;
}
.mailpoet-automation-editor-automation-notices {
background: $color-wp-gray-0;
padding: 32px 0 0;
}
.mailpoet-automation-flow-notice {
margin: 0 auto;
max-width: 480px;
width: 100%;
}

View File

@ -1,56 +0,0 @@
@import '../colors';
@import 'mixins';
.mailpoet-analytics-main-value {
font-size: 13px;
font-weight: 400;
line-height: 18px;
margin: 0 0 4px;
}
.mailpoet-analytics-badge {
font-weight: 600;
}
.mailpoet-analytics-badge-text {
@include badge;
}
.mailpoet-automation-analytics-email-name {
max-width: 300px;
}
.mailpoet-automation-analytics-email-clicked {
font-weight: 600;
}
.mailpoet-analytics-badge-success {
color: $color-gutenberg-alert-green;
.mailpoet-analytics-badge-text {
background: $color-wp-green-0;
color: $color-wp-green-60;
}
}
.mailpoet-analytics-badge-warning {
color: $color-wp-yellow-50;
.mailpoet-analytics-badge-text {
background: $color-wp-yellow-0;
color: $color-wp-yellow-60;
}
}
.mailpoet-automation-analytics-table-subvalue {
color: $color-gutenberg-grey-600;
font-size: 12px;
margin: 0;
}
.mailpoet-analytics-email-actions {
align-items: center;
display: flex;
gap: 8px;
justify-content: end;
}

View File

@ -1,32 +0,0 @@
@import '../colors';
.mailpoet-analytics-tabs {
background: $color-white;
border: 1px solid $color-grey;
.components-tab-panel__tabs-item.is-active {
box-shadow: inset 0 -4px 0 0 var(--wp-admin-theme-color);
}
.components-tab-panel__tabs {
border-bottom: 1px solid $color-grey;
}
.components-tab-panel__tab-content {
padding: 0;
}
.woocommerce-table {
box-shadow: none;
margin-bottom: 0;
/** Remove table header */
.components-card-header {
display: none;
}
}
}
.mailpoet-automation-analytics .woocommerce-summary__item {
box-sizing: border-box;
}

View File

@ -1,6 +0,0 @@
@import 'mixins';
@import 'general';
@import 'email';
@import 'orders';
@import 'automation_flow';
@import 'subscribers';

View File

@ -1,12 +0,0 @@
@import '../colors';
@mixin badge {
background: $color-grey;
border-radius: 2px;
font-size: 11px;
font-weight: 400;
line-height: 16px;
margin-right: 4px;
padding: 4px 8px;
white-space: nowrap;
}

View File

@ -1,91 +0,0 @@
@import '../colors';
@import 'mixins';
.mailpoet-analytics-tab-orders,
.mailpoet-analytics-tab-subscribers {
color: $color-gutenberg-grey-600;
}
.mailpoet-analytics-filter {
.is-loading {
background: $color-gutenberg-grey-100;
height: 20px;
max-width: 200px;
width: 45%;
}
}
.mailpoet-automation-analytics .woocommerce-table__item {
a.mailpoet-analytics-orders__customer {
align-items: flex-start;
display: flex;
flex: 1 0 0;
gap: 8px;
img {
border-radius: 50%;
}
}
.mailpoet-automations-analytics-order-products {
align-items: center;
column-gap: 8px;
display: flex;
flex-wrap: wrap;
.quantity {
color: $color-gutenberg-grey-700;
}
.woocommerce-view-more-list {
margin: 0;
padding: 0;
button {
background: transparent;
border-radius: 0;
color: $color-gutenberg-grey-700;
height: auto;
line-height: inherit;
margin: 0;
overflow: visible;
padding: 0;
text-decoration: underline dotted;
}
}
}
}
.mailpoet-analytics-order-status {
@include badge;
}
.mailpoet-analytics-order-status-completed,
.mailpoet-analytics-order-status-processing {
background: $color-wp-green-0;
color: $color-wp-green-60;
}
.mailpoet-analytics-order-status-failed {
background: $color-wp-red-0;
color: $color-wp-red-60;
}
.mailpoet-analytics-order-status-on-hold {
background: $color-wp-yellow-0;
color: $color-wp-yellow-60;
}
.mailpoet-analytics-upgrade-banner {
margin: 24px;
.components-notice__content {
margin: 0;
}
.mailpoet-analytics-upgrade-banner__inner {
align-items: center;
display: flex;
justify-content: space-between;
}
}

View File

@ -1,41 +0,0 @@
@import '../colors';
.mailpoet-analytics-clear-filters {
margin-right: 8px;
}
.mailpoet-analytics-filter {
align-items: end;
display: flex;
justify-content: space-between;
padding: 16px;
}
.mailpoet-analytics-filter-controls {
display: flex;
gap: 8px;
.components-base-control__field {
margin-bottom: 0;
}
}
.mailpoet-analytics-subscribers-step-cell {
column-gap: 8px;
display: grid;
grid-template-columns: 20px 1fr;
.mailpoet-automation-colored-icon {
padding: 4px;
}
p {
margin: 0;
}
span {
color: $color-gutenberg-grey-600;
font-size: 11px;
grid-column-start: 2;
}
}

View File

@ -14,12 +14,8 @@
&:focus { &:focus {
box-shadow: box-shadow:
// space 0 0 0 1px #fbfbfb, // space
0 0 0 1px #fbfbfb, 0 0 0 calc(var(--wp-admin-border-width-focus) + 1px) var(--wp-admin-theme-color), // focus ring
// focus ring 0 0 0 4px #fbfbfb; // separator space
0 0 0 calc(var(--wp-admin-border-width-focus) + 1px)
var(--wp-admin-theme-color),
// separator space
0 0 0 4px #fbfbfb;
} }
} }

View File

@ -13,10 +13,7 @@
&:focus { &:focus {
box-shadow: box-shadow:
// space 0 0 0 1px #fbfbfb, // space
0 0 0 1px #fbfbfb, 0 0 0 calc(var(--wp-admin-border-width-focus) + 1px) var(--wp-admin-theme-color), // focus ring
// focus ring
0 0 0 calc(var(--wp-admin-border-width-focus) + 1px)
var(--wp-admin-theme-color);
} }
} }

View File

@ -1,30 +1,16 @@
.mailpoet-automation-editor-automation { .mailpoet-automation-editor-automation {
background: #fbfbfb; background: #fbfbfb;
display: grid;
flex-grow: 1; flex-grow: 1;
grid-template-rows: auto 1fr;
overflow: auto;
width: 100%;
} }
.mailpoet-automation-editor-automation-wrapper { .mailpoet-automation-editor-automation-wrapper {
padding: 0 20px 50px;
}
.mailpoet-automation-editor-automation-flow {
margin: auto;
width: max-content;
}
.mailpoet-automation-editor-automation-row {
display: grid; display: grid;
grid-auto-flow: column; padding: 50px 20px;
} }
.mailpoet-automation-editor-automation-end { .mailpoet-automation-editor-automation-end {
background: #8c8f94; background: #8c8f94;
border-radius: 999999px; border-radius: 999999px;
display: block;
fill: white; fill: white;
height: 18px; height: 18px;
margin: 4px auto; margin: 4px auto;
@ -33,7 +19,7 @@
} }
.mailpoet-automation-editor-stats { .mailpoet-automation-editor-stats {
margin: 50px auto 32px; margin: 0 auto 32px;
max-width: 480px; max-width: 480px;
width: 100%; width: 100%;

View File

@ -1,8 +1,8 @@
.mailpoet-automation-chip { .mailpoet-automation-chip {
align-items: center; align-items: center;
background: #f0f0f1; background: #fcf0f1;
border-radius: 9999px; border-radius: 9999px;
color: #2c3338; color: #8a2424;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
font-size: 13px; font-size: 13px;
@ -24,18 +24,4 @@
height: 32px; height: 32px;
padding: 0 12px; padding: 0 12px;
} }
&.chip-danger {
background: #fcf0f1;
color: #8a2424;
}
&[aria-expanded='true'] {
filter: brightness(95%);
}
&:focus {
box-shadow: 0 0 0 calc(var(--wp-admin-border-width-focus))
var(--wp-admin-theme-color);
}
} }

View File

@ -1,4 +1,4 @@
.mailpoet-automation-deactivate-modal { .mailpoet-automatoin-deactivate-modal {
color: #1d2327; color: #1d2327;
font-size: 13px; font-size: 13px;
line-height: 21px; line-height: 21px;

View File

@ -34,15 +34,15 @@
.mailpoet-automation-field__error { .mailpoet-automation-field__error {
position: relative; position: relative;
input:not([type='radio']) select, input,
textarea, select,
input[type='text'].components-form-token-field__input { textarea {
background: right top/26px no-repeat url('../../img/icons/alert.svg'); background: right top/26px no-repeat url('../../img/icons/alert.svg');
padding-right: 26px; padding-right: 26px;
} }
select, select,
input[type='number'] { input[type=number] {
background-position-x: calc(100% - 26px); background-position-x: calc(100% - 26px);
padding-right: 8px !important; padding-right: 8px !important;
} }

View File

@ -1,88 +0,0 @@
.mailpoet-automation-filters-panel-content {
margin-top: 16px;
}
button.components-button.mailpoet-automation-filters-panel-add-filter {
padding-right: 12px;
&.has-icon > svg {
margin-right: 4px;
}
}
.mailpoet-automation-filters-list {
display: grid;
gap: 12px;
}
.mailpoet-automation-filters-list-group-description {
color: #646970;
font-size: 13px;
margin-bottom: 16px;
}
.mailpoet-automation-filters-list-group-description-operator {
font-weight: 600;
}
.mailpoet-automation-filters-list-group-operator {
.components-base-control__field > div {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px 16px;
justify-content: flex-start;
}
}
.mailpoet-automation-filters-list-item {
align-items: center;
background: #f0f0f0;
display: grid;
grid-template-columns: 1fr auto;
&.mailpoet-automation-filters-list-item-has-error {
background: #fcf0f1;
color: #8a2424;
}
.mailpoet-automation-filters-list-item-content {
color: inherit;
display: block;
height: auto;
line-height: inherit;
padding: 8px 12px;
text-align: left;
&:disabled {
opacity: 1;
}
}
.mailpoet-automation-filters-list-item-remove {
color: #757575;
margin: 4px;
padding: 0;
}
}
.mailpoet-automation-filters-list-item-error {
color: #8a2424;
font-size: 12px;
margin-top: 4px;
}
.mailpoet-automation-filters-list-item-field,
.mailpoet-automation-filters-list-item-value {
font-weight: 600;
}
.mailpoet-automation-filters-list-item-value-missing {
color: #757575;
display: inline-block;
vertical-align: middle;
svg {
margin: -2px 0;
}
}

View File

@ -1,3 +0,0 @@
#mailpoet_automation_editor .interface-interface-skeleton__header {
border-bottom: none;
}

View File

@ -9,7 +9,7 @@
.mailpoet-automation-editor-notices__notice-list { .mailpoet-automation-editor-notices__notice-list {
// Notices have some unusual margin and padding by default, reset that. // Notices have some unusual margin and padding by default, reset that.
.components-notice { .components-notice {
border-bottom: 1px solid rgba(0, 0, 0, 0.2); border-bottom: 1px solid rgba(0, 0, 0, .2);
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
min-height: 60px; min-height: 60px;

View File

@ -5,10 +5,6 @@
.components-panel__body-title.mailpoet-automation-panel-plain-body-title { .components-panel__body-title.mailpoet-automation-panel-plain-body-title {
display: grid; display: grid;
grid-template-columns: 1fr auto; grid-template-columns: 1fr auto;
&:hover {
background: none;
}
} }
.mailpoet-automation-panel-plain-body-title-text { .mailpoet-automation-panel-plain-body-title-text {
@ -67,13 +63,16 @@
} }
.mailpoet-automation-activate-panel { .mailpoet-automation-activate-panel {
animation: mailpoet-automation-activate-panel-animation 0.1s forwards; animation: mailpoet-automation-activate-panel-animation .1s forwards;
background: #fff; background: #fff;
border-left: 1px solid #ddd; border-left: 1px solid #ddd;
bottom: 0;
height: 100%; height: 100%;
inset: 0 0 0 auto; left: auto;
overflow: auto; overflow: auto;
position: fixed; position: fixed;
right: 0;
top: 0;
transform: translateX(100%); transform: translateX(100%);
width: 281px; width: 281px;
z-index: 999999; z-index: 999999;

View File

@ -1,22 +0,0 @@
/* See: https://github.com/WordPress/gutenberg/blob/0b4ad0072a5c3dd4832081ed00d4e27389ae88c8/packages/editor/src/components/post-saved-state/index.js */
.mailpoet-automation-editor-saved-state {
align-items: center;
color: #757575;
display: flex;
overflow: hidden;
white-space: nowrap;
&.is-saving[aria-disabled='true'],
&.is-saving[aria-disabled='true']:hover,
&.is-saved[aria-disabled='true'],
&.is-saved[aria-disabled='true']:hover {
background: transparent;
color: #757575;
}
svg {
display: inline-block;
fill: currentColor;
flex: 0 0 auto;
}
}

View File

@ -1,5 +1,3 @@
$separator-width: 1px;
.mailpoet-automation-editor-separator { .mailpoet-automation-editor-separator {
align-items: center; align-items: center;
background: #c3c4c7; background: #c3c4c7;
@ -7,76 +5,5 @@ $separator-width: 1px;
height: 64px; height: 64px;
justify-content: center; justify-content: center;
margin: auto; margin: auto;
white-space: nowrap; width: 1px;
width: $separator-width;
}
.mailpoet-automation-editor-separator-curve-root {
display: flex;
}
.mailpoet-automation-editor-separator-curve-root-left,
.mailpoet-automation-editor-separator-curve-root-right {
border-bottom: $separator-width solid #c3c4c7;
border-bottom-right-radius: 70px 30px;
border-right: $separator-width solid #c3c4c7;
height: 20px;
justify-self: end;
width: 100%;
//box-shadow: 0 0 1px transparent;
&.mailpoet-automation-editor-separator-curve-root-left {
margin-right: calc(-1 * $separator-width / 2);
transform: scaleX(1);
}
&.mailpoet-automation-editor-separator-curve-root-right {
margin-left: calc(-1 * $separator-width / 2);
transform: scaleX(-1);
}
}
.mailpoet-automation-editor-separator-curve-leaf-left,
.mailpoet-automation-editor-separator-curve-leaf-right {
$width: 70px;
&.mailpoet-automation-editor-separator-curve-leaf-left {
transform: scaleX(1);
}
&.mailpoet-automation-editor-separator-curve-leaf-right {
transform: scaleX(-1);
}
// cover rest of full-width line coming from curve root
&:before {
background: #fbfbfb;
content: '';
display: block;
height: 20px;
position: absolute;
right: calc(50% - $width);
top: 0;
width: calc(100% - $width);
z-index: -1;
}
// add curve leaf ending rounded to the bottom
&:after {
border-left: $separator-width solid #c3c4c7;
border-top: $separator-width solid #c3c4c7;
border-top-left-radius: 35px 20px;
content: '';
display: block;
height: 16px;
margin: -$separator-width auto 0 calc(50% - $separator-width / 2);
transform-origin: left;
width: calc($width + $separator-width / 2);
}
}
.mailpoet-automation-editor-branch-badge {
height: 32px;
margin: 4px auto;
width: 32px;
} }

View File

@ -1,19 +0,0 @@
.mailpoet-automation-editor-step-filters {
display: grid;
gap: 8px;
max-height: 400px;
padding: 8px;
width: 300px;
}
.mailpoet-automation-editor-step-filters-title {
font-size: 13px;
font-weight: 600;
line-height: 1;
}
.mailpoet-automation-editor-step-filters-description {
color: #646970;
font-size: 13px;
margin-bottom: 4px;
}

View File

@ -1,5 +1,5 @@
.mailpoet-automation-editor-step-wrapper { .mailpoet-automation-editor-step-wrapper {
margin: 0 auto; margin: auto;
position: relative; position: relative;
width: 280px; width: 280px;
} }
@ -22,15 +22,15 @@
background: white; background: white;
border: 1px solid #dcdcde; border: 1px solid #dcdcde;
border-radius: 4px; border-radius: 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
display: grid; display: grid;
grid-gap: 12px; grid-gap: 12px;
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
line-height: 1.4; line-height: 1.4;
margin: 4px; margin: 4px auto;
padding: 12px; padding: 12px;
text-align: left; text-align: left;
width: calc(100% - 8px); width: 100%;
&.is-unknown-step { &.is-unknown-step {
background: #f0f0f1; background: #f0f0f1;
@ -39,13 +39,9 @@
&:focus, &:focus,
&.is-selected-step { &.is-selected-step {
box-shadow: box-shadow:
// space 0 0 0 1px #fbfbfb, // space
0 0 0 1px #fbfbfb, 0 0 0 calc(var(--wp-admin-border-width-focus) + 1px) var(--wp-admin-theme-color), // focus ring
// focus ring 0 1px 2px rgba(0, 0, 0, .05); // original shadow
0 0 0 calc(var(--wp-admin-border-width-focus) + 1px)
var(--wp-admin-theme-color),
// original shadow
0 1px 2px rgba(0, 0, 0, 0.05);
} }
&:has(.mailpoet-automation-editor-step-footer) { &:has(.mailpoet-automation-editor-step-footer) {
@ -58,10 +54,7 @@
} }
.mailpoet-automation-editor-step-title { .mailpoet-automation-editor-step-title {
align-items: center;
color: $color-wordpress-grey-dark; color: $color-wordpress-grey-dark;
display: flex;
gap: 8px;
} }
.mailpoet-automation-editor-step-subtitle { .mailpoet-automation-editor-step-subtitle {
@ -70,10 +63,12 @@
} }
.mailpoet-automation-editor-step-footer { .mailpoet-automation-editor-step-footer {
column-gap: 4px;
display: flex; display: flex;
grid-column: 1 / -1; grid-column: 1 / -1;
justify-content: flex-end; }
.mailpoet-automation-editor-step-error {
margin-left: auto;
} }
.mailpoet-automation-colored-icon { .mailpoet-automation-colored-icon {

View File

@ -1,25 +0,0 @@
// settings
@import '../settings/colors';
// styles
@import './add-step-button';
@import './add-trigger';
@import './automation';
@import './block-icon';
@import './chip';
@import './dropdown';
@import './empty-automation';
@import './errors';
@import './panel';
@import './saved-state';
@import './separator';
@import './status';
@import './step';
@import './step-filters';
@import './step-card';
@import './filters';
@import './header';
@import './notices';
@import './deactivate-modal';

View File

@ -1 +0,0 @@
@import './core/steps';

View File

@ -1,22 +0,0 @@
.mailpoet-automation-if-else-yes,
.mailpoet-automation-if-else-no {
align-items: center;
border-radius: 999px;
display: flex;
height: 100%;
justify-content: center;
width: 100%;
}
.mailpoet-automation-if-else-yes {
background: #edfaef;
border: 1px solid #008a20;
fill: #008a20;
//color: #007017;
}
.mailpoet-automation-if-else-no {
background: #fcf0f1;
border: 1px solid #d63638;
fill: #d63638;
}

View File

@ -1,4 +1,3 @@
@import './mailpoet/button'; @import './mailpoet/button';
@import './mailpoet/edit'; @import './mailpoet/edit';
@import './mailpoet/thumbnail'; @import './mailpoet/thumbnail';
@import './mailpoet/steps';

View File

@ -9,19 +9,20 @@
} }
&:disabled { &:disabled {
color: rgba(255, 255, 255, 0.4); color: rgba(255, 255, 255, .4);
} }
&.is-busy { &.is-busy {
--background-color-1: #2c3236; --background-color-1: #2c3236;
--background-color-2: #535659; --background-color-2: #535659;
background-image: linear-gradient( background-image:
-45deg, linear-gradient(
var(--background-color-1) 33%, -45deg,
var(--background-color-2) 33%, var(--background-color-1) 33%,
var(--background-color-2) 70%, var(--background-color-2) 33%,
var(--background-color-1) 70% var(--background-color-2) 70%,
); var(--background-color-1) 70%
);
} }
} }

View File

@ -1,15 +0,0 @@
.mailpoet-sendmail-description {
display: grid;
grid-gap: 4px;
grid-template-columns: 14px auto;
grid-template-rows: auto auto;
}
.mailpoet-sendemail-description-main {
grid-column-end: -1;
grid-column-start: 1;
}
.mailpoet-sendmail-description-type {
color: #787c82;
}

View File

@ -1,21 +0,0 @@
@import '../../../../node_modules/@woocommerce/components/build-style/style';
.mailpoet-product-search {
&.is-busy {
animation: components-button__busy-animation 2500ms infinite linear;
background-image: linear-gradient(
-45deg,
var(--background-color-1) 33%,
var(--background-color-2) 33%,
var(--background-color-2) 70%,
var(--background-color-1) 70%
);
background-size: 100px 100%;
--background-color-1: #2c3236;
--background-color-2: #535659;
}
.woocommerce-select-control__control {
background: transparent;
}
}

View File

@ -12,20 +12,27 @@
} }
} }
.mailpoet-automation-listing-heading {
margin-bottom: 16px;
}
.mailpoet-automation-listing { .mailpoet-automation-listing {
box-shadow: none; box-shadow: none;
margin-bottom: 0; margin-bottom: 0;
} }
.mailpoet-automation-listing-cell-name.woocommerce-table__item { .mailpoet-automation-listing-cell-name {
position: relative; position: relative;
width: 100%; width: 100%;
> a:only-child { > a:only-child {
bottom: 2px;
display: flex; display: flex;
inset: 0 0 2px; left: 0;
padding: 16px 24px; padding: 16px 24px;
position: absolute; position: absolute;
right: 0;
top: 0;
} }
} }
@ -33,7 +40,6 @@
background-color: #fff; background-color: #fff;
border: 1px solid #dcdcde; border: 1px solid #dcdcde;
border-radius: 2px; border-radius: 2px;
margin-top: 16px;
.components-tab-panel__tabs { .components-tab-panel__tabs {
box-shadow: inset 0 -1px 0 0 #dcdcde; box-shadow: inset 0 -1px 0 0 #dcdcde;
@ -48,13 +54,12 @@
} }
.components-tab-panel__tabs-item:focus-visible { .components-tab-panel__tabs-item:focus-visible {
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
var(--wp-admin-theme-color);
} }
.components-tab-panel__tabs-item.is-active:focus-visible { .components-tab-panel__tabs-item.is-active:focus-visible {
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) box-shadow:
var(--wp-admin-theme-color), inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),
inset 0 -4px 0 0 var(--wp-admin-theme-color); inset 0 -4px 0 0 var(--wp-admin-theme-color);
} }

View File

@ -1,5 +1,4 @@
.mailpoet-automation-listing-search.woocommerce-search.woocommerce-select-control .mailpoet-automation-listing-search.woocommerce-search.woocommerce-select-control > div {
> div {
border-color: $color-wordpress-heading; border-color: $color-wordpress-heading;
border-radius: 2px; border-radius: 2px;
box-shadow: none; box-shadow: none;

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