From 1956d156874035643ca541e5835caeeb92c5f6a3 Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 5 Oct 2020 17:58:40 +0200 Subject: [PATCH 01/15] Donations: Save fallback for non-frontend contexts --- extensions/blocks/donations/attributes.js | 12 + extensions/blocks/donations/controls.js | 18 ++ .../blocks/donations/deprecated/v1/index.js | 226 ++++++++++++++++++ extensions/blocks/donations/edit.js | 15 +- extensions/blocks/donations/save.js | 170 +------------ 5 files changed, 278 insertions(+), 163 deletions(-) create mode 100644 extensions/blocks/donations/deprecated/v1/index.js diff --git a/extensions/blocks/donations/attributes.js b/extensions/blocks/donations/attributes.js index 6c53e5672532..d6f19db68f51 100644 --- a/extensions/blocks/donations/attributes.js +++ b/extensions/blocks/donations/attributes.js @@ -53,4 +53,16 @@ export default { type: 'string', default: __( 'Or enter a custom amount', 'jetpack' ), }, + fallbackLinkUrl: { + type: 'string', + source: 'attribute', + selector: '.jetpack-donations-fallback-link', + attribute: 'href', + }, + fallbackLinkText: { + type: 'string', + source: 'html', + selector: '.jetpack-donations-fallback-link', + default: __( 'Click here to donate.', 'jetpack' ), + }, }; diff --git a/extensions/blocks/donations/controls.js b/extensions/blocks/donations/controls.js index 750d458d356c..3291abbe2290 100644 --- a/extensions/blocks/donations/controls.js +++ b/extensions/blocks/donations/controls.js @@ -8,6 +8,7 @@ import { CURRENCIES } from '@automattic/format-currency'; */ import { BlockControls, InspectorControls } from '@wordpress/block-editor'; import { + BaseControl, Button, Dashicon, Dropdown, @@ -15,6 +16,7 @@ import { MenuGroup, MenuItem, PanelBody, + TextControl, ToggleControl, ToolbarGroup, } from '@wordpress/components'; @@ -113,6 +115,22 @@ const Controls = props => { onChange={ value => setAttributes( { showCustomAmount: value } ) } label={ __( 'Show custom amount option', 'jetpack' ) } /> + + + this.props.setAttributes( { fallbackLinkText: newFallbackLinkText } ) + } + value={ this.props.attributes.fallbackLinkText } + /> + { __( 'View donation earnings', 'jetpack' ) } diff --git a/extensions/blocks/donations/deprecated/v1/index.js b/extensions/blocks/donations/deprecated/v1/index.js new file mode 100644 index 000000000000..f76d36a9c04f --- /dev/null +++ b/extensions/blocks/donations/deprecated/v1/index.js @@ -0,0 +1,226 @@ +/** + * External dependencies + */ +import formatCurrency, { CURRENCIES } from '@automattic/format-currency'; + +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { minimumTransactionAmountForCurrency } from '../../../../shared/currencies'; + +export default { + attributes: { + currency: { + type: 'string', + default: 'USD', + }, + oneTimeDonation: { + type: 'object', + default: { + show: true, + planId: null, + amounts: [ 5, 15, 100 ], + heading: __( 'Make a one-time donation', 'jetpack' ), + extraText: __( 'Your contribution is appreciated.', 'jetpack' ), + buttonText: __( 'Donate', 'jetpack' ), + }, + }, + monthlyDonation: { + type: 'object', + default: { + show: true, + planId: null, + amounts: [ 5, 15, 100 ], + heading: __( 'Make a monthly donation', 'jetpack' ), + extraText: __( 'Your contribution is appreciated.', 'jetpack' ), + buttonText: __( 'Donate monthly', 'jetpack' ), + }, + }, + annualDonation: { + type: 'object', + default: { + show: true, + planId: null, + amounts: [ 5, 15, 100 ], + heading: __( 'Make a yearly donation', 'jetpack' ), + extraText: __( 'Your contribution is appreciated.', 'jetpack' ), + buttonText: __( 'Donate yearly', 'jetpack' ), + }, + }, + showCustomAmount: { + type: 'boolean', + default: true, + }, + chooseAmountText: { + type: 'string', + default: __( 'Choose an amount', 'jetpack' ), + }, + customAmountText: { + type: 'string', + default: __( 'Or enter a custom amount', 'jetpack' ), + }, + }, + supports: { + html: false, + }, + save: ( { attributes } ) => { + const { + currency, + oneTimeDonation, + monthlyDonation, + annualDonation, + showCustomAmount, + chooseAmountText, + customAmountText, + } = attributes; + + if ( ! oneTimeDonation || ! oneTimeDonation.show || oneTimeDonation.planId === -1 ) { + return null; + } + + const tabs = { + 'one-time': { title: __( 'One-Time', 'jetpack' ) }, + ...( monthlyDonation.show && { '1 month': { title: __( 'Monthly', 'jetpack' ) } } ), + ...( annualDonation.show && { '1 year': { title: __( 'Yearly', 'jetpack' ) } } ), + }; + + return ( +
+
+ { Object.keys( tabs ).length > 1 && ( +
+ { Object.entries( tabs ).map( ( [ interval, { title } ] ) => ( +
+ { title } +
+ ) ) } +
+ ) } +
+
+ + { monthlyDonation.show && ( + + ) } + { annualDonation.show && ( + + ) } + +
+ { oneTimeDonation.amounts.map( amount => ( +
+ { formatCurrency( amount, currency ) } +
+ ) ) } +
+ { monthlyDonation.show && ( +
+ { monthlyDonation.amounts.map( amount => ( +
+ { formatCurrency( amount, currency ) } +
+ ) ) } +
+ ) } + { annualDonation.show && ( +
+ { annualDonation.amounts.map( amount => ( +
+ { formatCurrency( amount, currency ) } +
+ ) ) } +
+ ) } + { showCustomAmount && ( + <> + +
+ { CURRENCIES[ currency ].symbol } +
+
+ + ) } +
——
+ + { monthlyDonation.show && ( + + ) } + { annualDonation.show && ( + + ) } +
+ +
+ { monthlyDonation.show && ( +
+ +
+ ) } + { annualDonation.show && ( +
+ +
+ ) } +
+
+
+
+ ); + }, +}; diff --git a/extensions/blocks/donations/edit.js b/extensions/blocks/donations/edit.js index acf7a91b5cd6..a0bb81c5512b 100644 --- a/extensions/blocks/donations/edit.js +++ b/extensions/blocks/donations/edit.js @@ -1,6 +1,7 @@ /** * WordPress dependencies */ +import { useSelect } from '@wordpress/data'; import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -13,14 +14,24 @@ import fetchDefaultProducts from './fetch-default-products'; import fetchStatus from './fetch-status'; const Edit = props => { - const { attributes, className } = props; - const { currency } = attributes; + const { attributes, className, setAttributes } = props; + const { currency, fallbackLinkText } = attributes; const [ loadingError, setLoadingError ] = useState( '' ); const [ shouldUpgrade, setShouldUpgrade ] = useState( false ); const [ stripeConnectUrl, setStripeConnectUrl ] = useState( false ); const [ products, setProducts ] = useState( [] ); + const post = useSelect( select => select( 'core/editor' ).getCurrentPost(), [] ); + useEffect( () => { + setAttributes( { + fallbackLinkUrl: post.link, + ...( ! fallbackLinkText && { + fallbackLinkText: __( 'Click here to donate.', 'jetpack' ), + } ), + } ); + }, [ post.link, fallbackLinkText, setAttributes ] ); + const apiError = message => { setLoadingError( message ); }; diff --git a/extensions/blocks/donations/save.js b/extensions/blocks/donations/save.js index 482ca6607ede..6f80362c3441 100644 --- a/extensions/blocks/donations/save.js +++ b/extensions/blocks/donations/save.js @@ -1,171 +1,19 @@ -/** - * External dependencies - */ -import formatCurrency, { CURRENCIES } from '@automattic/format-currency'; - -/** - * WordPress dependencies - */ -import { RichText } from '@wordpress/block-editor'; -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import { minimumTransactionAmountForCurrency } from '../../shared/currencies'; - const Save = ( { attributes } ) => { - const { - currency, - oneTimeDonation, - monthlyDonation, - annualDonation, - showCustomAmount, - chooseAmountText, - customAmountText, - } = attributes; + const { fallbackLinkUrl, fallbackLinkText, oneTimeDonation } = attributes; if ( ! oneTimeDonation || ! oneTimeDonation.show || oneTimeDonation.planId === -1 ) { return null; } - const tabs = { - 'one-time': { title: __( 'One-Time', 'jetpack' ) }, - ...( monthlyDonation.show && { '1 month': { title: __( 'Monthly', 'jetpack' ) } } ), - ...( annualDonation.show && { '1 year': { title: __( 'Yearly', 'jetpack' ) } } ), - }; - return ( -
-
- { Object.keys( tabs ).length > 1 && ( -
- { Object.entries( tabs ).map( ( [ interval, { title } ] ) => ( -
- { title } -
- ) ) } -
- ) } -
-
- - { monthlyDonation.show && ( - - ) } - { annualDonation.show && ( - - ) } - -
- { oneTimeDonation.amounts.map( amount => ( -
- { formatCurrency( amount, currency ) } -
- ) ) } -
- { monthlyDonation.show && ( -
- { monthlyDonation.amounts.map( amount => ( -
- { formatCurrency( amount, currency ) } -
- ) ) } -
- ) } - { annualDonation.show && ( -
- { annualDonation.amounts.map( amount => ( -
- { formatCurrency( amount, currency ) } -
- ) ) } -
- ) } - { showCustomAmount && ( - <> - -
- { CURRENCIES[ currency ].symbol } -
-
- - ) } -
——
- - { monthlyDonation.show && ( - - ) } - { annualDonation.show && ( - - ) } -
- -
- { monthlyDonation.show && ( -
- -
- ) } - { annualDonation.show && ( -
- -
- ) } -
-
-
-
+ + { fallbackLinkText } + ); }; From 130befafb3afb703bdbb83dc902da3c43335e93d Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 12 Oct 2020 18:01:06 +0200 Subject: [PATCH 02/15] Add one time text to save --- extensions/blocks/donations/donations.php | 54 ++++++++++++++++++++--- extensions/blocks/donations/save.js | 41 +++++++++++++---- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index 134e6ac077a0..45cb087f10e9 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -40,16 +40,41 @@ function register_block() { * @return string */ function render_block( $attr, $content ) { + // Keep content as-is if rendered in other contexts than frontend (i.e. feed, emails, API, etc.). + if ( ! jetpack_is_frontend() ) { + return $content; + } + Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'thickbox' ) ); require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php'; add_thickbox(); - $donations = array( - 'one-time' => $attr['oneTimeDonation'], - 'monthly' => $attr['monthlyDonation'], - 'annual' => $attr['annualDonation'], - ); + $donations = array(); + foreach ( + array( + 'one-time' => $attr['oneTimeDonation'], + 'monthly' => $attr['monthlyDonation'], + 'annual' => $attr['annualDonation'], + ) as $interval => $donation + ) { + if ( ! $donation['show'] ) { + continue; + } + $donations[ $interval ] = $donation; + } + + /* + $tabs = ''; + if ( count( $donations ) > 1 ) { + $tabs .= '
'; + foreach ( $donations as $interval => $donation ) { + $tabs .= '
' . $interval . '
+ } + $tabs .= '
'; + } + */ + foreach ( $donations as $interval => $donation ) { if ( ! $donation['show'] ) { continue; @@ -66,3 +91,22 @@ function render_block( $attr, $content ) { return $content; } + +/** + * Determine if AMP should be disabled on posts having Donations blocks. + * + * @param bool $skip Skipped. + * @param int $post_id Post ID. + * @param WP_Post $post Post. + * + * @return bool Whether to skip the post from AMP. + */ +function amp_skip_post( $skip, $post_id, $post ) { + // When AMP is on standard mode, there are no non-AMP posts to link to where the donation can be completed, so let's + // prevent the post from being available in AMP. + if ( function_exists( 'amp_is_canonical' ) && \amp_is_canonical() && has_block( 'jetpack/donations', $post->post_content ) ) { + return true; + } + return $skip; +} +add_filter( 'amp_skip_post', __NAMESPACE__ . '\amp_skip_post', 10, 3 ); diff --git a/extensions/blocks/donations/save.js b/extensions/blocks/donations/save.js index 6f80362c3441..c43d86889689 100644 --- a/extensions/blocks/donations/save.js +++ b/extensions/blocks/donations/save.js @@ -1,19 +1,42 @@ +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; + const Save = ( { attributes } ) => { - const { fallbackLinkUrl, fallbackLinkText, oneTimeDonation } = attributes; + const { + fallbackLinkUrl, + fallbackLinkText, + oneTimeDonation, + monthlyDonation, + annualDonation, + } = attributes; if ( ! oneTimeDonation || ! oneTimeDonation.show || oneTimeDonation.planId === -1 ) { return null; } + const isOneTimeOnly = ! monthlyDonation.show && ! annualDonation.show; + return ( - - { fallbackLinkText } - +
+
+ { isOneTimeOnly && ( + <> + + + + ) } + + { fallbackLinkText } + +
+
); }; From 2e19ec0f0fb93d2b48e26e7f69fa00b587fc7a65 Mon Sep 17 00:00:00 2001 From: mmtr Date: Wed, 14 Oct 2020 15:41:10 +0200 Subject: [PATCH 03/15] Display all intervals in fallback --- extensions/blocks/donations/attributes.js | 6 --- extensions/blocks/donations/common.scss | 2 - extensions/blocks/donations/controls.js | 16 ------ extensions/blocks/donations/donations.php | 39 -------------- extensions/blocks/donations/edit.js | 11 ++-- extensions/blocks/donations/save.js | 66 ++++++++++++++--------- extensions/blocks/donations/tab.js | 2 +- 7 files changed, 45 insertions(+), 97 deletions(-) diff --git a/extensions/blocks/donations/attributes.js b/extensions/blocks/donations/attributes.js index d6f19db68f51..a82328fdc59b 100644 --- a/extensions/blocks/donations/attributes.js +++ b/extensions/blocks/donations/attributes.js @@ -59,10 +59,4 @@ export default { selector: '.jetpack-donations-fallback-link', attribute: 'href', }, - fallbackLinkText: { - type: 'string', - source: 'html', - selector: '.jetpack-donations-fallback-link', - default: __( 'Click here to donate.', 'jetpack' ), - }, }; diff --git a/extensions/blocks/donations/common.scss b/extensions/blocks/donations/common.scss index 75878343077f..7b41d68af360 100644 --- a/extensions/blocks/donations/common.scss +++ b/extensions/blocks/donations/common.scss @@ -91,8 +91,6 @@ } .donations__separator { - line-height: 8px; - height: 8px; margin-bottom: 16px; margin-top: 16px; diff --git a/extensions/blocks/donations/controls.js b/extensions/blocks/donations/controls.js index 3291abbe2290..7e4a938a1ec2 100644 --- a/extensions/blocks/donations/controls.js +++ b/extensions/blocks/donations/controls.js @@ -115,22 +115,6 @@ const Controls = props => { onChange={ value => setAttributes( { showCustomAmount: value } ) } label={ __( 'Show custom amount option', 'jetpack' ) } /> - - - this.props.setAttributes( { fallbackLinkText: newFallbackLinkText } ) - } - value={ this.props.attributes.fallbackLinkText } - /> - { __( 'View donation earnings', 'jetpack' ) } diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index 45cb087f10e9..b767256abb98 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -50,45 +50,6 @@ function render_block( $attr, $content ) { require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php'; add_thickbox(); - $donations = array(); - foreach ( - array( - 'one-time' => $attr['oneTimeDonation'], - 'monthly' => $attr['monthlyDonation'], - 'annual' => $attr['annualDonation'], - ) as $interval => $donation - ) { - if ( ! $donation['show'] ) { - continue; - } - $donations[ $interval ] = $donation; - } - - /* - $tabs = ''; - if ( count( $donations ) > 1 ) { - $tabs .= '
'; - foreach ( $donations as $interval => $donation ) { - $tabs .= '
' . $interval . '
- } - $tabs .= '
'; - } - */ - - foreach ( $donations as $interval => $donation ) { - if ( ! $donation['show'] ) { - continue; - } - $plan_id = (int) $donation['planId']; - $plan = get_post( $plan_id ); - if ( ! $plan || is_wp_error( $plan ) ) { - continue; - } - - $url = \Jetpack_Memberships::get_instance()->get_subscription_url( $plan_id ); - $content = preg_replace( '/(donations__donate-button donations__' . $interval . '-item")/i', '$1 href="' . esc_url( $url ) . '"', $content ); - } - return $content; } diff --git a/extensions/blocks/donations/edit.js b/extensions/blocks/donations/edit.js index a0bb81c5512b..c0667a599be9 100644 --- a/extensions/blocks/donations/edit.js +++ b/extensions/blocks/donations/edit.js @@ -15,7 +15,7 @@ import fetchStatus from './fetch-status'; const Edit = props => { const { attributes, className, setAttributes } = props; - const { currency, fallbackLinkText } = attributes; + const { currency } = attributes; const [ loadingError, setLoadingError ] = useState( '' ); const [ shouldUpgrade, setShouldUpgrade ] = useState( false ); @@ -24,13 +24,8 @@ const Edit = props => { const post = useSelect( select => select( 'core/editor' ).getCurrentPost(), [] ); useEffect( () => { - setAttributes( { - fallbackLinkUrl: post.link, - ...( ! fallbackLinkText && { - fallbackLinkText: __( 'Click here to donate.', 'jetpack' ), - } ), - } ); - }, [ post.link, fallbackLinkText, setAttributes ] ); + setAttributes( { fallbackLinkUrl: post.link } ); + }, [ post.link, setAttributes ] ); const apiError = message => { setLoadingError( message ); diff --git a/extensions/blocks/donations/save.js b/extensions/blocks/donations/save.js index c43d86889689..178070191b35 100644 --- a/extensions/blocks/donations/save.js +++ b/extensions/blocks/donations/save.js @@ -4,38 +4,54 @@ import { RichText } from '@wordpress/block-editor'; const Save = ( { attributes } ) => { - const { - fallbackLinkUrl, - fallbackLinkText, - oneTimeDonation, - monthlyDonation, - annualDonation, - } = attributes; + const { fallbackLinkUrl, oneTimeDonation, monthlyDonation, annualDonation } = attributes; if ( ! oneTimeDonation || ! oneTimeDonation.show || oneTimeDonation.planId === -1 ) { return null; } - const isOneTimeOnly = ! monthlyDonation.show && ! annualDonation.show; - return (
-
- { isOneTimeOnly && ( - <> - - - - ) } - - { fallbackLinkText } - -
+ + + + { monthlyDonation.show && ( + <> +
+ + + + + ) } + { annualDonation.show && ( + <> +
+ + + + + ) }
); }; diff --git a/extensions/blocks/donations/tab.js b/extensions/blocks/donations/tab.js index b231d9e0a2e8..23f4aa500df5 100644 --- a/extensions/blocks/donations/tab.js +++ b/extensions/blocks/donations/tab.js @@ -140,7 +140,7 @@ const Tab = ( { activeTab, attributes, setAttributes } ) => { /> ) } -
——
+
Date: Wed, 14 Oct 2020 17:10:17 +0200 Subject: [PATCH 04/15] Augment block UI when rendered on frontend --- extensions/blocks/donations/donations.php | 136 +++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index b767256abb98..f279414969a4 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -50,7 +50,141 @@ function render_block( $attr, $content ) { require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php'; add_thickbox(); - return $content; + $donations = array( + 'one-time' => array_merge( + array( + 'title' => __( 'One-Time', 'jetpack' ), + 'class' => 'donations__one-time-item', + ), + $attr['oneTimeDonation'] + ), + ); + if ( $attr['monthlyDonation']['show'] ) { + $donations['1 month'] = array_merge( + array( + 'title' => __( 'Monthly', 'jetpack' ), + 'class' => 'donations__monthly-item', + ), + $attr['monthlyDonation'] + ); + } + if ( $attr['annualDonation']['show'] ) { + $donations['1 year'] = array_merge( + array( + 'title' => __( 'Yearly', 'jetpack' ), + 'class' => 'donations__annual-item', + ), + $attr['annualDonation'] + ); + } + + $currency = $attr['currency']; + + $classes = 'wp-block-jetpack-donations'; + if ( ! empty( $attr['className'] ) ) { + $classes .= ' ' . $attr['className']; + } + + $nav = ''; + $headings = ''; + $amounts = ''; + $extra_text = ''; + $buttons = ''; + foreach ( $donations as $interval => $donation ) { + $plan_id = intval( $donation['planId'] ); + $plan = get_post( $plan_id ); + if ( ! $plan || is_wp_error( $plan ) ) { + continue; + } + + if ( count( $donations ) > 1 ) { + if ( ! $nav ) { + $nav .= '
'; + } + $nav .= sprintf( + '
%2$s
', + esc_attr( $interval ), + $donation['title'] + ); + } + $headings .= sprintf( + '

%2$s

', + esc_attr( $donation['class'] ), + $donation['heading'] + ); + $amounts .= sprintf( + '
', + esc_attr( $donation['class'] ) + ); + foreach ( $donation['amounts'] as $amount ) { + $amounts .= sprintf( + '
%3$s%4$s
', + esc_attr( $amount ), + esc_attr( $currency ), + $currency, + $amount + ); + } + $amounts .= '
'; + $extra_text .= sprintf( + '

%2$s

', + esc_attr( $donation['class'] ), + $donation['extraText'] + ); + $buttons .= sprintf( + '%3$s', + esc_attr( $donation['class'] ), + \Jetpack_Memberships::get_instance()->get_subscription_url( $plan_id ), + $donation['buttonText'] + ); + } + if ( $nav ) { + $nav .= '
'; + } + + $custom_amount = ''; + if ( $attr['showCustomAmount'] ) { + $custom_amount .= sprintf( + '

%s

', + $attr['customAmountText'] + ); + $custom_amount .= sprintf( + '
+ %1$s +
+
', + $attr['currency'], + $attr['currency'] + ); + } + + return sprintf( + ' +
+
+ %2$s +
+
+ %3$s +

%4$s

+ %5$s + %6$s +
+ %7$s + %8$s +
+
+
+', + esc_attr( $classes ), + $nav, + $headings, + $attr['chooseAmountText'], + $amounts, + $custom_amount, + $extra_text, + $buttons + ); } /** From 8c5b856b1a86e777045fcfc8f4d26b35bd0a5c88 Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 19 Oct 2020 17:40:01 +0200 Subject: [PATCH 05/15] Register block attributes in the server and format amounts --- class-jetpack-currencies.php | 175 ++++++++++++++++++ extensions/blocks/donations/attributes.js | 62 ------- extensions/blocks/donations/donations.php | 89 +++++++-- extensions/blocks/donations/index.js | 2 - extensions/shared/currencies.js | 6 +- .../memberships/class-jetpack-memberships.php | 30 +++ modules/simple-payments/simple-payments.php | 148 +-------------- 7 files changed, 285 insertions(+), 227 deletions(-) create mode 100644 class-jetpack-currencies.php delete mode 100644 extensions/blocks/donations/attributes.js diff --git a/class-jetpack-currencies.php b/class-jetpack-currencies.php new file mode 100644 index 000000000000..5aa2a6f16e4b --- /dev/null +++ b/class-jetpack-currencies.php @@ -0,0 +1,175 @@ + array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => '$', + 'decimal' => 2, + ), + 'GBP' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => '£', + 'decimal' => 2, + ), + 'JPY' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => '¥', + 'decimal' => 0, + ), + 'BRL' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => 'R$', + 'decimal' => 2, + ), + 'EUR' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => '€', + 'decimal' => 2, + ), + 'NZD' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => 'NZ$', + 'decimal' => 2, + ), + 'AUD' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => 'A$', + 'decimal' => 2, + ), + 'CAD' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => 'C$', + 'decimal' => 2, + ), + 'ILS' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => '₪', + 'decimal' => 2, + ), + 'RUB' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => '₽', + 'decimal' => 2, + ), + 'MXN' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => 'MX$', + 'decimal' => 2, + ), + 'MYR' => array( + 'format' => '%2$s%1$s', // 1: Symbol 2: currency value + 'symbol' => 'RM', + 'decimal' => 2, + ), + 'SEK' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'Skr', + 'decimal' => 2, + ), + 'HUF' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'Ft', + 'decimal' => 0, // Decimals are supported by Stripe but not by PayPal. + ), + 'CHF' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'CHF', + 'decimal' => 2, + ), + 'CZK' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'Kč', + 'decimal' => 2, + ), + 'DKK' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'Dkr', + 'decimal' => 2, + ), + 'HKD' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'HK$', + 'decimal' => 2, + ), + 'NOK' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'Kr', + 'decimal' => 2, + ), + 'PHP' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => '₱', + 'decimal' => 2, + ), + 'PLN' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => 'PLN', + 'decimal' => 2, + ), + 'SGD' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => 'S$', + 'decimal' => 2, + ), + 'TWD' => array( + 'format' => '%1$s%2$s', // 1: Symbol 2: currency value + 'symbol' => 'NT$', + 'decimal' => 0, // Decimals are supported by Stripe but not by PayPal. + ), + 'THB' => array( + 'format' => '%2$s%1$s', // 1: Symbol 2: currency value + 'symbol' => '฿', + 'decimal' => 2, + ), + ); + + /** + * Format a price with currency. + * + * Uses currency-aware formatting to output a formatted price with a simple fallback. + * + * Largely inspired by WordPress.com's Store_Price::display_currency + * + * @param string $price Price. + * @param string $currency Currency. + * @param string $symbol (Optional) If provided, overrides the default currency symbol. + * @return string Formatted price. + */ + public static function format_price( $price, $currency, $symbol = null ) { + $currency_details = self::CURRENCIES[ $currency ]; + + if ( $currency_details ) { + // Ensure USD displays as 1234.56 even in non-US locales. + $amount = 'USD' === $currency + ? number_format( $price, $currency_details['decimal'], '.', ',' ) + : number_format_i18n( $price, $currency_details['decimal'] ); + + return sprintf( + $currency_details['format'], + null !== $symbol ? $symbol : $currency_details['symbol'], + $amount + ); + } + + // Fall back to unspecified currency symbol like `¤1,234.05`. + // @link https://en.wikipedia.org/wiki/Currency_sign_(typography). + if ( ! $currency ) { + return '¤' . number_format_i18n( $price, 2 ); + } + + return number_format_i18n( $price, 2 ) . ' ' . $currency; + } +} diff --git a/extensions/blocks/donations/attributes.js b/extensions/blocks/donations/attributes.js deleted file mode 100644 index a82328fdc59b..000000000000 --- a/extensions/blocks/donations/attributes.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -export default { - currency: { - type: 'string', - default: 'USD', - }, - oneTimeDonation: { - type: 'object', - default: { - show: true, - planId: null, - amounts: [ 5, 15, 100 ], - heading: __( 'Make a one-time donation', 'jetpack' ), - extraText: __( 'Your contribution is appreciated.', 'jetpack' ), - buttonText: __( 'Donate', 'jetpack' ), - }, - }, - monthlyDonation: { - type: 'object', - default: { - show: true, - planId: null, - amounts: [ 5, 15, 100 ], - heading: __( 'Make a monthly donation', 'jetpack' ), - extraText: __( 'Your contribution is appreciated.', 'jetpack' ), - buttonText: __( 'Donate monthly', 'jetpack' ), - }, - }, - annualDonation: { - type: 'object', - default: { - show: true, - planId: null, - amounts: [ 5, 15, 100 ], - heading: __( 'Make a yearly donation', 'jetpack' ), - extraText: __( 'Your contribution is appreciated.', 'jetpack' ), - buttonText: __( 'Donate yearly', 'jetpack' ), - }, - }, - showCustomAmount: { - type: 'boolean', - default: true, - }, - chooseAmountText: { - type: 'string', - default: __( 'Choose an amount', 'jetpack' ), - }, - customAmountText: { - type: 'string', - default: __( 'Or enter a custom amount', 'jetpack' ), - }, - fallbackLinkUrl: { - type: 'string', - source: 'attribute', - selector: '.jetpack-donations-fallback-link', - attribute: 'href', - }, -}; diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index f279414969a4..24bc42b40892 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -26,6 +26,63 @@ function register_block() { array( 'render_callback' => __NAMESPACE__ . '\render_block', 'plan_check' => true, + 'attributes' => array( + 'currency' => array( + 'type' => 'string', + 'default' => 'USD', + ), + 'oneTimeDonation' => array( + 'type' => 'object', + 'default' => array( + 'show' => true, + 'planId' => null, + 'amounts' => array( 5, 15, 100 ), + 'heading' => __( 'Make a one-time donation', 'jetpack' ), + 'extraText' => __( 'Your contribution is appreciated.', 'jetpack' ), + 'buttonText' => __( 'Donate', 'jetpack' ), + ), + ), + 'monthlyDonation' => array( + 'type' => 'object', + 'default' => array( + 'show' => true, + 'planId' => null, + 'amounts' => array( 5, 15, 100 ), + 'heading' => __( 'Make a monthly donation', 'jetpack' ), + 'extraText' => __( 'Your contribution is appreciated.', 'jetpack' ), + 'buttonText' => __( 'Donate monthly', 'jetpack' ), + ), + ), + 'annualDonation' => array( + 'type' => 'object', + 'default' => array( + 'show' => true, + 'planId' => null, + 'amounts' => array( 5, 15, 100 ), + 'heading' => __( 'Make a yearly donation', 'jetpack' ), + 'extraText' => __( 'Your contribution is appreciated.', 'jetpack' ), + 'buttonText' => __( 'Donate yearly', 'jetpack' ), + ), + ), + 'showCustomAmount' => array( + 'type' => 'boolean', + 'default' => true, + ), + 'chooseAmountText' => array( + 'type' => 'string', + 'default' => __( 'Choose an amount', 'jetpack' ), + ), + 'customAmountText' => array( + 'type' => 'string', + 'default' => __( 'Or enter a custom amount', 'jetpack' ), + ), + 'fallbackLinkUrl' => array( + 'type' => 'string', + 'source' => 'attribute', + 'selector' => '.jetpack-donations-fallback-link', + 'attribute' => 'href', + ), + ), ) ); } @@ -47,7 +104,9 @@ function render_block( $attr, $content ) { Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'thickbox' ) ); - require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php'; + require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php'; + require_once JETPACK__PLUGIN_DIR . 'class-jetpack-currencies.php'; + add_thickbox(); $donations = array( @@ -91,7 +150,7 @@ function render_block( $attr, $content ) { $extra_text = ''; $buttons = ''; foreach ( $donations as $interval => $donation ) { - $plan_id = intval( $donation['planId'] ); + $plan_id = (int) $donation['planId']; $plan = get_post( $plan_id ); if ( ! $plan || is_wp_error( $plan ) ) { continue; @@ -118,11 +177,9 @@ function render_block( $attr, $content ) { ); foreach ( $donation['amounts'] as $amount ) { $amounts .= sprintf( - '
%3$s%4$s
', + '
%2$s
', esc_attr( $amount ), - esc_attr( $currency ), - $currency, - $amount + \Jetpack_Currencies::format_price( $amount, $currency ) ); } $amounts .= '
'; @@ -144,32 +201,34 @@ function render_block( $attr, $content ) { $custom_amount = ''; if ( $attr['showCustomAmount'] ) { - $custom_amount .= sprintf( - '

%s

', + $custom_amount .= sprintf( + '

%s

', $attr['customAmountText'] ); - $custom_amount .= sprintf( + $default_custom_amount = \Jetpack_Memberships::SUPPORTED_CURRENCIES[ $currency ] * 100; + $custom_amount .= sprintf( '
%1$s -
+
', + \Jetpack_Currencies::CURRENCIES[ $attr['currency'] ]['symbol'], $attr['currency'], - $attr['currency'] + \Jetpack_Currencies::format_price( $default_custom_amount, $currency, '' ) ); } return sprintf( '
-
+
%2$s -
-
+
+
%3$s

%4$s

%5$s %6$s -
+
%7$s %8$s
diff --git a/extensions/blocks/donations/index.js b/extensions/blocks/donations/index.js index f5e5b0ba3237..3727bd1f828d 100644 --- a/extensions/blocks/donations/index.js +++ b/extensions/blocks/donations/index.js @@ -6,7 +6,6 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import attributes from './attributes'; import edit from './edit'; import save from './save'; import GridiconHeart from 'gridicons/dist/heart-outline'; @@ -34,6 +33,5 @@ export const settings = { }, edit, save, - attributes, example: {}, }; diff --git a/extensions/shared/currencies.js b/extensions/shared/currencies.js index 7d13b43f1db5..e638f61cd441 100644 --- a/extensions/shared/currencies.js +++ b/extensions/shared/currencies.js @@ -8,10 +8,8 @@ import { CURRENCIES } from '@automattic/format-currency'; * * @link https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts * - * List has to be in sync with the Memberships library in WP.com. - * @see Memberships_Product::SUPPORTED_CURRENCIES - * - * @type { [currency: string]: number } + * List has to be in with `Jetpack_Memberships::SUPPORTED_CURRENCIES` in modules/memberships/class-jetpack-memberships.php and + * `Memberships_Product::SUPPORTED_CURRENCIES` in the WP.com memberships library. */ export const SUPPORTED_CURRENCIES = { USD: 0.5, diff --git a/modules/memberships/class-jetpack-memberships.php b/modules/memberships/class-jetpack-memberships.php index 1cabbcde0901..419fbc1d5a83 100644 --- a/modules/memberships/class-jetpack-memberships.php +++ b/modules/memberships/class-jetpack-memberships.php @@ -66,6 +66,36 @@ class Jetpack_Memberships { */ private static $instance; + /** + * Currencies we support and Stripe's minimum amount for a transaction in that currency. + * + * @link https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts + * + * List has to be in with `SUPPORTED_CURRENCIES` in extensions/shared/currencies.js and + * `Memberships_Product::SUPPORTED_CURRENCIES` in the WP.com memberships library. + * + * @type { [currency: string]: number } + */ + const SUPPORTED_CURRENCIES = array( + 'USD' => 0.5, + 'AUD' => 0.5, + 'BRL' => 0.5, + 'CAD' => 0.5, + 'CHF' => 0.5, + 'DKK' => 2.5, + 'EUR' => 0.5, + 'GBP' => 0.3, + 'HKD' => 4.0, + 'INR' => 0.5, + 'JPY' => 50, + 'MXN' => 10, + 'NOK' => 3.0, + 'NZD' => 0.5, + 'PLN' => 2.0, + 'SEK' => 3.0, + 'SGD' => 0.5, + ); + /** * Jetpack_Memberships constructor. */ diff --git a/modules/simple-payments/simple-payments.php b/modules/simple-payments/simple-payments.php index 66fd2a142f13..8d36a00774dc 100644 --- a/modules/simple-payments/simple-payments.php +++ b/modules/simple-payments/simple-payments.php @@ -290,28 +290,8 @@ public function output_shortcode( $data ) { * @return string Formatted price. */ private function format_price( $price, $currency ) { - $currency_details = self::get_currency( $currency ); - - if ( $currency_details ) { - // Ensure USD displays as 1234.56 even in non-US locales. - $amount = 'USD' === $currency - ? number_format( $price, $currency_details['decimal'], '.', ',' ) - : number_format_i18n( $price, $currency_details['decimal'] ); - - return sprintf( - $currency_details['format'], - $currency_details['symbol'], - $amount - ); - } - - // Fall back to unspecified currency symbol like `¤1,234.05`. - // @link https://en.wikipedia.org/wiki/Currency_sign_(typography). - if ( ! $currency ) { - return '¤' . number_format_i18n( $price, 2 ); - } - - return number_format_i18n( $price, 2 ) . ' ' . $currency; + require_once JETPACK__PLUGIN_DIR . 'class.jetpack-currencies.php'; + return Jetpack_Currencies::format_price( $price, $currency ); } /** @@ -573,128 +553,8 @@ function setup_cpts() { * @return ?array Currency object or null if not found. */ private static function get_currency( $the_currency ) { - $currencies = array( - 'USD' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => '$', - 'decimal' => 2, - ), - 'GBP' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => '£', - 'decimal' => 2, - ), - 'JPY' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => '¥', - 'decimal' => 0, - ), - 'BRL' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => 'R$', - 'decimal' => 2, - ), - 'EUR' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => '€', - 'decimal' => 2, - ), - 'NZD' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => 'NZ$', - 'decimal' => 2, - ), - 'AUD' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => 'A$', - 'decimal' => 2, - ), - 'CAD' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => 'C$', - 'decimal' => 2, - ), - 'ILS' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => '₪', - 'decimal' => 2, - ), - 'RUB' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => '₽', - 'decimal' => 2, - ), - 'MXN' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => 'MX$', - 'decimal' => 2, - ), - 'MYR' => array( - 'format' => '%2$s%1$s', // 1: Symbol 2: currency value - 'symbol' => 'RM', - 'decimal' => 2, - ), - 'SEK' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'Skr', - 'decimal' => 2, - ), - 'HUF' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'Ft', - 'decimal' => 0, // Decimals are supported by Stripe but not by PayPal. - ), - 'CHF' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'CHF', - 'decimal' => 2, - ), - 'CZK' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'Kč', - 'decimal' => 2, - ), - 'DKK' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'Dkr', - 'decimal' => 2, - ), - 'HKD' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'HK$', - 'decimal' => 2, - ), - 'NOK' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'Kr', - 'decimal' => 2, - ), - 'PHP' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => '₱', - 'decimal' => 2, - ), - 'PLN' => array( - 'format' => '%2$s %1$s', // 1: Symbol 2: currency value - 'symbol' => 'PLN', - 'decimal' => 2, - ), - 'SGD' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => 'S$', - 'decimal' => 2, - ), - 'TWD' => array( - 'format' => '%1$s%2$s', // 1: Symbol 2: currency value - 'symbol' => 'NT$', - 'decimal' => 0, // Decimals are supported by Stripe but not by PayPal. - ), - 'THB' => array( - 'format' => '%2$s%1$s', // 1: Symbol 2: currency value - 'symbol' => '฿', - 'decimal' => 2, - ), - ); + require_once JETPACK__PLUGIN_DIR . 'class.jetpack-currencies.php'; + $currencies = Jetpack_Currencies::CURRENCIES; if ( isset( $currencies[ $the_currency ] ) ) { return $currencies[ $the_currency ]; From bf16dd82b40aca3095c390a509ac120c765e641a Mon Sep 17 00:00:00 2001 From: mmtr Date: Tue, 20 Oct 2020 16:12:17 +0200 Subject: [PATCH 06/15] Escape output --- class-jetpack-currencies.php | 6 +++--- extensions/blocks/donations/donations.php | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/class-jetpack-currencies.php b/class-jetpack-currencies.php index 5aa2a6f16e4b..39497ab6f290 100644 --- a/class-jetpack-currencies.php +++ b/class-jetpack-currencies.php @@ -145,10 +145,10 @@ class Jetpack_Currencies { * * @param string $price Price. * @param string $currency Currency. - * @param string $symbol (Optional) If provided, overrides the default currency symbol. + * @param bool $symbol Whether to display the currency symbol. * @return string Formatted price. */ - public static function format_price( $price, $currency, $symbol = null ) { + public static function format_price( $price, $currency, $symbol = true ) { $currency_details = self::CURRENCIES[ $currency ]; if ( $currency_details ) { @@ -159,7 +159,7 @@ public static function format_price( $price, $currency, $symbol = null ) { return sprintf( $currency_details['format'], - null !== $symbol ? $symbol : $currency_details['symbol'], + $symbol ? $currency_details['symbol'] : '', $amount ); } diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index 24bc42b40892..964b84d23daa 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -179,7 +179,7 @@ function render_block( $attr, $content ) { $amounts .= sprintf( '
%2$s
', esc_attr( $amount ), - \Jetpack_Currencies::format_price( $amount, $currency ) + esc_html( \Jetpack_Currencies::format_price( $amount, $currency ) ) ); } $amounts .= '
'; @@ -191,7 +191,7 @@ function render_block( $attr, $content ) { $buttons .= sprintf( '%3$s', esc_attr( $donation['class'] ), - \Jetpack_Memberships::get_instance()->get_subscription_url( $plan_id ), + esc_url( \Jetpack_Memberships::get_instance()->get_subscription_url( $plan_id ) ), $donation['buttonText'] ); } @@ -211,9 +211,9 @@ function render_block( $attr, $content ) { %1$s
', - \Jetpack_Currencies::CURRENCIES[ $attr['currency'] ]['symbol'], - $attr['currency'], - \Jetpack_Currencies::format_price( $default_custom_amount, $currency, '' ) + esc_html( \Jetpack_Currencies::CURRENCIES[ $attr['currency'] ]['symbol'] ), + esc_attr( $attr['currency'] ), + esc_attr( \Jetpack_Currencies::format_price( $default_custom_amount, $currency, false ) ) ); } From 2c3cdea7a0525f1e2ac9f6a2b3f25bb65d486341 Mon Sep 17 00:00:00 2001 From: mmtr Date: Tue, 20 Oct 2020 16:45:08 +0200 Subject: [PATCH 07/15] Import deprecation --- extensions/blocks/donations/index.js | 8 +++++++- extensions/blocks/donations/save.js | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/extensions/blocks/donations/index.js b/extensions/blocks/donations/index.js index 3727bd1f828d..cd4b41be5358 100644 --- a/extensions/blocks/donations/index.js +++ b/extensions/blocks/donations/index.js @@ -1,6 +1,11 @@ /** * External dependencies */ +import GridiconHeart from 'gridicons/dist/heart-outline'; + +/** + * WordPress dependencies + */ import { __ } from '@wordpress/i18n'; /** @@ -8,8 +13,8 @@ import { __ } from '@wordpress/i18n'; */ import edit from './edit'; import save from './save'; -import GridiconHeart from 'gridicons/dist/heart-outline'; import { getIconColor } from '../../shared/block-icons'; +import deprecatedV1 from './deprecated/v1'; /** * Style dependencies @@ -34,4 +39,5 @@ export const settings = { edit, save, example: {}, + deprecated: [ deprecatedV1 ], }; diff --git a/extensions/blocks/donations/save.js b/extensions/blocks/donations/save.js index 178070191b35..b07302e278dd 100644 --- a/extensions/blocks/donations/save.js +++ b/extensions/blocks/donations/save.js @@ -6,7 +6,12 @@ import { RichText } from '@wordpress/block-editor'; const Save = ( { attributes } ) => { const { fallbackLinkUrl, oneTimeDonation, monthlyDonation, annualDonation } = attributes; - if ( ! oneTimeDonation || ! oneTimeDonation.show || oneTimeDonation.planId === -1 ) { + if ( + ! oneTimeDonation || + ! oneTimeDonation.show || + ! oneTimeDonation.planId || + oneTimeDonation.planId === -1 + ) { return null; } From f630f6d6c7a179d289549a1ed7333093c16a07f0 Mon Sep 17 00:00:00 2001 From: mmtr Date: Wed, 21 Oct 2020 12:15:13 +0200 Subject: [PATCH 08/15] Add INR format --- class-jetpack-currencies.php | 7 ++++++- extensions/blocks/donations/controls.js | 2 -- extensions/blocks/donations/donations.php | 5 +---- modules/memberships/class-jetpack-memberships.php | 2 -- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/class-jetpack-currencies.php b/class-jetpack-currencies.php index 39497ab6f290..9ac05fe79669 100644 --- a/class-jetpack-currencies.php +++ b/class-jetpack-currencies.php @@ -7,7 +7,7 @@ */ /** - * General Gutenberg editor specific functionality + * General currencies specific functionality */ class Jetpack_Currencies { /** @@ -134,6 +134,11 @@ class Jetpack_Currencies { 'symbol' => '฿', 'decimal' => 2, ), + 'INR' => array( + 'format' => '%2$s %1$s', // 1: Symbol 2: currency value + 'symbol' => '₹', + 'decimal' => 0, + ), ); /** diff --git a/extensions/blocks/donations/controls.js b/extensions/blocks/donations/controls.js index 7e4a938a1ec2..750d458d356c 100644 --- a/extensions/blocks/donations/controls.js +++ b/extensions/blocks/donations/controls.js @@ -8,7 +8,6 @@ import { CURRENCIES } from '@automattic/format-currency'; */ import { BlockControls, InspectorControls } from '@wordpress/block-editor'; import { - BaseControl, Button, Dashicon, Dropdown, @@ -16,7 +15,6 @@ import { MenuGroup, MenuItem, PanelBody, - TextControl, ToggleControl, ToolbarGroup, } from '@wordpress/components'; diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index 964b84d23daa..03fee7afed60 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -77,10 +77,7 @@ function register_block() { 'default' => __( 'Or enter a custom amount', 'jetpack' ), ), 'fallbackLinkUrl' => array( - 'type' => 'string', - 'source' => 'attribute', - 'selector' => '.jetpack-donations-fallback-link', - 'attribute' => 'href', + 'type' => 'string', ), ), ) diff --git a/modules/memberships/class-jetpack-memberships.php b/modules/memberships/class-jetpack-memberships.php index 419fbc1d5a83..cb87fda2ddf1 100644 --- a/modules/memberships/class-jetpack-memberships.php +++ b/modules/memberships/class-jetpack-memberships.php @@ -73,8 +73,6 @@ class Jetpack_Memberships { * * List has to be in with `SUPPORTED_CURRENCIES` in extensions/shared/currencies.js and * `Memberships_Product::SUPPORTED_CURRENCIES` in the WP.com memberships library. - * - * @type { [currency: string]: number } */ const SUPPORTED_CURRENCIES = array( 'USD' => 0.5, From 3aa3b90804c04a0957110f72f6cf153a18d02556 Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 26 Oct 2020 12:45:27 +0100 Subject: [PATCH 09/15] Move currencies lib to _inc/lib --- .../lib/class-jetpack-currencies.php | 0 extensions/blocks/donations/donations.php | 5 ++--- 2 files changed, 2 insertions(+), 3 deletions(-) rename class-jetpack-currencies.php => _inc/lib/class-jetpack-currencies.php (100%) diff --git a/class-jetpack-currencies.php b/_inc/lib/class-jetpack-currencies.php similarity index 100% rename from class-jetpack-currencies.php rename to _inc/lib/class-jetpack-currencies.php diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index 03fee7afed60..e23955663457 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -100,11 +100,10 @@ function render_block( $attr, $content ) { } Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'thickbox' ) ); + add_thickbox(); require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php'; - require_once JETPACK__PLUGIN_DIR . 'class-jetpack-currencies.php'; - - add_thickbox(); + jetpack_require_lib( 'class-jetpack-currencies' ); $donations = array( 'one-time' => array_merge( From 5598a4196c67c5fcfe8bdf00748b4090989ecd47 Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 26 Oct 2020 12:50:44 +0100 Subject: [PATCH 10/15] Set classes with Blocks::classes --- extensions/blocks/donations/donations.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index e23955663457..7b223b297263 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -133,13 +133,7 @@ function render_block( $attr, $content ) { ); } - $currency = $attr['currency']; - - $classes = 'wp-block-jetpack-donations'; - if ( ! empty( $attr['className'] ) ) { - $classes .= ' ' . $attr['className']; - } - + $currency = $attr['currency']; $nav = ''; $headings = ''; $amounts = ''; @@ -231,7 +225,7 @@ function render_block( $attr, $content ) {
', - esc_attr( $classes ), + esc_attr( Blocks::classes( FEATURE_NAME, $attr ) ), $nav, $headings, $attr['chooseAmountText'], From 1d8618b62ed442891534f500ba4225beb40ece3d Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 26 Oct 2020 12:56:09 +0100 Subject: [PATCH 11/15] Escape output --- extensions/blocks/donations/donations.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index 7b223b297263..5316e2297ff1 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -153,13 +153,13 @@ function render_block( $attr, $content ) { $nav .= sprintf( '
%2$s
', esc_attr( $interval ), - $donation['title'] + esc_html( $donation['title'] ) ); } $headings .= sprintf( '

%2$s

', esc_attr( $donation['class'] ), - $donation['heading'] + wp_kses_post( $donation['heading'] ) ); $amounts .= sprintf( '
', @@ -176,13 +176,13 @@ function render_block( $attr, $content ) { $extra_text .= sprintf( '

%2$s

', esc_attr( $donation['class'] ), - $donation['extraText'] + wp_kses_post( $donation['extraText'] ) ); $buttons .= sprintf( '%3$s', esc_attr( $donation['class'] ), esc_url( \Jetpack_Memberships::get_instance()->get_subscription_url( $plan_id ) ), - $donation['buttonText'] + wp_kses_post( $donation['buttonText'] ) ); } if ( $nav ) { @@ -193,7 +193,7 @@ function render_block( $attr, $content ) { if ( $attr['showCustomAmount'] ) { $custom_amount .= sprintf( '

%s

', - $attr['customAmountText'] + wp_kses_post( $attr['customAmountText'] ) ); $default_custom_amount = \Jetpack_Memberships::SUPPORTED_CURRENCIES[ $currency ] * 100; $custom_amount .= sprintf( From 6df75bec24e60f0527c70f9815e7c98c303a34b4 Mon Sep 17 00:00:00 2001 From: Miguel Torres Date: Mon, 26 Oct 2020 13:00:33 +0100 Subject: [PATCH 12/15] Update extensions/blocks/donations/donations.php Co-authored-by: Jeremy Herve --- extensions/blocks/donations/donations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/blocks/donations/donations.php b/extensions/blocks/donations/donations.php index 5316e2297ff1..a392791bf731 100644 --- a/extensions/blocks/donations/donations.php +++ b/extensions/blocks/donations/donations.php @@ -248,7 +248,7 @@ function render_block( $attr, $content ) { function amp_skip_post( $skip, $post_id, $post ) { // When AMP is on standard mode, there are no non-AMP posts to link to where the donation can be completed, so let's // prevent the post from being available in AMP. - if ( function_exists( 'amp_is_canonical' ) && \amp_is_canonical() && has_block( 'jetpack/donations', $post->post_content ) ) { + if ( function_exists( 'amp_is_canonical' ) && \amp_is_canonical() && has_block( BLOCK_NAME, $post->post_content ) ) { return true; } return $skip; From 2b52cbc7403ee21424b714c03850400aea82e2ec Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 26 Oct 2020 13:01:45 +0100 Subject: [PATCH 13/15] Use BLOCK_NAME in Pay with PayPal's amp_skip_post --- extensions/blocks/simple-payments/simple-payments.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/blocks/simple-payments/simple-payments.php b/extensions/blocks/simple-payments/simple-payments.php index 96c394597b0e..c145fa762d43 100644 --- a/extensions/blocks/simple-payments/simple-payments.php +++ b/extensions/blocks/simple-payments/simple-payments.php @@ -88,7 +88,7 @@ function render_block( $attr, $content ) { function amp_skip_post( $skip, $post_id, $post ) { // When AMP is on standard mode, there are no non-AMP posts to link to where the purchase can be completed, so let's // prevent the post from being available in AMP. - if ( function_exists( 'amp_is_canonical' ) && \amp_is_canonical() && has_block( 'jetpack/simple-payments', $post->post_content ) ) { + if ( function_exists( 'amp_is_canonical' ) && \amp_is_canonical() && has_block( BLOCK_NAME, $post->post_content ) ) { return true; } return $skip; From cf64f54f5a0710afd96aa0c514968230da9993ae Mon Sep 17 00:00:00 2001 From: mmtr Date: Mon, 26 Oct 2020 13:50:20 +0100 Subject: [PATCH 14/15] Add unit tests for Jetpack_Currencies --- _inc/lib/class-jetpack-currencies.php | 30 ++++------ .../lib/test-class-jetpack-currencies.php | 59 +++++++++++++++++++ 2 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 tests/php/_inc/lib/test-class-jetpack-currencies.php diff --git a/_inc/lib/class-jetpack-currencies.php b/_inc/lib/class-jetpack-currencies.php index 9ac05fe79669..adebcf2b94d7 100644 --- a/_inc/lib/class-jetpack-currencies.php +++ b/_inc/lib/class-jetpack-currencies.php @@ -154,27 +154,23 @@ class Jetpack_Currencies { * @return string Formatted price. */ public static function format_price( $price, $currency, $symbol = true ) { - $currency_details = self::CURRENCIES[ $currency ]; - - if ( $currency_details ) { - // Ensure USD displays as 1234.56 even in non-US locales. - $amount = 'USD' === $currency - ? number_format( $price, $currency_details['decimal'], '.', ',' ) - : number_format_i18n( $price, $currency_details['decimal'] ); - - return sprintf( - $currency_details['format'], - $symbol ? $currency_details['symbol'] : '', - $amount - ); - } - // Fall back to unspecified currency symbol like `¤1,234.05`. // @link https://en.wikipedia.org/wiki/Currency_sign_(typography). - if ( ! $currency ) { + if ( ! array_key_exists( $currency, self::CURRENCIES ) ) { return '¤' . number_format_i18n( $price, 2 ); } - return number_format_i18n( $price, 2 ) . ' ' . $currency; + $currency_details = self::CURRENCIES[ $currency ]; + + // Ensure USD displays as 1234.56 even in non-US locales. + $amount = 'USD' === $currency + ? number_format( $price, $currency_details['decimal'], '.', ',' ) + : number_format_i18n( $price, $currency_details['decimal'] ); + + return sprintf( + $currency_details['format'], + $symbol ? $currency_details['symbol'] : '', + $amount + ); } } diff --git a/tests/php/_inc/lib/test-class-jetpack-currencies.php b/tests/php/_inc/lib/test-class-jetpack-currencies.php new file mode 100644 index 000000000000..3f7982530b1c --- /dev/null +++ b/tests/php/_inc/lib/test-class-jetpack-currencies.php @@ -0,0 +1,59 @@ +number_format; + $wp_locale->number_format = array( + 'thousands_sep' => '-', + 'decimal_point' => '|', + ); + $formatted_price = Jetpack_Currencies::format_price( '12345.67890', 'USD' ); + $this->assertEquals( '$12,345.68', $formatted_price ); + $wp_locale->number_format = $previous_number_format; + } + + /** + * Test that non-USD currencies are formatted according to the user locale. + */ + public function test_format_price_non_usd() { + global $wp_locale; + $previous_number_format = $wp_locale->number_format; + $wp_locale->number_format = array( + 'thousands_sep' => '-', + 'decimal_point' => '|', + ); + $formatted_price = Jetpack_Currencies::format_price( '12345.67890', 'EUR' ); + $this->assertEquals( '€12-345|68', $formatted_price ); + $wp_locale->number_format = $previous_number_format; + } + + /** + * Test that no currency symbol is displayed when specified. + */ + public function test_format_price_no_currency_symbol() { + $formatted_price = Jetpack_Currencies::format_price( '12345.67890', 'USD', false ); + $this->assertEquals( '12,345.68', $formatted_price ); + } + + /** + * Test that the unspecified currency symbol is displayed when the currency is not found. + */ + public function test_format_price_unspecified_currency_symbol() { + $formatted_price = Jetpack_Currencies::format_price( '12345.67890', 'TEST', false ); + $this->assertEquals( '¤12,345.68', $formatted_price ); + } +} From 4030797b0a52173323d31aae57a5b15b8bec639b Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Mon, 26 Oct 2020 18:45:20 +0100 Subject: [PATCH 15/15] Add new filet to PHPCS requirelist --- bin/phpcs-requirelist.js | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/phpcs-requirelist.js b/bin/phpcs-requirelist.js index 244d96f147cb..30926fdf56f3 100644 --- a/bin/phpcs-requirelist.js +++ b/bin/phpcs-requirelist.js @@ -23,6 +23,7 @@ module.exports = [ '_inc/lib/admin-pages/class-jetpack-about-page.php', '_inc/lib/class.media-extractor.php', '_inc/lib/class.media-summary.php', + '_inc/lib/class-jetpack-currencies.php', '_inc/lib/class-jetpack-instagram-gallery-helper.php', '_inc/lib/class-jetpack-tweetstorm-helper.php', '_inc/lib/class-jetpack-mapbox-helper.php',