From 1372de1bbac2d4736ace6e2b60a5d6a8bccc3572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ja=CC=81n=20Mikla=CC=81s=CC=8C?= Date: Thu, 16 Jan 2025 11:17:18 +0100 Subject: [PATCH 01/18] Update CheckboxControl types https://github.com/woocommerce/woocommerce/blob/6b8a403a0365cf7dd37c9fe6886417816e2888e9/plugins/woocommerce-blocks/packages/components/checkbox-control/index.tsx#L12-L21 [MAILPOET-6436] --- mailpoet/assets/js/src/global.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mailpoet/assets/js/src/global.d.ts b/mailpoet/assets/js/src/global.d.ts index 16c133b424..855a5079cc 100644 --- a/mailpoet/assets/js/src/global.d.ts +++ b/mailpoet/assets/js/src/global.d.ts @@ -39,13 +39,13 @@ interface JQuery { declare module '@woocommerce/blocks-checkout' { type CheckboxControlProps = { className?: string; - label?: string; + label?: string | React.ReactNode; id?: string; - instanceId?: string; - onChange?: (value: boolean) => void; - children?: React.ReactChildren | React.ReactElement; + onChange: (value: boolean) => void; + children?: React.ReactChildren; hasError?: boolean; checked?: boolean; + disabled?: string | boolean | undefined; }; export const CheckboxControl: (props: CheckboxControlProps) => JSX.Element; } From a4d67a319a33b010fda81e32bc9a828f6ee8b4fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ja=CC=81n=20Mikla=CC=81s=CC=8C?= Date: Thu, 16 Jan 2025 11:18:33 +0100 Subject: [PATCH 02/18] Properly set block opt-in checkbox label to render with correct classes This fixes verical misalignment between the checkbox and the label [MAILPOET-6436] --- mailpoet/assets/js/src/marketing-optin-block/block.tsx | 8 +++++--- mailpoet/assets/js/src/marketing-optin-block/edit.tsx | 6 +++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mailpoet/assets/js/src/marketing-optin-block/block.tsx b/mailpoet/assets/js/src/marketing-optin-block/block.tsx index fff9921748..be76efe896 100644 --- a/mailpoet/assets/js/src/marketing-optin-block/block.tsx +++ b/mailpoet/assets/js/src/marketing-optin-block/block.tsx @@ -30,8 +30,10 @@ export function FrontendBlock({ } return ( - - {text || defaultText} - + {text || defaultText}} + /> ); } diff --git a/mailpoet/assets/js/src/marketing-optin-block/edit.tsx b/mailpoet/assets/js/src/marketing-optin-block/edit.tsx index c8cd83b6e0..d34c0c77df 100644 --- a/mailpoet/assets/js/src/marketing-optin-block/edit.tsx +++ b/mailpoet/assets/js/src/marketing-optin-block/edit.tsx @@ -56,7 +56,11 @@ export function Edit({
{optinEnabled ? (
- + {}} + /> setAttributes({ text: value })} From cd44c42a1d107b7510b512cc1f0d97683a68a248 Mon Sep 17 00:00:00 2001 From: David Remer Date: Wed, 12 Feb 2025 11:49:38 +0200 Subject: [PATCH 03/18] Upgrade Action Scheduler to 3.9.2 [MAILPOET-6467] --- mailpoet/composer.json | 2 +- mailpoet/composer.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mailpoet/composer.json b/mailpoet/composer.json index c5fe7f2fff..6db54d4a3d 100644 --- a/mailpoet/composer.json +++ b/mailpoet/composer.json @@ -5,7 +5,7 @@ "dragonmantank/cron-expression": "^3.3", "mailpoet/email-editor": "*", "mixpanel/mixpanel-php": "2.*", - "woocommerce/action-scheduler": "^3.8.0" + "woocommerce/action-scheduler": "3.9.2" }, "require-dev": { "ext-gd": "*", diff --git a/mailpoet/composer.lock b/mailpoet/composer.lock index 999c1e8d8b..e1c204bff0 100644 --- a/mailpoet/composer.lock +++ b/mailpoet/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "51893b0f5ed38d130932b86b48e55b94", + "content-hash": "a95263a51332277e75d7147e3dc4551e", "packages": [ { "name": "dragonmantank/cron-expression", @@ -221,20 +221,20 @@ }, { "name": "woocommerce/action-scheduler", - "version": "3.8.0", + "version": "3.9.2", "source": { "type": "git", "url": "https://github.com/woocommerce/action-scheduler.git", - "reference": "99cd7981f51c98883082534d4852491858d72834" + "reference": "efbb7953f72a433086335b249292f280dd43ddfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/99cd7981f51c98883082534d4852491858d72834", - "reference": "99cd7981f51c98883082534d4852491858d72834", + "url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/efbb7953f72a433086335b249292f280dd43ddfe", + "reference": "efbb7953f72a433086335b249292f280dd43ddfe", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5", @@ -258,9 +258,9 @@ "homepage": "https://actionscheduler.org/", "support": { "issues": "https://github.com/woocommerce/action-scheduler/issues", - "source": "https://github.com/woocommerce/action-scheduler/tree/3.8.0" + "source": "https://github.com/woocommerce/action-scheduler/tree/3.9.2" }, - "time": "2024-05-22T13:50:29+00:00" + "time": "2025-02-03T09:09:30+00:00" } ], "packages-dev": [ @@ -8343,7 +8343,7 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { From 40f946f25c87ba44d6a0b65eab5cc601cd93f52f Mon Sep 17 00:00:00 2001 From: alex-mpoet Date: Mon, 17 Feb 2025 19:30:19 +0300 Subject: [PATCH 04/18] Release 5.7.1 --- mailpoet/changelog.txt | 4 ++++ mailpoet/mailpoet.php | 4 ++-- mailpoet/readme.txt | 11 ++++------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mailpoet/changelog.txt b/mailpoet/changelog.txt index becd424ac6..9cce33698b 100644 --- a/mailpoet/changelog.txt +++ b/mailpoet/changelog.txt @@ -1,5 +1,9 @@ == Changelog == += 5.7.1 - 2025-02-17 = +* Improved: Apply get_the_excerpt filter to MailPoets post excerpts; +* Fixed: conflict with Rank Math plugin breaking "Scheduled Actions" page. + = 5.7.0 - 2025-02-11 = * Improved: Rename Review Trigger in Automations; * Changed: minimum required WooCommerce is 9.5; diff --git a/mailpoet/mailpoet.php b/mailpoet/mailpoet.php index 3e784a1a16..a79c1094f8 100644 --- a/mailpoet/mailpoet.php +++ b/mailpoet/mailpoet.php @@ -2,7 +2,7 @@ /* * Plugin Name: MailPoet - * Version: 5.7.0 + * Version: 5.7.1 * Plugin URI: https://www.mailpoet.com * Description: Create and send newsletters, post notifications and welcome emails from your WordPress. * Author: MailPoet @@ -20,7 +20,7 @@ */ $mailpoetPlugin = [ - 'version' => '5.7.0', + 'version' => '5.7.1', 'filename' => __FILE__, 'path' => dirname(__FILE__), 'autoloader' => dirname(__FILE__) . '/vendor/autoload.php', diff --git a/mailpoet/readme.txt b/mailpoet/readme.txt index 8f796f735a..df219339f9 100644 --- a/mailpoet/readme.txt +++ b/mailpoet/readme.txt @@ -3,7 +3,7 @@ Contributors: mailpoet, woocommerce, automattic Tags: email marketing, post notification, woocommerce emails, email automation, newsletter Requires at least: 6.6 Tested up to: 6.7 -Stable tag: 5.7.0 +Stable tag: 5.7.1 Requires PHP: 7.4 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -222,11 +222,8 @@ Check our [Knowledge Base](https://kb.mailpoet.com) or contact us through our [s == Changelog == -= 5.7.0 - 2025-02-11 = -* Improved: Rename Review Trigger in Automations; -* Changed: minimum required WooCommerce is 9.5; -* Fixed: Automation UI shows wrong saved status after failed activation; -* Fixed: Email preview does not work with sent emails; -* Fixed: email content patterns are mixed with page starter patterns. += 5.7.1 - 2025-02-17 = +* Improved: Apply get_the_excerpt filter to MailPoets post excerpts; +* Fixed: conflict with Rank Math plugin breaking "Scheduled Actions" page. [See the changelog for all versions.](https://github.com/mailpoet/mailpoet/blob/trunk/mailpoet/changelog.txt) From 96eb805c5cd5efebbec5d1fb3dd70cb4448978e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Feb 2025 06:07:08 +0000 Subject: [PATCH 05/18] Update used WordPress images in Circle CI - latest version: 6.7.2-php8.3 - previous version: 6.6.2 --- tests_env/docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests_env/docker/docker-compose.yml b/tests_env/docker/docker-compose.yml index 3b128e3bc3..642d9047c3 100644 --- a/tests_env/docker/docker-compose.yml +++ b/tests_env/docker/docker-compose.yml @@ -75,7 +75,7 @@ services: - mailhog-data:/mailhog-data wordpress: - image: wordpress:${WORDPRESS_IMAGE_VERSION:-6.7.1-php8.3} + image: wordpress:${WORDPRESS_IMAGE_VERSION:-6.7.2-php8.3} container_name: wordpress_${CIRCLE_NODE_INDEX:-default} depends_on: smtp: From 227aab5c473b301cc69a7fa1744429e949e279d8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Feb 2025 06:07:08 +0000 Subject: [PATCH 06/18] Update used WooCommerce plugin in Circle CI - latest version: 9.6.2 - previous version: 9.5.2 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3639d98414..1240e14017 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -197,7 +197,7 @@ jobs: - run: name: Download additional WP Plugins for tests command: | - ./do download:woo-commerce-zip 9.6.0 + ./do download:woo-commerce-zip 9.6.2 ./do download:woo-commerce-subscriptions-zip 7.1.0 ./do download:woo-commerce-memberships-zip 1.26.5 ./do download:automate-woo-zip 6.1.5 From fec3ae12394dab7bd64fd9df9fc52fcf61a92697 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Feb 2025 06:07:09 +0000 Subject: [PATCH 07/18] Update used Automate Woo plugin in Circle CI - latest version: 6.1.6 - previous version: 6.0.33 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1240e14017..efb0d3499f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -200,7 +200,7 @@ jobs: ./do download:woo-commerce-zip 9.6.2 ./do download:woo-commerce-subscriptions-zip 7.1.0 ./do download:woo-commerce-memberships-zip 1.26.5 - ./do download:automate-woo-zip 6.1.5 + ./do download:automate-woo-zip 6.1.6 - run: name: Dump tests ENV variables for acceptance tests command: | From 336b63b43cc7d27e2ed162b5b7a6eda521196b2f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Feb 2025 06:07:09 +0000 Subject: [PATCH 08/18] Update used WooCommerce Subscriptions plugin in Circle CI - latest version: 7.2.1 - previous version: 7.1.0 --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index efb0d3499f..1d35640064 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -198,7 +198,7 @@ jobs: name: Download additional WP Plugins for tests command: | ./do download:woo-commerce-zip 9.6.2 - ./do download:woo-commerce-subscriptions-zip 7.1.0 + ./do download:woo-commerce-subscriptions-zip 7.2.1 ./do download:woo-commerce-memberships-zip 1.26.5 ./do download:automate-woo-zip 6.1.6 - run: @@ -1083,7 +1083,7 @@ workflows: <<: *slack-fail-post-step name: acceptance_oldest woo_core_version: 9.5.2 - woo_subscriptions_version: 7.0.0 + woo_subscriptions_version: 7.1.0 woo_memberships_version: 1.25.2 automate_woo_version: 6.0.33 mysql_command: --max_allowed_packet=100M @@ -1124,7 +1124,7 @@ workflows: <<: *slack-fail-post-step name: integration_oldest woo_core_version: 9.5.2 - woo_subscriptions_version: 7.0.0 + woo_subscriptions_version: 7.1.0 woo_memberships_version: 1.25.2 automate_woo_version: 6.0.33 codeception_image_version: 7.4-cli_20220605.0 @@ -1187,7 +1187,7 @@ workflows: <<: *slack-fail-post-step name: acceptance_with_premium_oldest woo_core_version: 9.5.2 - woo_subscriptions_version: 7.0.0 + woo_subscriptions_version: 7.1.0 woo_memberships_version: 1.25.2 automate_woo_version: 6.0.33 codeception_image_version: 7.4-cli_20220605.0 @@ -1199,7 +1199,7 @@ workflows: <<: *slack-fail-post-step name: integration_with_premium_oldest woo_core_version: 9.5.2 - woo_subscriptions_version: 7.0.0 + woo_subscriptions_version: 7.1.0 woo_memberships_version: 1.25.2 automate_woo_version: 6.0.33 codeception_image_version: 7.4-cli_20220605.0 From 919a855f3403594f7f262746f69f1a71d490b9db Mon Sep 17 00:00:00 2001 From: alex-mpoet Date: Wed, 19 Feb 2025 17:21:56 +0300 Subject: [PATCH 09/18] Update mocha [MAILPOET-6486] --- mailpoet/package.json | 2 +- pnpm-lock.yaml | 152 +++++++++++++++++++----------------------- 2 files changed, 68 insertions(+), 86 deletions(-) diff --git a/mailpoet/package.json b/mailpoet/package.json index 18b6785428..96e6467136 100644 --- a/mailpoet/package.json +++ b/mailpoet/package.json @@ -162,7 +162,7 @@ "js-yaml": "^4.1.0", "jsdom": "^24.1.0", "json-loader": "^0.5.7", - "mocha": "^10.4.0", + "mocha": "^10.8.2", "phplint": "^2.0.5", "postcss-cli": "^11.0.0", "postcss-scss": "^4.0.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a462dac039..19b096d5dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -482,8 +482,8 @@ importers: specifier: ^0.5.7 version: 0.5.7 mocha: - specifier: ^10.4.0 - version: 10.4.0 + specifier: ^10.8.2 + version: 10.8.2 phplint: specifier: ^2.0.5 version: 2.0.5 @@ -992,7 +992,7 @@ packages: '@wordpress/primitives': 3.56.0 '@wordpress/react-i18n': 3.36.0 classnames: 2.5.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@18.3.1)(react@18.3.1) @@ -1168,7 +1168,7 @@ packages: '@babel/core': 7.24.7 '@babel/helper-compilation-targets': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -2528,7 +2528,7 @@ packages: '@babel/helper-split-export-declaration': 7.24.7 '@babel/parser': 7.24.7 '@babel/types': 7.24.7 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -2542,7 +2542,7 @@ packages: '@babel/parser': 7.26.3 '@babel/template': 7.25.9 '@babel/types': 7.26.3 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -3109,7 +3109,7 @@ packages: deprecated: Use @eslint/config-array instead dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.4.0 + debug: 4.3.5(supports-color@9.3.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -3572,7 +3572,7 @@ packages: typescript: optional: true dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 extract-zip: 2.0.1 progress: 2.0.3 proxy-agent: 6.3.0 @@ -4651,7 +4651,7 @@ packages: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(typescript@5.0.2) '@typescript-eslint/utils': 5.62.0(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) graphemer: 1.4.0 ignore: 5.3.1 natural-compare-lite: 1.4.0 @@ -4679,7 +4679,7 @@ packages: '@typescript-eslint/type-utils': 6.21.0(eslint@8.36.0)(typescript@5.0.2) '@typescript-eslint/utils': 6.21.0(eslint@8.36.0)(typescript@5.0.2) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) eslint: 8.36.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -4724,7 +4724,7 @@ packages: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) typescript: 5.0.2 transitivePeerDependencies: - supports-color @@ -4744,7 +4744,7 @@ packages: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.0.2) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) eslint: 8.36.0 typescript: 5.0.2 transitivePeerDependencies: @@ -4787,7 +4787,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 5.56.0(typescript@5.0.2) '@typescript-eslint/utils': 5.56.0(eslint@8.36.0)(typescript@5.0.2) - debug: 4.4.0 + debug: 4.3.5(supports-color@9.3.1) eslint: 8.36.0 tsutils: 3.21.0(typescript@5.0.2) typescript: 5.0.2 @@ -4807,7 +4807,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.2) '@typescript-eslint/utils': 5.62.0(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) tsutils: 3.21.0(typescript@5.0.2) typescript: 5.0.2 transitivePeerDependencies: @@ -4826,7 +4826,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.0.2) '@typescript-eslint/utils': 6.21.0(eslint@8.36.0)(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) eslint: 8.36.0 ts-api-utils: 1.3.0(typescript@5.0.2) typescript: 5.0.2 @@ -4860,7 +4860,7 @@ packages: dependencies: '@typescript-eslint/types': 5.56.0 '@typescript-eslint/visitor-keys': 5.56.0 - debug: 4.4.0 + debug: 4.3.5(supports-color@9.3.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.2 @@ -4881,7 +4881,7 @@ packages: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.2 @@ -4902,7 +4902,7 @@ packages: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -8272,7 +8272,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.4.0 + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -8281,7 +8281,7 @@ packages: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -8361,8 +8361,8 @@ packages: uri-js: 4.4.1 dev: true - /ansi-colors@4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} dev: true @@ -9017,8 +9017,8 @@ packages: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} dev: true - /bare-events@2.5.0: - resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==} + /bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} requiresBuild: true dev: true optional: true @@ -10325,7 +10325,7 @@ packages: ms: 2.1.2 dev: false - /debug@4.3.4(supports-color@8.1.1): + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -10335,7 +10335,6 @@ packages: optional: true dependencies: ms: 2.1.2 - supports-color: 8.1.1 dev: true /debug@4.3.5(supports-color@9.3.1): @@ -10351,7 +10350,7 @@ packages: supports-color: 9.3.1 dev: true - /debug@4.4.0: + /debug@4.4.0(supports-color@8.1.1): resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} peerDependencies: @@ -10361,6 +10360,7 @@ packages: optional: true dependencies: ms: 2.1.3 + supports-color: 8.1.1 /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -10591,11 +10591,6 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - /diff@5.0.0: - resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} - engines: {node: '>=0.3.1'} - dev: true - /diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} @@ -10876,7 +10871,7 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} dependencies: - ansi-colors: 4.1.1 + ansi-colors: 4.1.3 strip-ansi: 6.0.1 dev: true @@ -11137,7 +11132,7 @@ packages: optional: true dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) enhanced-resolve: 5.17.1 fast-glob: 3.3.2 get-tsconfig: 4.8.1 @@ -11399,7 +11394,7 @@ packages: '@es-joy/jsdoccomment': 0.41.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint: 8.36.0 esquery: 1.5.0 @@ -11791,7 +11786,7 @@ packages: engines: {node: '>= 10.17.0'} hasBin: true dependencies: - debug: 4.4.0 + debug: 4.3.4 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -11995,7 +11990,7 @@ packages: dependencies: chalk: 4.1.2 commander: 5.1.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12370,7 +12365,7 @@ packages: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.4.0 + debug: 4.3.4 fs-extra: 11.2.0 transitivePeerDependencies: - supports-color @@ -12419,7 +12414,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.0.1 + minimatch: 5.1.6 once: 1.4.0 dev: true @@ -12678,7 +12673,6 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - dev: true /has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -12886,7 +12880,7 @@ packages: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12896,7 +12890,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12936,7 +12930,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -12946,7 +12940,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12971,7 +12965,7 @@ packages: '@babel/runtime': 7.24.7 '@tannin/sprintf': 1.2.0 '@wordpress/compose': 5.20.0(react@18.3.1) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) events: 3.3.0 hash.js: 1.1.7 lodash: 4.17.21 @@ -13564,7 +13558,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -15002,8 +14996,8 @@ packages: dependencies: brace-expansion: 1.1.11 - /minimatch@5.0.1: - resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 @@ -15051,30 +15045,30 @@ packages: minimist: 1.2.8 dev: true - /mocha@10.4.0: - resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==} + /mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} engines: {node: '>= 14.0.0'} hasBin: true dependencies: - ansi-colors: 4.1.1 + ansi-colors: 4.1.3 browser-stdout: 1.3.1 chokidar: 3.5.3 - debug: 4.3.4(supports-color@8.1.1) - diff: 5.0.0 + debug: 4.4.0(supports-color@8.1.1) + diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 glob: 8.1.0 he: 1.2.0 js-yaml: 4.1.0 log-symbols: 4.1.0 - minimatch: 5.0.1 + minimatch: 5.1.6 ms: 2.1.3 - serialize-javascript: 6.0.0 + serialize-javascript: 6.0.2 strip-json-comments: 3.1.1 supports-color: 8.1.1 - workerpool: 6.2.1 + workerpool: 6.5.1 yargs: 16.2.0 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 yargs-unparser: 2.0.0 dev: true @@ -15262,7 +15256,7 @@ packages: ajv-errors: 1.0.1(ajv@6.12.6) chalk: 4.1.2 cosmiconfig: 8.3.6(typescript@5.0.2) - debug: 4.3.5(supports-color@9.3.1) + debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 ignore: 5.3.1 is-plain-obj: 3.0.0 @@ -15558,7 +15552,7 @@ packages: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.3.4 get-uri: 6.0.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 @@ -15752,7 +15746,7 @@ packages: dependencies: '@babel/runtime': 7.24.7 crc32: 0.2.2 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) seed-random: 2.2.0 transitivePeerDependencies: - supports-color @@ -16434,7 +16428,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.3.4 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 lru-cache: 7.18.3 @@ -16483,7 +16477,7 @@ packages: engines: {node: '>=10.18.1'} dependencies: cross-fetch: 3.1.5 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 devtools-protocol: 0.0.981744 extract-zip: 2.0.1 https-proxy-agent: 5.0.1 @@ -16513,7 +16507,7 @@ packages: '@puppeteer/browsers': 1.4.6(typescript@5.0.2) chromium-bidi: 0.4.16(devtools-protocol@0.0.1147663) cross-fetch: 4.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 devtools-protocol: 0.0.1147663 typescript: 5.0.2 ws: 8.18.0 @@ -17617,12 +17611,6 @@ packages: tslib: 2.6.3 upper-case-first: 2.0.2 - /serialize-javascript@6.0.0: - resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} - dependencies: - randombytes: 2.1.0 - dev: true - /serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} dependencies: @@ -17766,7 +17754,7 @@ packages: resolution: {integrity: sha512-D1SaWpOW8afq1CZGWB8xTfrT3FekjQmPValrqncJMX7QFl8YwhrPTZvMCANLtgBwwdS+7zURyqxDDEmY558tTw==} dependencies: buffer: 6.0.3 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) err-code: 3.0.1 get-browser-rtc: 1.1.0 queue-microtask: 1.2.3 @@ -17878,7 +17866,7 @@ packages: base64-arraybuffer: 0.1.5 component-bind: 1.0.0 component-emitter: 1.2.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) engine.io-client: 3.4.4 has-binary2: 1.0.3 has-cors: 1.1.0 @@ -17917,7 +17905,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.3.4 socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -18037,7 +18025,7 @@ packages: /spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -18051,7 +18039,7 @@ packages: resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} engines: {node: '>=6.0.0'} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -18120,7 +18108,7 @@ packages: queue-tick: 1.0.1 text-decoder: 1.1.1 optionalDependencies: - bare-events: 2.5.0 + bare-events: 2.5.4 dev: true /string-argv@0.3.1: @@ -18386,7 +18374,7 @@ packages: colord: 2.9.3 cosmiconfig: 7.1.0 css-functions-list: 3.2.2 - debug: 4.3.5(supports-color@9.3.1) + debug: 4.4.0(supports-color@8.1.1) fast-glob: 3.3.2 fastest-levenshtein: 1.0.16 file-entry-cache: 6.0.1 @@ -18498,7 +18486,6 @@ packages: engines: {node: '>=10'} dependencies: has-flag: 4.0.0 - dev: true /supports-color@9.3.1: resolution: {integrity: sha512-knBY82pjmnIzK3NifMo3RxEIRD9E0kIzV4BKcyTZ9+9kWgLMxd4PrsTSMoFQUabgRBbF8KOLRDCyKgNV+iK44Q==} @@ -19714,8 +19701,8 @@ packages: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: false - /workerpool@6.2.1: - resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + /workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} dev: true /wp-error@1.3.0: @@ -19747,7 +19734,7 @@ packages: resolution: {integrity: sha512-NMp0YsBM40CuI5vWtHpjWOuf96rPfbpGkamlJpVwYvgenIh1ynRzqVnGfsnjofgz13T2qcKkdwJY0Y2X7z+W+w==} dependencies: '@babel/runtime': 7.24.7 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) progress-event: 1.0.0 uuid: 7.0.3 wp-error: 1.3.0 @@ -19931,11 +19918,6 @@ packages: camelcase: 5.3.1 decamelize: 1.2.0 - /yargs-parser@20.2.4: - resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} - engines: {node: '>=10'} - dev: true - /yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} From 838d896cec5227b3e4a36edd1d41d77a6f5e0692 Mon Sep 17 00:00:00 2001 From: Pavel Dohnal Date: Thu, 6 Feb 2025 13:25:10 +0100 Subject: [PATCH 10/18] Update the page capability type MailPoet default pages were created with the default post capability type. This means post navigation links (previous and next) are often found on the default pages, such as the unsubscribe and the manage subscription page. [MAILPOET-6424] --- mailpoet/lib/Settings/Pages.php | 1 + 1 file changed, 1 insertion(+) diff --git a/mailpoet/lib/Settings/Pages.php b/mailpoet/lib/Settings/Pages.php index 7de9787f2e..bb232f3732 100644 --- a/mailpoet/lib/Settings/Pages.php +++ b/mailpoet/lib/Settings/Pages.php @@ -27,6 +27,7 @@ class Pages { 'can_export' => false, 'publicly_queryable' => true, 'exclude_from_search' => true, + 'capability_type' => 'page', ]); } From e9baeadd6e7cae6df28459c9bcb767d42fc637eb Mon Sep 17 00:00:00 2001 From: Pavel Dohnal Date: Thu, 20 Feb 2025 13:13:27 +0100 Subject: [PATCH 11/18] Make sure the navigation links are hidden on all themes [MAILPOET-6424] --- mailpoet/lib/Settings/Pages.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mailpoet/lib/Settings/Pages.php b/mailpoet/lib/Settings/Pages.php index bb232f3732..85780c1084 100644 --- a/mailpoet/lib/Settings/Pages.php +++ b/mailpoet/lib/Settings/Pages.php @@ -29,6 +29,16 @@ class Pages { 'exclude_from_search' => true, 'capability_type' => 'page', ]); + + WPFunctions::get()->addFilter('next_post_link', [$this, 'disableNavigationLinks']); + WPFunctions::get()->addFilter('previous_post_link', [$this, 'disableNavigationLinks']); + } + + public function disableNavigationLinks($output) { + if (is_singular('mailpoet_page')) { + return ''; // Return an empty string to remove navigation links + } + return $output; } public static function createMailPoetPage($postName) { From c05670a8602a4e9477111279ee93f485443e1a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ja=CC=81n=20Mikla=CC=81s=CC=8C?= Date: Fri, 21 Feb 2025 23:31:50 +0100 Subject: [PATCH 12/18] Add additional QIT test commands [MAILPOET-6487] --- mailpoet/RoboFile.php | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/mailpoet/RoboFile.php b/mailpoet/RoboFile.php index 72b787e63d..25a5244502 100644 --- a/mailpoet/RoboFile.php +++ b/mailpoet/RoboFile.php @@ -815,6 +815,47 @@ class RoboFile extends \Robo\Tasks { return $this->_exec('./vendor/bin/qit run:security mailpoet --zip=mailpoet.zip --wait'); } + public function qaQitMalware() { + return $this->_exec('./vendor/bin/qit run:malware mailpoet --zip=mailpoet.zip --wait'); + } + + public function qaQitPhpCompatibility() { + return $this->_exec('./vendor/bin/qit run:phpcompatibility mailpoet --zip=mailpoet.zip --wait'); + } + + public function qaQitActivation($opts = ['wp' => 'stable', 'wc' => 'stable']) { + $command = './vendor/bin/qit run:activation mailpoet --zip=mailpoet.zip --wait'; + if ($opts['wp']) { + $command .= ' --wordpress_version=' . $opts['wp']; + } + if ($opts['wc']) { + $command .= ' --woocommerce_version=' . $opts['wc']; + } + return $this->_exec($command); + } + + public function qaQitWooApi($opts = ['wp' => 'stable', 'wc' => 'stable']) { + $command = './vendor/bin/qit run:woo-api mailpoet --zip=mailpoet.zip --wait'; + if ($opts['wp']) { + $command .= ' --wordpress_version=' . $opts['wp']; + } + if ($opts['wc']) { + $command .= ' --woocommerce_version=' . $opts['wc']; + } + return $this->_exec($command); + } + + public function qaQitWooE2e($opts = ['wp' => 'stable', 'wc' => 'stable']) { + $command = './vendor/bin/qit run:woo-e2e mailpoet --zip=mailpoet.zip --wait'; + if ($opts['wp']) { + $command .= ' --wordpress_version=' . $opts['wp']; + } + if ($opts['wc']) { + $command .= ' --woocommerce_version=' . $opts['wc']; + } + return $this->_exec($command); + } + public function svnCheckout() { $svnDir = ".mp_svn"; From 0e680d50e1e07c06e69a895bfdea82e2ec5fef4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ja=CC=81n=20Mikla=CC=81s=CC=8C?= Date: Sat, 22 Feb 2025 10:29:30 +0100 Subject: [PATCH 13/18] Add QIT workflow to CircleCI --- .circleci/config.yml | 173 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1d35640064..22c5a5b187 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -888,6 +888,146 @@ jobs: - store_artifacts: path: tests/_output + qit_malware_scan: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Malware Scan' + command: ./do qa:qit-malware | tee tests/_output/qit-malware + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-malware | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_php_compatibility: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT PHP Compatibility Check' + command: ./do qa:qit-php-compatibility | tee tests/_output/qit-php-compatibility + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-php-compatibility | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_activation_tests: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Activation Tests' + command: | + LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2) + if [ -z "$LATEST_WC_BETA" ]; then + echo "No WooCommerce Beta version found. Using stable." + ./do qa:qit-activation | tee tests/_output/qit-activation + else + echo "Using WooCommerce Beta Version: $LATEST_WC_BETA" + ./do qa:qit-activation --wc=$LATEST_WC_BETA | tee tests/_output/qit-activation + fi + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-activation | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_woo_api_tests: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Woo API Tests' + command: | + LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2) + if [ -z "$LATEST_WC_BETA" ]; then + echo "No WooCommerce Beta version found. Using stable." + ./do qa:qit-woo-api | tee tests/_output/qit-woo-api + else + echo "Using WooCommerce Beta Version: $LATEST_WC_BETA" + ./do qa:qit-woo-api --wc=$LATEST_WC_BETA | tee tests/_output/qit-woo-api + fi + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-woo-api | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_woo_e2e_tests: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Woo E2E Tests' + no_output_timeout: 1h # Woo E2E tests usually takes ~45m + command: | + LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2) + if [ -z "$LATEST_WC_BETA" ]; then + echo "No WooCommerce Beta version found. Using stable." + ./do qa:qit-woo-e2e | tee tests/_output/qit-woo-e2e + else + echo "Using WooCommerce Beta Version: $LATEST_WC_BETA" + ./do qa:qit-woo-e2e --wc=$LATEST_WC_BETA | tee tests/_output/qit-woo-e2e + fi + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-woo-e2e | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + workflows: build_and_test: jobs: @@ -1209,3 +1349,36 @@ workflows: mysql_image: mysql:5.5 requires: - build_premium + + nightly_qit: + jobs: + - build: + <<: *slack-fail-post-step + - build_release_zip: + <<: *slack-fail-post-step + requires: + - build + - qit_security_scan: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_activation_tests: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_malware_scan: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_php_compatibility: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_woo_api_tests: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_woo_e2e_tests: + <<: *slack-fail-post-step + requires: + - build_release_zip From 1d28e8d7c6b9d32f5ff99f55a5df8c96325d3a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ja=CC=81n=20Mikla=CC=81s=CC=8C?= Date: Sat, 22 Feb 2025 10:31:17 +0100 Subject: [PATCH 14/18] Run QIT workflow weekly (Wednesday at 2am) --- .circleci/config.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 22c5a5b187..815218a5ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1351,6 +1351,13 @@ workflows: - build_premium nightly_qit: + triggers: + - schedule: + cron: '0 2 * * 3' # Every Wednesday at 2am UTC + filters: + branches: + only: + - trunk jobs: - build: <<: *slack-fail-post-step From a3ec922ca522d660d83ce55b235a3417227f0702 Mon Sep 17 00:00:00 2001 From: alex-mpoet Date: Thu, 20 Feb 2025 15:00:47 +0300 Subject: [PATCH 15/18] Add an option to restrict coupon to current subscriber [MAILPOET-6384] --- .../src/newsletter-editor/blocks/coupon.tsx | 5 +++ .../blocks/coupon/usage-restriction.tsx | 22 ++++++++++++ .../newsletter-editor/components/content.js | 3 ++ .../lib/Newsletter/Renderer/Preprocessor.php | 2 +- .../lib/WooCommerce/CouponPreProcessor.php | 34 ++++++++++++++----- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx index b5c81f8d6a..a65f422513 100644 --- a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx +++ b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx @@ -19,6 +19,7 @@ Module.CouponBlockModel = base.BlockModel.extend({ return this._getDefaults( { isStandardEmail: App.getNewsletter().isStandardEmail(), + isAutomationEmail: App.getNewsletter().isAutomationEmail(), productIds: [], // selected product ids, excludedProductIds: [], productCategoryIds: [], // selected categories id @@ -33,6 +34,10 @@ Module.CouponBlockModel = base.BlockModel.extend({ minimumAmount: '', maximumAmount: '', emailRestrictions: '', + restrictToSubscriber: false, + showRestrictToSubscriber: + App.getNewsletter().isAutomationEmail() || + App.getNewsletter().isWelcomeEmail(), styles: { block: { backgroundColor: '#ffffff', diff --git a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx index 650c0a2b61..fee556f060 100644 --- a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx +++ b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx @@ -31,6 +31,7 @@ type State = { productCategoryIds: Post[]; excludedProductCategoryIds: Post[]; emailRestrictions: string; + restrictToSubscriber: boolean; }; class UsageRestriction extends Component { @@ -62,6 +63,8 @@ class UsageRestriction extends Component { 'excludedProductCategoryIds', ).toJSON() as Post[], emailRestrictions: this.getValueCallback('emailRestrictions') as string, + restrictToSubscriber: + (this.getValueCallback('restrictToSubscriber') as boolean) || false, }; } @@ -262,6 +265,25 @@ class UsageRestriction extends Component { )} /> + {this.getValueCallback('showRestrictToSubscriber') && ( + + { + this.setValueCallback( + 'restrictToSubscriber', + restrictToSubscriber, + ); + this.setState({ restrictToSubscriber }); + }} + help={__( + 'Restrict coupon usage to the subscriber receiving this email.', + 'mailpoet', + )} + /> + + )} ); diff --git a/mailpoet/assets/js/src/newsletter-editor/components/content.js b/mailpoet/assets/js/src/newsletter-editor/components/content.js index 0eba43ee87..f79122ed60 100644 --- a/mailpoet/assets/js/src/newsletter-editor/components/content.js +++ b/mailpoet/assets/js/src/newsletter-editor/components/content.js @@ -35,6 +35,9 @@ Module.NewsletterModel = SuperModel.extend({ isStandardEmail: function isStandardEmail() { return this.get('type') === NewsletterType.Standard; }, + isWelcomeEmail: function isWelcomeEmail() { + return this.get('type') === NewsletterType.Welcome; + }, }); // Content block view and model handlers for different content types diff --git a/mailpoet/lib/Newsletter/Renderer/Preprocessor.php b/mailpoet/lib/Newsletter/Renderer/Preprocessor.php index 64c78d782c..e23b68d22f 100644 --- a/mailpoet/lib/Newsletter/Renderer/Preprocessor.php +++ b/mailpoet/lib/Newsletter/Renderer/Preprocessor.php @@ -53,7 +53,7 @@ class Preprocessor { return $content; } $contentBlocks = $content['blocks']; - $contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview); + $contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview, $sendingQueue); $content['blocks'] = $this->processContainer($newsletter, $contentBlocks, $preview, $sendingQueue); return $content; } diff --git a/mailpoet/lib/WooCommerce/CouponPreProcessor.php b/mailpoet/lib/WooCommerce/CouponPreProcessor.php index 119afc61df..e5024b247d 100644 --- a/mailpoet/lib/WooCommerce/CouponPreProcessor.php +++ b/mailpoet/lib/WooCommerce/CouponPreProcessor.php @@ -3,6 +3,7 @@ namespace MailPoet\WooCommerce; use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\SendingQueueEntity; use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Renderer\Blocks\Coupon; use MailPoet\NewsletterProcessingException; @@ -30,12 +31,12 @@ class CouponPreProcessor { /** * @throws NewsletterProcessingException */ - public function processCoupons(NewsletterEntity $newsletter, array $blocks, bool $preview = false): array { + public function processCoupons(NewsletterEntity $newsletter, array $blocks, bool $preview = false, ?SendingQueueEntity $sendingQueue = null): array { if ($preview) { return $blocks; } - $generated = $this->ensureCouponForBlocks($blocks, $newsletter); + $generated = $this->ensureCouponForBlocks($blocks, $newsletter, $sendingQueue); $body = $newsletter->getBody(); if ($generated && $body && $this->shouldPersist($newsletter)) { @@ -54,11 +55,10 @@ class CouponPreProcessor { return $blocks; } - private function ensureCouponForBlocks(array &$blocks, NewsletterEntity $newsletter): bool { - + private function ensureCouponForBlocks(array &$blocks, NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue): bool { foreach ($blocks as &$innerBlock) { if (isset($innerBlock['blocks']) && !empty($innerBlock['blocks'])) { - $this->ensureCouponForBlocks($innerBlock['blocks'], $newsletter); + $this->ensureCouponForBlocks($innerBlock['blocks'], $newsletter, $sendingQueue); } if (isset($innerBlock['type']) && $innerBlock['type'] === Coupon::TYPE) { if (!$this->wcHelper->isWooCommerceActive()) { @@ -66,7 +66,7 @@ class CouponPreProcessor { } if ($this->shouldGenerateCoupon($innerBlock)) { try { - $innerBlock['couponId'] = $this->addOrUpdateCoupon($innerBlock, $newsletter); + $innerBlock['couponId'] = $this->addOrUpdateCoupon($innerBlock, $newsletter, $sendingQueue); $this->generated = true; } catch (\Exception $e) { throw NewsletterProcessingException::create()->withMessage($e->getMessage())->withCode($e->getCode()); @@ -81,10 +81,11 @@ class CouponPreProcessor { /** * @param array $couponBlock * @param NewsletterEntity $newsletter + * @param SendingQueueEntity|null $sendingQueue * @return int * @throws \WC_Data_Exception|\Exception */ - private function addOrUpdateCoupon(array $couponBlock, NewsletterEntity $newsletter) { + private function addOrUpdateCoupon(array $couponBlock, NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue) { $coupon = $this->wcHelper->createWcCoupon($couponBlock['couponId'] ?? ''); if ($this->shouldGenerateCoupon($couponBlock)) { $code = isset($couponBlock['code']) && $couponBlock['code'] !== Coupon::CODE_PLACEHOLDER ? $couponBlock['code'] : $this->generateRandomCode(); @@ -128,7 +129,24 @@ class CouponPreProcessor { $coupon->set_product_categories($this->getItemIds($couponBlock['productCategoryIds'] ?? [])); $coupon->set_excluded_product_categories($this->getItemIds($couponBlock['excludedProductCategoryIds'] ?? [])); - $coupon->set_email_restrictions(explode(',', $couponBlock['emailRestrictions'] ?? '')); + $emailRestrictions = []; + if (!empty($couponBlock['emailRestrictions'])) { + $emailRestrictions = explode(',', $couponBlock['emailRestrictions']); + } + + if (!empty($couponBlock['restrictToSubscriber']) && $sendingQueue && $sendingQueue->getTask()) { + $subscribers = $sendingQueue->getTask()->getSubscribers(); + if (is_iterable($subscribers) && count($subscribers) === 1) { // Only apply to single-subscriber sending queues + foreach ($subscribers as $taskSubscriber) { + $subscriber = $taskSubscriber->getSubscriber(); + if ($subscriber && $subscriber->getEmail()) { + $emailRestrictions[] = $subscriber->getEmail(); + } + } + } + } + + $coupon->set_email_restrictions(array_unique(array_filter($emailRestrictions))); // usage limit $coupon->set_usage_limit($couponBlock['usageLimit'] ?? 0); From e23e4c49741343fb95334e2369fdfdfcde4fca15 Mon Sep 17 00:00:00 2001 From: alex-mpoet Date: Thu, 20 Feb 2025 15:14:28 +0300 Subject: [PATCH 16/18] Add tests [MAILPOET-6384] --- .../WooCommerce/CouponPreProcessorTest.php | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php b/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php index 4789e7f933..547d3f2566 100644 --- a/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php +++ b/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php @@ -5,11 +5,16 @@ namespace unit\WooCommerce; use Codeception\Stub; use Helper\WordPress; use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\ScheduledTaskEntity; +use MailPoet\Entities\ScheduledTaskSubscriberEntity; +use MailPoet\Entities\SendingQueueEntity; +use MailPoet\Entities\SubscriberEntity; use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Renderer\Blocks\Coupon; use MailPoet\NewsletterProcessingException; use MailPoet\WooCommerce\CouponPreProcessor; use MailPoet\WooCommerce\Helper; +use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection; class CouponPreProcessorTest extends \MailPoetUnitTest { @@ -176,6 +181,68 @@ class CouponPreProcessorTest extends \MailPoetUnitTest { $processor->processCoupons($newsletter, $blocks, false); } + public function testItRestrictsCouponToSubscriber(): void { + $subscriberEmail = 'test@example.com'; + $wcCoupon = $this->createCouponMock(); + + $subscriber = $this->make(SubscriberEntity::class, [ + 'getEmail' => $subscriberEmail, + ]); + + $taskSubscriber = $this->make(ScheduledTaskSubscriberEntity::class, [ + 'getSubscriber' => $subscriber, + ]); + + $task = $this->make(ScheduledTaskEntity::class, [ + 'getSubscribers' => new ArrayCollection([$taskSubscriber]), + ]); + + $queue = $this->make(SendingQueueEntity::class, [ + 'getTask' => $task, + ]); + + $wcHelper = $this->make(Helper::class, [ + 'createWcCoupon' => $wcCoupon, + 'isWooCommerceActive' => true, + ]); + + $processor = new CouponPreProcessor( + $wcHelper, + $this->make(NewslettersRepository::class) + ); + + $newsletter = new NewsletterEntity(); + $newsletter->setType(NewsletterEntity::TYPE_AUTOMATION); + $blocks = [ + [ + 'type' => 'any', + 'blocks' => [ + [ + 'type' => Coupon::TYPE, + 'discountType' => 'percent', + 'amount' => '100', + 'restrictToSubscriber' => true, + ], + ], + ], + ]; + $newsletter->setBody(['blocks' => $blocks, 'content' => []]); + + $wcCoupon->expects($this->exactly(2)) + ->method('set_email_restrictions') + ->withConsecutive( + [[$subscriberEmail]], + [['other@example.com', $subscriberEmail]] + ); + + // Test with restrictToSubscriber enabled + $processor->processCoupons($newsletter, $blocks, false, $queue); + + // Test with additional emailRestrictions + $blocks[0]['blocks'][0]['emailRestrictions'] = 'other@example.com'; + $processor->processCoupons($newsletter, $blocks, false, $queue); + } + private function assertWCCouponReceivesCorrectValues($mockedWCCoupon, $expectedCouponId, $expiryDay) { $mockedWCCoupon->method('save')->willReturn($expectedCouponId); From 19abc8963a1757e7cb30a41b309425c001a23b46 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Feb 2025 06:06:56 +0000 Subject: [PATCH 17/18] Update used Automate Woo plugin in Circle CI - latest version: 6.1.7 - previous version: 6.0.33 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 815218a5ed..1bd2fe6a84 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -200,7 +200,7 @@ jobs: ./do download:woo-commerce-zip 9.6.2 ./do download:woo-commerce-subscriptions-zip 7.2.1 ./do download:woo-commerce-memberships-zip 1.26.5 - ./do download:automate-woo-zip 6.1.6 + ./do download:automate-woo-zip 6.1.7 - run: name: Dump tests ENV variables for acceptance tests command: | From 243dcfd6ccbd059ad8ea9c172c069f46fac6d69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ja=CC=81n=20Mikla=CC=81s=CC=8C?= Date: Mon, 24 Feb 2025 20:55:43 +0100 Subject: [PATCH 18/18] Release 5.8.0 --- mailpoet/changelog.txt | 5 +++++ mailpoet/mailpoet.php | 4 ++-- mailpoet/readme.txt | 9 +++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mailpoet/changelog.txt b/mailpoet/changelog.txt index 9cce33698b..e4891e62e9 100644 --- a/mailpoet/changelog.txt +++ b/mailpoet/changelog.txt @@ -1,5 +1,10 @@ == Changelog == += 5.8.0 - 2025-02-24 = +* Added: allow generating coupon code in automations for a subscriber the email is sent to; +* Changed: default MailPoet pages capability changed from post to page (one of improvements is hidden previous/next post links); +* Fixed: Prevent removing the content block from the Newsletter template in the new editor. + = 5.7.1 - 2025-02-17 = * Improved: Apply get_the_excerpt filter to MailPoets post excerpts; * Fixed: conflict with Rank Math plugin breaking "Scheduled Actions" page. diff --git a/mailpoet/mailpoet.php b/mailpoet/mailpoet.php index a79c1094f8..f1ca3e559a 100644 --- a/mailpoet/mailpoet.php +++ b/mailpoet/mailpoet.php @@ -2,7 +2,7 @@ /* * Plugin Name: MailPoet - * Version: 5.7.1 + * Version: 5.8.0 * Plugin URI: https://www.mailpoet.com * Description: Create and send newsletters, post notifications and welcome emails from your WordPress. * Author: MailPoet @@ -20,7 +20,7 @@ */ $mailpoetPlugin = [ - 'version' => '5.7.1', + 'version' => '5.8.0', 'filename' => __FILE__, 'path' => dirname(__FILE__), 'autoloader' => dirname(__FILE__) . '/vendor/autoload.php', diff --git a/mailpoet/readme.txt b/mailpoet/readme.txt index df219339f9..cafab78db6 100644 --- a/mailpoet/readme.txt +++ b/mailpoet/readme.txt @@ -3,7 +3,7 @@ Contributors: mailpoet, woocommerce, automattic Tags: email marketing, post notification, woocommerce emails, email automation, newsletter Requires at least: 6.6 Tested up to: 6.7 -Stable tag: 5.7.1 +Stable tag: 5.8.0 Requires PHP: 7.4 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -222,8 +222,9 @@ Check our [Knowledge Base](https://kb.mailpoet.com) or contact us through our [s == Changelog == -= 5.7.1 - 2025-02-17 = -* Improved: Apply get_the_excerpt filter to MailPoets post excerpts; -* Fixed: conflict with Rank Math plugin breaking "Scheduled Actions" page. += 5.8.0 - 2025-02-24 = +* Added: allow generating coupon code in automations for a subscriber the email is sent to; +* Changed: default MailPoet pages capability changed from post to page (one of improvements is hidden previous/next post links); +* Fixed: Prevent removing the content block from the Newsletter template in the new editor. [See the changelog for all versions.](https://github.com/mailpoet/mailpoet/blob/trunk/mailpoet/changelog.txt)