File: /var/www/html/ielts-store/wp-content/plugins/automatewoo/includes/Preview_Data.php
<?php
// phpcs:ignoreFile
namespace AutomateWoo;
use AutomateWoo\Actions\PreviewableInterface;
use AutomateWoo\Actions\TestableInterface;
use AutomateWoo\Exceptions\InvalidPreviewData;
use AutomateWoo\Workflows\Factory;
use WC_Order;
/**
* @class Preview_Data
* @since 2.4.6
*/
class Preview_Data {
/**
* The current preview workflow.
*
* @since 4.6.0
*
* @var Workflow
*/
private static $preview_workflow;
/**
* @param array $required_items list of specific data items to get for preview
*
* @return array
* @throws InvalidPreviewData When there's an error getting the preview data.
*/
static function get_preview_data_layer( $required_items = [] ) {
$data_layer = [];
if ( in_array( 'user', $required_items ) ) {
$data_layer['user'] = wp_get_current_user();
}
if ( in_array( 'customer', $required_items ) ) {
$data_layer['customer'] = Customer_Factory::get_by_user_id( get_current_user_id() );
}
/**
* Order and order item
*/
if ( in_array( 'order', $required_items ) || in_array( 'order_item', $required_items ) ) {
$order = self::get_preview_order();
$order_items = $order->get_items();
if ( empty( $order_items ) ) {
throw InvalidPreviewData::data_item_needed( 'order_item' );
}
$data_layer['order'] = $order;
$data_layer['order_item'] = current( $order_items );
}
/**
* Product
*/
if ( in_array( 'product', $required_items ) ) {
$product_ids = self::get_preview_product_ids();
$data_layer['product'] = wc_get_product( $product_ids[0] );
}
/**
* Category
*/
if ( in_array( 'category', $required_items ) ) {
$categories = get_terms(
[
'taxonomy' => 'product_cat',
'order' => 'count',
'number' => 1
]
);
if ( empty( $categories ) ) {
throw InvalidPreviewData::data_item_needed( 'category' );
}
$data_layer['category'] = current( $categories );
}
/**
* Cart
*/
if ( in_array( 'cart', $required_items ) ) {
$cart = new Cart();
$cart->set_id( 1 );
$cart->set_total( 100 );
$cart->set_user_id( get_current_user_id() );
$cart->set_token();
$cart->set_date_last_modified( new DateTime() );
$items = [];
foreach ( self::get_preview_product_ids() as $product_id ) {
$product = wc_get_product( $product_id );
// Reject products that can't be purchased
if ( ! $product->is_purchasable() ) {
continue;
}
$variation_id = 0;
$variation = [];
if ( $product->is_type('variable') ) {
/** @var \WC_Product_Variable $product */
$variations = $product->get_available_variations();
if ( $variations ) {
$variation_id = $variations[0]['variation_id'];
$variation = $variations[0]['attributes'];
}
}
$items[ uniqid() ] = [
'product_id' => $product_id,
'variation_id' => $variation_id,
'variation' => $variation,
'quantity' => 1,
'line_subtotal' => (float) $product->get_price(),
'line_subtotal_tax' => (float) wc_get_price_including_tax( $product ) - (float) $product->get_price(),
];
}
$cart->set_items( $items );
$cart->set_coupons([
'10off' => [
'discount_incl_tax' => '10',
'discount_excl_tax' => '9',
'discount_tax' => '1'
]
]);
$data_layer['cart'] = $cart;
}
/**
* Wishlist
*/
if ( in_array( 'wishlist', $required_items ) ) {
$wishlist = new Wishlist();
$wishlist->items = self::get_preview_product_ids();
$data_layer['wishlist'] = $wishlist;
}
/**
* Guest
*/
if ( in_array( 'guest', $required_items ) ) {
$guest = new Guest();
$guest->set_email( 'guest@example.com' );
$data_layer['guest'] = $guest;
}
/**
* Subscription
*/
if ( Integrations::is_subscriptions_active() && in_array( 'subscription', $required_items ) ) {
$subscriptions = wcs_get_subscriptions(
[
'subscriptions_per_page' => 1
]
);
if ( empty( $subscriptions ) ) {
throw InvalidPreviewData::data_item_needed( 'subscription' );
}
$data_layer['subscription'] = current( $subscriptions );
}
/**
* Membership
*/
if ( Integrations::is_memberships_enabled() && in_array( 'membership', $required_items ) ) {
$memberships = get_posts(
[
'post_type' => 'wc_user_membership',
'post_status' => 'any',
'posts_per_page' => 1,
]
);
if ( empty( $memberships ) ) {
throw InvalidPreviewData::data_item_needed( 'membership' );
}
$data_layer['membership'] = wc_memberships_get_user_membership( current( $memberships ) );
}
/**
* Bookings
*/
if ( Integrations::is_bookings_active() && in_array( 'booking', $required_items ) ) {
try {
$booking = AW()->bookings_proxy()->get_most_recent_booking();
$data_layer['booking'] = $booking;
$data_layer['product'] = $booking->get_product();
} catch ( \Exception $e ) {
// rethrow as user-facing InvalidPreviewData exception
throw InvalidPreviewData::data_item_needed( 'booking' );
}
}
/**
* Card
*/
if ( in_array( 'card', $required_items ) ) {
$token = new \WC_Payment_Token_CC();
$token->set_user_id( 0 );
$token->set_card_type('visa');
$token->set_expiry_month( 04 );
$token->set_expiry_year( 2020 );
$token->set_last4( 1234 );
$data_layer['card'] = $token;
}
return apply_filters( 'automatewoo/preview_data_layer', $data_layer, $required_items );
}
/**
* Generate a previewable or testable action object filled with preview data.
*
* @param int $workflow_id
* @param int $action_number
* @param string $mode test|preview
*
* @return Action|PreviewableInterface|TestableInterface
*
* TODO Remove Action return type when code-hinting isn't required for public Action props
*
* @throws InvalidPreviewData When there's an error with the preview data.
*/
static function generate_preview_action( $workflow_id, $action_number, $mode = 'preview' ) {
$preview_data = wp_unslash( get_option( 'aw_wf_preview_data_' . $workflow_id ) );
$workflow = Factory::get( $workflow_id );
if ( ! $workflow || ! $action_number || ! is_array( $preview_data ) ) {
throw InvalidPreviewData::generic();
}
$trigger = Triggers::get( Clean::string( $preview_data['trigger_name'] ) );
$action_fields = $workflow->format_action_fields( $preview_data['action_fields'] );
if ( ! $trigger || ! $action_fields ) {
throw InvalidPreviewData::generic();
}
try {
$action = clone $workflow->get_action_from_action_fields( $action_fields );
} catch ( Exception $e ) {
throw InvalidPreviewData::generic();
}
if ( ! $action instanceof PreviewableInterface && ! $action instanceof TestableInterface ) {
throw InvalidPreviewData::invalid_action();
}
// add the workflow in preview mode
if ( $mode === 'test' ) {
$workflow->enable_test_mode();
} else {
$workflow->enable_preview_mode();
}
// set the data layer from preview trigger
$workflow->set_data_layer( Preview_Data::get_preview_data_layer( $trigger->get_supplied_data_items() ), true );
$action->workflow = $workflow;
// replace saved options with live preview data
$action->set_options( $action_fields );
return $action;
}
/**
* Get an order for preview.
*
* @param int $offset used to do multiple attempts to get a valid order
*
* @return WC_Order
* @throws InvalidPreviewData When no preview order is found.
*/
protected static function get_preview_order( $offset = 0 ) {
if ( $offset > 8 ) {
throw InvalidPreviewData::order_not_found();
}
$orders = wc_get_orders(
[
'type' => 'shop_order',
'limit' => 1,
'offset' => $offset,
'return' => 'ids',
]
);
if ( ! $orders ) {
throw InvalidPreviewData::order_not_found();
}
$order = wc_get_order( $orders[0] );
// if the order has a blank email, it will cause issues
if ( $order && $order->get_billing_email() ) {
return $order;
}
return self::get_preview_order( $offset + 1 );
}
/**
* Add customer language filter.
*
* @since 4.6.0
*
* @param Action $action
*/
public static function add_customer_language_filter( $action ) {
self::$preview_workflow = $action->workflow;
add_filter( 'automatewoo/customer/get_language', [ __CLASS__, 'filter_customer_language' ], 10, 2 );
}
/**
* Filter the current customers language when previewing.
* Make it the same as the preview workflow language.
*
* @since 4.6.0
*
* @param string $lang
* @param Customer $customer
*
* @return string
*/
public static function filter_customer_language( $lang, $customer ) {
if ( ! self::$preview_workflow ) {
return $lang;
}
$workflow_customer = self::$preview_workflow->data_layer()->get_customer();
// Only filter the language of the customer in the preview workflow.
if ( $workflow_customer && $customer->get_id() === $workflow_customer->get_id() ) {
return (string) self::$preview_workflow->get_language();
}
return $lang;
}
/**
* Remove customer language filter.
*
* @since 4.6.0
*
* @param Action $action
*/
public static function remove_customer_language_filter( $action ) {
self::$preview_workflow = null;
remove_filter( 'automatewoo/customer/get_language', [ __CLASS__, 'filter_customer_language' ], 10 );
}
/**
* Get preview products.
*
* @return array
*
* @throws InvalidPreviewData When no products found.
*/
protected static function get_preview_product_ids(): array {
// Cache for request since this may be called multiple times
static $products = null;
if ( null === $products ) {
$product_query = new \WP_Query(
[
'post_type' => 'product',
'posts_per_page' => 4,
'fields' => 'ids'
]
);
$products = $product_query->posts;
if ( empty( $products ) ) {
throw InvalidPreviewData::data_item_needed( 'product' );
}
}
return $products;
}
}