PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / trunk
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster vtrunk
2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 1.8.1 All 42 releases
sellkit / includes / funnel / steps / upsell.php

upsell.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster trunk, at includes/funnel/steps/upsell.php

202 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Sellkit\Funnel\Steps;
4
5 use Sellkit\Funnel\Analytics\Data_Updater;
6 use Sellkit\Funnel\Contacts\Base_Contacts;
7 use Sellkit_Funnel;
8
9 defined( 'ABSPATH' ) || die();
10
11 /**
12 * Class Sellkit_Upsell.
13 *
14 * @since 1.1.0
15 */
16 class Upsell {
17 /**
18 * Current funnel.
19 *
20 * @since 1.8.6
21 * @var Sellkit_Funnel
22 */
23 public $funnel;
24
25 /**
26 * Upsell constructor.
27 *
28 * @since 1.1.0
29 */
30 public function __construct() {
31 $this->funnel = Sellkit_Funnel::get_instance();
32
33 add_action( 'wp_ajax_sellkit_upsell_operations', [ $this, 'upsell_handler' ] );
34 add_action( 'wp_ajax_nopriv_sellkit_upsell_operations', [ $this, 'upsell_handler' ] );
35 }
36
37 /**
38 * Ajax function to handle accepted offer actions.
39 *
40 * @since 1.1.0
41 * @SuppressWarnings(PHPMD.NPathComplexity)
42 */
43 public function upsell_handler() {
44 check_ajax_referer( 'sellkit_elementor', 'nonce' );
45
46 $order_key = sellkit_htmlspecialchars( INPUT_POST, 'order_key' );
47 $offer_type = sellkit_htmlspecialchars( INPUT_POST, 'offer_type' );
48
49 if ( empty( $order_key ) ) {
50 wp_send_json_error( __( 'Each upsell needs a main order.', 'sellkit' ) );
51 }
52
53 $order_id = wc_get_order_id_by_order_key( $order_key );
54 $main_order = new \WC_Order( $order_id );
55
56 if (
57 empty( $this->funnel->next_no_step_data['page_id'] ) &&
58 empty( $this->funnel->next_step_data['page_id'] ) &&
59 ! empty( $this->funnel->end_node_step_data['page_id'] )
60 ) {
61 $next_step_link = add_query_arg( [ 'order-key' => $main_order->get_order_key() ], get_permalink( $this->funnel->end_node_step_data['page_id'] ) );
62
63 wp_send_json_success( $next_step_link );
64 }
65
66 if ( 'reject' === $offer_type && ! empty( $this->funnel->next_no_step_data['page_id'] ) ) {
67 $next_step_link = add_query_arg( [ 'order-key' => $main_order->get_order_key() ], get_permalink( $this->funnel->next_no_step_data['page_id'] ) );
68
69 wp_send_json_success( $next_step_link );
70 }
71
72 Base_Contacts::step_is_passed();
73
74 $billing_address = $main_order->get_address();
75 $shipping_address = $main_order->get_address( 'shipping' );
76 $products = $this->funnel->current_step_data['data']['products']['list'];
77
78 $order = wc_create_order();
79
80 $order_total = 0;
81
82 foreach ( $products as $product_id => $product ) {
83 $product_object = wc_get_product( $product_id );
84 $regular_price = $product_object->get_regular_price();
85 $quantity = ! empty( $product['quantity'] ) ? $product['quantity'] : 1;
86 $discount = ! empty( $product['discount'] ) ? $product['discount'] : 0;
87 $sale_price = self::calculate_sale_price( $regular_price, $discount, $product['discountType'] );
88 $order_total = floatval( $order_total ) + intval( $quantity ) * floatval( $sale_price );
89
90 $product_object->set_price( $sale_price );
91 $order->add_product( $product_object, $quantity );
92 }
93
94 $order->set_address( $billing_address );
95 $order->set_address( $shipping_address, 'shipping' );
96 $order->set_payment_method( $main_order->get_payment_method() );
97 $order->set_total( $order_total );
98 $order->set_customer_id( get_current_user_id() );
99 $order->update_meta_data( 'sellkit_funnel_id', $this->funnel->funnel_id );
100 $order->update_meta_data( 'sellkit_main_order_id', $main_order->get_id() );
101
102 if ( ! empty( $this->funnel->next_step_data ) ) {
103 $order->update_meta_data( 'sellkit_funnel_next_step_data', $this->funnel->next_step_data );
104 }
105
106 if (
107 empty( $this->funnel->next_step_data ) &&
108 ! empty( $this->funnel->current_step_data['targets'][0]['nodeId'] ) &&
109 'none' === $this->funnel->current_step_data['targets'][0]['nodeId'] &&
110 ! empty( $this->funnel->end_node_step_data )
111 ) {
112 $order->update_meta_data( 'sellkit_funnel_next_step_data', $this->funnel->end_node_step_data );
113 }
114
115 $order->save();
116
117 $analytics_updater = new Data_Updater();
118
119 // Adding order logs.
120 $analytics_updater->set_funnel_id( $this->funnel->funnel_id );
121 $analytics_updater->add_new_order_log( $order, 'upsell' );
122
123 $main_order->update_meta_data( 'sellkit_upsell_order_id', $order->get_id() );
124 $main_order->save();
125
126 $gateways = WC()->payment_gateways->payment_gateways();
127
128 if ( 'ppcp-gateway' !== $main_order->get_payment_method() ) {
129 $payment_process = $gateways[ $main_order->get_payment_method() ]->process_payment( $order->get_id() );
130 }
131
132 if ( 'ppcp-gateway' === $main_order->get_payment_method() ) {
133 $payment_process = self::ppcp_process_payment( $order->get_id() );
134 }
135
136 if ( 'success' === $payment_process['result'] && ! empty( $payment_process['redirect'] ) ) {
137 wp_send_json_success( $payment_process['redirect'] );
138 }
139
140 wp_send_json_error( __( 'Something went wrong', 'sellkit' ) );
141 }
142
143 /**
144 * Calculate the sale price.
145 *
146 * @param string $price Main price.
147 * @param string $discount Discount value.
148 * @param string $discount_type Discount type.
149 */
150 public static function calculate_sale_price( $price, $discount, $discount_type ) {
151 if ( $discount <= 0 ) {
152 return $price;
153 }
154
155 if ( 'fixed' === $discount_type ) {
156 return floatval( $price ) - floatval( $discount );
157 }
158
159 if ( 'percentage' === $discount_type ) {
160 return floatval( $price ) - ( ( floatval( $price ) * floatval( $discount ) ) / 100 );
161 }
162 }
163
164 /**
165 * Upsell actions.
166 *
167 * @since 1.1.0
168 * @SuppressWarnings(PHPMD.NPathComplexity)
169 */
170 public function do_actions() {
171 $conditions = ! empty( $this->funnel->current_step_data['data']['conditions'] ) ? $this->funnel->current_step_data['data']['conditions'] : [];
172 $is_valid = sellkit_conditions_validation( $conditions );
173
174 $args = [];
175
176 if ( ! empty( $_GET['order-key'] ) ) { // phpcs:ignore
177 $args['order-key'] = $_GET['order-key']; // phpcs:ignore
178 }
179
180 if ( ! $is_valid && ! empty( $this->funnel->next_step_data['page_id'] ) ) {
181 wp_safe_redirect( add_query_arg( $args, get_permalink( $this->funnel->next_step_data['page_id'] ) ) );
182 exit;
183 }
184 }
185
186 /**
187 * Process the payment and return the result.
188 *
189 * @param int $order_id Order ID.
190 * @since 1.1.0
191 */
192 public static function ppcp_process_payment( $order_id ) {
193 if ( ! class_exists( 'WC_Gateway_Paypal' ) ) {
194 return false;
195 }
196
197 $paypal = new \WC_Gateway_Paypal();
198
199 return $paypal->process_payment( $order_id );
200 }
201 }
202