Skip to content

Commit 28a43e6

Browse files
committed
fix: improve formatting of donation amount options
1 parent e4c327a commit 28a43e6

File tree

5 files changed

+45
-30
lines changed

5 files changed

+45
-30
lines changed

includes/class-newspack-blocks.php

+14-14
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ public static function enqueue_block_editor_assets() {
213213
'custom_taxonomies' => self::get_custom_taxonomies(),
214214
'can_use_name_your_price' => self::can_use_name_your_price(),
215215
'tier_amounts_template' => self::get_formatted_amount(),
216+
'currency' => function_exists( 'get_woocommerce_currency' ) ? \get_woocommerce_currency() : 'USD',
216217
];
217218

218219
if ( class_exists( 'WP_REST_Newspack_Author_List_Controller' ) ) {
@@ -1414,13 +1415,13 @@ public static function get_article_meta_footer( $post = null ) {
14141415
/**
14151416
* Get a formatted HTML string containing amount and frequency of a donation.
14161417
*
1417-
* @param float $amount Amount.
1418-
* @param string $frequency Frequency.
1419-
* @param bool $hide_once_label Whether to hide the "once" label.
1418+
* @param float|string $amount Amount.
1419+
* @param string $frequency Frequency.
1420+
* @param bool $hide_once_label Whether to hide the "once" label.
14201421
*
14211422
* @return string
14221423
*/
1423-
public static function get_formatted_amount( $amount = 0, $frequency = 'day', $hide_once_label = false ) {
1424+
public static function get_formatted_amount( $amount = 'AMOUNT_PLACEHOLDER', $frequency = 'day', $hide_once_label = false ) {
14241425
if ( ! function_exists( 'wc_price' ) || ( method_exists( 'Newspack\Donations', 'is_platform_wc' ) && ! \Newspack\Donations::is_platform_wc() ) ) {
14251426
if ( 0 === $amount ) {
14261427
return false;
@@ -1432,23 +1433,22 @@ public static function get_formatted_amount( $amount = 0, $frequency = 'day', $h
14321433
$formatted_price = '<span class="price-amount">' . $formatter->formatCurrency( $amount, 'USD' ) . '</span> <span class="tier-frequency">' . $frequency_string . '</span>';
14331434
return str_replace( '.00', '', $formatted_price );
14341435
}
1436+
1437+
// Format the amount with currency symbol and separators.
1438+
$amount_string = \wc_price(
1439+
$amount,
1440+
[ 'decimals' => is_int( $amount ) ? 0 : 2 ]
1441+
);
1442+
14351443
if ( ! function_exists( 'wcs_price_string' ) ) {
1436-
return \wc_price( $amount );
1444+
return $amount_string;
14371445
}
14381446
$price_args = [
1439-
'recurring_amount' => $amount,
1447+
'recurring_amount' => $amount_string,
14401448
'subscription_period' => 'once' === $frequency ? 'day' : $frequency,
14411449
];
14421450
$wc_formatted_amount = \wcs_price_string( $price_args );
14431451

1444-
// A '0' value means we want a placeholder string to replace in the editor.
1445-
if ( 0 === $amount ) {
1446-
preg_match( '/<\/span>(.*)<\/bdi>/', $wc_formatted_amount, $matches );
1447-
if ( ! empty( $matches[1] ) ) {
1448-
$wc_formatted_amount = str_replace( $matches[1], 'AMOUNT_PLACEHOLDER', $wc_formatted_amount );
1449-
}
1450-
}
1451-
14521452
// A 'day' frequency means we want a placeholder string to replace in the editor.
14531453
if ( 'day' === $frequency ) {
14541454
$wc_formatted_amount = preg_replace( '/ \/ ?.*/', 'FREQUENCY_PLACEHOLDER', $wc_formatted_amount );

src/blocks/donate/edit/FrequencyBasedLayout.tsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { RichText } from '@wordpress/block-editor';
1414
* Internal dependencies
1515
*/
1616
import { AmountValueInput } from './components';
17-
import { getColorForContrast, getFrequencyLabel, getFrequencyLabelWithAmount } from '../utils';
17+
import { getColorForContrast, getFrequencyLabel, getFormattedAmount, getFrequencyLabelWithAmount } from '../utils';
1818
import { FREQUENCIES } from '../consts';
1919
import type { ComponentProps, DonationFrequencySlug } from '../types';
2020
import { updateBlockClassName, getFormData } from '../view'
@@ -105,9 +105,6 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
105105
</button>
106106
);
107107

108-
// This code is fired on tab select and updates aria elements, tabindex states, and radio buttons
109-
const displayAmount = ( amount: number ) => amount.toFixed( 2 ).replace( /\.?0*$/, '' );
110-
111108
const renderFormHeader = () => {
112109
return ! rendersSingleFrequency && (
113110
<div className="tab-container">{ availableFrequencies.map( renderTab ) }</div>
@@ -197,7 +194,7 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
197194
}`;
198195
const tierLabel = isOtherTier
199196
? __( 'Other', 'newspack-blocks' )
200-
: `${settings.currencySymbol}${displayAmount( suggestedAmount )}`
197+
: getFormattedAmount( suggestedAmount, true );
201198
return (
202199
<div
203200
className={ classNames(

src/blocks/donate/frontend/class-newspack-blocks-donate-renderer-frequency-based.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,12 @@ class='wp-block-newspack-blocks-donate__frequency frequency'
264264
'donation_price_summary_' . $frequency_slug => $product_price_summary,
265265
]
266266
);
267+
268+
$decimals = intval( $amount ) == floatval( $amount ) ? 0 : 2;
269+
$format_options = [ 'decimals' => $decimals ];
270+
$formatted_amount = function_exists( 'wc_price' ) ?
271+
wp_strip_all_tags( \wc_price( (float) $amount, $format_options ) ) :
272+
$configuration['currencySymbol'] . number_format( $amount, $decimals );
267273
?>
268274
<div
269275
class='wp-block-newspack-blocks-donate__tier donation-tier__<?php echo esc_attr( $frequency_slug ); ?>'
@@ -315,7 +321,7 @@ class='odl'
315321
class='tier-select-label tier-label'
316322
for='newspack-tier-<?php echo esc_attr( $frequency_slug . '-' . $uid ); ?>-<?php echo (int) $index; ?>'
317323
>
318-
<?php echo esc_html( $configuration['currencySymbol'] . $amount ); ?>
324+
<?php echo wp_kses_post( $formatted_amount ); ?>
319325
</label>
320326
<?php endif; ?>
321327
</div>

src/blocks/donate/utils.ts

+21-10
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ export const getFrequencyLabel = (
6666
);
6767
}
6868

69+
export const getFormattedAmount = ( amount: number, withCurrency = false ) => {
70+
type NumberFormatOptions = {
71+
minimumFractionDigits: number;
72+
style?: string;
73+
currency?: string;
74+
}
75+
const options = <NumberFormatOptions>{
76+
minimumFractionDigits: 0 === amount % 1 ? 0 : 2,
77+
};
78+
if ( withCurrency ) {
79+
options.style = 'currency';
80+
options.currency = window.newspack_blocks_data?.currency || 'USD';
81+
}
82+
const formatter = new Intl.NumberFormat( navigator?.language || 'en-US', options as object );
83+
84+
return formatter.format( amount );
85+
}
86+
6987
export const getFrequencyLabelWithAmount = (
7088
amount: number,
7189
frequencySlug: DonationFrequencySlug,
@@ -75,11 +93,6 @@ export const getFrequencyLabelWithAmount = (
7593

7694
if ( ! template ) {
7795
try {
78-
const formatter = new Intl.NumberFormat( navigator?.language || 'en-US', {
79-
style: 'currency',
80-
currency: 'USD',
81-
} );
82-
8396
const frequencyString =
8497
frequencySlug === 'once'
8598
? frequencySlug
@@ -91,7 +104,7 @@ export const getFrequencyLabelWithAmount = (
91104

92105
const formattedPrice =
93106
'<span class="price-amount">' +
94-
formatter.format( amount ) +
107+
getFormattedAmount( amount, true ) +
95108
'</span> <span class="tier-frequency">' +
96109
frequencyString +
97110
'</span>';
@@ -102,11 +115,9 @@ export const getFrequencyLabelWithAmount = (
102115
}
103116
}
104117

105-
const formattedAmount = ( amount || 0 ).toFixed( 2 ).replace( /\.?0*$/, '' );
106-
107-
const frequency = getFrequencyLabel(frequencySlug, hideOnceLabel)
118+
const frequency = getFrequencyLabel( frequencySlug, hideOnceLabel );
108119

109120
return template
110-
.replace( 'AMOUNT_PLACEHOLDER', formattedAmount )
121+
.replace( 'AMOUNT_PLACEHOLDER', getFormattedAmount( amount ) )
111122
.replace( 'FREQUENCY_PLACEHOLDER', frequency );
112123
};

src/types/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ declare global {
1111
post_subtitle: boolean;
1212
can_use_name_your_price: boolean;
1313
tier_amounts_template: string;
14+
currency: string;
1415
};
1516
grecaptcha: any;
1617
newspackReaderActivation: {

0 commit comments

Comments
 (0)