Compare commits
24 Commits
update-plu
...
5.7.0-pira
Author | SHA1 | Date | |
---|---|---|---|
f5a4a300af | |||
d2723938aa | |||
25262cff80 | |||
c31795cd4d | |||
73d410eb86 | |||
b8a25410d4 | |||
85e067e7dc | |||
4afd82778a | |||
84c95293e0 | |||
f96e74cf96 | |||
ee513fd871 | |||
2adc6d23ca | |||
5023bbb6f2 | |||
b16071ee0e | |||
e5498b6baf | |||
9ad79e75b5 | |||
aa17e90365 | |||
4b917dd1b3 | |||
7c425cb04d | |||
43990d9e8b | |||
8024708c1d | |||
95a750365b | |||
2cee607749 | |||
9c9193eeed |
71
.github/workflows/codeql-analysis.yml
vendored
71
.github/workflows/codeql-analysis.yml
vendored
@ -1,71 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
name: 'CodeQL'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [trunk]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [trunk]
|
||||
schedule:
|
||||
- cron: '0 17 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['javascript']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
212
.github/workflows/email-editor-package.yml
vendored
212
.github/workflows/email-editor-package.yml
vendored
@ -1,212 +0,0 @@
|
||||
name: Email Editor Package Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.4', '8.2']
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache Composer vendor dependencies for MailPoet
|
||||
id: composer-mailpoet-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('mailpoet/composer.lock') }}-${{ hashFiles('mailpoet/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor-prefixed dependencies for MailPoet
|
||||
id: vendor-prefixed-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor-prefixed
|
||||
key: ${{ runner.os }}-vendor-prefixed-${{ matrix.php-version }}-${{ hashFiles('mailpoet/prefixer/composer.lock') }}-${{ hashFiles('mailpoet/prefixer/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor for test environment
|
||||
id: composer-tests-env-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tests_env/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('tests_env/composer.lock') }}-${{ hashFiles('tests_env/composer.json') }}
|
||||
|
||||
- name: Cache Composer dependencies for Email Editor
|
||||
id: composer-email-editor-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: packages/php/email-editor/vendor
|
||||
key: ${{ runner.os }}-composer-email-editor-${{ matrix.php-version }}-${{ hashFiles('packages/php/email-editor/composer.lock') }}-${{ hashFiles('packages/php/email-editor/composer.json') }}
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
extensions: gd
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
COMPOSER_DEV_MODE=1 php tools/install.php
|
||||
touch .env
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Test Environment dependencies only if the cache was not hit
|
||||
- name: Install test environment dependencies
|
||||
if: steps.composer-tests-env-cache.outputs.cache-hit != 'true'
|
||||
run: ../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: tests_env
|
||||
|
||||
# Install MailPoet dependencies only if the cache was not hit
|
||||
- name: Install mailpoet dependencies
|
||||
if: |
|
||||
steps.composer-mailpoet-cache.outputs.cache-hit != 'true' || steps.vendor-prefixed-cache.outputs.cache-hit != 'true'
|
||||
run: ./tools/vendor/composer.phar install
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Email Editor dependencies only if the cache was not hit
|
||||
- name: Install email-editor dependencies
|
||||
if: steps.composer-email-editor-cache.outputs.cache-hit != 'true'
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
# Dump Email Editor autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump email-editor autoload
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar dump-autoload
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
# Dump MailPoet autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump MailPoet autoload
|
||||
run: ./tools/vendor/composer.phar dump-autoload
|
||||
working-directory: mailpoet
|
||||
|
||||
# Run Email Editor unit tests
|
||||
- name: Run email-editor package unit tests
|
||||
run: ../../../tests_env/vendor/bin/codecept build && ../../../mailpoet/tools/vendor/composer.phar unit-test
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
- name: Run email-editor package integration tests
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar integration-test
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
code-style:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.2'
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
COMPOSER_DEV_MODE=1 php tools/install.php
|
||||
touch .env
|
||||
working-directory: mailpoet
|
||||
|
||||
- name: Install composer dependencies
|
||||
run: ../../tools/vendor/composer.phar install
|
||||
working-directory: mailpoet/tasks/code_sniffer
|
||||
|
||||
- name: Run code style check
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar code-style
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
phpstan-static-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.4', '8.2']
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache Composer vendor dependencies for MailPoet
|
||||
id: composer-mailpoet-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('mailpoet/composer.lock') }}-${{ hashFiles('mailpoet/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor-prefixed dependencies for MailPoet
|
||||
id: vendor-prefixed-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mailpoet/vendor-prefixed
|
||||
key: ${{ runner.os }}-vendor-prefixed-${{ matrix.php-version }}-${{ hashFiles('mailpoet/prefixer/composer.lock') }}-${{ hashFiles('mailpoet/prefixer/composer.json') }}
|
||||
|
||||
- name: Cache Composer vendor for test environment
|
||||
id: composer-tests-env-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tests_env/vendor
|
||||
key: ${{ runner.os }}-composer-mailpoet-${{ matrix.php-version }}-${{ hashFiles('tests_env/composer.lock') }}-${{ hashFiles('tests_env/composer.json') }}
|
||||
|
||||
- name: Cache Composer dependencies for Email Editor
|
||||
id: composer-email-editor-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: packages/php/email-editor/vendor
|
||||
key: ${{ runner.os }}-composer-email-editor-${{ matrix.php-version }}-${{ hashFiles('packages/php/email-editor/composer.lock') }}-${{ hashFiles('packages/php/email-editor/composer.json') }}
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
extensions: gd
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
COMPOSER_DEV_MODE=1 php tools/install.php
|
||||
touch .env
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Test Environment dependencies only if the cache was not hit
|
||||
- name: Install test environment dependencies
|
||||
if: steps.composer-tests-env-cache.outputs.cache-hit != 'true'
|
||||
run: ../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: tests_env
|
||||
|
||||
# Install MailPoet dependencies only if the cache was not hit
|
||||
- name: Install mailpoet dependencies
|
||||
if: |
|
||||
steps.composer-mailpoet-cache.outputs.cache-hit != 'true' || steps.vendor-prefixed-cache.outputs.cache-hit != 'true'
|
||||
run: ./tools/vendor/composer.phar install
|
||||
working-directory: mailpoet
|
||||
|
||||
# Install Email Editor dependencies only if the cache was not hit
|
||||
- name: Install email-editor dependencies
|
||||
if: steps.composer-email-editor-cache.outputs.cache-hit != 'true'
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar install
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
- name: Install composer dependencies
|
||||
run: ../../tools/vendor/composer.phar install
|
||||
working-directory: mailpoet/tasks/phpstan
|
||||
|
||||
# Dump Email Editor autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump email-editor autoload
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar dump-autoload
|
||||
working-directory: packages/php/email-editor
|
||||
|
||||
# Dump MailPoet autoload
|
||||
# This is needed to refresh classmap autoload when the composer cache is hit
|
||||
- name: Dump MailPoet autoload
|
||||
run: ./tools/vendor/composer.phar dump-autoload
|
||||
working-directory: mailpoet
|
||||
|
||||
- name: Run code phpstan
|
||||
run: ../../../mailpoet/tools/vendor/composer.phar phpstan -- --php-version=${{ matrix.php-version == '7.4' && '70400' || '80200' }}
|
||||
working-directory: packages/php/email-editor
|
48
.github/workflows/release.yml
vendored
Normal file
48
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
name: Make release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*' # Trigger on any tag push
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Pre-reqs
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y php php-symfony composer php-cli php-gd php-mysql golang
|
||||
|
||||
- name: Prepare for build
|
||||
run: |
|
||||
cd mailpoet || { echo "Directory 'mailpoet' not found"; exit 1; }
|
||||
cp .env.sample .env
|
||||
|
||||
- name: Update Composer dependencies
|
||||
run: |
|
||||
composer update
|
||||
|
||||
- name: Install pnpm globally
|
||||
run: |
|
||||
npm install -g pnpm
|
||||
|
||||
- name: Run the build script
|
||||
run: |
|
||||
sh build.sh
|
||||
|
||||
- name: Move built zip file
|
||||
run: |
|
||||
mkdir -p ../output
|
||||
mv mailpoet.zip ../output
|
||||
|
||||
- name: Upload Release
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: |-
|
||||
output/mailpoet.zip
|
||||
api_key: '${{secrets.RELEASE_SMITH_TOKEN}}'
|
182
.github/workflows/update-wordpress-and-plugins.yml
vendored
182
.github/workflows/update-wordpress-and-plugins.yml
vendored
@ -1,182 +0,0 @@
|
||||
name: Check new versions of plugins and WordPress
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 6 * * 1' # At 06:00 on Monday
|
||||
workflow_dispatch: # Allows manual triggering
|
||||
|
||||
jobs:
|
||||
check-versions:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.3' # Specify the PHP version you want to use
|
||||
|
||||
# Updating used WordPress
|
||||
- name: Check WordPress Docker Versions
|
||||
run: php .github/workflows/scripts/check_wordpress_versions.php
|
||||
|
||||
- name: Check for WordPress changes
|
||||
id: check_wp_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "WORDPRESS_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WordPress versions from files
|
||||
id: get_wp_versions
|
||||
run: |
|
||||
echo "WORDPRESS_LATEST_VERSION=$(cat /tmp/latest_wordpress_version.txt)" >> $GITHUB_ENV
|
||||
echo "WORDPRESS_PREVIOUS_VERSION=$(cat /tmp/previous_wordpress_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WordPress changes
|
||||
if: env.WORDPRESS_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WordPress images in Circle CI\n\n - latest version: ${{ env.WORDPRESS_LATEST_VERSION }}\n - previous version: ${{ env.WORDPRESS_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used WooCommerce plugin
|
||||
- name: Check WooCommerce Versions
|
||||
run: php .github/workflows/scripts/check_woocommerce_versions.php
|
||||
|
||||
- name: Check for WooCommerce changes
|
||||
id: check_wc_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WooCommerce versions from files
|
||||
id: get_wc_versions
|
||||
run: |
|
||||
echo "WOOCOMMERCE_LATEST_VERSION=$(cat /tmp/latest_woocommerce_version.txt)" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_PREVIOUS_VERSION=$(cat /tmp/previous_woocommerce_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WooCommerce changes
|
||||
if: env.WOOCOMMERCE_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WooCommerce plugin in Circle CI\n\n - latest version: ${{ env.WOOCOMMERCE_LATEST_VERSION }}\n - previous version: ${{ env.WOOCOMMERCE_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used Automate Woo plugin
|
||||
- name: Check Automate Woo Versions
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
run: php .github/workflows/scripts/check_automate_woo_versions.php
|
||||
|
||||
- name: Check for Automate Woo changes
|
||||
id: check_aw_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "AUTOMATE_WOO_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get Automate Woo versions from files
|
||||
id: get_aw_versions
|
||||
run: |
|
||||
echo "AUTOMATE_WOO_LATEST_VERSION=$(cat /tmp/latest_automate_woo_version.txt)" >> $GITHUB_ENV
|
||||
echo "AUTOMATE_WOO_PREVIOUS_VERSION=$(cat /tmp/previous_automate_woo_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit Automate Woo changes
|
||||
if: env.AUTOMATE_WOO_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used Automate Woo plugin in Circle CI\n\n - latest version: ${{ env.AUTOMATE_WOO_LATEST_VERSION }}\n - previous version: ${{ env.AUTOMATE_WOO_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used WooCommerce Subscriptions plugin
|
||||
- name: Check WooCommerce Subscriptions Versions
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
run: php .github/workflows/scripts/check_woocommerce_subscriptions_versions.php
|
||||
|
||||
- name: Check for WooCommerce Subscriptions changes
|
||||
id: check_ws_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "SUBSCRIPTIONS_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WooCommerce Subscriptions versions from files
|
||||
id: get_ws_versions
|
||||
run: |
|
||||
echo "WOOCOMMERCE_SUBSCRIPTIONS_LATEST_VERSION=$(cat /tmp/latest_woocommerce_subscriptions_version.txt)" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_SUBSCRIPTIONS_PREVIOUS_VERSION=$(cat /tmp/previous_woocommerce_subscriptions_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WooCommerce Subscriptions changes
|
||||
if: env.SUBSCRIPTIONS_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WooCommerce Subscriptions plugin in Circle CI\n\n - latest version: ${{ env.WOOCOMMERCE_SUBSCRIPTIONS_LATEST_VERSION }}\n - previous version: ${{ env.WOOCOMMERCE_SUBSCRIPTIONS_PREVIOUS_VERSION }}'
|
||||
|
||||
# Updating used WooCommerce Memberships plugin
|
||||
- name: Check WooCommerce Memberships Versions
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
run: php .github/workflows/scripts/check_woocommerce_memberships_versions.php
|
||||
|
||||
- name: Check for WooCommerce Memberships changes
|
||||
id: check_wm_changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
if [ "$(git status --porcelain)" != "" ]; then
|
||||
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
echo "MEMBERSHIPS_CHANGES=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Get WooCommerce Memberships versions from files
|
||||
id: get_wm_versions
|
||||
run: |
|
||||
echo "WOOCOMMERCE_MEMBERSHIPS_LATEST_VERSION=$(cat /tmp/latest_woocommerce_memberships_version.txt)" >> $GITHUB_ENV
|
||||
echo "WOOCOMMERCE_MEMBERSHIPS_PREVIOUS_VERSION=$(cat /tmp/previous_woocommerce_memberships_version.txt)" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit WooCommerce Memberships changes
|
||||
if: env.MEMBERSHIPS_CHANGES == 'true'
|
||||
run: |
|
||||
git add .
|
||||
git commit -m $'Update used WooCommerce Memberships plugin in Circle CI\n\n - latest version: ${{ env.WOOCOMMERCE_MEMBERSHIPS_LATEST_VERSION }}\n - previous version: ${{ env.WOOCOMMERCE_MEMBERSHIPS_PREVIOUS_VERSION }}'
|
||||
|
||||
# Push all changes at the end if any changes were detected
|
||||
#
|
||||
# For local testing with act tool add following:
|
||||
# env:
|
||||
# GH_PAT: ${{ secrets.GH_TOKEN }}
|
||||
# run: |
|
||||
# git remote set-url origin https://${GH_PAT}@github.com/mailpoet/mailpoet
|
||||
# git push -f origin HEAD:refs/heads/update-plugins-and-wordpress-test
|
||||
- name: Push changes
|
||||
if: env.CHANGES_DETECTED == 'true'
|
||||
run: |
|
||||
git push -f origin HEAD:refs/heads/update-plugins-and-wordpress
|
||||
|
||||
# Create a pull request if there are changes
|
||||
- name: Create Pull Request
|
||||
if: env.CHANGES_DETECTED == 'true'
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
branch: update-plugins-and-wordpress
|
||||
title: Update WordPress and plugins in CI jobs
|
||||
base: trunk
|
||||
labels: automated, check-versions
|
||||
body: |
|
||||
1. If all checks passed, you can merge this PR.
|
||||
2. If the build failed, please investigate the failure and either address the issues or delegate the job. Then, make sure these changes are merged.
|
@ -1,27 +0,0 @@
|
||||
name: Add link to WordPress Playground preview
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
add-wp-playground-link:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check and append description
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
PR_NUMBER="${{ github.event.pull_request.number }}"
|
||||
BRANCH_NAME="${{ github.head_ref }}"
|
||||
DESCRIPTION="$(gh pr view $PR_NUMBER --json body -q .body)"
|
||||
HEADING="## Preview"
|
||||
CONTENT="$(printf "${HEADING}\n\n[Preview in WordPress Playground](https://account.mailpoet.com/playground/new/branch:${BRANCH_NAME})\n\n_The latest successful build from \`${BRANCH_NAME}\` will be used. If none is available, the link won't work._")"
|
||||
|
||||
if [[ "$DESCRIPTION" != *"$HEADING"* ]]; then
|
||||
gh pr edit $PR_NUMBER --body "$(printf "${DESCRIPTION}\n\n${CONTENT}")"
|
||||
fi
|
@ -1,30 +0,0 @@
|
||||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
settings:
|
||||
depth: 1
|
||||
|
||||
steps:
|
||||
build:
|
||||
image: node:current-bookworm-slim
|
||||
commands:
|
||||
- apt update
|
||||
- apt install php php-symfony bash -y
|
||||
- npm install pnpm
|
||||
- cd mailpoet
|
||||
- bash build.sh
|
||||
- mkdir ../output
|
||||
- mv mailpoet.zip ../output
|
||||
- cd ..
|
||||
|
||||
release:
|
||||
image: woodpeckerci/plugin-gitea-release:latest
|
||||
settings:
|
||||
base_url: https://git.cavemanon.xyz
|
||||
api_key:
|
||||
from_secret: releasesmithapikey
|
||||
files: "output/"
|
||||
prerelease: false
|
||||
title: "${CI_COMMIT_TAG}"
|
||||
when:
|
||||
- event: tag
|
@ -0,0 +1,142 @@
|
||||
import { ExternalLink } from '@wordpress/components';
|
||||
import { select, dispatch } from '@wordpress/data';
|
||||
import { store as coreDataStore, useEntityProp } from '@wordpress/core-data';
|
||||
import { store as editorStore } from '@wordpress/editor';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createInterpolateElement } from '@wordpress/element';
|
||||
import classnames from 'classnames';
|
||||
|
||||
const previewTextMaxLength = 150;
|
||||
const previewTextRecommendedLength = 80;
|
||||
|
||||
export function EmailSidebarExtensionBody({ RichTextWithButton }) {
|
||||
const [mailpoetEmailData] = useEntityProp(
|
||||
'postType',
|
||||
'mailpoet_email',
|
||||
'mailpoet_data',
|
||||
);
|
||||
|
||||
const updateEmailMailPoetProperty = (name: string, value: string) => {
|
||||
const postId = select(editorStore).getCurrentPostId();
|
||||
const currentPostType = 'mailpoet_email'; // only for mailpoet_email post-type
|
||||
|
||||
const editedPost = select(coreDataStore).getEditedEntityRecord(
|
||||
'postType',
|
||||
currentPostType,
|
||||
postId,
|
||||
);
|
||||
|
||||
// @ts-expect-error Property 'mailpoet_data' does not exist on type 'Updatable<Attachment<any>>'.
|
||||
const mailpoetData = editedPost?.mailpoet_data || {};
|
||||
void dispatch(coreDataStore).editEntityRecord(
|
||||
'postType',
|
||||
currentPostType,
|
||||
postId,
|
||||
{
|
||||
mailpoet_data: {
|
||||
...mailpoetData,
|
||||
[name]: value,
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const subjectHelp = createInterpolateElement(
|
||||
__(
|
||||
'Use personalization tags to personalize your email, or learn more about <bestPracticeLink>best practices</bestPracticeLink> and using <emojiLink>emoji in subject lines</emojiLink>.',
|
||||
'mailpoet',
|
||||
),
|
||||
{
|
||||
bestPracticeLink: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href="https://www.mailpoet.com/blog/17-email-subject-line-best-practices-to-boost-engagement/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
emojiLink: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href="https://www.mailpoet.com/blog/tips-using-emojis-in-subject-lines/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
const previewTextLength = mailpoetEmailData?.preheader?.length ?? 0;
|
||||
|
||||
const preheaderHelp = createInterpolateElement(
|
||||
__(
|
||||
'<link>This text</link> will appear in the inbox, underneath the subject line.',
|
||||
'mailpoet',
|
||||
),
|
||||
{
|
||||
link: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href={new URL(
|
||||
'article/418-preview-text',
|
||||
'https://kb.mailpoet.com/',
|
||||
).toString()}
|
||||
key="preview-text-kb"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<RichTextWithButton
|
||||
attributeName="subject"
|
||||
attributeValue={mailpoetEmailData?.subject}
|
||||
updateProperty={updateEmailMailPoetProperty}
|
||||
label={__('Subject', 'mailpoet')}
|
||||
labelSuffix={
|
||||
<ExternalLink href="https://kb.mailpoet.com/article/435-a-guide-to-personalisation-tags-for-tailored-newsletters#list">
|
||||
{__('Guide', 'mailpoet')}
|
||||
</ExternalLink>
|
||||
}
|
||||
help={subjectHelp}
|
||||
placeholder={__('Eg. The summer sale is here!', 'mailpoet')}
|
||||
/>
|
||||
|
||||
<br />
|
||||
|
||||
<RichTextWithButton
|
||||
attributeName="preheader"
|
||||
attributeValue={mailpoetEmailData?.preheader}
|
||||
updateProperty={updateEmailMailPoetProperty}
|
||||
label={__('Preview text', 'mailpoet')}
|
||||
labelSuffix={
|
||||
<span
|
||||
className={classnames(
|
||||
'mailpoet-settings-panel__preview-text-length',
|
||||
{
|
||||
'mailpoet-settings-panel__preview-text-length-warning':
|
||||
previewTextLength > previewTextRecommendedLength,
|
||||
'mailpoet-settings-panel__preview-text-length-error':
|
||||
previewTextLength > previewTextMaxLength,
|
||||
},
|
||||
)}
|
||||
>
|
||||
{previewTextLength}/{previewTextMaxLength}
|
||||
</span>
|
||||
}
|
||||
help={preheaderHelp}
|
||||
placeholder={__(
|
||||
"Add a preview text to capture subscribers' attention and increase open rates.",
|
||||
'mailpoet',
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function EmailSidebarExtension(RichTextWithButton: JSX.Element) {
|
||||
return <EmailSidebarExtensionBody RichTextWithButton={RichTextWithButton} />;
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
import { addFilter, addAction } from '@wordpress/hooks';
|
||||
import { MailPoet } from 'mailpoet';
|
||||
import { withSatismeterSurvey } from './satismeter-survey';
|
||||
import { EmailSidebarExtension } from './email-sidebar-extension';
|
||||
import './index.scss';
|
||||
import { useValidationRules } from './validate-email-content';
|
||||
|
||||
@ -12,10 +13,12 @@ addFilter('mailpoet_email_editor_wrap_editor_component', 'mailpoet', (editor) =>
|
||||
withSatismeterSurvey(editor),
|
||||
);
|
||||
|
||||
// validate email editor content using the defined validation rules
|
||||
// content is first validated when the "Send" button is clicked and revalidated on "Save Draft"
|
||||
addFilter(
|
||||
'mailpoet_email_editor_content_validation_rules',
|
||||
'mailpoet',
|
||||
(validationRules: []) => [...validationRules, ...useValidationRules()],
|
||||
() => useValidationRules(), // returns a memorized set of rules (array of rules)
|
||||
);
|
||||
|
||||
const EVENTS_TO_TRACK = [
|
||||
@ -53,3 +56,22 @@ addFilter(
|
||||
'mailpoet',
|
||||
() => !!window.mailpoet_analytics_enabled,
|
||||
);
|
||||
|
||||
// integration point for settings sidebar
|
||||
addFilter(
|
||||
'mailpoet_email_editor_setting_sidebar_extension_component',
|
||||
'mailpoet',
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
(RichTextWithButton) => EmailSidebarExtension.bind(null, RichTextWithButton),
|
||||
);
|
||||
|
||||
// use mailpoet data subject if available
|
||||
addFilter(
|
||||
'mailpoet_email_editor_preferred_template_title',
|
||||
'mailpoet',
|
||||
(...args) => {
|
||||
const [, post] = args;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return post?.mailpoet_data?.subject || ''; // use MailPoet subject as title
|
||||
},
|
||||
);
|
||||
|
@ -64,12 +64,14 @@ export function useValidationRules() {
|
||||
label: __('Insert link', 'mailpoet'),
|
||||
onClick: () => {
|
||||
if (!hasFooter) {
|
||||
// update the email content
|
||||
void dispatch(blockEditorStore).insertBlock(
|
||||
linksParagraphBlock,
|
||||
undefined,
|
||||
contentBlockId,
|
||||
);
|
||||
} else {
|
||||
// update the template
|
||||
void dispatch(coreDataStore).editEntityRecord(
|
||||
'postType',
|
||||
'wp_template',
|
||||
|
@ -57,17 +57,17 @@ echo '[BUILD] Fetching prefixed production libraries'
|
||||
|
||||
# Remove Doctrinne Annotations (no need since generated metadata are packed)
|
||||
# Should be removed before `dump-autoload` to not include the annotations classes on the autoloader.
|
||||
rm -rf vendor-prefixed/doctrine/annotations
|
||||
#rm -rf vendor-prefixed/doctrine/annotations
|
||||
|
||||
# Remove DI Container files used for container dump (no need since generated metadata are packed)
|
||||
# Should be removed before `dump-autoload` to not include these classes in the autoloader.
|
||||
echo '[BUILD] Removing DI Container development dependencies'
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Compiler
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Config
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Dumper
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Loader
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/LazyProxy
|
||||
rm -rf vendor-prefixed/symfony/dependency-injection/Extension
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Compiler
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Config
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Dumper
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Loader
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/LazyProxy
|
||||
#rm -rf vendor-prefixed/symfony/dependency-injection/Extension
|
||||
|
||||
./tools/vendor/composer.phar dump-autoload
|
||||
|
||||
|
@ -35,7 +35,7 @@ class EmailEditorPreviewEmail {
|
||||
}
|
||||
|
||||
private function validateData($data) {
|
||||
if (empty($data['email']) || empty($data['postId']) || empty($data['newsletterId'])) {
|
||||
if (empty($data['email']) || empty($data['postId'])) {
|
||||
throw new \InvalidArgumentException(esc_html__('Missing required data', 'mailpoet'));
|
||||
}
|
||||
|
||||
@ -50,9 +50,9 @@ class EmailEditorPreviewEmail {
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function fetchNewsletter($postData): NewsletterEntity {
|
||||
$newsletter = $this->newslettersRepository->findOneById((int)$postData['newsletterId']);
|
||||
$newsletter = $this->newslettersRepository->findOneBy(['wpPost' => (int)$postData['postId']]);
|
||||
|
||||
if (!$newsletter) {
|
||||
if (!$newsletter instanceof NewsletterEntity) {
|
||||
throw new \Exception(esc_html__('This email does not exist.', 'mailpoet'));
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,8 @@ class CreateAndSendEmailUsingGutenbergCest {
|
||||
$i->click('Save Draft');
|
||||
$i->waitForText('Saved');
|
||||
$i->waitForText('Email saved!');
|
||||
$i->click('Send');
|
||||
$i->click('[aria-label="Close sidebar"]'); // close the sidebar. It sometimes interferes with the send button click
|
||||
$i->click('[data-automation-id="email_editor_send_button"]');
|
||||
$i->waitForElement('[name="subject"]');
|
||||
$subject = $i->grabValueFrom('[name="subject"]');
|
||||
verify($subject)->equals('My New Subject');
|
||||
|
@ -35,8 +35,7 @@ export function MoreMenu(): JSX.Element {
|
||||
editorCurrentPostType,
|
||||
'status'
|
||||
);
|
||||
const { saveEditedEmail, updateEmailMailPoetProperty } =
|
||||
useDispatch( storeName );
|
||||
const { saveEditedEmail } = useDispatch( storeName );
|
||||
const goToListings = () => {
|
||||
window.location.href = urls.listings;
|
||||
};
|
||||
@ -132,10 +131,6 @@ export function MoreMenu(): JSX.Element {
|
||||
<MenuItem
|
||||
onClick={ async () => {
|
||||
await setStatus( 'draft' );
|
||||
await updateEmailMailPoetProperty(
|
||||
'deleted_at',
|
||||
''
|
||||
);
|
||||
await saveEditedEmail();
|
||||
recordEvent(
|
||||
'header_more_menu_restore_from_trash_button_clicked'
|
||||
|
@ -63,6 +63,7 @@ export function SendButton( { validateContent, isContentInvalid } ) {
|
||||
}
|
||||
} }
|
||||
disabled={ isDisabled }
|
||||
data-automation-id="email_editor_send_button"
|
||||
>
|
||||
{ label }
|
||||
</Button>
|
||||
|
@ -18,7 +18,7 @@ type Replacement = {
|
||||
function getChildElement( rootElement: HTMLElement ): HTMLElement | null {
|
||||
let currentElement: HTMLElement | null = rootElement;
|
||||
|
||||
while ( currentElement && currentElement.children.length > 0 ) {
|
||||
while ( currentElement && currentElement?.children?.length > 0 ) {
|
||||
// Traverse into the first child element
|
||||
currentElement = currentElement.children[ 0 ] as HTMLElement;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { ReactNode } from 'react';
|
||||
import { BaseControl, Button } from '@wordpress/components';
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { useCallback, useRef, useState } from '@wordpress/element';
|
||||
import { useEntityProp } from '@wordpress/core-data';
|
||||
import { create, insert, toHTMLString } from '@wordpress/rich-text';
|
||||
import { RichText } from '@wordpress/block-editor';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
@ -17,25 +17,32 @@ import {
|
||||
getCursorPosition,
|
||||
replacePersonalizationTagsWithHTMLComments,
|
||||
} from './rich-text-utils';
|
||||
import { storeName, editorCurrentPostType } from '../../store';
|
||||
import { storeName } from '../../store';
|
||||
import { PersonalizationTagsPopover } from './personalization-tags-popover';
|
||||
import { recordEvent, recordEventOnce } from '../../events';
|
||||
|
||||
type Props = {
|
||||
label: string;
|
||||
labelSuffix?: ReactNode;
|
||||
help?: ReactNode;
|
||||
placeholder: string;
|
||||
attributeName: string;
|
||||
attributeValue?: string;
|
||||
updateProperty: (
|
||||
theAttributeName: string,
|
||||
theUpdatedValue: string
|
||||
) => void;
|
||||
};
|
||||
|
||||
export function RichTextWithButton( {
|
||||
label,
|
||||
labelSuffix,
|
||||
help,
|
||||
placeholder,
|
||||
attributeName,
|
||||
} ) {
|
||||
const [ mailpoetEmailData ] = useEntityProp(
|
||||
'postType',
|
||||
editorCurrentPostType,
|
||||
'mailpoet_data'
|
||||
);
|
||||
|
||||
const { updateEmailMailPoetProperty } = useDispatch( storeName );
|
||||
|
||||
attributeValue,
|
||||
updateProperty = () => {},
|
||||
}: Props ) {
|
||||
const [ selectionRange, setSelectionRange ] = useState( null );
|
||||
const [ isModalOpened, setIsModalOpened ] = useState( false );
|
||||
const list = useSelect(
|
||||
@ -61,11 +68,11 @@ export function RichTextWithButton( {
|
||||
const updatedValue = toHTMLString( { value: richTextValue } );
|
||||
|
||||
// Update the corresponding property
|
||||
updateEmailMailPoetProperty( attributeName, updatedValue );
|
||||
updateProperty( attributeName, updatedValue );
|
||||
|
||||
setSelectionRange( null );
|
||||
},
|
||||
[ attributeName, updateEmailMailPoetProperty ]
|
||||
[ attributeName, updateProperty ]
|
||||
);
|
||||
|
||||
const finalLabel = (
|
||||
@ -90,13 +97,13 @@ export function RichTextWithButton( {
|
||||
</>
|
||||
);
|
||||
|
||||
if ( ! mailpoetEmailData ) {
|
||||
if ( ! attributeName ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseControl
|
||||
id={ `mailpoet-settings-panel__${ attributeName }` }
|
||||
id="" // See https://github.com/mailpoet/mailpoet/pull/6089#discussion_r1952126850 to understand why the ID is empty
|
||||
label={ finalLabel }
|
||||
className={ `mailpoet-settings-panel__${ attributeName }-text` }
|
||||
help={ help }
|
||||
@ -107,7 +114,7 @@ export function RichTextWithButton( {
|
||||
onInsert={ ( value ) => {
|
||||
handleInsertPersonalizationTag(
|
||||
value,
|
||||
mailpoetEmailData[ attributeName ] ?? '',
|
||||
attributeValue ?? '',
|
||||
selectionRange
|
||||
);
|
||||
setIsModalOpened( false );
|
||||
@ -125,17 +132,13 @@ export function RichTextWithButton( {
|
||||
<PersonalizationTagsPopover
|
||||
contentRef={ richTextRef }
|
||||
onUpdate={ ( originalTag, updatedTag ) => {
|
||||
const currentValue =
|
||||
mailpoetEmailData[ attributeName ] ?? '';
|
||||
const currentValue = attributeValue ?? '';
|
||||
// When we update the tag, we need to add brackets to the tag, because the popover removes them
|
||||
const updatedContent = currentValue.replace(
|
||||
`<!--[${ originalTag }]-->`,
|
||||
`<!--[${ updatedTag }]-->`
|
||||
);
|
||||
updateEmailMailPoetProperty(
|
||||
attributeName,
|
||||
updatedContent
|
||||
);
|
||||
updateProperty( attributeName, updatedContent );
|
||||
} }
|
||||
/>
|
||||
<RichText
|
||||
@ -144,26 +147,17 @@ export function RichTextWithButton( {
|
||||
placeholder={ placeholder }
|
||||
onFocus={ () => {
|
||||
setSelectionRange(
|
||||
getCursorPosition(
|
||||
richTextRef,
|
||||
mailpoetEmailData[ attributeName ] ?? ''
|
||||
)
|
||||
getCursorPosition( richTextRef, attributeValue ?? '' )
|
||||
);
|
||||
} }
|
||||
onKeyUp={ () => {
|
||||
setSelectionRange(
|
||||
getCursorPosition(
|
||||
richTextRef,
|
||||
mailpoetEmailData[ attributeName ] ?? ''
|
||||
)
|
||||
getCursorPosition( richTextRef, attributeValue ?? '' )
|
||||
);
|
||||
} }
|
||||
onClick={ () => {
|
||||
setSelectionRange(
|
||||
getCursorPosition(
|
||||
richTextRef,
|
||||
mailpoetEmailData[ attributeName ] ?? ''
|
||||
)
|
||||
getCursorPosition( richTextRef, attributeValue ?? '' )
|
||||
);
|
||||
} }
|
||||
onChange={ ( value ) => {
|
||||
@ -171,7 +165,7 @@ export function RichTextWithButton( {
|
||||
value ?? '',
|
||||
list
|
||||
);
|
||||
updateEmailMailPoetProperty( attributeName, value );
|
||||
updateProperty( attributeName, value );
|
||||
recordEventOnce(
|
||||
'rich_text_with_button_input_field_updated',
|
||||
{
|
||||
@ -179,7 +173,7 @@ export function RichTextWithButton( {
|
||||
}
|
||||
);
|
||||
} }
|
||||
value={ mailpoetEmailData[ attributeName ] ?? '' }
|
||||
value={ attributeValue ?? '' }
|
||||
data-automation-id={ `email_${ attributeName }` }
|
||||
/>
|
||||
</BaseControl>
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { Button, Modal, TextControl } from '@wordpress/components';
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import { check, Icon } from '@wordpress/icons';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import {
|
||||
useEffect,
|
||||
useRef,
|
||||
@ -13,19 +13,23 @@ import {
|
||||
} from '@wordpress/element';
|
||||
import { ENTER } from '@wordpress/keycodes';
|
||||
import { isEmail } from '@wordpress/url';
|
||||
import { useEntityProp } from '@wordpress/core-data';
|
||||
import { applyFilters } from '@wordpress/hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
MailPoetEmailData,
|
||||
SendingPreviewStatus,
|
||||
storeName,
|
||||
editorCurrentPostType,
|
||||
} from '../../store';
|
||||
import { recordEvent, recordEventOnce } from '../../events';
|
||||
|
||||
const sendingMethodConfigurationLink = applyFilters(
|
||||
'mailpoet_email_editor_check_sending_method_configuration_link',
|
||||
'admin.php?page=mailpoet-settings#mta'
|
||||
) as string;
|
||||
|
||||
function RawSendPreviewEmail() {
|
||||
const sendToRef = useRef( null );
|
||||
|
||||
@ -40,19 +44,11 @@ function RawSendPreviewEmail() {
|
||||
isSendingPreviewEmail,
|
||||
sendingPreviewStatus,
|
||||
isModalOpened,
|
||||
errorMessage,
|
||||
} = useSelect( ( select ) => select( storeName ).getPreviewState(), [] );
|
||||
|
||||
const [ mailpoetEmailData ] = useEntityProp(
|
||||
'postType',
|
||||
editorCurrentPostType,
|
||||
'mailpoet_data'
|
||||
) as [ MailPoetEmailData, unknown, unknown ];
|
||||
|
||||
const handleSendPreviewEmail = () => {
|
||||
void requestSendingNewsletterPreview(
|
||||
mailpoetEmailData.id,
|
||||
previewToEmail
|
||||
);
|
||||
void requestSendingNewsletterPreview( previewToEmail );
|
||||
};
|
||||
|
||||
const closeCallback = () => {
|
||||
@ -81,33 +77,48 @@ function RawSendPreviewEmail() {
|
||||
>
|
||||
{ sendingPreviewStatus === SendingPreviewStatus.ERROR ? (
|
||||
<div className="mailpoet-send-preview-modal-notice-error">
|
||||
{ __(
|
||||
'Sorry, we were unable to send this email.',
|
||||
'mailpoet'
|
||||
) }
|
||||
<p>
|
||||
{ __(
|
||||
'Sorry, we were unable to send this email.',
|
||||
'mailpoet'
|
||||
) }
|
||||
</p>
|
||||
|
||||
<strong>
|
||||
{ errorMessage &&
|
||||
sprintf(
|
||||
// translators: %s is an error message.
|
||||
__( 'Error: %s', 'mailpoet' ),
|
||||
errorMessage
|
||||
) }
|
||||
</strong>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
{ createInterpolateElement(
|
||||
__(
|
||||
'Please check your <link>sending method configuration</link> with your hosting provider.',
|
||||
'mailpoet'
|
||||
),
|
||||
{
|
||||
link: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href="admin.php?page=mailpoet-settings#mta"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={ () =>
|
||||
recordEvent(
|
||||
'send_preview_email_modal_check_sending_method_configuration_link_clicked'
|
||||
)
|
||||
}
|
||||
/>
|
||||
{ sendingMethodConfigurationLink &&
|
||||
createInterpolateElement(
|
||||
__(
|
||||
'Please check your <link>sending method configuration</link> with your hosting provider.',
|
||||
'mailpoet'
|
||||
),
|
||||
}
|
||||
) }
|
||||
{
|
||||
link: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href={
|
||||
sendingMethodConfigurationLink
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={ () =>
|
||||
recordEvent(
|
||||
'send_preview_email_modal_check_sending_method_configuration_link_clicked'
|
||||
)
|
||||
}
|
||||
/>
|
||||
),
|
||||
}
|
||||
) }
|
||||
</li>
|
||||
<li>
|
||||
{ createInterpolateElement(
|
||||
@ -119,10 +130,7 @@ function RawSendPreviewEmail() {
|
||||
link: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href={ new URL(
|
||||
'free-plan',
|
||||
'https://www.mailpoet.com/'
|
||||
).toString() }
|
||||
href={ `https://account.mailpoet.com/?s=1&g=1&utm_source=mailpoet_email_editor&utm_medium=plugin&utm_source_platform=${ editorCurrentPostType }` }
|
||||
key="sign-up-for-free"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
|
@ -1,92 +1,22 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { ExternalLink, PanelBody } from '@wordpress/components';
|
||||
import { useEntityProp } from '@wordpress/core-data';
|
||||
import { PanelBody } from '@wordpress/components';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createInterpolateElement } from '@wordpress/element';
|
||||
import classnames from 'classnames';
|
||||
import { applyFilters } from '@wordpress/hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { editorCurrentPostType } from '../../store';
|
||||
import { recordEvent } from '../../events';
|
||||
import { RichTextWithButton } from '../personalization-tags/rich-text-with-button';
|
||||
|
||||
const previewTextMaxLength = 150;
|
||||
const previewTextRecommendedLength = 80;
|
||||
const SidebarExtensionComponent = applyFilters(
|
||||
'mailpoet_email_editor_setting_sidebar_extension_component',
|
||||
RichTextWithButton
|
||||
) as () => JSX.Element;
|
||||
|
||||
export function DetailsPanel() {
|
||||
const [ mailpoetEmailData ] = useEntityProp(
|
||||
'postType',
|
||||
editorCurrentPostType,
|
||||
'mailpoet_data'
|
||||
);
|
||||
|
||||
const subjectHelp = createInterpolateElement(
|
||||
__(
|
||||
'Use personalization tags to personalize your email, or learn more about <bestPracticeLink>best practices</bestPracticeLink> and using <emojiLink>emoji in subject lines</emojiLink>.',
|
||||
'mailpoet'
|
||||
),
|
||||
{
|
||||
bestPracticeLink: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href="https://www.mailpoet.com/blog/17-email-subject-line-best-practices-to-boost-engagement/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={ () =>
|
||||
recordEvent(
|
||||
'details_panel_subject_help_best_practice_link_clicked'
|
||||
)
|
||||
}
|
||||
/>
|
||||
),
|
||||
emojiLink: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href="https://www.mailpoet.com/blog/tips-using-emojis-in-subject-lines/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={ () =>
|
||||
recordEvent(
|
||||
'details_panel_subject_help_emoji_in_subject_lines_link_clicked'
|
||||
)
|
||||
}
|
||||
/>
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
const previewTextLength = mailpoetEmailData?.preheader?.length ?? 0;
|
||||
|
||||
const preheaderHelp = createInterpolateElement(
|
||||
__(
|
||||
'<link>This text</link> will appear in the inbox, underneath the subject line.',
|
||||
'mailpoet'
|
||||
),
|
||||
{
|
||||
link: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
|
||||
<a
|
||||
href={ new URL(
|
||||
'article/418-preview-text',
|
||||
'https://kb.mailpoet.com/'
|
||||
).toString() }
|
||||
key="preview-text-kb"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={ () =>
|
||||
recordEvent(
|
||||
'details_panel_preheader_help_text_link_clicked'
|
||||
)
|
||||
}
|
||||
/>
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<PanelBody
|
||||
title={ __( 'Details', 'mailpoet' ) }
|
||||
@ -95,50 +25,7 @@ export function DetailsPanel() {
|
||||
recordEvent( 'details_panel_body_toggle', { opened: data } )
|
||||
}
|
||||
>
|
||||
<RichTextWithButton
|
||||
attributeName="subject"
|
||||
label={ __( 'Subject', 'mailpoet' ) }
|
||||
labelSuffix={
|
||||
<ExternalLink
|
||||
href="https://kb.mailpoet.com/article/435-a-guide-to-personalisation-tags-for-tailored-newsletters#list"
|
||||
onClick={ () =>
|
||||
recordEvent(
|
||||
'details_panel_personalisation_tags_guide_link_clicked'
|
||||
)
|
||||
}
|
||||
>
|
||||
{ __( 'Guide', 'mailpoet' ) }
|
||||
</ExternalLink>
|
||||
}
|
||||
help={ subjectHelp }
|
||||
placeholder={ __( 'Eg. The summer sale is here!', 'mailpoet' ) }
|
||||
/>
|
||||
|
||||
<RichTextWithButton
|
||||
attributeName="preheader"
|
||||
label={ __( 'Preview text', 'mailpoet' ) }
|
||||
labelSuffix={
|
||||
<span
|
||||
className={ classnames(
|
||||
'mailpoet-settings-panel__preview-text-length',
|
||||
{
|
||||
'mailpoet-settings-panel__preview-text-length-warning':
|
||||
previewTextLength >
|
||||
previewTextRecommendedLength,
|
||||
'mailpoet-settings-panel__preview-text-length-error':
|
||||
previewTextLength > previewTextMaxLength,
|
||||
}
|
||||
) }
|
||||
>
|
||||
{ previewTextLength }/{ previewTextMaxLength }
|
||||
</span>
|
||||
}
|
||||
help={ preheaderHelp }
|
||||
placeholder={ __(
|
||||
"Add a preview text to capture subscribers' attention and increase open rates.",
|
||||
'mailpoet'
|
||||
) }
|
||||
/>
|
||||
<>{ <SidebarExtensionComponent /> }</>
|
||||
</PanelBody>
|
||||
);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { useMemo } from '@wordpress/element';
|
||||
import { parse } from '@wordpress/blocks';
|
||||
import { BlockInstance } from '@wordpress/blocks/index';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { applyFilters } from '@wordpress/hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
@ -163,6 +164,11 @@ export function usePreviewTemplates(
|
||||
|
||||
const allEmailPosts = useMemo( () => {
|
||||
return emailPosts?.map( ( post: EmailEditorPostType ) => {
|
||||
const preferredTitle = applyFilters(
|
||||
'mailpoet_email_editor_preferred_template_title',
|
||||
'',
|
||||
post
|
||||
);
|
||||
const { postTemplateContent } = generateTemplateContent(
|
||||
post,
|
||||
allTemplates
|
||||
@ -180,9 +186,8 @@ export function usePreviewTemplates(
|
||||
const template = {
|
||||
...post,
|
||||
title: {
|
||||
raw: post?.mailpoet_data?.subject || post.title.raw,
|
||||
rendered:
|
||||
post?.mailpoet_data?.subject || post.title.rendered, // use MailPoet subject as title
|
||||
raw: post.title.raw,
|
||||
rendered: preferredTitle || post.title.rendered,
|
||||
},
|
||||
};
|
||||
return {
|
||||
|
@ -134,29 +134,6 @@ export function* saveEditedEmail() {
|
||||
} );
|
||||
}
|
||||
|
||||
export function* updateEmailMailPoetProperty( name: string, value: string ) {
|
||||
const postId = select( storeName ).getEmailPostId();
|
||||
// There can be a better way how to get the edited post data
|
||||
const editedPost = select( coreDataStore ).getEditedEntityRecord(
|
||||
'postType',
|
||||
editorCurrentPostType,
|
||||
postId
|
||||
);
|
||||
// @ts-expect-error Property 'mailpoet_data' does not exist on type 'Updatable<Attachment<any>>'.
|
||||
const mailpoetData = editedPost?.mailpoet_data || {};
|
||||
yield dispatch( coreDataStore ).editEntityRecord(
|
||||
'postType',
|
||||
editorCurrentPostType,
|
||||
postId,
|
||||
{
|
||||
mailpoet_data: {
|
||||
...mailpoetData,
|
||||
[ name ]: value,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const setTemplateToPost =
|
||||
( templateSlug ) =>
|
||||
async ( { registry } ) => {
|
||||
@ -168,10 +145,7 @@ export const setTemplateToPost =
|
||||
} );
|
||||
};
|
||||
|
||||
export function* requestSendingNewsletterPreview(
|
||||
newsletterId: number,
|
||||
email: string
|
||||
) {
|
||||
export function* requestSendingNewsletterPreview( email: string ) {
|
||||
// If preview is already sending do nothing
|
||||
const previewState = select( storeName ).getPreviewState();
|
||||
if ( previewState.isSendingPreviewEmail ) {
|
||||
@ -192,7 +166,6 @@ export function* requestSendingNewsletterPreview(
|
||||
path: '/mailpoet-email-editor/v1/send_preview_email',
|
||||
method: 'POST',
|
||||
data: {
|
||||
newsletterId,
|
||||
email,
|
||||
postId,
|
||||
},
|
||||
@ -213,6 +186,9 @@ export function* requestSendingNewsletterPreview(
|
||||
state: {
|
||||
sendingPreviewStatus: SendingPreviewStatus.ERROR,
|
||||
isSendingPreviewEmail: false,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
errorMessage: JSON.stringify( errorResponse?.error ),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -96,13 +96,8 @@ export const isEmpty = createRegistrySelector( ( select ) => (): boolean => {
|
||||
return true;
|
||||
}
|
||||
|
||||
const { content, mailpoet_data: mailpoetData, title } = post;
|
||||
return (
|
||||
! content.raw &&
|
||||
! mailpoetData.subject &&
|
||||
! mailpoetData.preheader &&
|
||||
! title.raw
|
||||
);
|
||||
const { content, title } = post;
|
||||
return ! content.raw && ! title.raw;
|
||||
} );
|
||||
|
||||
export const hasEmptyContent = createRegistrySelector(
|
||||
|
@ -202,6 +202,7 @@ export type State = {
|
||||
isModalOpened: boolean;
|
||||
isSendingPreviewEmail: boolean;
|
||||
sendingPreviewStatus: SendingPreviewStatus | null;
|
||||
errorMessage?: string;
|
||||
};
|
||||
personalizationTags: {
|
||||
list: PersonalizationTag[];
|
||||
@ -209,13 +210,6 @@ export type State = {
|
||||
};
|
||||
};
|
||||
|
||||
export type MailPoetEmailData = {
|
||||
id: number;
|
||||
subject: string;
|
||||
preheader: string;
|
||||
preview_url: string;
|
||||
};
|
||||
|
||||
export type EmailTemplate = {
|
||||
id: string;
|
||||
slug: string;
|
||||
@ -267,7 +261,6 @@ export type MailPoetEmailPostContentExtended = {
|
||||
|
||||
export type EmailEditorPostType = Omit< Post, 'type' > & {
|
||||
type: string;
|
||||
mailpoet_data?: MailPoetEmailPostContentExtended;
|
||||
};
|
||||
|
||||
export type EmailContentValidationAction = {
|
||||
|
@ -75,5 +75,3 @@ We may add, update and delete any of them.
|
||||
| `mailpoet_email_editor_send_preview_email` | `Array` $postData | `boolean` Result of processing. Was email sent successfully? | Allows override of the send preview mail function. Folks may choose to use custom implementation |
|
||||
| `mailpoet_email_editor_post_sent_status_args` | `Array` `sent` post status args | `Array` register_post_status args | Allows update of the argument for the sent post status |
|
||||
|
||||
## TODO
|
||||
- We use `mailpoet_data` in some section of the codebase. This will be updated.
|
||||
|
@ -66,7 +66,6 @@ class Email_Api_Controller {
|
||||
* $data - Post Data
|
||||
* format
|
||||
* [_locale] => user
|
||||
* [newsletterId] => NEWSLETTER_ID
|
||||
* [email] => Provided email address
|
||||
* [postId] => POST_ID
|
||||
*/
|
||||
|
Reference in New Issue
Block a user