Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(reader-revenue): make NYP and Stripe Gateway optional #1645

Merged
merged 18 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions includes/class-modal-checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,17 @@ function ( $item ) {
}

/** Apply NYP custom price */
if ( class_exists( 'WC_Name_Your_Price_Helpers' ) ) {
$is_product_nyp = \WC_Name_Your_Price_Helpers::is_nyp( $product_id );
$price = filter_input( INPUT_GET, 'price', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
if ( $is_product_nyp ) {
if ( empty( $price ) ) {
$price = \WC_Name_Your_Price_Helpers::get_suggested_price( $product_id );
}
$min_price = \WC_Name_Your_Price_Helpers::get_minimum_price( $product_id );
$max_price = \WC_Name_Your_Price_Helpers::get_maximum_price( $product_id );
$price = ! empty( $max_price ) ? min( $price, $max_price ) : $price;
$price = ! empty( $min_price ) ? max( $price, $min_price ) : $price;

$cart_item_data['nyp'] = (float) \WC_Name_Your_Price_Helpers::standardize_number( $price );
$price = filter_input( INPUT_GET, 'price', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
if ( \Newspack_Blocks::can_use_name_your_price() ? \WC_Name_Your_Price_Helpers::is_nyp( $product_id ) : false ) {
if ( empty( $price ) ) {
$price = \WC_Name_Your_Price_Helpers::get_suggested_price( $product_id );
}
$min_price = \WC_Name_Your_Price_Helpers::get_minimum_price( $product_id );
$max_price = \WC_Name_Your_Price_Helpers::get_maximum_price( $product_id );
$price = ! empty( $max_price ) ? min( $price, $max_price ) : $price;
$price = ! empty( $min_price ) ? max( $price, $min_price ) : $price;

$cart_item_data['nyp'] = (float) \WC_Name_Your_Price_Helpers::standardize_number( $price );
}

/**
Expand Down
50 changes: 50 additions & 0 deletions includes/class-newspack-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ function( $tax ) {
return apply_filters( 'newspack_blocks_home_page_block_custom_taxonomies', $custom_taxonomies );
}

/**
* Check if the Name Your Price extension is available.
*
* @return bool True if available, false if not.
*/
public static function can_use_name_your_price() {
return class_exists( 'WC_Name_Your_Price_Helpers' );
}

/**
* Enqueue block scripts and styles for editor.
*/
Expand Down Expand Up @@ -257,6 +266,8 @@ public static function enqueue_block_editor_assets() {
'has_recaptcha' => class_exists( 'Newspack\Recaptcha' ) && \Newspack\Recaptcha::can_use_captcha(),
'recaptcha_url' => admin_url( 'admin.php?page=newspack-connections-wizard' ),
'custom_taxonomies' => self::get_custom_taxonomies(),
'can_use_name_your_price' => self::can_use_name_your_price(),
'tier_amounts_template' => self::get_formatted_amount(),
];

if ( class_exists( 'WP_REST_Newspack_Author_List_Controller' ) ) {
Expand Down Expand Up @@ -1528,5 +1539,44 @@ public static function get_sanitized_image_attributes() {
],
];
}

/**
* Get a formatted HTML string containing amount and frequency of a donation.
*
* @param float $amount Amount.
* @param string $frequency Frequency.
* @param bool $hide_once_label Whether to hide the "once" label.
*
* @return string
*/
public static function get_formatted_amount( $amount = 0, $frequency = 'day', $hide_once_label = false ) {
if ( ! function_exists( 'wcs_price_string' ) ) {
return \wc_price( $amount );
}
$price_args = [
'recurring_amount' => $amount,
'subscription_period' => 'once' === $frequency ? 'day' : $frequency,
];
$wc_formatted_amount = \wcs_price_string( $price_args );

// A '0' value means we want a placeholder string to replace in the editor.
if ( 0 === $amount ) {
preg_match( '/<\/span>(.*)<\/bdi>/', $wc_formatted_amount, $matches );
if ( ! empty( $matches[1] ) ) {
$wc_formatted_amount = str_replace( $matches[1], 'AMOUNT_PLACEHOLDER', $wc_formatted_amount );
}
}

// A 'day' frequency means we want a placeholder string to replace in the editor.
if ( 'day' === $frequency ) {
$wc_formatted_amount = preg_replace( '/ \/ ?.*/', 'FREQUENCY_PLACEHOLDER', $wc_formatted_amount );
} elseif ( 'once' === $frequency ) {
$once_label = $hide_once_label ? '' : __( ' once', 'newspack-blocks' );
$wc_formatted_amount = preg_replace( '/ \/ ?.*/', $once_label, $wc_formatted_amount );
}
$wc_formatted_amount = str_replace( ' / ', __( ' per ', 'newspack-blocks' ), $wc_formatted_amount );

return '<span class="wpbnbd__tiers__amount__value">' . $wc_formatted_amount . '</span>';
}
}
Newspack_Blocks::init();
6 changes: 5 additions & 1 deletion src/blocks/checkout-button/edit.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* eslint-disable @wordpress/no-unsafe-wp-apis */
/* globals newspack_blocks_data */

/**
* External dependencies
*/
Expand Down Expand Up @@ -47,7 +49,9 @@ function getVariationName( variation ) {

function getNYP( product ) {
return {
isNYP: product?.meta_data?.some( meta => meta.key === '_nyp' && meta.value === 'yes' ),
isNYP:
newspack_blocks_data?.can_use_name_your_price &&
product?.meta_data?.some( meta => meta.key === '_nyp' && meta.value === 'yes' ),
suggestedPrice: product?.meta_data?.find( meta => meta.key === '_suggested_price' )?.value,
minPrice: product?.meta_data?.find( meta => meta.key === '_min_price' )?.value,
maxPrice: product?.meta_data?.find( meta => meta.key === '_maximum_price' )?.value,
Expand Down
78 changes: 53 additions & 25 deletions src/blocks/donate/edit/FrequencyBasedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { RichText } from '@wordpress/block-editor';
* Internal dependencies
*/
import { AmountValueInput } from './components';
import { getColorForContrast } from '../utils';
import { getColorForContrast, getFrequencyLabel } from '../utils';
import { FREQUENCIES } from '../consts';
import type { ComponentProps, DonationFrequencySlug } from '../types';

Expand Down Expand Up @@ -55,7 +55,7 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
}, [ attributes.defaultFrequency ] );

const [ selectedFrequency, setSelectedFrequency ] = useState( attributes.defaultFrequency );

const canUseNameYourPrice = window.newspack_blocks_data?.can_use_name_your_price;
const renderFrequencySelect = ( frequencySlug: DonationFrequencySlug ) => (
<>
<input
Expand Down Expand Up @@ -96,31 +96,59 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
<div className="wp-block-newspack-blocks-donate__options">
<div className="wp-block-newspack-blocks-donate__frequencies frequencies">
<div className="tab-container">{ availableFrequencies.map( renderTab ) }</div>
{ availableFrequencies.map( frequencySlug => (
<div
className="wp-block-newspack-blocks-donate__frequency frequency"
key={ frequencySlug }
>
{ renderFrequencySelect( frequencySlug ) }
<div className="input-container">
<label
className="donate-label"
htmlFor={ 'newspack-' + frequencySlug + '-' + uid + '-untiered-input' }
>
{ __( 'Donation amount', 'newspack-blocks' ) }
</label>
<div className="wp-block-newspack-blocks-donate__money-input money-input">
<span className="currency">{ settings.currencySymbol }</span>
<AmountValueInput
{ ...props }
frequencySlug={ frequencySlug }
tierIndex={ 3 }
id={ `newspack-${ frequencySlug }-${ uid }-untiered-input` }
/>
{ availableFrequencies.map( frequencySlug => {
const untieredAmount = amounts[ frequencySlug ][ 3 ];
return (
<div
className="wp-block-newspack-blocks-donate__frequency frequency"
key={ frequencySlug }
>
{ renderFrequencySelect( frequencySlug ) }
<div className="input-container">
{ canUseNameYourPrice ? (
<>
<label
className="donate-label"
htmlFor={ 'newspack-' + frequencySlug + '-' + uid + '-untiered-input' }
>
{ __( 'Donation amount', 'newspack-blocks' ) }
</label>
<div className="wp-block-newspack-blocks-donate__money-input money-input">
<span className="currency">{ settings.currencySymbol }</span>
<AmountValueInput
{ ...props }
frequencySlug={ frequencySlug }
tierIndex={ 3 }
id={ `newspack-${ frequencySlug }-${ uid }-untiered-input` }
/>
</div>
</>
) : (
<>
<input
type="radio"
value={ untieredAmount }
className={ 'frequency-input' }
id={ `newspack-${ frequencySlug }-${ uid }-untiered-input` }
name={ `donation_value_${ frequencySlug }` }
defaultChecked={ true }
/>
<label
className="tier-select-label tier-label"
htmlFor={ `newspack-${ frequencySlug }-${ uid }-untiered-input` }
>
<div
dangerouslySetInnerHTML={ {
__html: getFrequencyLabel( untieredAmount, frequencySlug ),
} }
/>
</label>
</>
) }
</div>
</div>
</div>
) ) }
);
} ) }
</div>
</div>
);
Expand Down
33 changes: 7 additions & 26 deletions src/blocks/donate/edit/TierBasedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,10 @@ import classNames from 'classnames';
/**
* Internal dependencies
*/
import type {
ComponentProps,
DonationFrequencySlug,
DonateBlockAttributes,
TierBasedOptionValue,
} from '../types';
import { getColorForContrast } from '../utils';
import type { ComponentProps, DonateBlockAttributes, TierBasedOptionValue } from '../types';
import { getColorForContrast, getFrequencyLabel } from '../utils';
import { FREQUENCIES, DISABLED_IN_TIERS_BASED_LAYOUT_TIER_INDEX } from '../consts';

const getFrequencyLabel = ( frequencySlug: DonationFrequencySlug ) => {
switch ( frequencySlug ) {
case 'once':
return __( 'once', 'newspack-blocks' );
case 'month':
return __( 'per month', 'newspack-blocks' );
case 'year':
return __( 'per year', 'newspack-blocks' );
}
};

const TierBasedLayout = ( props: ComponentProps ) => {
const { amounts, availableFrequencies, attributes } = props;
const [ currentFrequency, setCurrencyFrequency ] = useState( availableFrequencies[ 0 ] );
Expand Down Expand Up @@ -108,14 +92,11 @@ const TierBasedLayout = ( props: ComponentProps ) => {
</h3>
</div>
<div className="wpbnbd__tiers__amount">
<h3 className="wpbnbd__tiers__amount__number">
{ props.settings.currencySymbol }
<span>{ amount }</span>
</h3>
<span className="wpbnbd__tiers__amount__frequency">
{ ' ' }
{ getFrequencyLabel( currentFrequency ) }
</span>
<div
dangerouslySetInnerHTML={ {
__html: getFrequencyLabel( amount, currentFrequency ),
} }
/>
</div>
<div
className="submit-button"
Expand Down
Loading