Compare commits
2 Commits
update-plu
...
3.73.2
Author | SHA1 | Date | |
---|---|---|---|
fb94413256 | |||
7b23f86445 |
32
.babelrc
Normal file
32
.babelrc
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-typescript",
|
||||
"@babel/preset-react",
|
||||
"@babel/preset-env"
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
"babel-plugin-typescript-to-proptypes",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
[
|
||||
"@babel/plugin-transform-runtime",
|
||||
{
|
||||
"sourceType": "unambiguous",
|
||||
"corejs": 3
|
||||
}
|
||||
],
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@babel/plugin-syntax-import-meta",
|
||||
"@babel/plugin-proposal-json-strings",
|
||||
[
|
||||
"@babel/plugin-proposal-decorators",
|
||||
{
|
||||
"legacy": true
|
||||
}
|
||||
],
|
||||
"@babel/plugin-proposal-function-sent",
|
||||
"@babel/plugin-proposal-export-namespace-from",
|
||||
"@babel/plugin-proposal-numeric-separator",
|
||||
"@babel/plugin-proposal-throw-expressions"
|
||||
]
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fetch the versions of WooCommerce from the WordPress API
|
||||
VERSIONS=$(curl -s https://api.wordpress.org/plugins/info/1.0/woocommerce.json | jq -r '.versions | keys_unsorted | .[]' | grep -v 'trunk')
|
||||
LATEST_VERSION=""
|
||||
|
||||
# Find the latest version
|
||||
for version in $VERSIONS; do
|
||||
LATEST_VERSION=$version
|
||||
done
|
||||
|
||||
# Check if the latest version is a beta/RC version
|
||||
if [[ $LATEST_VERSION != *'beta'* && $LATEST_VERSION != *'rc'* ]]; then
|
||||
echo "No WooCommerce beta/RC version found."
|
||||
echo "LATEST_BETA="
|
||||
else
|
||||
echo "Latest WooCommerce beta/RC version: $LATEST_VERSION"
|
||||
echo "LATEST_BETA=$LATEST_VERSION"
|
||||
fi
|
@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fetch the WordPress releases RSS feed
|
||||
RSS_FEED=$(curl -s https://wordpress.org/news/category/releases/feed/)
|
||||
|
||||
# Extract the latest version from the feed and convert it to lowercase
|
||||
LAST_VERSION=$(echo "$RSS_FEED" | grep -o '<title>WordPress [^<]*</title>' | sed -E 's/<\/?title>//g' | head -n 1 | tr [:upper:] [:lower:])
|
||||
|
||||
# Check if a beta or RC version is found
|
||||
if [[ $LAST_VERSION == *'beta'* ]]; then
|
||||
# Extract titles containing beta versions from the feed
|
||||
VERSION_LINE=$(echo "$RSS_FEED" | grep -o '<code>wp core update [^<]*</code>' | sed -E 's/<\/?code>//g' | head -n 1 | grep 'beta')
|
||||
LATEST_BETA=$(echo "$VERSION_LINE" | sed -E 's/.*--version=([0-9\.]+-beta[0-9]+).*/\1/')
|
||||
|
||||
echo "Latest WordPress beta version: $LATEST_BETA"
|
||||
echo "LATEST_BETA=$LATEST_BETA"
|
||||
|
||||
elif [[ $LAST_VERSION == *'release candidate'* ]]; then
|
||||
# Extract titles containing RC versions from the feed
|
||||
VERSION_LINE=$(echo "$RSS_FEED" | grep -o '<code>wp core update [^<]*</code>' | sed -E 's/<\/?code>//g' | head -n 1 | grep 'RC')
|
||||
LATEST_BETA=$(echo "$VERSION_LINE" | sed -E 's/.*--version=([0-9\.]+-RC[0-9]+).*/\1/')
|
||||
|
||||
echo "Latest WordPress RC version: $LATEST_BETA"
|
||||
echo "LATEST_BETA=$LATEST_BETA"
|
||||
else
|
||||
echo "No WordPress beta/RC version found."
|
||||
echo "LATEST_BETA="
|
||||
fi
|
1050
.circleci/config.yml
1050
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
@ -6,3 +6,4 @@ sendmail_path = /usr/local/bin/fake-sendmail.php
|
||||
; Defines the default timezone used by the date functions
|
||||
; http://php.net/date.timezone
|
||||
date.timezone = UTC
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
import * as fs from 'fs/promises';
|
||||
import * as os from 'os';
|
||||
|
||||
// Get logical CPU count for a container on CircleCI. Adapted from:
|
||||
// https://circleci.canny.io/cloud-feature-requests/p/have-nproc-accurately-reporter-number-of-cpus-available-to-container
|
||||
|
||||
async function cgroupCpuCount() {
|
||||
const quotaS = await fs.readFile('/sys/fs/cgroup/cpu/cpu.cfs_quota_us');
|
||||
const periodS = await fs.readFile('/sys/fs/cgroup/cpu/cpu.cfs_period_us');
|
||||
const quota = parseInt(quotaS);
|
||||
const period = parseInt(periodS);
|
||||
return quota / period;
|
||||
}
|
||||
|
||||
async function cpuCount() {
|
||||
try {
|
||||
return await cgroupCpuCount();
|
||||
} catch {
|
||||
return os.cpus().length;
|
||||
}
|
||||
}
|
||||
|
||||
cpuCount().then(console.log);
|
@ -1,19 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function setup {
|
||||
local script_dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
local root_dir="$(dirname "$script_dir")"
|
||||
|
||||
local version=$1
|
||||
local wp_cli_wordpress_path="--path=$root_dir/wordpress"
|
||||
local wp_cli_wordpress_path="--path=wordpress"
|
||||
local wp_cli_allow_root="--allow-root"
|
||||
|
||||
# Add a fake sendmail mailer
|
||||
sudo cp "$script_dir/fake-sendmail.php" /usr/local/bin/
|
||||
sudo cp ./.circleci/fake-sendmail.php /usr/local/bin/
|
||||
|
||||
# configure Apache
|
||||
sudo cp "$script_dir/mailpoet_php.ini" /etc/php.d/
|
||||
sudo cp "$script_dir/apache/mailpoet.loc.conf" /etc/apache2/sites-available
|
||||
sudo cp ./.circleci/mailpoet_php.ini /usr/local/etc/php/conf.d/
|
||||
sudo cp ./.circleci/apache/mailpoet.loc.conf /etc/apache2/sites-available
|
||||
sudo a2dissite 000-default.conf
|
||||
sudo a2ensite mailpoet.loc
|
||||
sudo a2enmod rewrite
|
||||
@ -29,33 +26,35 @@ function setup {
|
||||
wp core download $wp_cli_wordpress_path $wp_cli_allow_root --version=${2:-latest}
|
||||
|
||||
# Generate `wp-config.php` file with debugging enabled
|
||||
wp config create --dbname=wordpress --dbuser=root --dbhost=127.0.0.1 --dbprefix='mp_' $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
wp config set WP_DEBUG true --raw $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
echo "define(\"WP_DEBUG\", true);" | wp core config --dbname=wordpress --dbuser=root --dbhost=127.0.0.1 --extra-php $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
|
||||
# Disable WP Cron so that it doesn't interfere with tests
|
||||
wp config set DISABLE_WP_CRON true --raw $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
|
||||
# Change default table prefix
|
||||
sed -i "s/\$table_prefix = 'wp_';/\$table_prefix = 'mp_';/" ./wordpress/wp-config.php
|
||||
|
||||
# Install WordPress
|
||||
if [[ $version == "php7_multisite" ]]; then
|
||||
# Configure multisite environment
|
||||
wp core multisite-install --admin_name=admin --admin_password=admin --admin_email=admin@mailpoet.loc --url=http://mailpoet.loc --title="WordPress MultiSite" $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
cp "$script_dir/wordpress/.htaccess" "$root_dir/wordpress/"
|
||||
cp ./.circleci/wordpress/.htaccess ./wordpress/
|
||||
|
||||
# Add a second blog
|
||||
wp site create --slug=php7_multisite $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
echo "WP_TEST_MULTISITE_SLUG=php7_multisite" >> "$root_dir/mailpoet/.env"
|
||||
echo "WP_ROOT_MULTISITE=/home/circleci/mailpoet/wordpress" >> "$root_dir/mailpoet/.env"
|
||||
echo "HTTP_HOST=mailpoet.loc" >> "$root_dir/mailpoet/.env"
|
||||
echo "WP_TEST_MULTISITE_SLUG=php7_multisite" >> .env
|
||||
echo "WP_ROOT_MULTISITE=/home/circleci/mailpoet/wordpress" >> .env
|
||||
echo "HTTP_HOST=mailpoet.loc" >> .env
|
||||
|
||||
# Add a third dummy blog
|
||||
wp site create --slug=dummy_multisite $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
else
|
||||
wp core install --admin_name=admin --admin_password=admin --admin_email=admin@mailpoet.loc --url=http://mailpoet.loc --title="WordPress Single" $wp_cli_wordpress_path $wp_cli_allow_root
|
||||
echo "WP_ROOT=/home/circleci/mailpoet/wordpress" >> "$root_dir/mailpoet/.env"
|
||||
echo "WP_ROOT=/home/circleci/mailpoet/wordpress" >> .env
|
||||
fi
|
||||
|
||||
# Softlink plugin to plugin path
|
||||
ln -s ../../../mailpoet ../wordpress/wp-content/plugins/mailpoet
|
||||
ln -s ../../.. wordpress/wp-content/plugins/mailpoet
|
||||
|
||||
# Activate plugin
|
||||
if [[ $version == "php7_multisite" ]]; then
|
||||
@ -66,13 +65,8 @@ function setup {
|
||||
|
||||
if [[ $CIRCLE_JOB == *"_with_premium_"* ]]; then
|
||||
# Softlink MailPoet Premium to plugin path
|
||||
ln -s ../../../mailpoet-premium ../wordpress/wp-content/plugins/mailpoet-premium
|
||||
ln -s ../../../mp3premium wordpress/wp-content/plugins/mailpoet-premium
|
||||
# Activate MailPoet Premium
|
||||
wp plugin activate mailpoet-premium --path="$root_dir/wordpress"
|
||||
wp plugin activate mailpoet-premium --path=wordpress
|
||||
fi
|
||||
|
||||
# Fix WP formatting file for compatibility with PHP8.1
|
||||
sed -i "s|if ( strlen( \$email ) < 6 ) {|if ( strlen( (string) \$email ) < 6 ) {|" ../wordpress/wp-includes/formatting.php
|
||||
sed -i "s|return rtrim( \$string, '/\\\\\\\\' );|return rtrim( (string) \$string, '/\\\\\\\\' );|" ../wordpress/wp-includes/formatting.php
|
||||
sed -i "s|return \$wp_hasher->HashPassword( trim( \$password ) );|return \$wp_hasher->HashPassword( trim( (string) \$password ) );|" ../wordpress/wp-includes/pluggable.php
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
.idea
|
||||
mailpoet
|
||||
mailpoet-premium
|
||||
wordpress
|
@ -7,59 +7,3 @@ insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
ij_smart_tabs = false
|
||||
max_line_length = off
|
||||
|
||||
[packages/php/email-editor/**]
|
||||
indent_style = tab
|
||||
|
||||
[packages/js/email-editor/**.{js,jsx,ts,tsx,scss}]
|
||||
indent_style = tab
|
||||
|
||||
[*.php]
|
||||
ij_php_align_key_value_pairs = false
|
||||
ij_php_align_multiline_chained_methods = false
|
||||
ij_php_align_assignments = false
|
||||
ij_php_align_class_constants = false
|
||||
ij_php_align_multiline_parameters = false
|
||||
ij_php_align_multiline_ternary_operation = false
|
||||
ij_php_align_inline_comments = false
|
||||
ij_php_align_multiline_for = true
|
||||
ij_php_align_named_arguments = false
|
||||
ij_php_align_multiline_array_initializer_expression = false
|
||||
ij_php_align_phpdoc_comments = false
|
||||
ij_php_blank_lines_after_class_header = 0
|
||||
ij_php_blank_lines_around_class = 1
|
||||
ij_php_blank_lines_before_class_end = 0
|
||||
ij_php_blank_lines_around_method = 1
|
||||
ij_php_blank_lines_after_opening_tag = 0
|
||||
ij_php_keep_indents_on_empty_lines = false
|
||||
ij_php_keep_blank_lines_after_lbrace = 0
|
||||
ij_php_keep_blank_lines_before_right_brace = 0
|
||||
ij_php_keep_blank_lines_in_declarations = 1
|
||||
ij_php_spaces_around_arrow = false
|
||||
ij_php_space_after_type_cast = false
|
||||
ij_php_blank_lines_after_function = 1
|
||||
ij_any_space_after_colon = true
|
||||
ij_any_space_before_comma = false
|
||||
ij_any_space_after_comma = true
|
||||
ij_php_space_before_catch_left_brace = true
|
||||
ij_php_space_before_if_left_brace = true
|
||||
ij_php_space_before_if_parentheses = true
|
||||
ij_php_space_after_quest = true
|
||||
ij_php_space_after_unary_not = false
|
||||
ij_php_space_before_quest = true
|
||||
ij_php_anonymous_brace_style = end_of_line
|
||||
ij_php_space_before_method_parentheses = false
|
||||
ij_php_space_before_method_call_parentheses = false
|
||||
ij_php_spaces_around_assignment_in_declare = true
|
||||
ij_php_method_parameters_new_line_after_left_paren = true
|
||||
ij_php_method_brace_style = end_of_line
|
||||
ij_php_blank_lines_before_method_body = 0
|
||||
ij_php_space_before_method_left_brace = true
|
||||
ij_php_space_after_for_semicolon = true
|
||||
ij_php_space_after_colon_in_return_type = true
|
||||
ij_php_space_before_else_keyword = true
|
||||
ij_php_for_statement_new_line_after_left_paren = true
|
||||
ij_php_class_brace_style = end_of_line
|
||||
ij_php_comma_after_last_array_element = true
|
||||
|
34
.env.sample
Normal file
34
.env.sample
Normal file
@ -0,0 +1,34 @@
|
||||
# Required
|
||||
WP_ROOT="/var/www/wordpress"
|
||||
WP_TEST_ENABLE_NETWORK_TESTS="false"
|
||||
WP_TEST_MAILER_ENABLE_SENDING="false"
|
||||
|
||||
# Optional: for multisite acceptance tests
|
||||
WP_ROOT_MULTISITE="/var/www/wordpress"
|
||||
WP_TEST_MULTISITE_SLUG=""
|
||||
HTTP_HOST="" # URL of your site (used for multisite env and equals to DOMAIN_CURRENT_SITE from wp-config.php)
|
||||
|
||||
# Optional: for sending tests
|
||||
# These are required if WP_TEST_MAILER_ENABLE_SENDING is "true"
|
||||
WP_TEST_IMPORT_MAILCHIMP_API=""
|
||||
WP_TEST_IMPORT_MAILCHIMP_LISTS="" # (separated with comma)
|
||||
WP_TEST_MAILER_AMAZON_ACCESS=""
|
||||
WP_TEST_MAILER_AMAZON_SECRET=""
|
||||
WP_TEST_MAILER_AMAZON_REGION=""
|
||||
WP_TEST_MAILER_MAILPOET_API=""
|
||||
WP_TEST_MAILER_SENDGRID_API=""
|
||||
WP_TEST_MAILER_SMTP_HOST=""
|
||||
WP_TEST_MAILER_SMTP_LOGIN=""
|
||||
WP_TEST_MAILER_SMTP_PASSWORD=""
|
||||
|
||||
# Optional: for plugin deployment
|
||||
WP_SVN_USERNAME=""
|
||||
WP_SVN_PASSWORD=""
|
||||
WP_TRANSIFEX_API_TOKEN=""
|
||||
WP_JIRA_USER="" # JIRA username/email
|
||||
WP_JIRA_TOKEN="" # JIRA token from https://id.atlassian.com/manage/api-tokens
|
||||
WP_CIRCLECI_USERNAME="" # CircleCI organization or user
|
||||
WP_CIRCLECI_TOKEN="" # CircleCI token from https://circleci.com/gh/{user|org}/{project}/edit#api
|
||||
WP_GITHUB_USERNAME="" # GitHub username (not email)
|
||||
WP_GITHUB_TOKEN="" # GitHub token from https://github.com/settings/tokens
|
||||
WP_SLACK_WEBHOOK_URL="" # Webhook URL from https://mailpoet.slack.com/services/BHRB9AHSQ
|
3
.eslintignore
Normal file
3
.eslintignore
Normal file
@ -0,0 +1,3 @@
|
||||
**/vendor/**
|
||||
**/vendor-prefixed/**
|
||||
**/testBundles/**
|
16
.eslintrc.es5.json
Normal file
16
.eslintrc.es5.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "airbnb/legacy",
|
||||
"env": {
|
||||
"amd": true,
|
||||
"browser": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"import/prefer-default-export": 0, // we want to stop using default exports and start using named exports
|
||||
"no-underscore-dangle": 0, // Backbone uses underscores, we cannot remove them
|
||||
"comma-dangle": ["error", "always-multiline"]
|
||||
}
|
||||
}
|
57
.eslintrc.es6.json
Normal file
57
.eslintrc.es6.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"extends": "airbnb",
|
||||
"env": {
|
||||
"amd": true,
|
||||
"browser": true,
|
||||
"mocha": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"react-hooks",
|
||||
"no-only-tests"
|
||||
],
|
||||
"settings": {
|
||||
"import/resolver": "webpack"
|
||||
},
|
||||
"rules": {
|
||||
// Hooks
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "warn",
|
||||
// Exceptions
|
||||
"arrow-parens": ["error", "always"],
|
||||
"comma-dangle": ["error", "always-multiline"],
|
||||
"no-only-tests/no-only-tests": 2,
|
||||
"no-script-url": 0,
|
||||
"import/extensions": 0, // we wouldn't be able to import jQuery without this line
|
||||
"import/prefer-default-export": 0, // we want to stop using default exports and start using named exports
|
||||
"react/destructuring-assignment": 0, // that would be too many changes to fix this one
|
||||
"prefer-destructuring": 0, // that would be too many changes to fix this one
|
||||
"jsx-a11y/label-has-for": [2, {
|
||||
"required": {"some": ["nesting", "id"]} // some of our labels are hidden and we cannot nest those
|
||||
}],
|
||||
"jsx-a11y/anchor-is-valid": 0, // cannot fix this one, it would break wprdpress themes
|
||||
"jsx-a11y/label-has-associated-control": [ 2, {
|
||||
"either": "either" // control has to be either nested or associated via htmlFor
|
||||
}],
|
||||
"indent": ["error", 2, {// bug in babel eslint https://github.com/babel/babel-eslint/issues/681#issuecomment-451336031 we can remove this whole exception in the future when the bug is fixed
|
||||
"ignoredNodes": ["TemplateLiteral"],
|
||||
"SwitchCase": 1
|
||||
}],
|
||||
"template-curly-spacing": "off"// bug in babel eslint https://github.com/babel/babel-eslint/issues/681#issuecomment-623101005 we can remove this whole exception in the future when the bug is fixed
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.spec.js"],
|
||||
"rules": {
|
||||
"no-unused-expressions": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
20
.eslintrc.tests_newsletter_editor.json
Normal file
20
.eslintrc.tests_newsletter_editor.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "airbnb/legacy",
|
||||
"env": {
|
||||
"amd": true,
|
||||
"mocha": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"no-only-tests/no-only-tests": 2,
|
||||
// Exceptions
|
||||
"func-names": 0,
|
||||
"comma-dangle": ["error", "always-multiline"],
|
||||
// Temporary
|
||||
"no-underscore-dangle": 0
|
||||
},
|
||||
"plugins": ["no-only-tests"]
|
||||
}
|
365
.eslintrc.ts.json
Normal file
365
.eslintrc.ts.json
Normal file
@ -0,0 +1,365 @@
|
||||
{
|
||||
"extends": [
|
||||
"airbnb",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-requiring-type-checking"
|
||||
],
|
||||
"env": {
|
||||
"amd": true,
|
||||
"browser": true,
|
||||
"mocha": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"tsconfigRootDir": ".",
|
||||
"project": ["./tsconfig.json"],
|
||||
"ecmaVersion": 6,
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"react-hooks",
|
||||
"no-only-tests",
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"settings": {
|
||||
"import/resolver": "webpack"
|
||||
},
|
||||
"rules": {
|
||||
// PropTypes
|
||||
"react/prop-types": 0,
|
||||
"react/jsx-props-no-spreading": 0,
|
||||
"react/require-default-props": 0,
|
||||
// Hooks
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "warn",
|
||||
// Exceptions
|
||||
"@typescript-eslint/no-explicit-any": "error", // make it an error instead of warning - we treat them the same, this is more visible
|
||||
"no-use-before-define": 0, //use the typescript version
|
||||
"camelcase": 0, //use the typescript version
|
||||
"no-shadow": 0, //use the typescript version
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"error",
|
||||
{ "selector": "classProperty", "format": [] },
|
||||
{ "selector": "typeProperty", "format": [] },
|
||||
{ "selector": "objectLiteralProperty", "format": [] },
|
||||
{ "selector": "variableLike", "format": ["UPPER_CASE", "camelCase", "PascalCase"] }
|
||||
],
|
||||
"react/jsx-filename-extension": 0,
|
||||
"arrow-parens": ["error", "always"],
|
||||
"comma-dangle": ["error", "always-multiline"],
|
||||
"no-only-tests/no-only-tests": 2,
|
||||
"no-script-url": 0,
|
||||
"@typescript-eslint/no-unsafe-return": 0, // we need to disable it for wordpress select :(
|
||||
"@typescript-eslint/no-unsafe-member-access": 0, // this needs to be off until mailpoet.js is converted to typescript
|
||||
"@typescript-eslint/no-unsafe-call": 0, // this needs to be off until mailpoet.js is converted to typescript
|
||||
"@typescript-eslint/no-unsafe-assignment": 0, // this needs to be off until mailpoet.js is converted to typescript
|
||||
"import/extensions": 0, // we wouldn't be able to import jQuery without this line
|
||||
"import/prefer-default-export": 0, // we want to stop using default exports and start using named exports
|
||||
"react/destructuring-assignment": 0, // that would be too many changes to fix this one
|
||||
"prefer-destructuring": 0, // that would be too many changes to fix this one
|
||||
"jsx-a11y/label-has-for": [2, {
|
||||
"required": {"some": ["nesting", "id"]} // some of our labels are hidden and we cannot nest those
|
||||
}],
|
||||
"jsx-a11y/anchor-is-valid": 0, // cannot fix this one, it would break wprdpress themes
|
||||
"jsx-a11y/label-has-associated-control": [ 2, {
|
||||
"either": "either" // control has to be either nested or associated via htmlFor
|
||||
}],
|
||||
"@typescript-eslint/explicit-module-boundary-types": "error"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/_stories/*.tsx"],
|
||||
"rules": {
|
||||
"import/no-extraneous-dependencies": ["error", { "devDependencies": true }]
|
||||
}
|
||||
},
|
||||
{
|
||||
// this violation has been added by a formed employee and we don't know how that works any more, so ignore
|
||||
"files": [
|
||||
"assets/js/src/settings/pages/advanced/reinstall.tsx",
|
||||
"assets/js/src/settings/pages/advanced/recalculate_subscriber_score.tsx",
|
||||
"assets/js/src/settings/pages/key_activation/key_activation.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/activate_or_cancel.tsx",
|
||||
"assets/js/src/settings/pages/send_with/send_with_choice.tsx"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/await-thenable": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
// too many violations, skipping for now
|
||||
"files": [
|
||||
"assets/js/src/announcements/feature_announcement.tsx",
|
||||
"assets/js/src/announcements/with_feature_announcement.tsx",
|
||||
"assets/js/src/common/controls/call_api.ts",
|
||||
"assets/js/src/common/form/react_select/react_select.tsx",
|
||||
"assets/js/src/common/functions/is_email.ts",
|
||||
"assets/js/src/common/functions/t.ts",
|
||||
"assets/js/src/common/listings/newsletter_stats/stats.tsx",
|
||||
"assets/js/src/common/listings/newsletter_status.tsx",
|
||||
"assets/js/src/common/set_from_address_modal.tsx",
|
||||
"assets/js/src/common/tabs/routed_tabs.tsx",
|
||||
"assets/js/src/common/thumbnail.ts",
|
||||
"assets/js/src/form_editor/blocks/submit/edit.tsx",
|
||||
"assets/js/src/form_editor/components/close_button_settings.tsx",
|
||||
"assets/js/src/form_editor/components/font_family_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/below_pages.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/fixed_bar.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/other.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/popup.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/settings_panels/animation_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/settings_panels/below_posts_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/settings_panels/fixed_bar_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/settings_panels/other_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/settings_panels/placement_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/settings_panels/popup_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/settings_panels/slide_in_settings.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_placement_options/slide_in.tsx",
|
||||
"assets/js/src/form_editor/components/form_settings/form_settings.tsx",
|
||||
"assets/js/src/form_editor/components/fullscreen.tsx",
|
||||
"assets/js/src/form_editor/components/history_redo.tsx",
|
||||
"assets/js/src/form_editor/components/history_undo.tsx",
|
||||
"assets/js/src/form_editor/components/preview/preview.tsx",
|
||||
"assets/js/src/form_editor/components/sidebar/default_sidebar.tsx",
|
||||
"assets/js/src/form_editor/components/sidebar/placement_settings_sidebar.tsx",
|
||||
"assets/js/src/form_editor/components/sidebar/sidebar.tsx",
|
||||
"assets/js/src/form_editor/components/tutorial.tsx",
|
||||
"assets/js/src/form_editor/form_preview.ts",
|
||||
"assets/js/src/form_editor/hooks.tsx",
|
||||
"assets/js/src/form_editor/rich_text/font_selection_format.tsx",
|
||||
"assets/js/src/form_editor/store/actions.ts",
|
||||
"assets/js/src/form_editor/store/reducers/change_active_sidebar.ts",
|
||||
"assets/js/src/form_editor/store/reducers/history_record.ts",
|
||||
"assets/js/src/form_editor/store/reducers/toggle_form.ts",
|
||||
"assets/js/src/form_editor/store/reducers/toggle_fullscreen.ts",
|
||||
"assets/js/src/form_editor/store/reducers/tutorial_dismiss.ts",
|
||||
"assets/js/src/form_editor/templates/selection.tsx",
|
||||
"assets/js/src/form_editor/templates/store/actions.ts",
|
||||
"assets/js/src/form_editor/utils/link_suggestions.tsx",
|
||||
"assets/js/src/logs/list.tsx",
|
||||
"assets/js/src/newsletters/automatic_emails/events/event_options.tsx",
|
||||
"assets/js/src/newsletters/campaign_stats/newsletter_general_stats.tsx",
|
||||
"assets/js/src/newsletters/campaign_stats/page.tsx",
|
||||
"assets/js/src/newsletters/listings/heading_steps.tsx",
|
||||
"assets/js/src/newsletters/send/congratulate/success_pitch_mss.tsx",
|
||||
"assets/js/src/newsletters/types.tsx",
|
||||
"assets/js/src/segments/dynamic/dynamic_segments_filters/email_opens_absolute_count.tsx",
|
||||
"assets/js/src/segments/dynamic/dynamic_segments_filters/email_statistics.tsx",
|
||||
"assets/js/src/segments/dynamic/dynamic_segments_filters/subscriber_subscribed_date.tsx",
|
||||
"assets/js/src/segments/dynamic/dynamic_segments_filters/subscriber_wordpress_role.tsx",
|
||||
"assets/js/src/segments/dynamic/dynamic_segments_filters/woocommerce.tsx",
|
||||
"assets/js/src/segments/dynamic/dynamic_segments_filters/woocommerce_subscription.tsx",
|
||||
"assets/js/src/segments/dynamic/form.tsx",
|
||||
"assets/js/src/segments/dynamic/subscribers_calculator.ts",
|
||||
"assets/js/src/segments/dynamic/subscribers_counter.tsx",
|
||||
"assets/js/src/segments/dynamic/validator.ts",
|
||||
"assets/js/src/settings/components/segments_select.tsx",
|
||||
"assets/js/src/settings/pages/basics/stats_notifications.tsx",
|
||||
"assets/js/src/settings/pages/basics/subscribe_on.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/sending_frequency.tsx",
|
||||
"assets/js/src/settings/pages/send_with/send_with_choice.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/checkout_optin.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/email_customizer.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/enable_cookies.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/subscribe_old_customers.tsx",
|
||||
"assets/js/src/settings/store/actions/settings.ts",
|
||||
"assets/js/src/settings/store/controls.ts",
|
||||
"assets/js/src/settings/store/hooks/useActions.ts",
|
||||
"assets/js/src/settings/store/hooks/useSelector.ts",
|
||||
"assets/js/src/settings/store/hooks/useSetting.ts",
|
||||
"assets/js/src/settings/store/index.ts",
|
||||
"assets/js/src/settings/store/normalize_settings.ts",
|
||||
"assets/js/src/settings/store/selectors.ts",
|
||||
"assets/js/src/settings/store/types.ts",
|
||||
"assets/js/src/subscribers/importExport/export.ts"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/restrict-template-expressions": 0,
|
||||
"@typescript-eslint/no-unsafe-return": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
// there are so many violations of this rule we need to keep slowly removing it
|
||||
"files": [
|
||||
"assets/js/src/_storybook/action.ts",
|
||||
"assets/js/src/announcements/feature_announcement.tsx",
|
||||
"assets/js/src/announcements/with_feature_announcement.tsx",
|
||||
"assets/js/src/common/background/_stories/background.tsx",
|
||||
"assets/js/src/common/background/background.tsx",
|
||||
"assets/js/src/common/badge/_stories/badge.tsx",
|
||||
"assets/js/src/common/badge/badge.tsx",
|
||||
"assets/js/src/common/button/_stories/button.tsx",
|
||||
"assets/js/src/common/button/_stories/button_icons.tsx",
|
||||
"assets/js/src/common/button/button.tsx",
|
||||
"assets/js/src/common/categories/_stories/categories.tsx",
|
||||
"assets/js/src/common/categories/categories.tsx",
|
||||
"assets/js/src/common/categories/categories_item.tsx",
|
||||
"assets/js/src/common/controls/call_api.ts",
|
||||
"assets/js/src/common/controls/track_event.ts",
|
||||
"assets/js/src/common/datepicker/_stories/datepicker.tsx",
|
||||
"assets/js/src/common/datepicker/datepicker.tsx",
|
||||
"assets/js/src/common/form/checkbox/_stories/checkbox.tsx",
|
||||
"assets/js/src/common/form/checkbox/checkbox.tsx",
|
||||
"assets/js/src/common/form/checkbox/group.tsx",
|
||||
"assets/js/src/common/form/input/_stories/input.tsx",
|
||||
"assets/js/src/common/form/input/input.tsx",
|
||||
"assets/js/src/common/form/radio/_stories/radio.tsx",
|
||||
"assets/js/src/common/form/radio/group.tsx",
|
||||
"assets/js/src/common/form/radio/radio.tsx",
|
||||
"assets/js/src/common/form/react_select/_stories/react_select.tsx",
|
||||
"assets/js/src/common/form/react_select/react_select.tsx",
|
||||
"assets/js/src/common/form/select/_stories/select.tsx",
|
||||
"assets/js/src/common/form/textarea/_stories/textarea.tsx",
|
||||
"assets/js/src/common/form/textarea/textarea.tsx",
|
||||
"assets/js/src/common/form/toggle/_stories/toggle.tsx",
|
||||
"assets/js/src/common/form/toggle/toggle.tsx",
|
||||
"assets/js/src/common/form/yesno/_stories/yesno.tsx",
|
||||
"assets/js/src/common/form/yesno/yesno.tsx",
|
||||
"assets/js/src/common/functions/change_handlers.ts",
|
||||
"assets/js/src/common/hide_screen_options/hide_screen_options.tsx",
|
||||
"assets/js/src/common/listings/_stories/newsletter_stats.tsx",
|
||||
"assets/js/src/common/listings/_stories/newsletter_status.tsx",
|
||||
"assets/js/src/common/listings/newsletter_stats.tsx",
|
||||
"assets/js/src/common/listings/newsletter_stats/badge.tsx",
|
||||
"assets/js/src/common/listings/newsletter_stats/stats.tsx",
|
||||
"assets/js/src/common/listings/newsletter_status.tsx",
|
||||
"assets/js/src/common/loader/_stories/loader.tsx",
|
||||
"assets/js/src/common/loader/loader.tsx",
|
||||
"assets/js/src/common/modal/_stories/modal.tsx",
|
||||
"assets/js/src/common/modal/frame.tsx",
|
||||
"assets/js/src/common/modal/header.tsx",
|
||||
"assets/js/src/common/modal/modal.tsx",
|
||||
"assets/js/src/common/modal/overlay.tsx",
|
||||
"assets/js/src/common/premium_required/_stories/premium_required.tsx",
|
||||
"assets/js/src/common/premium_required/premium_required.tsx",
|
||||
"assets/js/src/common/preview/desktop_icon.tsx",
|
||||
"assets/js/src/common/preview/mobile_icon.tsx",
|
||||
"assets/js/src/common/remove_wrap_margin/remove_wrap_margin.tsx",
|
||||
"assets/js/src/common/set_from_address_modal.tsx",
|
||||
"assets/js/src/common/steps/_stories/steps.tsx",
|
||||
"assets/js/src/common/steps/content_wrapper_fix.tsx",
|
||||
"assets/js/src/common/steps/steps.tsx",
|
||||
"assets/js/src/common/steps/steps_content.tsx",
|
||||
"assets/js/src/common/subscribers_in_plan.tsx",
|
||||
"assets/js/src/common/tabs/_stories/tabs.tsx",
|
||||
"assets/js/src/common/tabs/_stories/tabs_icons.tsx",
|
||||
"assets/js/src/common/tabs/routed_tabs.tsx",
|
||||
"assets/js/src/common/tabs/tab.tsx",
|
||||
"assets/js/src/common/tabs/tabs.tsx",
|
||||
"assets/js/src/common/tag/_stories/tag.tsx",
|
||||
"assets/js/src/common/tag/_stories/tags.tsx",
|
||||
"assets/js/src/common/tag/tag.tsx",
|
||||
"assets/js/src/common/tag/tags.tsx",
|
||||
"assets/js/src/common/template_box/_stories/template_box.tsx",
|
||||
"assets/js/src/common/template_box/template_box.tsx",
|
||||
"assets/js/src/common/thumbnail.ts",
|
||||
"assets/js/src/common/tooltip/_stories/tooltip.tsx",
|
||||
"assets/js/src/common/tooltip/tooltip.tsx",
|
||||
"assets/js/src/common/top_bar/_stories/top_bar_no_children.tsx",
|
||||
"assets/js/src/common/top_bar/_stories/top_bar_with_children.tsx",
|
||||
"assets/js/src/common/top_bar/beamer_icon.tsx",
|
||||
"assets/js/src/common/top_bar/mailpoet_logo.tsx",
|
||||
"assets/js/src/common/top_bar/mailpoet_logo_mobile.tsx",
|
||||
"assets/js/src/common/top_bar/screen_options_fix.tsx",
|
||||
"assets/js/src/common/top_bar/top_bar.tsx",
|
||||
"assets/js/src/common/typography/heading/_stories/heading.tsx",
|
||||
"assets/js/src/common/typography/heading/heading.tsx",
|
||||
"assets/js/src/common/typography/list/_stories/list.tsx",
|
||||
"assets/js/src/common/typography/list/list.tsx",
|
||||
"assets/js/src/form_editor/store/actions.ts",
|
||||
"assets/js/src/form_editor/store/mapping/from_blocks/styles_mapper.ts",
|
||||
"assets/js/src/form_editor/store/mapping/to_blocks/styles_mapper.ts",
|
||||
"assets/js/src/form_editor/store/reducers/change_active_sidebar.ts",
|
||||
"assets/js/src/form_editor/store/reducers/history_record.ts",
|
||||
"assets/js/src/form_editor/store/reducers/toggle_form.ts",
|
||||
"assets/js/src/form_editor/store/reducers/toggle_fullscreen.ts",
|
||||
"assets/js/src/form_editor/store/reducers/toggle_sidebar.ts",
|
||||
"assets/js/src/form_editor/store/reducers/tutorial_dismiss.ts",
|
||||
"assets/js/src/form_editor/template_selection.tsx",
|
||||
"assets/js/src/form_editor/translations.ts",
|
||||
"assets/js/src/form_editor/utils/link_suggestions.tsx",
|
||||
"assets/js/src/newsletters/automatic_emails/events/event_options.tsx",
|
||||
"assets/js/src/newsletters/campaign_stats/newsletter_general_stats.tsx",
|
||||
"assets/js/src/newsletters/campaign_stats/newsletter_stats_info.tsx",
|
||||
"assets/js/src/newsletters/campaign_stats/page.tsx",
|
||||
"assets/js/src/notices/api_errors_notice.tsx",
|
||||
"assets/js/src/notices/invalid_mss_key_notice.tsx",
|
||||
"assets/js/src/notices/notice.tsx",
|
||||
"assets/js/src/notices/transactional_emails_propose_opt_in_notice.tsx",
|
||||
"assets/js/src/sending-paused-notices-fix-button.tsx",
|
||||
"assets/js/src/settings/components/inputs.tsx",
|
||||
"assets/js/src/settings/components/label.tsx",
|
||||
"assets/js/src/settings/components/pages_select.tsx",
|
||||
"assets/js/src/settings/components/save_button.tsx",
|
||||
"assets/js/src/settings/components/segments_select.tsx",
|
||||
"assets/js/src/settings/index.tsx",
|
||||
"assets/js/src/settings/pages/advanced/advanced.tsx",
|
||||
"assets/js/src/settings/pages/advanced/bounce_address.tsx",
|
||||
"assets/js/src/settings/pages/advanced/captcha.tsx",
|
||||
"assets/js/src/settings/pages/advanced/inactive_subscribers.tsx",
|
||||
"assets/js/src/settings/pages/advanced/libs_3rd_party.tsx",
|
||||
"assets/js/src/settings/pages/advanced/logging.tsx",
|
||||
"assets/js/src/settings/pages/advanced/reinstall.tsx",
|
||||
"assets/js/src/settings/pages/advanced/roles.tsx",
|
||||
"assets/js/src/settings/pages/advanced/share_data.tsx",
|
||||
"assets/js/src/settings/pages/advanced/task_scheduler.tsx",
|
||||
"assets/js/src/settings/pages/advanced/tracking.tsx",
|
||||
"assets/js/src/settings/pages/advanced/transactional.tsx",
|
||||
"assets/js/src/settings/pages/basics/basics.tsx",
|
||||
"assets/js/src/settings/pages/basics/default_sender.tsx",
|
||||
"assets/js/src/settings/pages/basics/gdpr_compliant.tsx",
|
||||
"assets/js/src/settings/pages/basics/manage_subscription.tsx",
|
||||
"assets/js/src/settings/pages/basics/new_subscriber_notifications.tsx",
|
||||
"assets/js/src/settings/pages/basics/shortcode.tsx",
|
||||
"assets/js/src/settings/pages/basics/stats_notifications.tsx",
|
||||
"assets/js/src/settings/pages/basics/subscribe_on.tsx",
|
||||
"assets/js/src/settings/pages/basics/unsubscribe_page.tsx",
|
||||
"assets/js/src/settings/pages/key_activation/key_activation.tsx",
|
||||
"assets/js/src/settings/pages/key_activation/messages/key_messages.tsx",
|
||||
"assets/js/src/settings/pages/key_activation/messages/mss_messages.tsx",
|
||||
"assets/js/src/settings/pages/key_activation/messages/premium_messages.tsx",
|
||||
"assets/js/src/settings/pages/key_activation/messages/service_unavailable_messages.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/activate_or_cancel.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/amazon_ses_fields.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/other_sending_methods.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/php_mail_fields.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/sendgrid_fields.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/sending_frequency.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/sending_method.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/smtp_fields.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/spf.tsx",
|
||||
"assets/js/src/settings/pages/send_with/other/test_sending.tsx",
|
||||
"assets/js/src/settings/pages/send_with/send_with.tsx",
|
||||
"assets/js/src/settings/pages/send_with/send_with_choice.tsx",
|
||||
"assets/js/src/settings/pages/signup_confirmation/confirmation_page.tsx",
|
||||
"assets/js/src/settings/pages/signup_confirmation/email_content.tsx",
|
||||
"assets/js/src/settings/pages/signup_confirmation/email_subject.tsx",
|
||||
"assets/js/src/settings/pages/signup_confirmation/enable_signup_confirmation.tsx",
|
||||
"assets/js/src/settings/pages/signup_confirmation/signup_confirmation.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/checkout_optin.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/email_customizer.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/enable_cookies.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/subscribe_old_customers.tsx",
|
||||
"assets/js/src/settings/pages/woo_commerce/woo_commerce.tsx",
|
||||
"assets/js/src/settings/settings.tsx",
|
||||
"assets/js/src/settings/store/actions/mss_and_premium.ts",
|
||||
"assets/js/src/settings/store/actions/open_woocommerce_customizer.ts",
|
||||
"assets/js/src/settings/store/actions/reinstall.ts",
|
||||
"assets/js/src/settings/store/actions/send_test_email.ts",
|
||||
"assets/js/src/settings/store/actions/settings.ts",
|
||||
"assets/js/src/settings/store/controls.ts",
|
||||
"assets/js/src/settings/store/create_reducer.ts",
|
||||
"assets/js/src/settings/store/index.ts",
|
||||
"assets/js/src/settings/store/make_default_state.ts",
|
||||
"assets/js/src/settings/store/selectors.ts"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-function-return-type": 0,
|
||||
"@typescript-eslint/explicit-module-boundary-types": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -37,17 +37,3 @@ e66c76133ec3ef667e382203426d91a4b4aa5174
|
||||
# Updating rule name in php:cs ignore comments
|
||||
65b834a9fff72b1ec5fc81ac383ebb27321da9dc
|
||||
|
||||
# Prettier autoformatting
|
||||
ab27eaee2df740c0add4331a7f8c115a87ecfa2b
|
||||
|
||||
# Move email editor to JS packages folder
|
||||
912282f57ccc839491ff951ec5cf7aa10c14f429
|
||||
|
||||
# Switch email editor js packages to WP coding style
|
||||
b2fb96f8793b63db629d5237010d87332330c51e
|
||||
|
||||
# Email editor Prettier autoformatting
|
||||
8c604453b1d82e3a2c731241e1c96ea8b32ec716
|
||||
|
||||
# Move email editor components out of the engine folder
|
||||
1c3ea9cd0a5fc8848a64d840e2fa16a6c7d8c1fe
|
||||
|
3
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@ -4,6 +4,7 @@ about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
@ -11,7 +12,6 @@ A clear and concise description of what the bug is.
|
||||
|
||||
**To reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to ...
|
||||
2. Click on ...
|
||||
3. Scroll down to ...
|
||||
@ -26,7 +26,6 @@ A clear and concise description of what you expected to happen.
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Versions (please complete the following information):**
|
||||
|
||||
- WordPress version: [e.g: 5.3.2]
|
||||
- PHP version: [e.g: 7.4.2]
|
||||
- MailPoet version: [e.g: 3.46.13]
|
||||
|
1
.github/ISSUE_TEMPLATE/feature_request.md
vendored
1
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -4,6 +4,7 @@ about: https://feedback.mailpoet.com/
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please use https://feedback.mailpoet.com/ for feature requests.
|
||||
|
22
.github/SECURITY.md
vendored
22
.github/SECURITY.md
vendored
@ -4,7 +4,7 @@ Full details of the Automattic Security Policy can be found on [automattic.com/s
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Generally, _only the latest version of MailPoet has continued support_. If a critical vulnerability is found in the current version of MailPoet, we may opt to backport any patches to previous versions.
|
||||
Generally, *only the latest version of MailPoet has continued support*. If a critical vulnerability is found in the current version of MailPoet, we may opt to backport any patches to previous versions.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
@ -14,9 +14,9 @@ Generally, _only the latest version of MailPoet has continued support_. If a cri
|
||||
|
||||
Our most critical targets are:
|
||||
|
||||
- MailPoet plugin (this repository)
|
||||
- MailPoet Premium
|
||||
- mailpoet.com -- the primary site, and all of it subdomains, e.g. [account.mailpoet.com](https://account.mailpoet.com/)
|
||||
* MailPoet plugin (this repository)
|
||||
* MailPoet Premium
|
||||
* mailpoet.com -- the primary site, and all of it subdomains, e.g. [account.mailpoet.com](https://account.mailpoet.com/)
|
||||
|
||||
For more targets, see the `In Scope` section on [HackerOne](https://hackerone.com/automattic).
|
||||
|
||||
@ -26,12 +26,12 @@ _Please note that the **WordPress software is a separate entity** from Automatti
|
||||
|
||||
We're committed to working with security researchers to resolve the vulnerabilities they discover. You can help us by following these guidelines:
|
||||
|
||||
- Follow [HackerOne's disclosure guidelines](https://www.hackerone.com/disclosure-guidelines).
|
||||
- Pen-testing Production:
|
||||
- Please **setup a local environment** instead whenever possible. Most of our code is open source (see above).
|
||||
- If that's not possible, **limit any data access/modification** to the bare minimum necessary to reproduce a PoC.
|
||||
- **_Don't_ automate form submissions!** That's very annoying for us, because it adds extra work for the volunteers who manage those systems, and reduces the signal/noise ratio in our communication channels.
|
||||
- To be eligible for a bounty, please follow all of these guidelines.
|
||||
- Be Patient - Give us a reasonable time to correct the issue before you disclose the vulnerability.
|
||||
* Follow [HackerOne's disclosure guidelines](https://www.hackerone.com/disclosure-guidelines).
|
||||
* Pen-testing Production:
|
||||
* Please **setup a local environment** instead whenever possible. Most of our code is open source (see above).
|
||||
* If that's not possible, **limit any data access/modification** to the bare minimum necessary to reproduce a PoC.
|
||||
* **_Don't_ automate form submissions!** That's very annoying for us, because it adds extra work for the volunteers who manage those systems, and reduces the signal/noise ratio in our communication channels.
|
||||
* To be eligible for a bounty, please follow all of these guidelines.
|
||||
* Be Patient - Give us a reasonable time to correct the issue before you disclose the vulnerability.
|
||||
|
||||
We also expect you to comply with all applicable laws. You're responsible to pay any taxes associated with your bounties.
|
||||
|
29
.github/pull_request_template.md
vendored
29
.github/pull_request_template.md
vendored
@ -1,29 +0,0 @@
|
||||
## Description
|
||||
|
||||
_N/A_
|
||||
|
||||
## Code review notes
|
||||
|
||||
_N/A_
|
||||
|
||||
## QA notes
|
||||
|
||||
_N/A_
|
||||
|
||||
## Linked PRs
|
||||
|
||||
_N/A_
|
||||
|
||||
## Linked tickets
|
||||
|
||||
_N/A_
|
||||
|
||||
## After-merge notes
|
||||
|
||||
_N/A_
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] I followed [best practices](https://codex.wordpress.org/I18n_for_WordPress_Developers) for translations
|
||||
- [ ] I added sufficient test coverage
|
||||
- [ ] I embraced TypeScript by either creating new files in TypeScript or converting existing JavaScript files when making changes
|
72
.github/workflows/codeql-analysis.yml
vendored
72
.github/workflows/codeql-analysis.yml
vendored
@ -3,14 +3,14 @@
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
name: 'CodeQL'
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [trunk]
|
||||
branches: [master]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [trunk]
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 17 * * 4'
|
||||
|
||||
@ -29,43 +29,43 @@ jobs:
|
||||
# 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
|
||||
- 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' }}
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
# ℹ️ 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
|
||||
# ✏️ 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
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
- 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
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
$repository = 'woocommerce/automatewoo';
|
||||
$downloadCommand = 'download:automate-woo-zip';
|
||||
$configParameterName = 'automate_woo_version';
|
||||
$versionsFilenameSuffix = 'automate_woo_version.txt';
|
||||
|
||||
replacePrivatePluginVersion($repository, $downloadCommand, $configParameterName, $versionsFilenameSuffix);
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
$repository = 'woocommerce/woocommerce-memberships';
|
||||
$downloadCommand = 'download:woo-commerce-memberships-zip';
|
||||
$configParameterName = 'woo_memberships_version';
|
||||
$versionsFilenameSuffix = 'woocommerce_memberships_version.txt';
|
||||
|
||||
replacePrivatePluginVersion($repository, $downloadCommand, $configParameterName, $versionsFilenameSuffix);
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
$repository = 'woocommerce/woocommerce-subscriptions';
|
||||
$downloadCommand = 'download:woo-commerce-subscriptions-zip';
|
||||
$configParameterName = 'woo_subscriptions_version';
|
||||
$versionsFilenameSuffix = 'woocommerce_subscriptions_version.txt';
|
||||
|
||||
replacePrivatePluginVersion($repository, $downloadCommand, $configParameterName, $versionsFilenameSuffix);
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
$downloadCommand = 'download:woo-commerce-zip';
|
||||
$configParameterName = 'woo_core_version';
|
||||
$versionsFilenameSuffix = 'woocommerce_version.txt';
|
||||
|
||||
/**
|
||||
* We get the official WooCommerce versions from the WordPress API.
|
||||
*/
|
||||
function getWooCommerceVersions(): array {
|
||||
$url = "https://api.wordpress.org/plugins/info/1.0/woocommerce.json";
|
||||
$response = file_get_contents($url);
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if (!isset($data['versions'])) {
|
||||
die("Failed to fetch WooCommerce versions.");
|
||||
}
|
||||
|
||||
return array_keys($data['versions']);
|
||||
}
|
||||
|
||||
$allVersions = getWooCommerceVersions();
|
||||
$stableVersions = filterStableVersions($allVersions);
|
||||
[$latestVersion, $previousVersion] = getLatestAndPreviousMinorMajorVersions($stableVersions);
|
||||
|
||||
echo "Latest WooCommerce version: $latestVersion\n";
|
||||
echo "Previous WooCommerce version: $previousVersion\n";
|
||||
|
||||
if ($latestVersion) {
|
||||
echo "Replacing the latest version in the config file...\n";
|
||||
replaceLatestVersion($latestVersion, $downloadCommand);
|
||||
} else {
|
||||
echo "No latest version found.\n";
|
||||
}
|
||||
|
||||
if ($previousVersion) {
|
||||
echo "Replacing the previous version in the config file...\n";
|
||||
replacePreviousVersion($previousVersion, $configParameterName);
|
||||
} else {
|
||||
echo "No previous version found.\n";
|
||||
}
|
||||
|
||||
saveVersionsToFiles($latestVersion, $previousVersion, $versionsFilenameSuffix);
|
@ -1,123 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
/**
|
||||
* We try to get the current available official Docker images for WordPress.
|
||||
*/
|
||||
function getWordpressVersions(int $page = 1, int $pageSize = 100): array {
|
||||
$url = "https://registry.hub.docker.com/v2/repositories/library/wordpress/tags?page_size={$pageSize}&page={$page}";
|
||||
$response = file_get_contents($url);
|
||||
$data = json_decode($response, true);
|
||||
return array_column($data['results'], 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* We prefer the latest patch versions of WordPress with specified PHP versions.
|
||||
* For example: 6.5.4-php8.3
|
||||
*/
|
||||
function filterVersions(array $versions): array {
|
||||
return array_filter($versions, fn($version) => preg_match('/^\d+\.\d+\.\d+-php\d+\.\d+$/', $version));
|
||||
}
|
||||
|
||||
/**
|
||||
* We sort the versions by WordPress version and PHP version.
|
||||
* The expected output is:
|
||||
* - 6.5.4-php8.3
|
||||
* - 6.5.4-php8.2
|
||||
* - 6.5.3-php8.3
|
||||
* - 6.5.3-php8.2
|
||||
*/
|
||||
function sortVersions(&$versions) {
|
||||
usort($versions, function($a, $b) {
|
||||
[$wpA, $phpA] = explode('-php', $a);
|
||||
[$wpB, $phpB] = explode('-php', $b);
|
||||
|
||||
$wpCompare = version_compare($wpB, $wpA);
|
||||
return $wpCompare !== 0 ? $wpCompare : version_compare($phpB, $phpA);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function group docker tags by the WordPress version and returns the latest with the higher PHP version
|
||||
* abd the previous with the lower PHP version.
|
||||
*/
|
||||
function getLatestAndPreviousVersions(array $sortedVersions): array {
|
||||
$uniqueVersions = [];
|
||||
foreach ($sortedVersions as $version) {
|
||||
[$wpVersion] = explode('-php', $version);
|
||||
$majorMinorVersion = preg_replace('/\.\d+$/', '', $wpVersion);
|
||||
$uniqueVersions[$majorMinorVersion][] = $version;
|
||||
}
|
||||
|
||||
krsort($uniqueVersions);
|
||||
$latestVersionGroup = reset($uniqueVersions);
|
||||
$previousVersionGroup = next($uniqueVersions);
|
||||
|
||||
$latestVersion = $latestVersionGroup === false ? null : reset($latestVersionGroup);
|
||||
$previousVersion = $previousVersionGroup === false ? null : end($previousVersionGroup);
|
||||
|
||||
return [$latestVersion, $previousVersion];
|
||||
}
|
||||
|
||||
/**
|
||||
* We specify the latest WordPress version only in the docker-compose file for the tests.
|
||||
*/
|
||||
function replaceLatestWordPressVersion(string $latestVersion): void {
|
||||
replaceVersionInFile(
|
||||
__DIR__ . './../../../tests_env/docker/docker-compose.yml',
|
||||
'/(wordpress:\${WORDPRESS_IMAGE_VERSION:-\s*)\d+\.\d+\.?\d*-php\d+\.\d+(})/',
|
||||
'${1}' . $latestVersion . '${2}'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* We use the previous WordPress version only in the CircleCI config file.
|
||||
*/
|
||||
function replacePreviousWordPressVersion(string $previousVersion): void {
|
||||
replaceVersionInFile(
|
||||
__DIR__ . './../../../.circleci/config.yml',
|
||||
'/(wordpress_version: )\d+\.\d+\.?\d*/',
|
||||
'${1}' . $previousVersion
|
||||
);
|
||||
}
|
||||
|
||||
$allVersions = [];
|
||||
$page = 1;
|
||||
$maxPages = 8;
|
||||
$latestVersion = null;
|
||||
$previousVersion = null;
|
||||
|
||||
echo "Fetching WordPress versions...\n";
|
||||
|
||||
// We fetch the versions until we find the latest and previous versions. But there is a limit of 4 pages.
|
||||
while (($latestVersion === null || $previousVersion === null) && $page <= $maxPages) {
|
||||
echo "Fetching page $page...\n";
|
||||
$versions = getWordpressVersions($page);
|
||||
$allVersions = array_merge($allVersions, $versions);
|
||||
$allVersions = filterVersions($allVersions);
|
||||
sortVersions($allVersions);
|
||||
[$latestVersion, $previousVersion] = getLatestAndPreviousVersions($allVersions);
|
||||
$page++;
|
||||
}
|
||||
|
||||
echo "Latest version: $latestVersion\n";
|
||||
echo "Previous version: $previousVersion\n";
|
||||
|
||||
if ($latestVersion) {
|
||||
echo "Replacing the latest version in the docker file...\n";
|
||||
replaceLatestWordPressVersion($latestVersion);
|
||||
} else {
|
||||
echo "No latest version found.\n";
|
||||
}
|
||||
|
||||
if ($previousVersion) {
|
||||
echo "Replacing the previous version in the config file...\n";
|
||||
// We install previous WordPress version via CLI so we need a version without PHP in the name.
|
||||
$previousVersion = preg_replace('/-php\d+\.\d+$/', '', $previousVersion);
|
||||
replacePreviousWordPressVersion($previousVersion);
|
||||
} else {
|
||||
echo "No previous version found.\n";
|
||||
}
|
||||
|
||||
saveVersionsToFiles($latestVersion, $previousVersion, 'wordpress_version.txt');
|
156
.github/workflows/scripts/helpers.php
vendored
156
.github/workflows/scripts/helpers.php
vendored
@ -1,156 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Function replacing versions in a file by the regex pattern.
|
||||
*/
|
||||
function replaceVersionInFile(string $filePath, string $pattern, string $replacement): void {
|
||||
$content = file_get_contents($filePath);
|
||||
|
||||
if ($content === false) {
|
||||
die("Failed to read the file at $filePath.");
|
||||
}
|
||||
|
||||
$updatedContent = preg_replace($pattern, $replacement, $content);
|
||||
|
||||
if ($updatedContent === null || $updatedContent === $content) {
|
||||
echo "Nothing to update in $filePath\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_put_contents($filePath, $updatedContent) === false) {
|
||||
die("Failed to write the updated file at $filePath.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to filter stable versions from a list of versions.
|
||||
*/
|
||||
function filterStableVersions(array $versions): array {
|
||||
return array_filter($versions, function($version) {
|
||||
// Only include stable versions (exclude versions with -rc, -beta, -alpha, etc.)
|
||||
return preg_match('/^\d+\.\d+\.\d+$/', $version);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the latest and previous minor/major versions from a list of versions.
|
||||
*/
|
||||
function getLatestAndPreviousMinorMajorVersions(array $versions): array {
|
||||
usort($versions, 'version_compare');
|
||||
$currentVersion = end($versions);
|
||||
|
||||
$previousVersion = null;
|
||||
foreach (array_reverse($versions) as $version) {
|
||||
if (version_compare($version, $currentVersion, '<') && getMinorMajorVersion($version) !== getMinorMajorVersion($currentVersion)) {
|
||||
$previousVersion = $version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [$currentVersion, $previousVersion];
|
||||
}
|
||||
|
||||
function getMinorMajorVersion(string $version): string {
|
||||
$parts = explode('.', $version);
|
||||
return $parts[0] . '.' . $parts[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to fetch tags from a GitHub repository.
|
||||
*/
|
||||
function fetchGitHubTags(string $repo, string $token, int $page = 1, int $limit = 50): array {
|
||||
$url = "https://api.github.com/repos/$repo/tags?per_page=$limit&page=$page";
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0'); // GitHub API requires a user agent
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: token $token"
|
||||
]);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
die("Failed to fetch tags from GitHub.");
|
||||
}
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if (isset($data['message']) && $data['message'] == 'Not Found') {
|
||||
die("Repository not found or access denied.");
|
||||
}
|
||||
|
||||
return array_column($data, 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Function saving versions to a temporary files.
|
||||
* File containing latest version is prefixed with 'latest_' and previous version is prefixed with 'previous_'.
|
||||
*/
|
||||
function saveVersionsToFiles(?string $latestVersion, ?string $previousVersion, string $fileNameSuffix): void {
|
||||
file_put_contents("/tmp/latest_{$fileNameSuffix}", $latestVersion);
|
||||
file_put_contents("/tmp/previous_{$fileNameSuffix}", $previousVersion);
|
||||
}
|
||||
|
||||
function replaceLatestVersion(string $latestVersion, string $downloadCommand): void {
|
||||
replaceVersionInFile(
|
||||
__DIR__ . '/../../../.circleci/config.yml',
|
||||
'/(.\/do ' . $downloadCommand . ' )\d+\.\d+\.\d+/',
|
||||
'${1}' . $latestVersion
|
||||
);
|
||||
}
|
||||
|
||||
function replacePreviousVersion(string $previousVersion, string $configParameterName): void {
|
||||
replaceVersionInFile(
|
||||
__DIR__ . '/../../../.circleci/config.yml',
|
||||
'/(' . $configParameterName . ': )\d+\.\d+\.\d+/',
|
||||
'${1}' . $previousVersion
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function replacing the latest and previous versions of a private plugin in the config file.
|
||||
* The function fetches the tags from the GitHub repository, filters stable versions,
|
||||
* gets the latest and previous minor/major versions, and replaces the versions in the CircleCI config file.
|
||||
*/
|
||||
function replacePrivatePluginVersion(
|
||||
string $repository,
|
||||
string $downloadCommand,
|
||||
string $configParameterName,
|
||||
string $versionsFilename
|
||||
): void {
|
||||
// Read the GitHub token from environment variable
|
||||
$token = getenv('GH_TOKEN');
|
||||
if (!$token) {
|
||||
die("GitHub token not found. Make sure it's set in the environment variable 'GH_TOKEN'.");
|
||||
}
|
||||
|
||||
$page = 1;
|
||||
$latestVersion = null;
|
||||
$previousVersion = null;
|
||||
$allVersions = [];
|
||||
while (($latestVersion === null || $previousVersion === null) && $page < 10) {
|
||||
$allVersions = array_merge($allVersions, fetchGitHubTags($repository, $token, $page));
|
||||
$stableVersions = filterStableVersions($allVersions);
|
||||
[$latestVersion, $previousVersion] = getLatestAndPreviousMinorMajorVersions($stableVersions);
|
||||
$page++;
|
||||
}
|
||||
|
||||
echo "Latest version: $latestVersion\n";
|
||||
echo "Previous version: $previousVersion\n";
|
||||
|
||||
if ($latestVersion) {
|
||||
echo "Replacing the latest version in the config file...\n";
|
||||
replaceLatestVersion($latestVersion, $downloadCommand);
|
||||
} else {
|
||||
echo "No latest version found.\n";
|
||||
}
|
||||
|
||||
if ($previousVersion) {
|
||||
echo "Replacing the previous version in the config file...\n";
|
||||
replacePreviousVersion($previousVersion, $configParameterName);
|
||||
} else {
|
||||
echo "No previous version found.\n";
|
||||
}
|
||||
|
||||
saveVersionsToFiles($latestVersion, $previousVersion, $versionsFilename);
|
||||
}
|
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
|
39
.gitignore
vendored
39
.gitignore
vendored
@ -1,13 +1,36 @@
|
||||
.DS_Store
|
||||
TODO
|
||||
/vendor
|
||||
/vendor-prefixed
|
||||
/vendor_backup
|
||||
/vendor-backup
|
||||
/vendor-prefixed-backup
|
||||
tests/_output/*
|
||||
tests/_support/_generated/*
|
||||
tests/plugins
|
||||
node_modules
|
||||
.env
|
||||
npm-debug.log
|
||||
!tasks/**
|
||||
/views/cache/**
|
||||
temp
|
||||
.idea
|
||||
.vscode
|
||||
dev/data
|
||||
mailpoet.zip
|
||||
tests/javascript_newsletter_editor/testBundles
|
||||
assets/dist
|
||||
.vagrant
|
||||
lang
|
||||
.mp_svn
|
||||
/nbproject/
|
||||
tests/_data/acceptanceBackup.sql
|
||||
lib/DI/CachedContainer.php
|
||||
prefixer/vendor
|
||||
prefixer/build
|
||||
docker-compose.override.yml
|
||||
node_modules
|
||||
npm-debug.log
|
||||
mailpoet-premium
|
||||
tsconfig.tsbuildinfo
|
||||
/wordpress
|
||||
packages/php/*/vendor
|
||||
tests_env/vendor
|
||||
tasks/code_sniffer/vendor
|
||||
tasks/phpstan/vendor
|
||||
tasks/phpstan/_phpstan-wp-source.neon
|
||||
/tools/vendor
|
||||
/storybook-static
|
||||
assets/js/src/newsletter_editor/behaviors/tinymce_icons.js
|
||||
|
@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
. "$(dirname "$0")/../mailpoet/.env"
|
||||
|
||||
export MP_GIT_HOOKS_ENABLE="${MP_GIT_HOOKS_ENABLE:-true}"
|
||||
export MP_GIT_HOOKS_ESLINT="${MP_GIT_HOOKS_ESLINT:-true}"
|
||||
export MP_GIT_HOOKS_STYLELINT="${MP_GIT_HOOKS_STYLELINT:-true}"
|
||||
export MP_GIT_HOOKS_PHPLINT="${MP_GIT_HOOKS_PHPLINT:-true}"
|
||||
export MP_GIT_HOOKS_CODE_SNIFFER="${MP_GIT_HOOKS_CODE_SNIFFER:-true}"
|
||||
export MP_GIT_HOOKS_PHPSTAN="${MP_GIT_HOOKS_PHPSTAN:-true}"
|
||||
export MP_GIT_HOOKS_INSTALL_JS="${MP_GIT_HOOKS_INSTALL_JS:-false}"
|
||||
export MP_GIT_HOOKS_INSTALL_PHP="${MP_GIT_HOOKS_INSTALL_PHP:-false}"
|
||||
|
||||
fileChanged() {
|
||||
local filePattern="$1"
|
||||
local changedFiles="$2"
|
||||
if echo "$changedFiles" | grep -qE "$filePattern"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
installIfUpdates() {
|
||||
local changedFiles="$(git diff-tree -r --name-only --no-commit-id HEAD@{1} HEAD)"
|
||||
|
||||
if [ "$MP_GIT_HOOKS_INSTALL_JS" = "true" ] && fileChanged "pnpm-lock.yaml" "$changedFiles"; then
|
||||
echo "Change detected in pnpm-lock.yaml, running do install:js"
|
||||
pushd mailpoet
|
||||
./do install:js
|
||||
popd
|
||||
fi
|
||||
|
||||
if [ "$MP_GIT_HOOKS_INSTALL_PHP" = "true" ] && fileChanged "mailpoet/composer.lock" "$changedFiles"; then
|
||||
echo "Change detected in mailpoet/composer.lock, running do install:php"
|
||||
pushd mailpoet
|
||||
./do install:php
|
||||
popd
|
||||
fi
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
. "$(dirname "$0")/common.sh"
|
||||
[ "$MP_GIT_HOOKS_ENABLE" != "true" ] && exit 0
|
||||
|
||||
installIfUpdates
|
||||
|
||||
./do cleanup:cached-files
|
@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
. "$(dirname "$0")/common.sh"
|
||||
[ "$MP_GIT_HOOKS_ENABLE" != "true" ] && exit 0
|
||||
|
||||
|
||||
installIfUpdates
|
@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
. "$(dirname "$0")/common.sh"
|
||||
[ "$MP_GIT_HOOKS_ENABLE" != "true" ] && exit 0
|
||||
|
||||
|
||||
installIfUpdates
|
@ -1,8 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/common.sh"
|
||||
[ "$MP_GIT_HOOKS_ENABLE" != "true" ] && exit 0
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged -c mailpoet/package.json --cwd mailpoet
|
||||
npx lint-staged -c package.json
|
||||
npx lint-staged -c packages/js/email-editor/package.json --cwd packages/js/email-editor
|
||||
npx lint-staged -c packages/php/email-editor/.lintstagedrc.json --cwd packages/php/email-editor
|
||||
npx lint-staged
|
||||
|
3
.npmrc
3
.npmrc
@ -1,2 +1 @@
|
||||
auto-install-peers=false
|
||||
strict-peer-dependencies=false
|
||||
engine-strict=true
|
||||
|
@ -1,22 +0,0 @@
|
||||
function readPackage(pkg) {
|
||||
// Resolve @wordpress/* dependencies of @woocommerce packages to those used by MailPoet.
|
||||
// This avoids their duplication and downgrading due to @woocommerce pinning them to wp-6.0.
|
||||
// This should be removed once we adopt similar pinning strategy and use dependency extraction.
|
||||
// See: https://github.com/woocommerce/woocommerce/pull/37034
|
||||
if (pkg.name?.startsWith('@woocommerce/')) {
|
||||
pkg.dependencies = Object.fromEntries(
|
||||
Object.entries(pkg.dependencies).map(([name, version]) =>
|
||||
name.startsWith('@wordpress/') || name.startsWith('@types/wordpress__')
|
||||
? [name, '*']
|
||||
: [name, version],
|
||||
),
|
||||
);
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hooks: {
|
||||
readPackage,
|
||||
},
|
||||
};
|
@ -1,29 +0,0 @@
|
||||
*.hbs
|
||||
.mp_svn
|
||||
_generated
|
||||
_output
|
||||
composer.json
|
||||
composer.lock
|
||||
node_modules
|
||||
pnpm-lock.yaml
|
||||
vendor
|
||||
vendor-prefixed
|
||||
/.mp_svn
|
||||
/dev/data
|
||||
/mailpoet/assets/dist
|
||||
/mailpoet/assets/js/lib
|
||||
/mailpoet/assets/js/src/newsletter-editor/behaviors/tinymce-icons.js
|
||||
/mailpoet/generated
|
||||
/mailpoet/lang
|
||||
/mailpoet/lib/Newsletter/Renderer/Template.html
|
||||
/mailpoet/lib-3rd-party
|
||||
/mailpoet/plugin_repository
|
||||
/mailpoet/temp
|
||||
/mailpoet/tests/javascript-newsletter-editor/testBundles
|
||||
/mailpoet/tests/plugins
|
||||
/mailpoet/tools/wpscan-semgrep-rules
|
||||
/mailpoet/views
|
||||
/mailpoet-premium
|
||||
/wordpress
|
||||
/packages/php/email-editor
|
||||
/packages/js/email-editor
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
48
.storybook/main.js
Normal file
48
.storybook/main.js
Normal file
@ -0,0 +1,48 @@
|
||||
const path = require('path');
|
||||
|
||||
const modulesDir = path.join( __dirname, '../node_modules' );
|
||||
console.log('NODE', modulesDir);
|
||||
// Workaround for Emotion 11
|
||||
// https://github.com/storybookjs/storybook/pull/13300#issuecomment-783268111
|
||||
const updateEmotionAliases = (config) => ({
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
alias: {
|
||||
...config.resolve.alias,
|
||||
'@emotion/core': path.join(modulesDir, '@emotion/react'),
|
||||
'@emotion/styled': path.join(modulesDir, '@emotion/styled'),
|
||||
'@emotion/styled-base': path.join(modulesDir, '@emotion/styled'),
|
||||
'emotion-theming': path.join(modulesDir, '@emotion/react'),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
core: {
|
||||
builder: 'webpack5',
|
||||
},
|
||||
stories: ['../assets/js/src/**/_stories/*.tsx'],
|
||||
webpackFinal: (config) => {
|
||||
config.resolve.modules = ['node_modules', '../assets/js/src'];
|
||||
return updateEmotionAliases(config);
|
||||
},
|
||||
managerWebpack: updateEmotionAliases,
|
||||
addons: [
|
||||
'@storybook/addon-actions',
|
||||
'@storybook/addon-links',
|
||||
'storybook-addon-performance/register',
|
||||
{
|
||||
name: '@storybook/addon-storysource',
|
||||
options: {
|
||||
rule: {
|
||||
test: [/_stories\/.*\.tsx?$/],
|
||||
include: [path.resolve(__dirname, '../assets/js/src')],
|
||||
},
|
||||
loaderOptions: {
|
||||
parser: 'typescript',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
9
.storybook/preview.js
Normal file
9
.storybook/preview.js
Normal file
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import { addDecorator } from '@storybook/react';
|
||||
import { withPerformance } from 'storybook-addon-performance';
|
||||
import '../assets/css/src/storybook/wordpress-buttons-5.7.2.css';
|
||||
import '../assets/dist/css/mailpoet-plugin.css';
|
||||
import '../assets/dist/css/mailpoet-form-editor.css';
|
||||
|
||||
addDecorator(withPerformance);
|
||||
addDecorator(story => <div class="wp-core-ui" id="wpbody"><div id="mailpoet-modal"></div>{story()}</div>);
|
110
.stylelintrc
Normal file
110
.stylelintrc
Normal file
@ -0,0 +1,110 @@
|
||||
{
|
||||
"plugins": [
|
||||
"stylelint-order",
|
||||
"stylelint-scss"
|
||||
],
|
||||
"customSyntax": "postcss-scss",
|
||||
"rules": {
|
||||
"at-rule-empty-line-before": ["always", {
|
||||
except: ["first-nested", "blockless-after-blockless"],
|
||||
}],
|
||||
"at-rule-name-case": "lower",
|
||||
"at-rule-semicolon-newline-after": "always",
|
||||
"block-closing-brace-empty-line-before": "never",
|
||||
"block-closing-brace-newline-after": "always",
|
||||
"block-closing-brace-newline-before": "always-multi-line",
|
||||
"block-closing-brace-space-before": "always-single-line",
|
||||
"block-no-empty": true,
|
||||
"block-opening-brace-newline-after": "always-multi-line",
|
||||
"block-opening-brace-space-after": "always-single-line",
|
||||
"block-opening-brace-space-before": "always",
|
||||
"color-hex-case": "lower",
|
||||
"color-hex-length": "short",
|
||||
"color-no-invalid-hex": true,
|
||||
"comment-no-empty": true,
|
||||
"comment-whitespace-inside": "always",
|
||||
"declaration-bang-space-after": "never",
|
||||
"declaration-bang-space-before": "always",
|
||||
"declaration-block-no-duplicate-properties": [true, {
|
||||
ignore: ["consecutive-duplicates-with-different-values"],
|
||||
}],
|
||||
"declaration-block-no-redundant-longhand-properties": [true, {
|
||||
ignoreShorthands: [/flex/, /grid/]
|
||||
}],
|
||||
"declaration-block-semicolon-newline-after": "always-multi-line",
|
||||
"declaration-block-semicolon-space-after": "always-single-line",
|
||||
"declaration-block-semicolon-space-before": "never",
|
||||
"declaration-block-single-line-max-declarations": 1,
|
||||
"declaration-colon-newline-after": "always-multi-line",
|
||||
"declaration-colon-space-after": "always-single-line",
|
||||
"declaration-colon-space-before": "never",
|
||||
"declaration-empty-line-before": "never",
|
||||
"font-family-no-duplicate-names": true,
|
||||
"function-comma-space-after": "always-single-line",
|
||||
"function-comma-space-before": "never",
|
||||
"function-max-empty-lines": 0,
|
||||
"function-name-case": "lower",
|
||||
"function-parentheses-newline-inside": "always-multi-line",
|
||||
"function-parentheses-space-inside": "never-single-line",
|
||||
"function-url-quotes": "always",
|
||||
"function-whitespace-after": "always",
|
||||
"indentation": 2,
|
||||
"keyframe-declaration-no-important": true,
|
||||
"length-zero-no-unit": true,
|
||||
"max-empty-lines": 1,
|
||||
"media-feature-colon-space-after": "always",
|
||||
"media-feature-colon-space-before": "never",
|
||||
"media-feature-name-case": "lower",
|
||||
"media-feature-name-no-unknown": true,
|
||||
"media-feature-parentheses-space-inside": "never",
|
||||
"media-feature-range-operator-space-after": "always",
|
||||
"media-query-list-comma-newline-after": "always-multi-line",
|
||||
"media-query-list-comma-space-after": "always-single-line",
|
||||
"media-query-list-comma-space-before": "never",
|
||||
"no-duplicate-selectors": true,
|
||||
"no-eol-whitespace": true,
|
||||
"no-extra-semicolons": true,
|
||||
"no-missing-end-of-source-newline": true,
|
||||
"number-leading-zero": "never",
|
||||
"number-no-trailing-zeros": true,
|
||||
"order/properties-alphabetical-order": true,
|
||||
"property-case": "lower",
|
||||
"property-no-unknown": true,
|
||||
"rule-empty-line-before": ["always-multi-line", {
|
||||
except: ["first-nested"],
|
||||
ignore: ["after-comment"]
|
||||
}],
|
||||
"scss/at-rule-no-unknown": true,
|
||||
"scss/dollar-variable-colon-space-after": "always",
|
||||
"scss/dollar-variable-colon-space-before": "never",
|
||||
"scss/operator-no-newline-after": true,
|
||||
"scss/operator-no-newline-before": true,
|
||||
"scss/operator-no-unspaced": true,
|
||||
"scss/selector-no-redundant-nesting-selector": true,
|
||||
"selector-attribute-brackets-space-inside": "never",
|
||||
"selector-attribute-operator-space-after": "never",
|
||||
"selector-attribute-operator-space-before": "never",
|
||||
"selector-combinator-space-after": "always",
|
||||
"selector-combinator-space-before": "always",
|
||||
"selector-list-comma-newline-after": "always",
|
||||
"selector-list-comma-space-before": "never",
|
||||
"selector-max-empty-lines": 0,
|
||||
"selector-nested-pattern": "^(?!&-|&_).*",
|
||||
"selector-pseudo-class-case": "lower",
|
||||
"selector-pseudo-class-no-unknown": true,
|
||||
"selector-pseudo-class-parentheses-space-inside": "never",
|
||||
"selector-pseudo-element-case": "lower",
|
||||
"selector-pseudo-element-colon-notation": "single",
|
||||
"selector-pseudo-element-no-unknown": true,
|
||||
"selector-type-case": "lower",
|
||||
"shorthand-property-no-redundant-values": true,
|
||||
"string-no-newline": true,
|
||||
"string-quotes": "single",
|
||||
"unit-case": "lower",
|
||||
"unit-no-unknown": true,
|
||||
"value-list-comma-newline-after": "always-multi-line",
|
||||
"value-list-comma-space-after": "always-single-line",
|
||||
"value-list-comma-space-before": "never",
|
||||
"value-list-max-empty-lines": 0,
|
||||
},
|
||||
}
|
9
.tx/config
Normal file
9
.tx/config
Normal file
@ -0,0 +1,9 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[mp3.mailpoet]
|
||||
file_filter = lang/mailpoet-<lang>.po
|
||||
minimum_perc = 30
|
||||
source_file = lang/mailpoet.pot
|
||||
source_lang = en_US
|
||||
type = PO
|
@ -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
|
@ -1,51 +1,45 @@
|
||||
# Contributing
|
||||
|
||||
There is a `./do` command that helps with the development process. See [README](README.md) for more details.
|
||||
|
||||
## PHP Code
|
||||
|
||||
- Two spaces indentation.
|
||||
- Space between keyword and left bracket (`if ()`, `for ()`, `switch ()`...).
|
||||
- `CamelCase` for classes.
|
||||
- `camelCase` for methods.
|
||||
- `snake_case` for variables and class properties.
|
||||
- Space between keyword (if, for, switch...) and left bracket
|
||||
- CamelCase for classes.
|
||||
- camelCase for methods.
|
||||
- snake_case for variables and class properties.
|
||||
- Composition over Inheritance.
|
||||
- Comments are a code smell. If you need to use a comment - see if same idea can be achieved by more clearly expressing code.
|
||||
- Require other classes with `use` at the beginning of the class file.
|
||||
- Require other classes with 'use' at the beginning of the class file.
|
||||
- Do not specify 'public' if method is public, it's implicit.
|
||||
- Always use guard clauses.
|
||||
- Ensure compatibility with PHP 7.4 and newer versions.
|
||||
- Ensure compatibility with PHP 7.1 and newer versions.
|
||||
- Cover your code in tests.
|
||||
|
||||
## SCSS Code
|
||||
|
||||
- `kebab-case` for file names.
|
||||
- Components files are prefixed with underscore, to indicate, that they aren't compiled separately (`_new-component.scss`).
|
||||
- camelCase for file name
|
||||
- Components files are prefixed with underscore, to indicate, that they aren't compiled separately.
|
||||
|
||||
## JS Code
|
||||
|
||||
- Javascript code should follow the [Airbnb style guide](https://github.com/airbnb/javascript).
|
||||
- Prefer named export before default export in JS and TS files
|
||||
- Default to TypeScript for new files.
|
||||
|
||||
## Disabling linting rules
|
||||
|
||||
- We want to avoid using `eslint-disable`
|
||||
- If we have to use it we need to use a comment explaining why do we need it:
|
||||
`/* eslint-disable no-new -- this class has a side-effect in the constructor and it's a library's. */`
|
||||
- For PHP we do the same with the exception `// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps` which for now doesn’t require an explanation
|
||||
- we want to avoid using `eslint-disable`
|
||||
- if we have to use it we need to use a comment explaining why do we need it:
|
||||
`/* eslint-disable no-new -- this class has a side-effect in the constructor and it's a library's. */`
|
||||
- for PHP we do the same with the exception `// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps` which for now doesn’t require an explanation
|
||||
|
||||
## Git flow
|
||||
|
||||
- Do not commit to trunk.
|
||||
- Do not commit to master.
|
||||
- Open a short-living feature branch.
|
||||
- Use good commit messages as explained here https://chris.beams.io/posts/git-commit. Include Jira ticket in the commit message.
|
||||
- Open a pull request.
|
||||
- Add Jira issue reference in the title of the Pull Request.
|
||||
- Work on the pull request.
|
||||
- Use the `./do qa` command to check your code style before pushing.
|
||||
- Create a pull request when finished. Include Jira ticket in the title of the pull request.
|
||||
- Use good commit messages as explained here https://chris.beams.io/posts/git-commit
|
||||
- Wait for review from another developer.
|
||||
|
||||
## Feature flags
|
||||
## Issues creation
|
||||
- Issues are managed on Jira.
|
||||
- Discuss issues on public Slack chats, discuss code in pull requests.
|
||||
- Open a small Jira issue only when it has been discussed.
|
||||
|
||||
We use feature flags to control the visibility of new features. This allows us to work on new features in smaller chunks before they are released to all customers.
|
||||
|
||||
- Feature flags can be enabled on the experimental page: `/admin.php?page=mailpoet-experimental`.
|
||||
- New feature flags can be added in the class `FeaturesController`.
|
||||
|
354
README.md
354
README.md
@ -1,218 +1,218 @@
|
||||
### Table of Contents
|
||||
# MailPoet
|
||||
|
||||
1. [MailPoet](#mailpoet)
|
||||
2. [Initial setup](#initial-setup)
|
||||
1. [Additional dependencies](#additional-dependencies)
|
||||
3. [Xdebug](#xdebug)
|
||||
1. [PhpStorm setup](#phpstorm-setup)
|
||||
2. [Xdebug develop mode](#xdebug-develop-mode)
|
||||
3. [Xdebug for integration tests](#xdebug-for-integration-tests)
|
||||
4. [Local development](#local-development)
|
||||
1. [NFS volume sharing for Mac](#nfs-volume-sharing-for-mac)
|
||||
2. [Husky hooks](#husky-hooks)
|
||||
5. [Docker](#docker)
|
||||
1. [Commands](#commands)
|
||||
2. [Available PHP versions](#available-php-versions)
|
||||
3. [Disabling the Tracy panel](#disabling-the-tracy-panel)
|
||||
4. [Running individual tests](#running-individual-tests)
|
||||
6. [TODO](#todo)
|
||||
MailPoet done the right way.
|
||||
|
||||
## MailPoet
|
||||
# Contents
|
||||
|
||||
The **MailPoet** plugin monorepo.
|
||||
- [Setup](#setup)
|
||||
- [Frameworks and libraries](#frameworks-and-libraries)
|
||||
- [Workflow Commands](#workflow-commands)
|
||||
- [Coding and Testing](#coding-and-testing)
|
||||
|
||||
If you have **any questions or need help or support**, please see the [Support](SUPPORT.md) document.
|
||||
# Setup
|
||||
|
||||
To use our Docker-based development environment (recommended), continue with the steps below.
|
||||
If you'd like to use the plugin code directly, see details in [the plugin's readme](mailpoet/README.md).
|
||||
## Requirements
|
||||
- PHP >= 7.3 (only for the development environment, to run the plugin PHP >= 7.1 is required)
|
||||
- NodeJS
|
||||
- WordPress
|
||||
|
||||
## Initial setup
|
||||
## Installation
|
||||
|
||||
1. Run `./do setup` to pull everything and install necessary dependencies.
|
||||
2. Add secrets to `.env` files in `mailpoet` and `mailpoet-premium` directories. Go to the Secret Store and look for "MailPoet: plugin .env"
|
||||
3. Run `./do start` to start the stack.
|
||||
4. Go to http://localhost:8888 to see the dashboard of the dev environment.
|
||||
The instructions below assume you already have a working WordPress development environment.
|
||||
|
||||
### Additional dependencies
|
||||
|
||||
Even though it's possible to run everything using Docker, in the development workflow,
|
||||
it may be faster and more convenient to run some tasks outside the container. Therefore,
|
||||
the following tools are recommended:
|
||||
|
||||
1. **PHP** as per `composer.json` requirements.
|
||||
2. **Node.js**, as specified by `.nvmrc`. For automatic management use [nvm](https://github.com/nvm-sh/nvm), [FNM](https://github.com/Schniz/fnm), or [Volta](https://github.com/volta-cli/volta).
|
||||
3. **pnpm**, as specified in `package.json`. For automatic setup enable [Corepack](https://nodejs.org/docs/latest-v17.x/api/corepack.html) using `corepack enable`.
|
||||
|
||||
## Xdebug
|
||||
|
||||
### PhpStorm setup
|
||||
|
||||
In `Languages & Preferences > PHP > Servers` set path mappings:
|
||||
|
||||
```shell
|
||||
wordpress -> /var/www/html
|
||||
mailpoet -> /var/www/html/wp-content/plugins/mailpoet
|
||||
mailpoet-premium -> /var/www/html/wp-content/plugins/mailpoet-premium
|
||||
```bash
|
||||
# go to WP plugins directory
|
||||
$ cd path_to_wp_directory/wp-content/plugins
|
||||
# clone this repository
|
||||
$ git clone https://github.com/mailpoet/mailpoet.git
|
||||
$ cd mailpoet
|
||||
# create the .env file
|
||||
$ cp .env.sample .env
|
||||
# change the values on .env file
|
||||
# install all dependencies (PHP and JS)
|
||||
$ ./do install
|
||||
# compile JS and CSS files
|
||||
$ ./do compile:all
|
||||
```
|
||||
|
||||
For PHP 8 and XDebug 3 we support **browser debugging extension**.
|
||||
You can choose extension by your browser in [JetBrains documentation](https://www.jetbrains.com/help/phpstorm/browser-debugging-extensions.html).
|
||||
|
||||
To use XDebug inside the **cron**, you need to pass a URL argument `&XDEBUG_TRIGGER=yes`
|
||||
[in the cron request](https://github.com/mailpoet/mailpoet/blob/bf7bd6d2d9090ed6ec7b8b575bb7d6b08e663a52/lib/Cron/CronHelper.php#L155-L166).
|
||||
Alternatively, you can add `XDEBUG_TRIGGER: yes` to the `wordpress` service in `docker-compose.yml` and restart it (which will run XDebug also for all other requests).
|
||||
|
||||
### Xdebug develop mode
|
||||
|
||||
[Xdebug develop mode](https://xdebug.org/docs/develop) is disabled by default because it causes performance issues due to conflicts with the DI container.
|
||||
|
||||
It can be enabled when needed using the `XDEBUG_MODE` environment variable. For example, it is possible to enable it by adding the following to `docker-compose.override.yml`:
|
||||
|
||||
```
|
||||
environment:
|
||||
XDEBUG_MODE: debug, develop
|
||||
```
|
||||
|
||||
### Xdebug for integration tests
|
||||
|
||||
- In Languages & Preferences > PHP > Servers create a new sever named `MailPoetTest`, set the host to `localhost` and port to `80` and set following path mappings:
|
||||
|
||||
```shell
|
||||
wordpress -> /wp-core
|
||||
mailpoet -> /wp-core/wp-content/plugins/mailpoet
|
||||
mailpoet-premium -> /wp-core/wp-content/plugins/mailpoet-premium
|
||||
mailpoet/vendor/bin/codecept -> /project/vendor/bin/codecept
|
||||
mailpoet/vendor/bin/wp -> /usr/local/bin/wp
|
||||
```
|
||||
|
||||
- Add `XDEBUG_TRIGGER: 1` environment to `tests_env/docker/docker-compose.yml` -> codeception service to start triggering Xdebug
|
||||
- Make PHPStorm listen to connections by clicking on the phone icon
|
||||
|
||||
## Local development
|
||||
|
||||
### NFS volume sharing for Mac
|
||||
|
||||
NFS volumes can bring more stability and performance on Docker for Mac. To setup NFS volume sharing run:
|
||||
|
||||
```shell
|
||||
sudo sh dev/mac-nfs-setup.sh
|
||||
```
|
||||
|
||||
Then create a Docker Compose override file with NFS settings and restart containers:
|
||||
|
||||
```shell
|
||||
cp docker-compose.override.macos-sample.yml docker-compose.override.yml
|
||||
|
||||
docker compose down -v --remove-orphans
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**NOTE:** If you are on MacOS Catalina or newer, make sure to put the repository
|
||||
outside your `Documents` folder, otherwise you may run into [file permission issues](https://objekt.click/2019/11/docker-the-problem-with-macos-catalina/).
|
||||
|
||||
### Husky hooks
|
||||
|
||||
We use [Husky](https://github.com/typicode/husky) to run automated checks in pre-commit hooks.
|
||||
|
||||
In case you're using [NVM](https://github.com/nvm-sh/nvm) for Node version management you may
|
||||
need to create or update your `~/.huskyrc` file with:
|
||||
|
||||
####Note for NVM users
|
||||
In case you use nvm for node versions management you may need to create or update `~/.huskyrc` with:
|
||||
```sh
|
||||
# This loads nvm.sh and sets the correct PATH before running the hooks:
|
||||
# This loads nvm.sh and sets the correct PATH before running hook
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
```
|
||||
Without it, you may experience errors in some git clients.
|
||||
|
||||
Without it, you may experience errors in some Git clients.
|
||||
# Frameworks and libraries
|
||||
|
||||
## Docker
|
||||
- [Paris ORM](https://github.com/j4mie/paris).
|
||||
- [Symfony/dependency-injection](https://github.com/symfony/dependency-injection) ([docs for 3.4](https://symfony.com/doc/3.4/components/dependency_injection.html)).
|
||||
- [PHP-Scoper](https://github.com/humbug/php-scoper) for moving dependencies into MP namespace
|
||||
- [Twig](https://twig.symfony.com/) and [Handlebars](https://handlebarsjs.com/) are used for templates rendering.
|
||||
- [Monolog](https://seldaek.github.io/monolog/) is used for logging.
|
||||
- [Robo](https://robo.li/) is used to write and run workflow commands.
|
||||
- [Codeception](https://codeception.com/) is used to write unit and acceptance tests.
|
||||
- [Docker](https://www.docker.com/), [Docker Compose](https://docs.docker.com/compose/) and [Selenium](https://www.seleniumhq.org/) to run acceptance tests.
|
||||
- [React](https://reactjs.org/) is used to create most of UIs.
|
||||
- [Marionette](https://marionettejs.com/) is used to build the newsletters editor.
|
||||
- [SCSS](http://sass-lang.com/) is used to write styles.
|
||||
- [Mocha](https://mochajs.org/), [Chai](https://www.chaijs.com/) and [Sinon](https://sinonjs.org/) are used to write Javascript tests.
|
||||
- [ESLint](https://eslint.org/) is used to lint JS files.
|
||||
- [Webpack](https://webpack.js.org/) is used to bundle assets.
|
||||
|
||||
### Commands
|
||||
# Workflow Commands
|
||||
|
||||
The `./do` script define aliases for most of the commands you will need while working on plugins:
|
||||
```bash
|
||||
$ ./do install # install PHP and JS dependencies
|
||||
$ ./do update # update PHP and JS dependencies
|
||||
|
||||
```shell
|
||||
./do setup Setup the environment.
|
||||
./do start Start the docker containers.
|
||||
./do stop Stop the docker containers.
|
||||
./do ssh [--test] Run an interactive bash shell inside the plugin directory.
|
||||
./do run [--test] <command> Run a custom bash command in the wordpress container.
|
||||
./do acceptance [--premium] Run acceptance tests.
|
||||
./do build [--premium] Builds a .zip for the plugin.
|
||||
./do templates Generates templates classes and assets.
|
||||
./do [--test] [--premium] <command> Run './do <command>' inside the plugin directory.
|
||||
$ ./do compile:css # compiles SCSS files into CSS.
|
||||
$ ./do compile:js # bundles JS files for the browser.
|
||||
$ ./do compile:all # compiles CSS and JS files.
|
||||
|
||||
Options:
|
||||
--test Run the command using the 'test_wordpress' service.
|
||||
--premium Run the command inside the premium plugin.
|
||||
$ ./do watch:css # watch CSS files for changes and compile them.
|
||||
$ ./do watch:js # watch JS files for changes and compile them.
|
||||
|
||||
$ ./do test:unit [--file=...] [--debug]
|
||||
# runs the PHP unit tests.
|
||||
# if --file specified then only tests on that file are executed.
|
||||
# if --debug then tests are executed in debugging mode.
|
||||
$ ./do test:integration [--file=...] [--multisite] [--debug]
|
||||
# runs the PHP integration tests.
|
||||
# if --file specified then only tests on that file are executed.
|
||||
# if --multisite then tests are executed in a multisite wordpress setup.
|
||||
# if --debug then tests are executed in debugging mode.
|
||||
$ ./do test:multisite-integration # alias for ./do test:integration --multisite
|
||||
$ ./do test:debug-unit # alias for ./do test:unit --debug
|
||||
$ ./do test:debug-integration # alias for ./do test:integration --debug
|
||||
$ ./do test:failed-unit # run the last failing unit test.
|
||||
$ ./do test:failed-integration # run the last failing integration test.
|
||||
$ ./do test:coverage # run tests and output coverage information.
|
||||
$ ./do test:javascript # run the JS tests.
|
||||
$ ./do test:acceptance [--file=...] [--skip-deps]
|
||||
# run acceptances tests into a docker environment.
|
||||
# if --file given then only tests on that file are executed.
|
||||
# if --skip-deps then it skips installation of composer dependencies.
|
||||
$ ./do test:acceptance-multisite [--file=...] [--skip-deps]
|
||||
# download 3rd party plugins for tests
|
||||
# if you pass tag it will attempt to download zip for the tag otherwise it downloads the latest release
|
||||
# e.g. ./do download:woo-commerce-zip 5.20.0
|
||||
$ ./do download:woo-commerce-zip [<tag>]
|
||||
$ ./do download:woo-commerce-subscriptions-zip [<tag>]
|
||||
# same as test:acceptance but runs into a multisite wordpress setup.
|
||||
$ ./do delete:docker # stop and remove all running docker containers.
|
||||
|
||||
$ ./do qa:lint # PHP code linter.
|
||||
$ ./do qa:lint-javascript # JS code linter.
|
||||
$ ./do qa:phpstan # PHP code static analysis using PHPStan.
|
||||
$ ./do qa # PHP and JS linters.
|
||||
|
||||
$ ./do release:changelog-get [--version-name=...] # Prints out changelog and release notes for given version or for newest version.
|
||||
$ ./do release:changelog-update [--version-name=...] [--quiet] # Updates changelog in readme.txt for given version or for newest version.
|
||||
|
||||
$ ./do container:dump # Generates DI container cache.
|
||||
|
||||
$ ./do generate:data [<generatorName>] [<threads>] # Generates random usage data (Note: requires WooCommerce active) e.g. ./do generate:data past_revenues 4
|
||||
```
|
||||
|
||||
You can access this help in your command line running `./do` without parameters.
|
||||
# Storybook
|
||||
|
||||
### Available PHP versions
|
||||
We use [Storybook.js](https://storybook.js.org/) to showcase our React components, which can be used throughout the plugin.
|
||||
|
||||
To switch the environment to a different PHP version:
|
||||
## Usage
|
||||
|
||||
1. Check https://github.com/mailpoet/mailpoet/tree/trunk/dev for a list of available PHP versions. Each directory starting with `php` corresponds to a available version.
|
||||
2. Configure the `wordpress` service in `docker-compose.override.yml` to build from the desired PHP version Dockerfile (replace {PHP_VERSION} with the name of the directory that corresponds to the version that you want to use):
|
||||
Currently, we don't have Storybook published publicly, so developers need to run or build it locally.
|
||||
|
||||
```yaml
|
||||
wordpress:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dev/{PHP_VERSION}/Dockerfile
|
||||
```
|
||||
To run it locally (on `http://localhost:8083`) while watching the changes (recommended when developing new component), run
|
||||
|
||||
3. Run `docker compose build wordpress`.
|
||||
4. Start the stack with `./do start`.
|
||||
|
||||
To switch back to the default PHP version remove what was added in 2) and, run `docker compose build wordpress` for application container and `docker compose build test_wordpress` for tests container,
|
||||
and start the stack using `./do start`.
|
||||
|
||||
### Disabling the Tracy panel
|
||||
|
||||
To disable the Tracy panel, add the following to `docker-compose.override.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
wordpress:
|
||||
environment:
|
||||
MAILPOET_DISABLE_TRACY_PANEL: 1
|
||||
```bash
|
||||
./do storybook:watch
|
||||
```
|
||||
|
||||
### Running individual tests
|
||||
To build the static version, which can be accessed via browser, run
|
||||
|
||||
It's recommended to run tests in Docker. Free plugin tests can be run using --test flag (`./do --test`). However, to run a premium test, you need to ssh into test container (`./do ssh --test`) and run tests there.
|
||||
|
||||
#### Integration test in the free plugin
|
||||
|
||||
```shell
|
||||
./do --test test:integration --skip-deps --file=tests/integration/WP/EmojiTest.php
|
||||
```bash
|
||||
./do storybook:build
|
||||
```
|
||||
|
||||
#### Acceptance test in the free plugin
|
||||
which will create a `storybook-static` folder with all necessary files. Don't forget to rebuild it when new components are added.
|
||||
|
||||
```shell
|
||||
./do --test test:acceptance --skip-deps --file=tests/acceptance/Misc/MailpoetMenuCest.php
|
||||
## Building new components
|
||||
|
||||
- All stories should be located in `_stories` folder inside the component folder they belong to.
|
||||
- Run `./do storybook:watch` so all changes are automatically reflected in `http://localhost:8083`.
|
||||
- Examples are available in `assets/js/src/storybook_demo/_stories` folder.
|
||||
|
||||
# Coding and Testing
|
||||
|
||||
## DI
|
||||
|
||||
We use Symfony/dependency-injection container. Container configuration can be found in `libs/DI/ContainerFactory.php`
|
||||
The container is configured and used with minimum sub-dependencies to keep final package size small.
|
||||
You can check [the docs](https://symfony.com/doc/3.4/components/dependency_injection.html) to learn more about Symfony Container.
|
||||
|
||||
## PHP-Scoper
|
||||
|
||||
We use PHP-Scoper package to prevent plugin libraries conflicts in PHP. Two plugins may be using different versions of a library. PHP-Scoper prefix dependencies namespaces and they are then moved into `vendor-prefixed` directory.
|
||||
Dependencies handled by PHP-Scoper are configured in extra configuration files `prefixer/composer.json` and `prefixer/scoper.inc.php`. Installation and processing is triggered in post scripts of the main `composer.json` file.
|
||||
|
||||
## i18n
|
||||
|
||||
We use functions `__()`, `_n()` and `_x()` with domain `mailpoet` to translate strings.
|
||||
|
||||
**in PHP code**
|
||||
|
||||
```php
|
||||
__('text to translate', 'mailpoet');
|
||||
_n('single text', 'plural text', $number, 'mailpoet');
|
||||
_x('text to translate', 'context for translators', 'mailpoet');
|
||||
```
|
||||
|
||||
#### Unit/integration test in the premium plugin
|
||||
**in Twig views**
|
||||
|
||||
```shell
|
||||
./do ssh --test # to enter the container
|
||||
cd ../mailpoet-premium # switch to premium plugin directory
|
||||
./do test:unit --file=tests/unit/Config/EnvTest.php
|
||||
```html
|
||||
<%= __('text to translate') %>
|
||||
<%= _n('single text', 'plural text', $number) %>
|
||||
<%= _x('text to translate', 'context for translators') %>
|
||||
```
|
||||
|
||||
#### Acceptance test in the premium plugin
|
||||
The domain `mailpoet` will be added automatically by the Twig functions.
|
||||
|
||||
```shell
|
||||
cd ./mailpoet-premium # switch to premium plugin directory on your local machine
|
||||
./do test:acceptance --skip-deps --file tests/acceptance/PremiumCheckCest.php
|
||||
**in Javascript code**
|
||||
|
||||
First add the string to the translations block in the Twig view:
|
||||
|
||||
```html
|
||||
<% block translations %>
|
||||
<%= localize({
|
||||
'key': __('string to translate'),
|
||||
...
|
||||
}) %>
|
||||
<% endblock %>
|
||||
```
|
||||
|
||||
## TODO
|
||||
Then use `MailPoet.I18n.t('key')` to get the translated string on your Javascript code.
|
||||
|
||||
- [ ] Install WooCommerce
|
||||
- [ ] Install Members
|
||||
- [ ] Install other useful plugins by default
|
||||
## Acceptance testing
|
||||
|
||||
To run the whole acceptance testing suite you need the docker daemon to be running and after that use a command: `./do test:acceptance`.
|
||||
If you want to run only a single test use the parameter `--file`:
|
||||
```bash
|
||||
./do test:acceptance --skip-deps --file tests/acceptance/ReceiveStandardEmailCest.php
|
||||
```
|
||||
The argument `--skip-deps` is useful locally to speed up the run.
|
||||
|
||||
If there are some unexpected errors you can delete all the runtime and start again.
|
||||
To delete all the docker runtime for acceptance tests use the command `./do d:d`.
|
||||
|
||||
When debugging you can add `$i->pause();` in to your test which pauses the execution.
|
||||
|
||||
We are using Gravity Flow plugin's setup as an example for our acceptance test suite: https://www.stevenhenty.com/learn-acceptance-testing-deeply/
|
||||
|
||||
From the article above:
|
||||
|
||||
_Windows users only: enable hard drive sharing in the Docker settings._
|
||||
|
||||
The browser runs in a docker container. You can use a VNC client to watch the test run, follow instructions in official
|
||||
repo: https://github.com/SeleniumHQ/docker-selenium
|
||||
If you’re on a Mac, you can open vnc://localhost:5900 in Safari to watch the tests running in Chrome. If you’re on Windows, you’ll need a VNC client. Password: secret.
|
||||
|
1074
RoboFile.php
Normal file
1074
RoboFile.php
Normal file
File diff suppressed because it is too large
Load Diff
24
SUPPORT.md
24
SUPPORT.md
@ -1,5 +1,23 @@
|
||||
# Support
|
||||
# Getting Support
|
||||
|
||||
Please visit our [Support](https://www.mailpoet.com/support/) page. We have a team of Happiness Engineers ready to help you.
|
||||
Welcome to MailPoet!
|
||||
This isn't the right place to get support for using MailPoet,
|
||||
but the following resources are available below,
|
||||
thanks for understanding.
|
||||
|
||||
For feature requests, please use our [tracker](https://feedback.mailpoet.com).
|
||||
- [Support](https://www.mailpoet.com/support)
|
||||
- [Feature Requests](https://feedback.mailpoet.com)
|
||||
|
||||
*DO NOT* use the issue tracker to ask questions;
|
||||
use the links above for that.
|
||||
Questions posed to the issue tracker will be closed.
|
||||
|
||||
When reporting an issue, please include the following details:
|
||||
|
||||
- A narrative description of what you are trying to accomplish.
|
||||
- The expected results.
|
||||
- The actual results received.
|
||||
- We may ask for additional details: what version of the plugin you are using, and what PHP version
|
||||
was used to reproduce the issue.
|
||||
|
||||
You may also submit a failing test case as a pull request.
|
||||
|
@ -3,8 +3,7 @@ Style for Members plugin
|
||||
*/
|
||||
.members-tab-title {
|
||||
.mailpoet-icon-logo {
|
||||
background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTIuMDIgMTU2LjQiPjxwYXRoIGQ9Ik0zNy43MSw4OS4xYzMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFYzNS43bDE3LDQ1LjFhMTIuNjgsMTIuNjgsMCwwLDAsMy43LDUuNGMxLjYsMS4zLDQsMiw3LjIsMmExMi41NCwxMi41NCwwLDAsMCw1LjktMS40LDguNDEsOC40MSwwLDAsMCwzLjktNWwxOC4xLTUwVjgxYTguNTMsOC41MywwLDAsMCwyLjEsNi4xYzEuNCwxLjQsMy43LDIuMiw2LjksMi4yLDMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFY4LjdhNy40OCw3LjQ4LDAsMCwwLTMuMy02LjZjLTIuMS0xLjQtNS0yLjEtOC42LTIuMWExOS4zLDE5LjMsMCwwLDAtOS40LDIsMTEuNjMsMTEuNjMsMCwwLDAtNS4xLDYuOEw3NC45MSw2Ny4xLDU0LjQxLDguNGExMi40LDEyLjQsMCwwLDAtNC41LTYuMmMtMi4xLTEuNS01LTIuMi04LjgtMi4yYTE2LjUxLDE2LjUxLDAsMCwwLTguOSwyLjFjLTIuMywxLjUtMy41LDMuOS0zLjUsNy4yVjgwLjhjMCwyLjguNyw0LjgsMiw2LjJDMzIuMjEsODguNCwzNC40MSw4OS4xLDM3LjcxLDg5LjFaIiAvPjxwYXRoIGQ9Ik0xNDksMTE2LjZsLTIuNC0xLjlhNy40LDcuNCwwLDAsMC05LjQuMywxOS42NSwxOS42NSwwLDAsMS0xMi41LDQuNmgtMjEuNEEzNy4wOCwzNy4wOCwwLDAsMCw3NywxMzAuNWwtMS4xLDEuMi0xLjEtMS4xYTM3LjI1LDM3LjI1LDAsMCwwLTI2LjMtMTAuOUgyN2ExOS41OSwxOS41OSwwLDAsMS0xMi40LTQuNiw3LjI4LDcuMjgsMCwwLDAtOS40LS4zbC0yLjQsMS45QTcuNDMsNy40MywwLDAsMCwwLDEyMi4yYTcuMTQsNy4xNCwwLDAsMCwyLjQsNS43QTM3LjI4LDM3LjI4LDAsMCwwLDI3LDEzNy40aDIxLjZhMTkuNTksMTkuNTksMCwwLDEsMTguOSwxNC40di4yYy4xLjcsMS4yLDQuNCw4LjUsNC40czguNC0zLjcsOC41LTQuNHYtLjJhMTkuNTksMTkuNTksMCwwLDEsMTguOS0xNC40SDEyNWEzNy4yOCwzNy4yOCwwLDAsMCwyNC42LTkuNSw3LjQyLDcuNDIsMCwwLDAsMi40LTUuN0E3Ljg2LDcuODYsMCwwLDAsMTQ5LDExNi42WiIgLz48L3N2Zz4=')
|
||||
no-repeat center;
|
||||
background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTIuMDIgMTU2LjQiPjxwYXRoIGQ9Ik0zNy43MSw4OS4xYzMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFYzNS43bDE3LDQ1LjFhMTIuNjgsMTIuNjgsMCwwLDAsMy43LDUuNGMxLjYsMS4zLDQsMiw3LjIsMmExMi41NCwxMi41NCwwLDAsMCw1LjktMS40LDguNDEsOC40MSwwLDAsMCwzLjktNWwxOC4xLTUwVjgxYTguNTMsOC41MywwLDAsMCwyLjEsNi4xYzEuNCwxLjQsMy43LDIuMiw2LjksMi4yLDMuNSwwLDUuOS0uOCw3LjItMi4zYTgsOCwwLDAsMCwyLTUuNFY4LjdhNy40OCw3LjQ4LDAsMCwwLTMuMy02LjZjLTIuMS0xLjQtNS0yLjEtOC42LTIuMWExOS4zLDE5LjMsMCwwLDAtOS40LDIsMTEuNjMsMTEuNjMsMCwwLDAtNS4xLDYuOEw3NC45MSw2Ny4xLDU0LjQxLDguNGExMi40LDEyLjQsMCwwLDAtNC41LTYuMmMtMi4xLTEuNS01LTIuMi04LjgtMi4yYTE2LjUxLDE2LjUxLDAsMCwwLTguOSwyLjFjLTIuMywxLjUtMy41LDMuOS0zLjUsNy4yVjgwLjhjMCwyLjguNyw0LjgsMiw2LjJDMzIuMjEsODguNCwzNC40MSw4OS4xLDM3LjcxLDg5LjFaIiAvPjxwYXRoIGQ9Ik0xNDksMTE2LjZsLTIuNC0xLjlhNy40LDcuNCwwLDAsMC05LjQuMywxOS42NSwxOS42NSwwLDAsMS0xMi41LDQuNmgtMjEuNEEzNy4wOCwzNy4wOCwwLDAsMCw3NywxMzAuNWwtMS4xLDEuMi0xLjEtMS4xYTM3LjI1LDM3LjI1LDAsMCwwLTI2LjMtMTAuOUgyN2ExOS41OSwxOS41OSwwLDAsMS0xMi40LTQuNiw3LjI4LDcuMjgsMCwwLDAtOS40LS4zbC0yLjQsMS45QTcuNDMsNy40MywwLDAsMCwwLDEyMi4yYTcuMTQsNy4xNCwwLDAsMCwyLjQsNS43QTM3LjI4LDM3LjI4LDAsMCwwLDI3LDEzNy40aDIxLjZhMTkuNTksMTkuNTksMCwwLDEsMTguOSwxNC40di4yYy4xLjcsMS4yLDQuNCw4LjUsNC40czguNC0zLjcsOC41LTQuNHYtLjJhMTkuNTksMTkuNTksMCwwLDEsMTguOS0xNC40SDEyNWEzNy4yOCwzNy4yOCwwLDAsMCwyNC42LTkuNSw3LjQyLDcuNDIsMCwwLDAsMi40LTUuN0E3Ljg2LDcuODYsMCwwLDAsMTQ5LDExNi42WiIgLz48L3N2Zz4=') no-repeat center;
|
||||
background-size: contain;
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
@ -14,18 +13,15 @@ Style for Members plugin
|
||||
}
|
||||
|
||||
&:not([aria-selected='true']) .mailpoet-icon-logo {
|
||||
filter: invert(24%) sepia(95%) saturate(1872%) hue-rotate(179deg)
|
||||
brightness(93%) contrast(101%);
|
||||
filter: invert(24%) sepia(95%) saturate(1872%) hue-rotate(179deg) brightness(93%) contrast(101%);
|
||||
}
|
||||
|
||||
> a:hover .mailpoet-icon-logo,
|
||||
> a:active .mailpoet-icon-logo {
|
||||
filter: invert(49%) sepia(50%) saturate(3683%) hue-rotate(163deg)
|
||||
brightness(94%) contrast(101%);
|
||||
filter: invert(49%) sepia(50%) saturate(3683%) hue-rotate(163deg) brightness(94%) contrast(101%);
|
||||
}
|
||||
|
||||
&[aria-selected='true'] a .mailpoet-icon-logo {
|
||||
filter: invert(33%) sepia(0%) saturate(7%) hue-rotate(205deg)
|
||||
brightness(94%) contrast(87%);
|
||||
filter: invert(33%) sepia(0%) saturate(7%) hue-rotate(205deg) brightness(94%) contrast(87%);
|
||||
}
|
||||
}
|
22
assets/css/src/components-admin/_menu.scss
Normal file
22
assets/css/src/components-admin/_menu.scss
Normal file
@ -0,0 +1,22 @@
|
||||
@font-face {
|
||||
font-family: 'mailpoet-icon';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url('data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAYcAAsAAAAABdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDxIFHGNtYXAAAAFoAAAAVAAAAFQXVtKHZ2FzcAAAAbwAAAAIAAAACAAAABBnbHlmAAABxAAAAhQAAAIU239UpGhlYWQAAAPYAAAANgAAADYYSCB9aGhlYQAABBAAAAAkAAAAJAelA8ZobXR4AAAENAAAABQAAAAUCeMAAGxvY2EAAARIAAAADAAAAAwAKAEebWF4cAAABFQAAAAgAAAAIAAIAMJuYW1lAAAEdAAAAYYAAAGGmUoJ+3Bvc3QAAAX8AAAAIAAAACAAAwAAAAMC8gGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA6QADwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADgAAAAKAAgAAgACAAEAIOkA//3//wAAAAAAIOkA//3//wAB/+MXBAADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAgAA/8AD4wPAAGQAvwAAEzI2Nz4BNTQwOQEREx4BFzEeATM4ATMyNjcjPgE3MRMRHAExFBYXMR4BMzI2Nz4BNTA0OQERPAE1NCYnMS4BIyoBIyIGBzMOAQcVCwEuASc1LgEjKgEjIgYHMw4BFREUFhceATMFJy4BIyIGBzEOASsBOAExIgYHMQcnLgErAS4BJxcuASMiBgcxBw4BFTEcATEUFhcxHgEXMTM4ATEyFhcdARQWMzI2PQE+ATM4ATEzPgE3Iz4BNTwBOQEuASc19xEYBgYHbwQNCAgXEAEKEwkBCg0DdggGBxcPEhcHBgcMCgodEQEDAg8dDQEMEQSBhgQPCgscEwEDAQ8bDAELDAcGBxcQAtkQBg8JCRAHECoYjDJZIQcHIVkyjRgpEQEHEAkJDwYQCAoICCBSL40sRAwUJCMUDEQsjS9TIAEICAEKCAF5BwgHEQoBASv+2QsRBwcGBAUFEQoBSP6+AQILEwcHCAgHBxIKAQHdAQEBDBYGBwcHBggWDgH+gwGADRQHAQcHBwcHGBD+LA4UBwYHtAwFBQYGDhAmIQgHISYBEA4BBgcGBQwGEwsBAQsSBh0hATUoAQEEGRkEASk1ASEdBhMKAQELEwYBAAEAAAAAAACzy1ndXw889QALBAAAAAAA2qNuAAAAAADao24AAAD/wAPjA8AAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAA+MAAQAAAAAAAAAAAAAAAAAAAAUEAAAAAAAAAAAAAAACAAAAA+MAAAAAAAAACgAUAB4BCgABAAAABQDAAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEABwAAAAEAAAAAAAIABwBgAAEAAAAAAAMABwA2AAEAAAAAAAQABwB1AAEAAAAAAAUACwAVAAEAAAAAAAYABwBLAAEAAAAAAAoAGgCKAAMAAQQJAAEADgAHAAMAAQQJAAIADgBnAAMAAQQJAAMADgA9AAMAAQQJAAQADgB8AAMAAQQJAAUAFgAgAAMAAQQJAAYADgBSAAMAAQQJAAoANACkaWNvbW9vbgBpAGMAbwBtAG8AbwBuVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwaWNvbW9vbgBpAGMAbwBtAG8AbwBuaWNvbW9vbgBpAGMAbwBtAG8AbwBuUmVndWxhcgBSAGUAZwB1AGwAYQByaWNvbW9vbgBpAGMAbwBtAG8AbwBuRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==') format('woff');
|
||||
}
|
||||
|
||||
#wpbody {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
/* menu icon */
|
||||
#adminmenu #toplevel_page_mailpoet-newsletters .wp-menu-image:before {
|
||||
content: '\e900';
|
||||
font-family: 'mailpoet-icon';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#adminmenu .wp-menu-image img {
|
||||
max-width: 20px;
|
||||
}
|
@ -30,7 +30,9 @@
|
||||
.tox {
|
||||
/* Small style changes to better fit TinyMCE to our editor */
|
||||
&.tox-tinymce-inline {
|
||||
box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid $color-editor-border-content;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 3px 1px rgba(0, 0, 0, .05);
|
||||
|
||||
/* Fix for fixed TinyMCE toolbar to be above WP menu */
|
||||
z-index: 50001;
|
||||
@ -50,11 +52,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Override white button color when not selected or manipulated to let them match the background */
|
||||
.tox-tbtn:not(.tox-tbtn--enabled):not(:hover):not(:active) {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Slightly smaller TinyMCE button */
|
||||
.tox-tbtn:not(.tox-tbtn--select) {
|
||||
height: 28px;
|
||||
@ -89,13 +86,9 @@
|
||||
}
|
||||
|
||||
&.auto-fold #wpcontent {
|
||||
@include respond-to(medium-screen) {
|
||||
margin-left: 36px;
|
||||
}
|
||||
@include respond-to(medium-screen) { margin-left: 36px; }
|
||||
|
||||
@include respond-to(small-screen) {
|
||||
margin-left: 0;
|
||||
}
|
||||
@include respond-to(small-screen) { margin-left: 0; }
|
||||
}
|
||||
|
||||
.wrap {
|
||||
@ -152,11 +145,11 @@
|
||||
|
||||
/* Sidepanel overrides */
|
||||
.mailpoet_panel_body {
|
||||
margin: 0;
|
||||
margin: 19px;
|
||||
padding: 0;
|
||||
|
||||
.mailpoet_editor_settings h3 {
|
||||
margin: 19px 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,19 +179,4 @@
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix TinyMCE toolbar breaks when changing page zoom
|
||||
We can remove this code after following issues are fixed:
|
||||
- https://github.com/tinymce/tinymce/issues/8909
|
||||
- https://github.com/tinymce/tinymce/issues/8865
|
||||
We can also try removing this code after each update of tinymce
|
||||
*/
|
||||
@include respond-to(not-small-screen) {
|
||||
.tox .tox-toolbar {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.tox .tox-toolbar__group {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
111
assets/css/src/components-editor/_common.scss
Normal file
111
assets/css/src/components-editor/_common.scss
Normal file
@ -0,0 +1,111 @@
|
||||
a {
|
||||
color: $color-primary-button;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mailpoet_hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mailpoet_form_narrow_select2 span.select2-container {
|
||||
width: 103px !important;
|
||||
}
|
||||
|
||||
span.select2-container--open > span.select2-dropdown {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
span.select2-container--open > span.select2-dropdown li.select2-results__option {
|
||||
font-size: 13px;
|
||||
margin: 0 !important;
|
||||
|
||||
.select2-results__group {
|
||||
color: #bfbfbf;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.select2-results__option {
|
||||
font-size: 13px;
|
||||
padding-left: 15px;
|
||||
|
||||
&[aria-selected=true] {
|
||||
background-color: #eee;
|
||||
color: #444;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_settings_notice {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#mailpoet_editor_content ol,
|
||||
#mailpoet_editor_content ul {
|
||||
margin-left: 0;
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
#mailpoet_editor_content ul {
|
||||
list-style-type: disc;
|
||||
|
||||
ul {
|
||||
list-style-type: circle;
|
||||
|
||||
ul { list-style-type: square; }
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip-help-designer-subject-line div,
|
||||
.tooltip-help-designer-preheader div {
|
||||
z-index: 100001;
|
||||
}
|
||||
|
||||
.tooltip-help-send-preview {
|
||||
color: #fff;
|
||||
margin-top: -10px;
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.tooltip-help-designer-ideal-width {
|
||||
color: #656565;
|
||||
font-weight: normal;
|
||||
margin-left: 5px;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.tooltip-help-designer-full-width .dashicons {
|
||||
line-height: 34px;
|
||||
}
|
||||
|
||||
.tooltip-help-designer-full-width span {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.mailpoet_text_content p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.mailpoet_separator {
|
||||
margin: 17px 20px;
|
||||
}
|
||||
|
||||
.mailpoet_option_offset_left_small {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
input.mailpoet_option_offset_left_small {
|
||||
margin-left: 10px !important;
|
||||
}
|
||||
|
||||
.mailpoet_editor_messages {
|
||||
font-size: $font-size-small;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
}
|
||||
|
||||
#mailpoet_editor_heading_right .mailpoet_notice {
|
||||
padding-right: 40px;
|
||||
}
|
@ -18,13 +18,13 @@
|
||||
padding: 3px 7px;
|
||||
position: relative;
|
||||
transform: translateY(100%);
|
||||
transition: all 250ms cubic-bezier(0.42, 0, 0.58, 1);
|
||||
transition: all 250ms cubic-bezier(.42, 0, .58, 1);
|
||||
}
|
||||
|
||||
.mailpoet_resize_active & .mailpoet_tools_slider,
|
||||
&.mailpoet_display_tools .mailpoet_tools_slider {
|
||||
transform: translateY(0);
|
||||
transition: all 250ms cubic-bezier(0.42, 0, 0.58, 1), visibility 0s linear;
|
||||
transition: all 250ms cubic-bezier(.42, 0, .58, 1), visibility 0s linear;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
|
||||
&:hover svg,
|
||||
&:focus svg {
|
||||
opacity: 0.7;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.mailpoet_delete_block_confirmation {
|
54
assets/css/src/components-editor/components/_forms.scss
Normal file
54
assets/css/src/components-editor/components/_forms.scss
Normal file
@ -0,0 +1,54 @@
|
||||
.admin_page_mailpoet-newsletter-editor {
|
||||
.mailpoet_form_field {
|
||||
margin-bottom: 15px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.mailpoet_form_field_title {
|
||||
clear: both;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.mailpoet_form_field_title_small {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.mailpoet_form_field_title_inline {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.mailpoet_form_field_optional {
|
||||
color: $color-primary-inactive;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.mailpoet_form_field_radio_option,
|
||||
.mailpoet_form_field_checkbox_option {
|
||||
display: inline-block;
|
||||
line-height: 30px;
|
||||
margin-right: 5px;
|
||||
vertical-align: top;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_form_field_input_option {
|
||||
display: inline-block;
|
||||
|
||||
input[type=checkbox] {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_form_field_block {
|
||||
display: block;
|
||||
}
|
||||
}
|
23
assets/css/src/components-editor/components/_history.scss
Normal file
23
assets/css/src/components-editor/components/_history.scss
Normal file
@ -0,0 +1,23 @@
|
||||
.mailpoet_history_wrapper {
|
||||
display: flex;
|
||||
padding: 12px 20px;
|
||||
}
|
||||
|
||||
.mailpoet_history_arrow {
|
||||
cursor: pointer;
|
||||
margin-right: 20px;
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
height: 26px;
|
||||
stroke: $color-primary;
|
||||
vertical-align: top;
|
||||
width: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_history_arrow_inactive {
|
||||
cursor: not-allowed;
|
||||
|
||||
svg { stroke: $color-primary-inactive; }
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
.mailpoet_container_layer_active {
|
||||
.mailpoet_block {
|
||||
opacity: 0.4;
|
||||
opacity: .4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@ -19,11 +19,12 @@
|
||||
}
|
||||
|
||||
.mailpoet_layer_overlay {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
margin: 0 !important;
|
||||
overflow: hidden auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
@ -87,7 +87,7 @@
|
||||
|
||||
.mailpoet_editor_last_saved {
|
||||
color: $color-primary-inactive;
|
||||
font-size: 0.9em;
|
||||
font-size: .9em;
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
}
|
157
assets/css/src/components-editor/components/_sidebar.scss
Normal file
157
assets/css/src/components-editor/components/_sidebar.scss
Normal file
@ -0,0 +1,157 @@
|
||||
#mailpoet_editor_sidebar {
|
||||
border-bottom: $color-editor-border-content;
|
||||
border-left: $color-editor-border-content;
|
||||
color: $editor-sidebar-color;
|
||||
font-size: $editor-sidebar-font-size;
|
||||
|
||||
.mailpoet_sidebar_region {
|
||||
border-bottom: 1px solid $color-editor-border-content;
|
||||
border-left: 1px solid $color-editor-border-content;
|
||||
border-right: 0;
|
||||
border-top: 0;
|
||||
margin-bottom: 0;
|
||||
|
||||
&.closed .mailpoet_region_content {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_region_content {
|
||||
margin-top: 12px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
&,
|
||||
.postbox {
|
||||
background-color: $editor-sidebar-background;
|
||||
}
|
||||
|
||||
.postbox {
|
||||
padding-bottom: 20px;
|
||||
|
||||
&.closed {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
&.closed h3 {
|
||||
color: $color-primary-inactive;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h3,
|
||||
&:hover h3 {
|
||||
color: $color-primary;
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
padding: 17px 20px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h3,
|
||||
.handlediv {
|
||||
border: 0;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.handlediv {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.handlediv:before {
|
||||
color: $color-primary;
|
||||
content: '\f142';
|
||||
display: inline-block;
|
||||
font: 400 20px / 1 dashicons;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
position: relative;
|
||||
right: 18px;
|
||||
speak: none;
|
||||
text-decoration: none !important;
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
&.closed .handlediv:before {
|
||||
color: $color-primary-inactive;
|
||||
content: '\f140';
|
||||
}
|
||||
|
||||
&.closed:hover .handlediv:before {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_widget {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
padding: 0 13px 15px;
|
||||
text-align: center;
|
||||
width: $editor-widget-size;
|
||||
|
||||
&:nth-child(3n+1) {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.mailpoet_widget_icon {
|
||||
background-color: $color-white;
|
||||
border-radius: 3px;
|
||||
box-shadow: 1px 2px $editor-widget-shadow-color;
|
||||
box-sizing: border-box;
|
||||
color: $editor-widget-icon-color;
|
||||
fill: $editor-widget-icon-color;
|
||||
height: $editor-widget-size;
|
||||
line-height: $editor-widget-size;
|
||||
margin-bottom: 9px;
|
||||
text-align: center;
|
||||
width: $editor-widget-size;
|
||||
|
||||
/* Vertically align widget icon glyphs */
|
||||
> * {
|
||||
font-size: $editor-widget-icon-size;
|
||||
height: $editor-widget-icon-size;
|
||||
vertical-align: middle;
|
||||
width: $editor-widget-icon-size;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 1px solid $editor-widget-icon-color-hover;
|
||||
color: $editor-widget-icon-color-hover;
|
||||
fill: $editor-widget-icon-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
&.mailpoet_droppable_active {
|
||||
color: $editor-widget-icon-color-hover;
|
||||
fill: $editor-widget-icon-color-hover;
|
||||
|
||||
.mailpoet_widget_icon {
|
||||
border: 1px solid $editor-widget-icon-color-hover;
|
||||
box-shadow: none;
|
||||
color: $editor-widget-icon-color-hover;
|
||||
fill: $editor-widget-icon-color-hover;
|
||||
}
|
||||
|
||||
.mailpoet_widget_title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Browser preview modal */
|
||||
.mailpoet_browser_preview_wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mailpoet_browser_preview_link {
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
}
|
||||
|
||||
.mailpoet_popup .mailpoet_browser_preview_toggle {
|
||||
top: -30px;
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
.mailpoet_editor_settings {
|
||||
color: $editor-sidebar-color;
|
||||
font-size: $editor-sidebar-font-size;
|
||||
padding: 0 20px;
|
||||
|
||||
p {
|
||||
font-size: 1em;
|
||||
@ -13,12 +12,6 @@
|
||||
font-size: 1.4em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.components-panel__row {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_sidepanel_field {
|
||||
@ -44,7 +37,7 @@
|
||||
|
||||
.mailpoet_sidepanel_field_optional {
|
||||
color: $color-primary-inactive;
|
||||
font-size: 0.8em;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.mailpoet_sidepanel_radio_option,
|
||||
@ -62,11 +55,11 @@
|
||||
.mailpoet_sidepanel_input_option {
|
||||
display: inline-block;
|
||||
|
||||
input[type='checkbox'] {
|
||||
input[type=checkbox] {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
input[type='text'] {
|
||||
input[type=text] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
@ -6,12 +6,12 @@
|
||||
background: rgba(#fff, 0);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
transition: background 0.15s ease-out;
|
||||
transition: background .15s ease-out;
|
||||
width: 100%;
|
||||
z-index: 19;
|
||||
|
||||
.mailpoet_abandoned_cart_content_block:hover & {
|
||||
background: rgba(#fff, 0.9);
|
||||
background: rgba(#fff, .9);
|
||||
cursor: pointer;
|
||||
|
||||
.mailpoet_overlay_message {
|
@ -6,12 +6,12 @@
|
||||
background: rgba(#fff, 0);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
transition: background 0.15s ease-out;
|
||||
transition: background .15s ease-out;
|
||||
width: 100%;
|
||||
z-index: 19;
|
||||
|
||||
.mailpoet_automated_latest_content_block:hover & {
|
||||
background: rgba(#fff, 0.9);
|
||||
background: rgba(#fff, .9);
|
||||
cursor: pointer;
|
||||
|
||||
.mailpoet_overlay_message {
|
@ -8,10 +8,13 @@
|
||||
|
||||
> .mailpoet_block_highlight {
|
||||
border: 2px solid $color-transparent;
|
||||
inset: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
transition: 0.3s;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition: .3s;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@ -20,12 +23,13 @@
|
||||
}
|
||||
|
||||
> .mailpoet_container_horizontal ~ .mailpoet_block_highlight {
|
||||
inset: -2px;
|
||||
bottom: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
&.mailpoet_highlight
|
||||
> .mailpoet_container_horizontal
|
||||
~ .mailpoet_block_highlight {
|
||||
&.mailpoet_highlight > .mailpoet_container_horizontal ~ .mailpoet_block_highlight {
|
||||
border: 2px solid $color-editor-background-column !important;
|
||||
}
|
||||
}
|
||||
@ -43,7 +47,7 @@
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
line-height: $editor-line-height;
|
||||
margin: 0 0 0.3em;
|
||||
margin: 0 0 .3em;
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
.mailpoet_container {
|
||||
min-height: 15px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mailpoet_container_block {
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mailpoet_container_vertical > * {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mailpoet_container_horizontal > * {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#mailpoet_editor_content {
|
||||
.mailpoet_container {
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
}
|
||||
|
||||
> .mailpoet_container_block {
|
||||
border: 0;
|
||||
width: $grid-editor-width;
|
||||
}
|
||||
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block {
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.mailpoet_container_horizontal > .mailpoet_container_block {
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
width: $editor-column-margin + $editor-column-width-one + $editor-column-margin;
|
||||
}
|
||||
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal,
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_posts_block > .mailpoet_posts_container > .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal,
|
||||
> .mailpoet_container_block > .mailpoet_container .mailpoet_automated_latest_content_block_posts .mailpoet_container_horizontal,
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_products_block > .mailpoet_products_container > .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal,
|
||||
> .mailpoet_container_block > .mailpoet_container .mailpoet_abandoned_cart_content_container .mailpoet_container_horizontal {
|
||||
> .mailpoet_block:first-child:nth-last-child(2),
|
||||
> .mailpoet_block:first-child:nth-last-child(2) ~ .mailpoet_block {
|
||||
width: $editor-column-margin + $editor-column-width-two + $editor-column-margin;
|
||||
}
|
||||
|
||||
> .mailpoet_block:first-child:nth-last-child(3),
|
||||
> .mailpoet_block:first-child:nth-last-child(3) ~ .mailpoet_block {
|
||||
width: $editor-column-margin + $editor-column-width-three + $editor-column-margin;
|
||||
}
|
||||
}
|
||||
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal.mailpoet_irregular_width_contents_container.column_layout_1_2 > .mailpoet_container_block:first-child,
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal.mailpoet_irregular_width_contents_container.column_layout_2_1 > .mailpoet_container_block:nth-child(2) {
|
||||
width: $editor-column-margin + $editor-column-width-three + $editor-column-margin;
|
||||
}
|
||||
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal.mailpoet_irregular_width_contents_container.column_layout_2_1 > .mailpoet_container_block:first-child,
|
||||
> .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal.mailpoet_irregular_width_contents_container.column_layout_1_2 > .mailpoet_container_block:nth-child(2) {
|
||||
width: $editor-column-margin + $editor-column-width-two-wider + $editor-column-margin;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_container_empty {
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 1px 2px 1px $color-primary-inactive;
|
||||
color: #656565;
|
||||
margin: 20px;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
|
||||
@include animation-background-color();
|
||||
}
|
@ -24,7 +24,6 @@
|
||||
.mailpoet_settings_posts_selection {
|
||||
@include animation-slide-open-downwards();
|
||||
overflow-x: hidden;
|
||||
padding: 0 19px;
|
||||
}
|
||||
|
||||
.mailpoet_settings_posts_show_display_options,
|
||||
@ -40,7 +39,8 @@
|
||||
|
||||
.mailpoet_post_scroll_container {
|
||||
max-height: 400px;
|
||||
overflow: hidden scroll;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.mailpoet_settings_posts_single_post {
|
@ -24,7 +24,6 @@
|
||||
.mailpoet_settings_products_selection {
|
||||
@include animation-slide-open-downwards();
|
||||
overflow-x: hidden;
|
||||
padding: 0 19px;
|
||||
}
|
||||
|
||||
.mailpoet_settings_products_show_display_options,
|
||||
@ -40,7 +39,8 @@
|
||||
|
||||
.mailpoet_product_scroll_container {
|
||||
max-height: 400px;
|
||||
overflow: hidden scroll;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.mailpoet_settings_products_single_product {
|
@ -47,7 +47,7 @@
|
||||
background: $color-white;
|
||||
border: 1px solid $color-editor-border-content;
|
||||
margin-bottom: 9px;
|
||||
padding: 28px 9px (18px - 10px);
|
||||
padding: 28px 9px (18px - 10px) 9px;
|
||||
position: relative;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
.mailpoet_woocommerce_content_overlay {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
background: rgba(255, 255, 255, .7);
|
||||
height: 100%;
|
||||
margin: -10px -20px; // cancel out the mailpoet_block padding
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
transition: opacity 0.15s ease-out;
|
||||
transition: opacity .15s ease-out;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
|
@ -1,9 +1,9 @@
|
||||
.mailpoet_woocommerce_heading_overlay {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
background: rgba(255, 255, 255, .7);
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
transition: opacity 0.15s ease-out;
|
||||
transition: opacity .15s ease-out;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
|
131
assets/css/src/components-form-editor/_block-editor.scss
Normal file
131
assets/css/src/components-form-editor/_block-editor.scss
Normal file
@ -0,0 +1,131 @@
|
||||
// We don't want to allow user to remove Submit or Email + we hide core/column toolbar because it is empty
|
||||
// There is no way to hide the delete button programmatically so we hide last toolbar that contains the delete option
|
||||
// There is a feature request for adding that into Gutenberg https://github.com/WordPress/gutenberg/issues/16364
|
||||
.mailpoet-form-submit-button,
|
||||
.mailpoet-form-email-input {
|
||||
.block-editor-block-toolbar > .components-toolbar-group {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.block-editor-block-toolbar .components-toolbar-group {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-post-layout .interface-interface-skeleton__content {
|
||||
background-color: $color-white;
|
||||
}
|
||||
|
||||
// Fix for fixed bar forms
|
||||
// This will prevent editor width to grow and push sidebar out of the screen
|
||||
.interface-interface-skeleton__editor {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
// Fix for settings toolbar placement in header
|
||||
.edit-post-header {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
// Hide tabs (Blocks, Patterns, ...) in block inserter, because we don't have patterns
|
||||
// They are always visible in case user adds a block in the top level
|
||||
.block-editor-inserter__tabs .components-tab-panel__tabs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Fix for default appender appearance
|
||||
// We don't use any default block (WP Post editor has paragraph)
|
||||
// and CSS distributed within packages is works only with the paragraph block
|
||||
// We want to display it in center
|
||||
.block-editor .block-editor-inserter .block-editor-button-block-appender.block-list-appender__toggle {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
// Html blocks contains iframe which captures clicks and in some cases prevents selecting block.
|
||||
// This adds an transparent overlay over the iframe.
|
||||
.mailpoet-html-block-editor-content-wrapper {
|
||||
position: relative;
|
||||
|
||||
&:after {
|
||||
background: transparent;
|
||||
content: ' ';
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// Wordpress displays h3 and h2 the same size by default. To make it less confusing we need to make h2 different size.
|
||||
h2 {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
// Remove block margins for first block and also first block in columns
|
||||
// This is done to improve WYSIWYG experience
|
||||
.mailpoet-form-background .block-editor-block-list__block:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
// Remove min-height so that lower values of input padding have visible effect in form editor
|
||||
.block-editor-block-list__layout .mailpoet_text,
|
||||
.block-editor-block-list__layout .mailpoet_textarea {
|
||||
min-height: 0;
|
||||
// Remove box shadow on focus since we don't allow interactions with text fields in editor
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure same default font size for input and submit button
|
||||
.block-editor-block-list__layout .mailpoet_paragraph {
|
||||
.mailpoet_text,
|
||||
.mailpoet_submit {
|
||||
font-size: 1em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.mailpoet_text_label {
|
||||
font-size: 1em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_toolbar_item {
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
display: flex;
|
||||
|
||||
.mailpoet-font-family-select {
|
||||
width: $grid-column-small;
|
||||
}
|
||||
|
||||
// Force rendering of select arrow on the right
|
||||
.components-custom-select-control__button svg {
|
||||
margin-right: initial;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjustments for correct form width rendering
|
||||
.wp-block {
|
||||
max-width: initial;
|
||||
}
|
||||
|
||||
.block-editor-block-list__layout.is-root-container {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.edit-post-visual-editor {
|
||||
background-color: $color-white;
|
||||
// We use lager padding on top so that block tools toolbar doesn't hide under top bar
|
||||
padding: $grid-gap-large 10px 10px;
|
||||
}
|
||||
|
||||
// Unify padding o wp-block-columns with background with front end rendering
|
||||
.wp-block-columns.has-background {
|
||||
padding: 10px;
|
||||
}
|
@ -1,8 +1,16 @@
|
||||
|
||||
.form-placement-option-list {
|
||||
display: grid;
|
||||
grid-gap: $grid-gap;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
margin: 0 -8px;
|
||||
}
|
||||
|
||||
.form-placement-option {
|
||||
height: $form-placement-option-height;
|
||||
text-align: center;
|
||||
width: $form-placement-option-width;
|
||||
}
|
||||
|
||||
.form-placement-settings {
|
||||
@ -32,7 +40,7 @@
|
||||
|
||||
.form-placement-option-icon {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 4px 18px 0 rgba(68, 75, 102, 0.15);
|
||||
box-shadow: 0 4px 18px 0 rgba(68, 75, 102, .15);
|
||||
height: 63px;
|
||||
margin: 0 auto;
|
||||
object-fit: contain;
|
9
assets/css/src/components-form-editor/_header.scss
Normal file
9
assets/css/src/components-form-editor/_header.scss
Normal file
@ -0,0 +1,9 @@
|
||||
.mailpoet-editor-header-button {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
|
||||
@media (min-width: 600px) {
|
||||
margin-right: 12px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
}
|
28
assets/css/src/components-form-editor/_helpscout.scss
Normal file
28
assets/css/src/components-form-editor/_helpscout.scss
Normal file
@ -0,0 +1,28 @@
|
||||
// Override CSS for HelpScout beacon on form editor page
|
||||
.admin_page_mailpoet-form-editor {
|
||||
.BeaconFabButtonFrame,
|
||||
.BeaconContainer {
|
||||
left: 175px;
|
||||
}
|
||||
|
||||
&.folded {
|
||||
.BeaconFabButtonFrame,
|
||||
.BeaconContainer {
|
||||
left: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
@include respond-to(medium-screen) {
|
||||
.BeaconFabButtonFrame,
|
||||
.BeaconContainer {
|
||||
left: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
@include respond-to(small-screen) {
|
||||
.BeaconFabButtonFrame,
|
||||
.BeaconContainer {
|
||||
left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
@ -59,9 +59,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_form_preview_modal_overlay {
|
||||
z-index: 100010; // Boosted z-index to cover Helpscout beacon
|
||||
}
|
||||
|
||||
.mailpoet_form_preview_disclaimer {
|
||||
bottom: 10px;
|
||||
font-size: 0.9em;
|
||||
font-size: .9em;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 380px;
|
@ -1,3 +1,4 @@
|
||||
|
||||
.selection-item {
|
||||
background-color: #fff;
|
||||
border: solid $selection-item-active-border $selection-item-base-color;
|
||||
@ -7,13 +8,14 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
padding: 6px;
|
||||
pointer-events: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.selection-item-overlay {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
border-radius: 2px;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
@ -26,7 +28,7 @@
|
||||
|
||||
.selection-item-active {
|
||||
border: solid $selection-item-active-border $gutenberg-control-active-color;
|
||||
box-shadow: 0 4px 8px 0 rgba(156, 166, 204, 0.5);
|
||||
box-shadow: 0 4px 8px 0 rgba(156, 166, 204, .5);
|
||||
}
|
||||
|
||||
.selection-item-settings {
|
@ -0,0 +1,119 @@
|
||||
.mailpoet-styles-settings {
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
grid-row-gap: 20px;
|
||||
|
||||
.components-base-control {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.components-base-control__label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.components-radio-control__option {
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.mailpoet-size-settings-control .components-range-control__number {
|
||||
min-width: 5em;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-font-family-select {
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.components-custom-select-control__label {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-styles-settings-image-url {
|
||||
max-width: 245px;
|
||||
|
||||
.mailpoet-styles-settings-image-url-body {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 4px;
|
||||
|
||||
input {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
margin-right: 4px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
button {
|
||||
flex-shrink: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-styles-settings-image-url-display {
|
||||
margin-right: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.close-button-selection-item-list {
|
||||
display: grid;
|
||||
grid-gap: 15px;
|
||||
grid-template-columns: repeat(3, 72px);
|
||||
}
|
||||
|
||||
.close-button-selection-item {
|
||||
background-color: $color-tertiary-light;
|
||||
height: 72px;
|
||||
|
||||
.selection-item-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.close-button-selection-item-icon {
|
||||
align-self: center;
|
||||
height: 24px;
|
||||
margin-top: -7px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.mailpoet-color-gradient-picker {
|
||||
.block-editor-color-gradient-control__color-indicator {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.component-color-indicator {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
// Styles for labels and headings for style setting components
|
||||
// We override some styles from @wordpress/components to have unified labels appearance
|
||||
.mailpoet-styles-settings .mailpoet-styles-settings-heading,
|
||||
.mailpoet-styles-settings .components-base-control__label,
|
||||
.mailpoet-styles-settings .components-input-control__label,
|
||||
.mailpoet-styles-settings .components-custom-select-control__label,
|
||||
.mailpoet-styles-settings .components-font-size-picker label {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
margin-bottom: .5em;
|
||||
|
||||
.component-color-indicator {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix for alignment of font size picker inputs
|
||||
.mailpoet-styles-settings .components-font-size-picker__number-container label {
|
||||
margin-bottom: 0;
|
||||
}
|
126
assets/css/src/components-form-editor/_sidebar.scss
Normal file
126
assets/css/src/components-form-editor/_sidebar.scss
Normal file
@ -0,0 +1,126 @@
|
||||
.components-panel {
|
||||
.select2-container {
|
||||
width: 100% !important;
|
||||
|
||||
input.select2-search__field:focus {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.select2-selection {
|
||||
border-color: $gutenberg-control-border-color;
|
||||
}
|
||||
|
||||
&.select2-container--focus {
|
||||
.select2-selection {
|
||||
border-color: $gutenberg-control-border-color-focus;
|
||||
box-shadow: 0 0 0 1px $gutenberg-control-border-color-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-form-missing-lists {
|
||||
.select2-selection {
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.mailpoet-form-lists-error {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.components-base-control.mailpoet-form-success-types__control {
|
||||
margin-bottom: 0;
|
||||
|
||||
.components-base-control__label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-radio-control__option {
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
|
||||
input {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-on-top,
|
||||
.button-on-top.components-button.is-link {
|
||||
margin-bottom: 12px;
|
||||
max-height: 30px;
|
||||
}
|
||||
|
||||
.mailpoet-dnd-items-list > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> * {
|
||||
margin-bottom: 12px
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-form-segments-settings-list {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.components-base-control {
|
||||
flex-grow: 1;
|
||||
margin: 8px 0;
|
||||
|
||||
.components-base-control__field {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-form-segments-segment-remove {
|
||||
cursor: pointer;
|
||||
flex-grow: 0;
|
||||
margin: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
border: 1px solid #eee;
|
||||
|
||||
textarea {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.components-button.mailpoet-save-button {
|
||||
background-color: $gutenberg-control-active-color;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
height: 48px;
|
||||
letter-spacing: normal;
|
||||
line-height: 1.25;
|
||||
margin-left: auto;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #fff !important;
|
||||
color: #ff5301 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet_form_editor_sidebar {
|
||||
.mailpoet-sidebar-header-heading {
|
||||
margin: auto 0;
|
||||
padding-left: 16px;
|
||||
}
|
||||
}
|
||||
// This style hides the horizontal scrollbar in Firefox browser
|
||||
.interface-interface-skeleton__sidebar {
|
||||
overflow-x: hidden;
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
@use 'sass:math';
|
||||
|
||||
$mailpoet-form-template-thumbnail-width: 480px;
|
||||
$mailpoet-form-template-thumbnail-height: 316px;
|
||||
|
||||
@mixin formTemplatesGrid() {
|
||||
display: grid;
|
||||
grid-gap: $grid-gap;
|
||||
grid-template-columns: repeat(auto-fill, $mailpoet-form-template-thumbnail-width + $grid-gap-half);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mailpoet-templates {
|
||||
@include formTemplatesGrid;
|
||||
padding-bottom: math.div($mailpoet-form-template-thumbnail-height, 3);
|
||||
padding-top: $grid-gap-large;
|
||||
|
||||
.mailpoet-categories {
|
||||
grid-column: 1 / -1;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-form-template {
|
||||
height: $mailpoet-form-template-thumbnail-height + (2 * $grid-gap-large);
|
||||
padding-bottom: math.div($grid-gap-half, 2);
|
||||
width: $mailpoet-form-template-thumbnail-width + $grid-gap-half;
|
||||
|
||||
.mailpoet-template-thumbnail {
|
||||
height: $mailpoet-form-template-thumbnail-height;
|
||||
padding: math.div($grid-gap-half, 2) math.div($grid-gap-half, 2) 0;
|
||||
}
|
||||
}
|
||||
|
||||
$templates-one-column-breakpoint: 2 * ($mailpoet-form-template-thumbnail-width + $grid-gap-half) + $grid-gap + 160;
|
||||
/**
|
||||
The header uses grid to position heading in center (second column) and a new form button on right (third column)
|
||||
*/
|
||||
.mailpoet-template-selection-header {
|
||||
@include formTemplatesGrid;
|
||||
background: $color-input-background;
|
||||
border-bottom: 1px solid $color-tertiary-light;
|
||||
grid-row-gap: 0;
|
||||
justify-items: center;
|
||||
padding: $grid-gap 0;
|
||||
position: relative;
|
||||
|
||||
@include breakpoint-min-width($templates-one-column-breakpoint) {
|
||||
justify-items: right;
|
||||
}
|
||||
|
||||
.mailpoet-h4 {
|
||||
// Keep heading centered when we are sure there are 2 or more columns
|
||||
|
||||
@include breakpoint-min-width($templates-one-column-breakpoint) {
|
||||
left: 50%;
|
||||
margin-top: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-button {
|
||||
align-self: center;
|
||||
grid-column-end: -1;
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
}
|
||||
|
||||
.mailpoet_preview_icon_fill {
|
||||
fill: rgba($color-text, 0.3);
|
||||
fill: rgba($color-text, .3);
|
||||
}
|
||||
|
||||
&.mailpoet_active {
|
||||
@ -44,7 +44,7 @@
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
padding: 20px;
|
||||
transition: width 0.5s;
|
||||
transition: width .5s;
|
||||
}
|
||||
|
||||
.mailpoet_browser_preview_container_desktop {
|
||||
@ -58,15 +58,13 @@
|
||||
|
||||
.mailpoet_browser_preview_container_mobile .mailpoet_preview_send_to_email,
|
||||
.mailpoet_browser_preview_container_desktop .mailpoet_preview_send_to_email,
|
||||
.mailpoet_browser_preview_container_send_to_email
|
||||
.mailpoet_browser_preview_border {
|
||||
.mailpoet_browser_preview_container_send_to_email .mailpoet_browser_preview_border {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mailpoet_browser_preview_container_mobile .mailpoet_browser_preview_border,
|
||||
.mailpoet_browser_preview_container_desktop .mailpoet_browser_preview_border,
|
||||
.mailpoet_browser_preview_container_send_to_email
|
||||
.mailpoet_preview_send_to_email {
|
||||
.mailpoet_browser_preview_container_send_to_email .mailpoet_preview_send_to_email {
|
||||
display: block;
|
||||
}
|
||||
|
90
assets/css/src/components-plugin/_common.scss
Normal file
90
assets/css/src/components-plugin/_common.scss
Normal file
@ -0,0 +1,90 @@
|
||||
.clearfix {
|
||||
@include clearfix();
|
||||
}
|
||||
|
||||
.relative-holder {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
a:focus {
|
||||
outline: 0 none !important;
|
||||
}
|
||||
|
||||
.nav-tab:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.mailpoet_success {
|
||||
color: #090;
|
||||
}
|
||||
|
||||
.mailpoet_error {
|
||||
color: #900;
|
||||
}
|
||||
|
||||
.mailpoet_hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mailpoet_spaced_block {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.mailpoet_centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* double class is intentional here, we need to be very specific here to
|
||||
something wrapping our warning message could override its style */
|
||||
p.sender_email_address_warning.sender_email_address_warning,
|
||||
p.sender_email_address_warning.sender_email_address_warning a {
|
||||
align-self: flex-start;
|
||||
color: #900;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
p.sender_email_address_warning:first-child {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.button.mailpoet-button-bigger {
|
||||
font-size: 1.5em;
|
||||
height: 46px;
|
||||
padding: 10px 18px;
|
||||
}
|
||||
|
||||
// Fix for select 2 placeholder padding rendering issue in Chrome
|
||||
.select2-container .select2-search--inline,
|
||||
.select2-container .select2-search--inline .select2-search__field {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.widefat {
|
||||
margin-bottom: $grid-gap;
|
||||
}
|
||||
|
||||
.mailpoet-subscribers-in-plan {
|
||||
font-size: 18px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.mailpoet-subscribers-in-plan-spacer {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@include respond-to(small-screen) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-subscribers-cache-notice {
|
||||
.mailpoet-subscribers-cache-notice-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user