File "class-drawer-ajax.php"
Full Path: /home/romayxjt/public_html/wp-content/plugins/orderable/inc/modules/drawer/class-drawer-ajax.php
File size: 7.93 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Module: Drawer Ajax.
*
* @package Orderable/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* Drawer module class.
*/
class Orderable_Drawer_Ajax {
/**
* Init.
*/
public static function run() {
Orderable_Ajax::add_ajax_methods(
array(
'cart_quantity' => true,
'update_cart_item_options' => true,
),
__CLASS__
);
}
/**
* Modify cart item qty.
*/
public static function cart_quantity() {
$product_id = empty( $_POST['product_id'] ) ? '' : sanitize_text_field( wp_unslash( $_POST['product_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
$cart_item_key = empty( $_POST['cart_item_key'] ) ? '' : sanitize_text_field( wp_unslash( $_POST['cart_item_key'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
$quantity = filter_input( INPUT_POST, 'quantity', FILTER_SANITIZE_NUMBER_INT );
if ( empty( $product_id ) || empty( $cart_item_key ) || ! is_numeric( $quantity ) ) {
wp_send_json_error();
}
$_product = wc_get_product( $product_id );
if ( empty( $_product ) ) {
wp_send_json_error();
}
$passed_validation = true;
$cart_updated = false;
$current_session_order_id = isset( WC()->session->order_awaiting_payment ) ? absint( WC()->session->order_awaiting_payment ) : 0;
$product_qty_in_cart = WC()->cart->get_cart_item_quantities();
// is_sold_individually.
if ( $_product->is_sold_individually() && $quantity > 1 ) {
/* Translators: %s Product title. */
wc_add_notice( sprintf( __( 'You can only have 1 %s in your cart.', 'orderable' ), $_product->get_name() ), 'error' );
$passed_validation = false;
}
// We only need to check products managing stock, with a limited stock qty.
if ( $_product->managing_stock() || $_product->backorders_allowed() ) {
// Check stock based on all items in the cart and consider any held stock within pending orders.
$held_stock = wc_get_held_stock_quantity( $_product, $current_session_order_id );
if ( $_product->get_stock_quantity() < ( $held_stock + $quantity ) ) {
/* translators: 1: product name 2: quantity in stock */
wc_add_notice( sprintf( __( 'Sorry, we do not have enough "%1$s" in stock to fulfill your order (%2$s available). We apologize for any inconvenience caused.', 'woocommerce' ), $_product->get_name(), wc_format_stock_quantity_for_display( $_product->get_stock_quantity() - $held_stock, $_product ) ), 'error' );
$passed_validation = false;
}
}
if ( $passed_validation ) {
WC()->cart->set_quantity( $cart_item_key, intval( $quantity ), false );
$cart_updated = true;
}
if ( $cart_updated ) {
WC()->cart->calculate_totals();
}
WC_AJAX::get_refreshed_fragments();
}
/**
* Update cart item attributes and addons.
*/
public static function update_cart_item_options() {
if ( empty( $_POST['cart_item_key'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
wp_send_json_error( null, 400 );
}
$cart_item_key = sanitize_text_field( wp_unslash( $_POST['cart_item_key'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
$product_id = absint( filter_input( INPUT_POST, 'product_id', FILTER_SANITIZE_NUMBER_INT ) );
$attributes = self::get_attributes();
$variation_id = empty( $attributes ) ? 0 : absint( filter_input( INPUT_POST, 'variation_id', FILTER_SANITIZE_NUMBER_INT ) );
$orderable_fields = self::get_orderable_fields();
if (
empty( $cart_item_key ) ||
( empty( $attributes ) && empty( $orderable_fields ) )
) {
wp_send_json_error( null, 400 );
}
$cart_item = WC()->cart->get_cart_item( $cart_item_key );
if ( empty( $cart_item ) ) {
wp_send_json_error();
}
$product_data = empty( $variation_id ) ? wc_get_product( $cart_item['product_id'] ) : wc_get_product( $variation_id );
if ( ! $product_data ) {
wp_send_json_error();
}
// If the same data is sent (i.e. there is nothing to udpate), return early.
if (
WC()->cart->generate_cart_id(
$product_id,
$variation_id,
empty( $attributes ) ? array( false ) : $attributes,
empty( $orderable_fields ) ? array() : array( 'orderable_fields' => $orderable_fields )
)
===
$cart_item_key
) {
wp_send_json_success();
}
self::update_cart_item_attributes( $cart_item, $variation_id, $attributes, $orderable_fields );
WC()->cart->calculate_totals();
WC_AJAX::get_refreshed_fragments();
}
/**
* Get attributes values to update.
*
* @return array.
*/
protected static function get_attributes() {
if ( empty( $_POST['attributes'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
return array();
}
$attributes = array_filter(
// phpcs:ignore WordPress.Security.NonceVerification.Missing
(array) json_decode( sanitize_text_field( wp_unslash( $_POST['attributes'] ) ) ),
function( $attribute_value, $attribute_name ) {
return ! empty( $attribute_value ) && false !== strpos( $attribute_name, 'attribute_' );
},
ARRAY_FILTER_USE_BOTH
);
return $attributes;
}
/**
* Get Orderable Product Addons fields.
*
* @return array
*/
protected static function get_orderable_fields() {
if (
! class_exists( 'Orderable_Addons_Pro_Field_Groups' ) ||
! class_exists( 'Orderable_Addons_Pro_Fees' )
) {
return array();
}
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$orderable_fields = empty( $_POST['orderable_fields'] ) ? array() : map_deep( wp_unslash( $_POST['orderable_fields'] ), 'sanitize_text_field' );
if ( empty( $orderable_fields ) || ! is_array( $orderable_fields ) ) {
return array();
}
$orderable_item_data = array();
foreach ( $orderable_fields as $group_id => $fields ) {
foreach ( $fields as $field_id => $field ) {
$field_setting = Orderable_Addons_Pro_Field_Groups::get_field_data( $field_id, $group_id );
$fees = Orderable_Addons_Pro_Fees::calculate_fees( $field, $field_id, $group_id );
$orderable_item_data[ $field_id ] = array(
'id' => $field_id,
'value' => $field,
'label' => $field_setting['title'],
'group_id' => $group_id,
'fees' => $fees,
);
}
}
return $orderable_item_data;
}
/**
* Update cart item attributes.
*
* @param array $original_cart_item The cart item to be updated.
* @param int $variation_id The new variation ID.
* @param array $attributes The new attributes.
* @return void
*/
protected static function update_cart_item_attributes( $original_cart_item, $variation_id, $attributes, $cart_item_data ) {
if ( empty( $cart_item_data ) && ! empty( $original_cart_item['orderable_fields'] ) ) {
$cart_item_data = $original_cart_item['orderable_fields'];
}
if ( ! empty( $cart_item_data ) ) {
$cart_item_data = array( 'orderable_fields' => $cart_item_data );
}
/**
* WooCommerce stores empty attributes ('variation' on the cart item)
* as `array( false )`.
*/
if ( empty( $attributes ) ) {
$attributes = array( false );
}
/**
* We update the cart item by adding the updated item to the cart.
* This allows 3rd plugins/themes to integrate with the default
* WooCommerce hooks.
*/
$updated_cart_item_key = WC()->cart->add_to_cart( $original_cart_item['product_id'], $original_cart_item['quantity'], $variation_id, $attributes, $cart_item_data );
$cart_content = WC()->cart->get_cart();
/**
* We remove the updated item from the cart to re-insert
* at the same position of the original item.
*/
unset( $cart_content[ $updated_cart_item_key ] );
$cart_content_updated = array();
foreach ( $cart_content as $key => $item ) {
// We re-insert the updated item at the same position of the original item.
if ( $key === $original_cart_item['key'] ) {
$updated_cart_item = WC()->cart->get_cart_item( $updated_cart_item_key );
$cart_content_updated[ $updated_cart_item['key'] ] = $updated_cart_item;
} else {
$cart_content_updated[ $key ] = $item;
}
}
WC()->cart->set_cart_contents( $cart_content_updated );
}
}