File "FreeShippingNoticeGenerator.php"
Full Path: /home/jlklyejr/public_html/wp-content/test/wp-content/plugins/flexible-shipping/src/WPDesk/FS/TableRate/FreeShipping/FreeShippingNoticeGenerator.php
File size: 9.66 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Free Shipping Notice Generator.
*
* @package WPDesk\FS\TableRate\FreeShipping
*/
namespace WPDesk\FS\TableRate\FreeShipping;
use FSVendor\WPDesk\PluginBuilder\Plugin\Hookable;
use WC_Cart;
use WC_Session;
use WC_Shipping_Rate;
use WPDesk\FS\TableRate\ShippingMethodSingle;
use WPDesk_Flexible_Shipping;
/**
* Can generate free shipping notice and save it on session.
*/
class FreeShippingNoticeGenerator implements Hookable {
const SETTING_METHOD_FREE_SHIPPING = 'method_free_shipping';
const META_DATA_FS_METHOD = '_fs_method';
const PRIORITY = 10;
/**
* @var WC_Cart|null
*/
protected $cart;
/**
* @var WC_Session|null
*/
private $session;
/**
* @var string
*/
private $session_variable_name;
/**
* FreeShippingNotice constructor.
*
* @param WC_Cart|null $cart .
* @param WC_Session|null $session .
* @param string $session_variable_name .
*/
public function __construct( $cart, $session, string $session_variable_name ) {
$this->cart = $cart;
$this->session = $session;
$this->session_variable_name = $session_variable_name;
}
/**
* Hooks.
*/
public function hooks() {
add_filter( 'woocommerce_package_rates', [ $this, 'add_free_shipping_notice_if_should' ], self::PRIORITY );
add_action( 'woocommerce_after_calculate_totals', [ $this, 'clear_notices_if_cart_not_needs_shipping' ], self::PRIORITY );
}
/**
* @param WC_Cart $cart
*
* @return void
*/
public function clear_notices_if_cart_not_needs_shipping( $cart ) {
if ( ! $cart->needs_shipping() ) {
$this->get_session()->set( $this->session_variable_name, null );
}
}
/**
* Triggered by filter. Must return $package_rates.
*
* @param array $package_rates .
* @param array $package .
*
* @return array
*/
public function add_free_shipping_notice_if_should( $package_rates ) {
$this->cart = WC()->cart;
if ( $this->cart->needs_shipping() && $this->has_shipping_rate_with_free_shipping( $package_rates ) && ! $this->has_free_shipping_rate( $package_rates ) && $this->get_shipping_packages_count() === 1 ) {
$this->add_free_shipping_amount_to_session( $package_rates );
} else {
$this->get_session()->set( $this->session_variable_name, null );
}
return $package_rates;
}
protected function get_session() {
return WC()->session;
}
/**
* @return int
*/
private function get_shipping_packages_count() {
return count( $this->cart->get_shipping_packages() );
}
/**
* Add free shipping notice.
*
* @param array $package_rates .
*/
private function add_free_shipping_amount_to_session( $package_rates ) {
$shipping_method_with_lowest_free_shipping_limit = $this->get_shipping_method_with_lowest_free_shipping_limit( $package_rates );
$lowest_free_shipping_limit = floatval( $shipping_method_with_lowest_free_shipping_limit[ self::SETTING_METHOD_FREE_SHIPPING ] );
$lowest_free_shipping_limit = round(
(float) apply_filters( 'flexible_shipping_value_in_currency', $lowest_free_shipping_limit, $lowest_free_shipping_limit ),
wc_get_rounding_precision()
);
$amount = $lowest_free_shipping_limit - $this->get_cart_value();
$free_shipping_notice_text = $shipping_method_with_lowest_free_shipping_limit[ NoticeTextSettings::FIELD_NAME ] ?? '';
$meta_data = apply_filters( 'flexible-shipping/free-shipping/metadata', [ 'method_settings' => $shipping_method_with_lowest_free_shipping_limit ], $shipping_method_with_lowest_free_shipping_limit );
$free_shipping_notice_data = $this->prepare_free_shipping_notice_data(
( $shipping_method_with_lowest_free_shipping_limit[ ProgressBarSettings::FIELD_NAME ] ?? 'no' ) === 'yes',
round( $this->get_cart_value() / $lowest_free_shipping_limit * 100 ),
$lowest_free_shipping_limit,
$amount,
$free_shipping_notice_text,
$this->get_notice_text_button_url(),
$this->get_notice_text_button_label(),
$meta_data
);
$this->get_session()->set( $this->session_variable_name, $free_shipping_notice_data->jsonSerialize() );
}
/**
* @param bool $show_progress_bar
* @param float $percentage
* @param float $lowest_free_shipping_limit
* @param float $amount
* @param string $free_shipping_notice_text
* @param string $button_url
* @param string $button_label
* @param array $meta_data
*
* @return FreeShippingNoticeData
*/
protected function prepare_free_shipping_notice_data(
bool $show_progress_bar,
float $percentage,
float $lowest_free_shipping_limit,
float $amount,
string $free_shipping_notice_text,
string $button_url,
string $button_label,
array $meta_data
): FreeShippingNoticeData {
return new FreeShippingNoticeData(
$show_progress_bar,
$percentage,
$lowest_free_shipping_limit,
wc_price( $lowest_free_shipping_limit ),
wc_price( 0 ),
$amount,
$this->get_notice_text_message( wc_price( $amount ), $free_shipping_notice_text ),
$button_url,
$button_label,
$meta_data
);
}
/**
* @return string
*/
protected function get_notice_text_message( string $amount, string $message ): string {
// Translators: amount with currency or number of items.
$message = sprintf(
empty( $message ) ? __( 'You only need %1$s more to get free shipping!', 'flexible-shipping' ) : wpdesk__( $message, 'flexible-shipping' ),
$amount
);
$text_message = apply_filters( 'flexible_shipping_free_shipping_notice_text_message', $message, $amount );
return is_string( $text_message ) ? $text_message : '';
}
/**
* @return string
*/
private function get_notice_text_button_url(): string {
return apply_filters( 'woocommerce_return_to_shop_redirect', wc_get_page_permalink( 'shop' ) );
}
/**
* @return string
*/
private function get_notice_text_button_label(): string {
return apply_filters( 'flexible_shipping_free_shipping_notice_text_button_label', __( 'Continue shopping', 'flexible-shipping' ) );
}
/**
* Has package free shipping rate?
*
* @param array $package_rates .
*
* @return bool
*/
private function has_free_shipping_rate( $package_rates ): bool {
/** @var WC_Shipping_Rate $package_rate */
foreach ( $package_rates as $package_rate ) {
if ( floatval( $package_rate->get_cost() ) === 0.0 && ! $this->is_excluded_shipping_method( $package_rate->get_method_id() ) ) {
return true;
}
}
return false;
}
/**
* Is shipping method excluded from free shipping?
*
* @param string $method_id .
*
* @return bool
*/
private function is_excluded_shipping_method( $method_id ): bool {
/**
* Exclude methods from free shipping.
*
* @param array $excluded_methods
*
* @return array
*/
$excluded_methods = apply_filters( 'flexible_shipping_free_shipping_notice_excluded_methods', [ 'local_pickup' ] );
$excluded_methods = is_array( $excluded_methods ) ? $excluded_methods : [];
return in_array( $method_id, $excluded_methods, true );
}
/**
* Has package rate with free shipping?
*
* @param array $package_rates .
*
* @return bool
*/
private function has_shipping_rate_with_free_shipping( $package_rates ) {
/** @var WC_Shipping_Rate $package_rate */
foreach ( $package_rates as $package_rate ) {
if ( $this->is_package_rate_from_flexible_shipping( $package_rate ) ) {
$meta_data = $package_rate->get_meta_data();
if ( isset( $meta_data[ self::META_DATA_FS_METHOD ] ) ) {
if ( $this->has_shipping_method_free_shipping_notice_enabled( $meta_data[ self::META_DATA_FS_METHOD ] ) ) {
return true;
}
}
}
}
return false;
}
/**
* @param array $fs_method .
*
* @return bool
*/
protected function has_shipping_method_free_shipping_notice_enabled( array $fs_method ): bool {
return ! empty( $fs_method[ self::SETTING_METHOD_FREE_SHIPPING ] )
&& isset( $fs_method[ WPDesk_Flexible_Shipping::SETTING_METHOD_FREE_SHIPPING_NOTICE ] )
&& 'yes' === $fs_method[ WPDesk_Flexible_Shipping::SETTING_METHOD_FREE_SHIPPING_NOTICE ]
&& apply_filters( 'flexible-shipping/shipping-method/free-shipping-notice-allowed', true, $fs_method );
}
/**
* Returns current cart value.
*
* @return float
*/
protected function get_cart_value(): float {
return $this->cart->display_prices_including_tax() ? $this->cart->get_cart_contents_total() + $this->cart->get_cart_contents_tax() : $this->cart->get_cart_contents_total();
}
/**
* @param $package_rates
*
* @return array
*/
protected function get_shipping_method_with_lowest_free_shipping_limit( $package_rates ): array {
$lowest_free_shipping_limit = null;
$shipping_method = [];
/** @var WC_Shipping_Rate $package_rate */
foreach ( $package_rates as $package_rate ) {
if ( $this->is_package_rate_from_flexible_shipping( $package_rate ) ) {
$meta_data = $package_rate->get_meta_data();
$fs_method = $meta_data[ self::META_DATA_FS_METHOD ] ?? [];
if ( $this->has_shipping_method_free_shipping_notice_enabled( $fs_method ) ) {
$method_free_shipping_limit = round( floatval( $fs_method[ self::SETTING_METHOD_FREE_SHIPPING ] ), wc_get_rounding_precision() );
if ( $lowest_free_shipping_limit === null || $method_free_shipping_limit < $lowest_free_shipping_limit ) {
$lowest_free_shipping_limit = $method_free_shipping_limit;
$shipping_method = $fs_method;
}
}
}
}
return $shipping_method;
}
/**
* @param WC_Shipping_Rate $package_rate .
*
* @return bool
*/
protected function is_package_rate_from_flexible_shipping( WC_Shipping_Rate $package_rate ): bool {
$shipping_methods = [ WPDesk_Flexible_Shipping::METHOD_ID, ShippingMethodSingle::SHIPPING_METHOD_ID ];
return in_array( $package_rate->get_method_id(), $shipping_methods, true );
}
}