| @@ -12,8 +12,30 @@ | ||
| 12 | 12 | * |
| 13 | 13 | * @package TierPricingTable\Managers |
| 14 | 14 | */ |
| 15 | 15 | class FormatPriceManager { |
| 16 | + /** | |
| 17 | + * Cache key for a formatted price. | |
| 18 | + * | |
| 19 | + * The formatted output depends on the display type and formatting flags, and several callers (for example, SEO | |
| 20 | + * integrations building schema or title variables) request a plain, prefix-less version early in the request. | |
| 21 | + * Keying by these arguments keeps each variant cached separately instead of letting the first caller win. | |
| 22 | + * | |
| 23 | + * @param string $displayType | |
| 24 | + * @param array $args | |
| 25 | + * | |
| 26 | + * @return string | |
| 27 | + */ | |
| 28 | + protected static function getPriceCacheKey( string $displayType, array $args ) : string { | |
| 29 | + return 'price_html_' . md5( wp_json_encode( array( | |
| 30 | + $displayType, | |
| 31 | + (bool) $args['html'], | |
| 32 | + (bool) $args['for_display'], | |
| 33 | + (bool) $args['with_suffix'], | |
| 34 | + (bool) $args['with_lowest_prefix'] | |
| 35 | + ) ) ); | |
| 36 | + } | |
| 37 | + | |
| 16 | 38 | public static function getFormattedPrice( WC_Product $product, array $args = array() ) : ?string { |
| 17 | 39 | $args = wp_parse_args( $args, array( |
| 18 | 40 | 'html' => true, |
| 19 | 41 | 'display_type' => null, |
| @@ -22,20 +44,25 @@ | ||
| 22 | 44 | 'with_suffix' => true, |
| 23 | 45 | 'with_lowest_prefix' => true, |
| 24 | 46 | 'with_default_price' => true, |
| 25 | 47 | ) ); |
| 26 | - $priceHTML = 'default'; | |
| 27 | - if ( 'default' === $priceHTML ) { | |
| 28 | - if ( $args['with_default_price'] ) { | |
| 29 | - $priceHTML = ( $args['html'] ? $product->get_price_html() : $product->get_price() ); | |
| 30 | - } else { | |
| 31 | - return null; | |
| 48 | + $GLOBALS['TPT_DISABLE_CATALOG_PRICE_FORMAT'] = true; | |
| 49 | + try { | |
| 50 | + $priceHTML = 'default'; | |
| 51 | + if ( 'default' === $priceHTML ) { | |
| 52 | + if ( $args['with_default_price'] ) { | |
| 53 | + $priceHTML = ( $args['html'] ? $product->get_price_html() : $product->get_price() ); | |
| 54 | + } else { | |
| 55 | + return null; | |
| 56 | + } | |
| 32 | 57 | } |
| 58 | + if ( isset( $args['html'] ) && !$args['html'] ) { | |
| 59 | + $priceHTML = strip_tags( $priceHTML ); | |
| 60 | + } | |
| 61 | + return $priceHTML; | |
| 62 | + } finally { | |
| 63 | + unset($GLOBALS['TPT_DISABLE_CATALOG_PRICE_FORMAT']); | |
| 33 | 64 | } |
| 34 | - if ( isset( $args['html'] ) && !$args['html'] ) { | |
| 35 | - $priceHTML = strip_tags( $priceHTML ); | |
| 36 | - } | |
| 37 | - return $priceHTML; | |
| 38 | 65 | } |
| 39 | 66 | |
| 40 | 67 | public static function getLowestPrice( WC_Product $product, $args = array() ) : ?string { |
| 41 | 68 | $args = wp_parse_args( $args, array( |
| @@ -57,13 +84,8 @@ | ||
| 57 | 84 | 'price' => $lowest, |
| 58 | 85 | ) ) : $lowest ); |
| 59 | 86 | return ( $args['html'] ? $product->get_price_html() : $lowestPrice ); |
| 60 | 87 | } |
| 61 | - if ( $args['for_display'] ) { | |
| 62 | - $lowestPrice = wc_get_price_to_display( $product, array( | |
| 63 | - 'price' => $lowestPrice, | |
| 64 | - ) ); | |
| 65 | - } | |
| 66 | 88 | if ( $args['html'] ) { |
| 67 | 89 | $lowestPrice = wc_price( $lowestPrice ); |
| 68 | 90 | } |
| 69 | 91 | if ( $args['with_suffix'] ) { |
| @@ -132,8 +154,38 @@ | ||
| 132 | 154 | } |
| 133 | 155 | return $range; |
| 134 | 156 | } |
| 135 | 157 | |
| 158 | + public static function getCustomPrice( WC_Product $product, array $args = array() ) : ?string { | |
| 159 | + $template = ServiceContainer::getInstance()->getSettings()->get( 'tiered_price_at_catalog_custom_template', __( 'From {tp_lowest_price} instead of {tp_original_price}', 'tier-pricing-table' ) ); | |
| 160 | + if ( empty( $template ) ) { | |
| 161 | + return null; | |
| 162 | + } | |
| 163 | + $lowestPrice = self::getLowestPrice( $product, array( | |
| 164 | + 'html' => $args['html'], | |
| 165 | + 'for_display' => $args['for_display'], | |
| 166 | + 'with_suffix' => $args['with_suffix'], | |
| 167 | + 'with_lowest_prefix' => false, | |
| 168 | + 'with_default_price' => false, | |
| 169 | + ) ); | |
| 170 | + if ( is_null( $lowestPrice ) ) { | |
| 171 | + return null; | |
| 172 | + } | |
| 173 | + $priceRange = self::getPriceRange( $product, array( | |
| 174 | + 'for_display' => $args['for_display'], | |
| 175 | + 'with_suffix' => $args['with_suffix'], | |
| 176 | + 'with_default_price' => false, | |
| 177 | + 'html' => $args['html'], | |
| 178 | + ) ); | |
| 179 | + $originalPrice = ( $args['html'] ? $product->get_price_html() : (( $args['for_display'] ? wc_get_price_to_display( $product ) : $product->get_price() )) ); | |
| 180 | + $replacements = array( | |
| 181 | + '{tp_lowest_price}' => $lowestPrice, | |
| 182 | + '{tp_prices_range}' => ( $priceRange ? $priceRange : $lowestPrice ), | |
| 183 | + '{tp_original_price}' => $originalPrice, | |
| 184 | + ); | |
| 185 | + return str_replace( array_keys( $replacements ), array_values( $replacements ), $template ); | |
| 186 | + } | |
| 187 | + | |
| 136 | 188 | public static function getLowestPrefix() : string { |
| 137 | 189 | $settings = ServiceContainer::getInstance()->getSettings(); |
| 138 | 190 | return (string) $settings->get( 'lowest_prefix', __( 'From', 'tier-pricing-table' ) ); |
| 139 | 191 | } |
| @@ -139,8 +191,12 @@ | ||
| 139 | 191 | } |
| 140 | 192 | |
| 141 | 193 | public static function getDisplayType() : string { |
| 142 | 194 | $settings = ServiceContainer::getInstance()->getSettings(); |
| 143 | - return ( $settings->get( 'tiered_price_at_catalog_type', 'range' ) === 'range' ? 'range' : 'lowest' ); | |
| 195 | + $type = $settings->get( 'tiered_price_at_catalog_type', 'range' ); | |
| 196 | + if ( 'custom' === $type ) { | |
| 197 | + return 'custom'; | |
| 198 | + } | |
| 199 | + return ( $type === 'range' ? 'range' : 'lowest' ); | |
| 144 | 200 | } |
| 145 | 201 | |
| 146 | 202 | } |