diff --git a/api/api.php b/api/api.php index 43ffa5f5754..8d2701b156c 100644 --- a/api/api.php +++ b/api/api.php @@ -33,3 +33,4 @@ require( 'tools/trigger-cron-job.php' ); require( 'tools/run-wc-admin-daily.php' ); require( 'options/rest-api.php' ); require( 'tools/delete-all-products.php'); +require( 'tools/disable-wc-email.php' ); diff --git a/api/tools/disable-wc-email.php b/api/tools/disable-wc-email.php new file mode 100644 index 00000000000..7997195fbc7 --- /dev/null +++ b/api/tools/disable-wc-email.php @@ -0,0 +1,46 @@ + 'GET', + ) +); + +function toggle_emails() { + $emails_disabled = 'yes'; + if ( $emails_disabled === get_option( 'wc_admin_test_helper_email_disabled', 'no' ) ) { + $emails_disabled = 'no'; + remove_filter('woocommerce_email_get_option', 'disable_wc_emails' ); + } + update_option('wc_admin_test_helper_email_disabled', $emails_disabled ); + return new WP_REST_Response( $emails_disabled, 200 ); +} + +function get_email_status() { + $emails_disabled = get_option( 'wc_admin_test_helper_email_disabled', 'no' ); + return new WP_REST_Response( $emails_disabled, 200 ); +} + +if ( 'yes' === get_option( 'wc_admin_test_helper_email_disabled', 'no' ) ) { + add_filter('woocommerce_email_get_option', 'disable_wc_emails' ); + add_action( 'woocommerce_email', 'unhook_other_wc_emails' ); +} + +function disable_wc_emails( $key ) { + if ( $key === 'enabled' ) { + return false; + } +} + +function unhook_other_wc_emails( $email ) { + remove_action( 'woocommerce_low_stock_notification', array( $email, 'low_stock' ) ); + remove_action( 'woocommerce_no_stock_notification', array( $email, 'no_stock' ) ); + remove_action( 'woocommerce_product_on_backorder_notification', array( $email, 'backorder' ) ); + remove_action( 'woocommerce_new_customer_note_notification', array( $email->emails['WC_Email_Customer_Note'], 'trigger' ) ); +} diff --git a/package-lock.json b/package-lock.json index 08031126a41..522f7a1ee50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "woocommerce-admin-test-helper", - "version": "0.1.0", + "version": "0.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2811,6 +2811,12 @@ "requireindex": "1.2.0" }, "dependencies": { + "@wordpress/prettier-config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-1.0.0.tgz", + "integrity": "sha512-s8EXokSxce1rnOY2gaL0tZgp7epg9qmmkg+z7nu3UWM61tPAXO9VWpzIUUVk5oF0lf1TARyrOMf3ZgdE3jl4Nw==", + "dev": true + }, "prettier": { "version": "npm:wp-prettier@2.2.1-beta-1", "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.2.1-beta-1.tgz", @@ -3231,9 +3237,9 @@ } }, "@wordpress/prettier-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-1.0.0.tgz", - "integrity": "sha512-s8EXokSxce1rnOY2gaL0tZgp7epg9qmmkg+z7nu3UWM61tPAXO9VWpzIUUVk5oF0lf1TARyrOMf3ZgdE3jl4Nw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-1.1.0.tgz", + "integrity": "sha512-cMYc/dtuiRo9VAb+m8S2Mvv/jELvoJAtcPsq6HT6XMppXC9slZ5z0q1A4PNf3ewMvvHtodjwkl2oHbO+vaAYzg==", "dev": true }, "@wordpress/primitives": { @@ -3428,6 +3434,15 @@ "strip-bom": "^2.0.0" } }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -3438,6 +3453,30 @@ "yallist": "^2.1.2" } }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -3467,6 +3506,59 @@ "pinkie-promise": "^2.0.0" } }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "prettier": { + "version": "npm:wp-prettier@2.2.1-beta-1", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.2.1-beta-1.tgz", + "integrity": "sha512-+JHkqs9LC/JPp51yy1hzs3lQ7qeuWCwOcSzpQNeeY/G7oSpnF61vxt7hRh87zNRTr6ob2ndy0W8rVzhgrcA+Gw==", + "dev": true + }, + "puppeteer": { + "version": "npm:puppeteer-core@5.5.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-5.5.0.tgz", + "integrity": "sha512-tlA+1n+ziW/Db03hVV+bAecDKse8ihFRXYiEypBe9IlLRvOCzYFG6qrCMBYK34HO/Q/Ecjc+tvkHRAfLVH+NgQ==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "devtools-protocol": "0.0.818844", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "node-fetch": "^2.6.1", + "pkg-dir": "^4.2.0", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -13746,9 +13838,9 @@ "dev": true }, "prettier": { - "version": "npm:wp-prettier@2.2.1-beta-1", - "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.2.1-beta-1.tgz", - "integrity": "sha512-+JHkqs9LC/JPp51yy1hzs3lQ7qeuWCwOcSzpQNeeY/G7oSpnF61vxt7hRh87zNRTr6ob2ndy0W8rVzhgrcA+Gw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true }, "prettier-linter-helpers": { @@ -13942,86 +14034,6 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "puppeteer": { - "version": "npm:puppeteer-core@5.5.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-5.5.0.tgz", - "integrity": "sha512-tlA+1n+ziW/Db03hVV+bAecDKse8ihFRXYiEypBe9IlLRvOCzYFG6qrCMBYK34HO/Q/Ecjc+tvkHRAfLVH+NgQ==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "devtools-protocol": "0.0.818844", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.6.1", - "pkg-dir": "^4.2.0", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^3.0.2", - "tar-fs": "^2.0.0", - "unbzip2-stream": "^1.3.3", - "ws": "^7.2.3" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } - } - }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", diff --git a/src/index.scss b/src/index.scss index 9b75936e7e9..7e82c41a608 100644 --- a/src/index.scss +++ b/src/index.scss @@ -57,6 +57,7 @@ text-align: center; } tbody td { + vertical-align: middle; &.command { white-space: nowrap; } diff --git a/src/tools/commands/disable-email.js b/src/tools/commands/disable-email.js new file mode 100644 index 00000000000..0aba29d4bb0 --- /dev/null +++ b/src/tools/commands/disable-email.js @@ -0,0 +1,37 @@ +/** + * External dependencies. + */ +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { STORE_KEY } from '../data/constants'; + +export const DisableEmail = () => { + const { isEmailDisabled } = useSelect( ( select ) => { + const { getIsEmailDisabled } = select( STORE_KEY ); + return { + isEmailDisabled: getIsEmailDisabled(), + }; + } ); + + const getEmailStatus = () => { + switch( isEmailDisabled ) { + case 'yes': + return 'WooCommerce emails are turned off 🔴'; + case 'no': + return 'WooCommerce emails are turned on 🟢'; + case 'error': + return 'Error 🙁'; + default: + return 'Loading ...'; + } + } + + return ( +
+ { getEmailStatus() } +
+ ); +}; diff --git a/src/tools/commands/index.js b/src/tools/commands/index.js index 0e43792989c..d43b7db2a92 100644 --- a/src/tools/commands/index.js +++ b/src/tools/commands/index.js @@ -1,4 +1,5 @@ import { TriggerCronJob, TRIGGER_CRON_ACTION_NAME } from './trigger-cron'; +import { DisableEmail } from './disable-email'; export default [ { @@ -46,4 +47,9 @@ export default [ description: , action: TRIGGER_CRON_ACTION_NAME, }, + { + command: 'Disable WC emails', + description: , + action: 'runDisableEmail', + }, ]; diff --git a/src/tools/data/action-types.js b/src/tools/data/action-types.js index b722f161f37..fc9265f96e6 100644 --- a/src/tools/data/action-types.js +++ b/src/tools/data/action-types.js @@ -6,6 +6,7 @@ const TYPES = { REMOVE_MESSAGE: 'REMOVE_MESSAGE', ADD_COMMAND_PARAMS: 'ADD_COMMAND_PARAMS', SET_CRON_JOBS: 'SET_CRON_JOBS', + IS_EMAIL_DISABLED: 'IS_EMAIL_DISABLED', }; export default TYPES; diff --git a/src/tools/data/actions.js b/src/tools/data/actions.js index 2cad7873301..c1b1bfb227b 100644 --- a/src/tools/data/actions.js +++ b/src/tools/data/actions.js @@ -62,6 +62,13 @@ export function setCronJobs(cronJobs) { }; } +export function setIsEmailDisabled(isEmailDisabled) { + return { + type: TYPES.IS_EMAIL_DISABLED, + isEmailDisabled, + }; +} + function* runCommand(commandName, func) { try { yield addCurrentlyRunning(commandName); @@ -175,3 +182,13 @@ export function* runSelectedCronJob(params) { }); }); } + +export function* runDisableEmail() { + yield runCommand('Disable/Enable WooCommerce emails', function* () { + const response = yield apiFetch({ + path: `${API_NAMESPACE}/tools/toggle-emails/v1`, + method: 'POST', + }); + yield setIsEmailDisabled( response ); + }); +} diff --git a/src/tools/data/reducer.js b/src/tools/data/reducer.js index dd534b81932..3a2303ad38b 100644 --- a/src/tools/data/reducer.js +++ b/src/tools/data/reducer.js @@ -7,6 +7,7 @@ const DEFAULT_STATE = { currentlyRunning: {}, errorMessages: [], cronJobs: false, + isEmailDisabled: '', messages: {}, params: [], status: '', @@ -61,6 +62,11 @@ const reducer = ( state = DEFAULT_STATE, action ) => { ...state, cronJobs: action.cronJobs, }; + case TYPES.IS_EMAIL_DISABLED: + return { + ...state, + isEmailDisabled: action.isEmailDisabled, + }; case TYPES.ADD_COMMAND_PARAMS: return { ...state, diff --git a/src/tools/data/resolvers.js b/src/tools/data/resolvers.js index d87b0c06897..54b53ef4eb8 100644 --- a/src/tools/data/resolvers.js +++ b/src/tools/data/resolvers.js @@ -7,7 +7,7 @@ import { apiFetch } from '@wordpress/data-controls'; * Internal dependencies */ import { API_NAMESPACE } from './constants'; -import { setCronJobs } from './actions'; +import { setCronJobs, setIsEmailDisabled } from './actions'; export function* getCronJobs() { const path = `${ API_NAMESPACE }/tools/get-cron-list/v1`; @@ -22,3 +22,18 @@ export function* getCronJobs() { throw new Error( error ); } } + +export function* getIsEmailDisabled() { + const path = `${API_NAMESPACE}/tools/get-email-status/v1`; + + try { + const response = yield apiFetch( { + path, + method: 'GET', + } ); + yield setIsEmailDisabled( response ); + } catch ( error ) { + yield setIsEmailDisabled( 'error' ); + throw new Error( error ); + } +} diff --git a/src/tools/data/selectors.js b/src/tools/data/selectors.js index aa4bdfeaac1..d34ee766934 100644 --- a/src/tools/data/selectors.js +++ b/src/tools/data/selectors.js @@ -17,3 +17,7 @@ export function getCommandParams( state ) { export function getCronJobs( state ) { return state.cronJobs; } + +export function getIsEmailDisabled( state ) { + return state.isEmailDisabled; +}