PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 2.3.0
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v2.3.0
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 / admin / class-custom-tables.php

class-custom-tables.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 2.3.0, at includes/admin/class-custom-tables.php

480 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Sellkit\Database;
4
5 defined( 'ABSPATH' ) || die();
6
7 /**
8 * Components class.
9 *
10 * @since 1.1.0
11 */
12 class Sellkit_Custom_Tables {
13
14 const CUSTOM_TABLE_PER_PAGE = 20;
15
16 /**
17 * Class instance.
18 *
19 * @since 1.1.0
20 * @var Sellkit_Custom_Tables
21 */
22 private static $instance = null;
23
24 /**
25 * Get a class instance.
26 *
27 * @since 1.1.0
28 *
29 * @return Sellkit_Custom_Tables Class instance.
30 */
31 public static function get_instance() {
32 if ( null === self::$instance ) {
33 self::$instance = new self();
34 }
35
36 return self::$instance;
37 }
38
39 /**
40 * Class constructor.
41 *
42 * @since 1.1.0
43 */
44 public function __construct() {
45 add_action( 'wp_ajax_sellkit_get_applied_discount', [ $this, 'get_applied_discounts' ] );
46 add_action( 'wp_ajax_sellkit_get_generated_coupons', [ $this, 'get_generated_coupons' ] );
47 add_action( 'wp_ajax_sellkit_funnel_get_contacts', [ $this, 'get_contacts' ] );
48 add_action( 'wp_ajax_sellkit_funnel_get_contacts_history', [ $this, 'get_history' ] );
49 add_action( 'wp_ajax_sellkit_funnel_delete_contact', [ $this, 'delete_contact' ] );
50 add_action( 'wp_ajax_sellkit_funnel_get_contact_details', [ $this, 'get_contact_details' ] );
51 add_action( 'wp_ajax_sellkit_funnel_get_funnel_orders', [ $this, 'get_funnel_orders' ] );
52 add_action( 'wp_ajax_sellkit_funnel_save_contact_details', [ $this, 'save_contact_details' ] );
53 }
54
55 /**
56 * Gets applied discounts.
57 *
58 * @since 1.1.0
59 */
60 public function get_applied_discounts() {
61 check_ajax_referer( 'sellkit', 'nonce' );
62
63 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
64 $id = sellkit_htmlspecialchars( INPUT_GET, 'id' );
65
66 if ( empty( $page ) ) {
67 $page = 1;
68 }
69
70 $page_index = ( $page - 1 ) * self::CUSTOM_TABLE_PER_PAGE;
71 $limit = self::CUSTOM_TABLE_PER_PAGE;
72
73 global $wpdb;
74
75 $sellkit_prefix = Database::DATABASE_PREFIX;
76 $discount_table = "{$wpdb->prefix}{$sellkit_prefix}applied_discount";
77
78 // phpcs:disable
79 $prepared_query = $wpdb->prepare( "SELECT $discount_table.*, {$wpdb->prefix}users.ID as user_id FROM {$discount_table}
80 LEFT JOIN {$wpdb->prefix}users on {$discount_table}.email = {$wpdb->prefix}users.user_email
81 where {$discount_table}.discount_id = %d order by {$discount_table}.id desc limit %d , %d;",
82 $id,
83 $page_index,
84 $limit
85 );
86
87 $prepared_total_query = $wpdb->prepare( "SELECT count(*) as total_discounts FROM {$wpdb->prefix}{$sellkit_prefix}applied_discount where discount_id = %d;",
88 $id
89 );
90
91 $discounts = $wpdb->get_results(
92 $prepared_query,
93 ARRAY_A );
94
95 $total = $wpdb->get_results(
96 $prepared_total_query,
97 ARRAY_A );
98
99 $total_discount_num = ! empty( $total[0]['total_discounts'] ) ? $total[0]['total_discounts'] : '';
100 // phpcs:enable
101
102 wp_send_json_success( [
103 'discounts' => $discounts,
104 'total' => $total_discount_num,
105 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
106 ] );
107 }
108
109 /**
110 * Gets generated coupons.
111 *
112 * @since 1.1.0
113 */
114 public function get_generated_coupons() {
115 check_ajax_referer( 'sellkit', 'nonce' );
116
117 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
118 $id = sellkit_htmlspecialchars( INPUT_GET, 'id' );
119
120 $args = [
121 'post_type' => 'shop_coupon',
122 'post_status' => 'publish',
123 'posts_per_page' => self::CUSTOM_TABLE_PER_PAGE,
124 'paged' => sanitize_text_field( $page ),
125 'orderby' => 'ID',
126 'order' => 'DESC',
127 'meta_key' => 'sellkit_personalised_coupon_rule', // phpcs:ignore
128 'meta_value' => sanitize_text_field( $id ), // phpcs:ignore
129 ];
130
131 $query = new WP_Query( $args );
132
133 $coupons = [];
134
135 foreach ( $query->posts as $post ) {
136 $expiry_date = get_post_meta( $post->ID, 'date_expires', true );
137 $customer_email = get_post_meta( $post->ID, 'customer_email', true );
138 $usage_limit = get_post_meta( $post->ID, 'usage_limit', true );
139 $usage_count = get_post_meta( $post->ID, 'usage_count', true );
140 $used_by = get_post_meta( $post->ID, '_used_by', true );
141
142 if ( empty( $customer_email ) && ! empty( $used_by ) ) {
143 $used_by_customer = is_email( $used_by ) ? $used_by : '';
144
145 if ( empty( $used_by_customer ) ) {
146 $used_by_customer = get_userdata( intval( $used_by ) )->user_email;
147 }
148
149 $customer_email = [ $used_by_customer ];
150 }
151
152 $post->customer = ! empty( $customer_email ) ? $customer_email : '';
153 $post->usage_limit = ! empty( $usage_limit ) ? $usage_limit : '';
154 $post->usage_count = ! empty( $usage_count ) ? $usage_count : '';
155 $post->created_at = date_i18n( 'Y/m/d h:i A', strtotime( $post->post_date ) );
156
157 if ( ! empty( $expiry_date ) ) {
158 $post->expiry_date = round( ( get_post_meta( $post->ID, 'date_expires', true ) - time() ) / 86400 );
159 }
160
161 $coupons[] = $post;
162 }
163
164 wp_send_json_success( [
165 'coupons' => $coupons,
166 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
167 'total' => $query->found_posts,
168 ] );
169 }
170
171 /**
172 * Gets contacts.
173 *
174 * @since 1.5.0
175 */
176 public function get_contacts() {
177 check_ajax_referer( 'sellkit', 'nonce' );
178
179 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
180 $funnel_id = sellkit_htmlspecialchars( INPUT_GET, 'funnel_id' );
181
182 if ( empty( $page ) ) {
183 $page = 1;
184 }
185
186 $page_index = ( $page - 1 ) * self::CUSTOM_TABLE_PER_PAGE;
187 $limit = self::CUSTOM_TABLE_PER_PAGE;
188
189 global $wpdb;
190
191 $sellkit_prefix = Database::DATABASE_PREFIX;
192 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
193 $users_table = "{$wpdb->prefix}users ";
194
195 // phpcs:disable
196 $contacts = $wpdb->get_results(
197 $wpdb->prepare( "SELECT ct.user_id as user_id, ct.id as id, ct.created_at, ut.user_email, ut.display_name, SUM( ct.total_spent ) as sum_total_spent FROM {$contact_table} AS ct
198 LEFT JOIN {$users_table} ut ON ut.ID = ct.user_id
199 where ct.funnel_id = %d
200 group by ct.user_id
201 order by ct.id desc limit %d , %d;", $funnel_id, $page_index, $limit ), ARRAY_A );
202
203 $total_contacts = $wpdb->get_results(
204 $wpdb->prepare( "SELECT count(*) as total_contacts FROM {$contact_table} where funnel_id = %d;", $funnel_id ), ARRAY_A );
205 $total_contacts_num = ! empty( $total_contacts[0]['total_contacts'] ) ? $total_contacts[0]['total_contacts'] : '';
206 // phpcs:enable
207
208 wp_send_json_success( [
209 'contacts' => $contacts,
210 'total' => intval( $total_contacts_num ),
211 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
212 ] );
213 }
214
215 /**
216 * Gets contacts.
217 *
218 * @since 1.5.0
219 */
220 public function get_history() {
221 check_ajax_referer( 'sellkit', 'nonce' );
222
223 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
224 $funnel_id = sellkit_htmlspecialchars( INPUT_GET, 'funnel_id' );
225 $contact_id = sellkit_htmlspecialchars( INPUT_GET, 'contact_id' );
226 $user_id = $this->get_user_id_by_contact_table( $contact_id );
227
228 if ( empty( $user_id ) ) {
229 wp_send_json_error( esc_html__( 'Something went wrong.', 'sellkit' ) );
230 }
231
232 if ( empty( $page ) ) {
233 $page = 1;
234 }
235
236 $page_index = ( $page - 1 ) * self::CUSTOM_TABLE_PER_PAGE;
237 $limit = self::CUSTOM_TABLE_PER_PAGE;
238
239 global $wpdb;
240
241 $sellkit_prefix = Database::DATABASE_PREFIX;
242 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
243 $users_table = "{$wpdb->prefix}users ";
244
245 // phpcs:disable
246 $contacts = $wpdb->get_results(
247 $wpdb->prepare( "SELECT ct.*, ct.created_at, ut.user_email, ut.display_name, ct.total_spent as sum_total_spent FROM {$contact_table} AS ct
248 LEFT JOIN {$users_table} ut ON ut.ID = ct.user_id
249 where ct.funnel_id = %d and ct.user_id = %d
250 order by ct.id desc limit %d , %d;", $funnel_id, $user_id, $page_index, $limit ), ARRAY_A );
251
252 $total_contacts = $wpdb->get_results(
253 $wpdb->prepare( "SELECT count(*) as total_contacts FROM {$contact_table} where funnel_id = %d;", $funnel_id ), ARRAY_A );
254 $total_contacts_num = ! empty( $total_contacts[0]['total_contacts'] ) ? $total_contacts[0]['total_contacts'] : '';
255 // phpcs:enable
256
257 wp_send_json_success( [
258 'contacts' => $contacts,
259 'total' => intval( $total_contacts_num ),
260 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
261 ] );
262 }
263
264 /**
265 * Delete a single contact.
266 *
267 * @since 1.5.0
268 */
269 public function delete_contact() {
270 check_ajax_referer( 'sellkit', 'nonce' );
271
272 $entry_id = sellkit_htmlspecialchars( INPUT_GET, 'entry_id' );
273
274 global $wpdb;
275
276 $sellkit_prefix = Database::DATABASE_PREFIX;
277 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
278
279 // phpcs:disable
280 $delete_result = $wpdb->delete( $contact_table, [ 'id' => intval( $entry_id ) ] );
281 // phpcs:enable
282
283 if ( ! $delete_result ) {
284 wp_send_json_error();
285 }
286
287 wp_send_json_success();
288 }
289
290 /**
291 * Gets contact details.
292 *
293 * @since 1.5.0
294 */
295 public function get_contact_details() {
296 check_ajax_referer( 'sellkit', 'nonce' );
297
298 $contact_id = sellkit_htmlspecialchars( INPUT_GET, 'contact_id' );
299
300 global $wpdb;
301
302 $sellkit_prefix = Database::DATABASE_PREFIX;
303 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
304 $contact_segmentation = "{$wpdb->prefix}{$sellkit_prefix}contact_segmentation";
305 $users_table = "{$wpdb->prefix}users ";
306
307 // phpcs:disable
308 $contact_details = $wpdb->get_results(
309 $wpdb->prepare( "SELECT ct.*, ut.user_email, ut.display_name, cs.* FROM {$contact_table} AS ct
310 LEFT JOIN {$users_table} ut ON ut.ID = ct.user_id
311 LEFT JOIN {$contact_segmentation} cs ON ut.user_email = cs.email
312 WHERE ct.id = %d limit 1;", $contact_id ), ARRAY_A );
313 // phpcs:enable
314
315 if ( empty( $contact_details[0] ) || ! is_array( $contact_details[0] ) ) {
316 wp_send_json_error( esc_html__( 'Something went wrong.', 'sellkit' ) );
317 }
318
319 $user_id = $contact_details[0]['user_id'];
320
321 wp_send_json_success( [
322 'user_details' => $contact_details[0],
323 'user_meta' => array_merge( get_user_meta( $user_id ), [ 'user_role' => get_userdata( $user_id )->roles ] ),
324 ] );
325 }
326
327 /**
328 * Gets funnel orders.
329 *
330 * @since 1.5.0
331 */
332 public function get_funnel_orders() {
333 check_ajax_referer( 'sellkit', 'nonce' );
334
335 $contact_id = sellkit_htmlspecialchars( INPUT_GET, 'contact_id' );
336 $funnel_id = sellkit_htmlspecialchars( INPUT_GET, 'funnel_id' );
337 $page_index = sellkit_htmlspecialchars( INPUT_GET, 'page' );
338 $limit = self::CUSTOM_TABLE_PER_PAGE;
339 $user_id = $this->get_user_id_by_contact_table( $contact_id );
340
341 if ( empty( $user_id ) ) {
342 wp_send_json_error( esc_html__( 'Something went wrong.', 'sellkit' ) );
343 }
344
345 $contact_orders = $this->get_contact_order_details( $funnel_id, $user_id, $page_index, $limit );
346
347 wp_send_json_success( [
348 'user_orders' => $contact_orders['orders'],
349 'total' => intval( $contact_orders['total'] ),
350 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
351 ] );
352 }
353
354 /**
355 * Gets funnel id by contact table.
356 *
357 * @since 1.5.0
358 * @param string $contact_id Contact Id.
359 */
360 public function get_user_id_by_contact_table( $contact_id ) {
361 global $wpdb;
362
363 $sellkit_prefix = Database::DATABASE_PREFIX;
364 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
365
366 // phpcs:disable
367 $contact_details = $wpdb->get_results(
368 $wpdb->prepare( "SELECT ct.user_id FROM {$contact_table} AS ct
369 WHERE ct.id = %d limit 1;", $contact_id ), ARRAY_A );
370 // phpcs:enable
371
372 if ( empty( $contact_details[0] ) || ! is_array( $contact_details[0] ) ) {
373 return false;
374 }
375
376 return $contact_details[0]['user_id'];
377 }
378
379 /**
380 * Saves contact details.
381 *
382 * @since 1.5.0
383 */
384 public function save_contact_details() {
385 check_ajax_referer( 'sellkit', 'nonce' );
386
387 $fields = sellkit_post( 'fields' );
388 $first_name = ! empty( $fields['contacts_detail_first_name'] ) ? sanitize_text_field( $fields['contacts_detail_first_name'] ) : '';
389 $last_name = ! empty( $fields['contacts_detail_last_name'] ) ? sanitize_text_field( $fields['contacts_detail_last_name'] ) : '';
390 $user_id = filter_input( INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT );
391
392 $result = wp_update_user( [
393 'ID' => $user_id,
394 'first_name' => $first_name,
395 'last_name' => $last_name,
396 ] );
397
398 if ( is_wp_error( $result ) ) {
399 wp_send_json_error( $result->get_error_message() );
400 }
401
402 wp_send_json_success( esc_html__( 'The details have been updated.', 'sellkit' ) );
403 }
404
405 /**
406 * Get order details of a contact ID related to a given funnel ID.
407 *
408 * @param int $funnel_id ID of the funnel.
409 * @param int $user_id Equals user ID of WordPress, customer ID of woocommerce and contact ID of sellkit.
410 * @param int $page Page number.
411 * @param int $limit Page limitation.
412 * @return array Order details with a custom structure which is parsed in frontend.
413 *
414 * @since 1.5.0
415 * @access private
416 */
417 private function get_contact_order_details( $funnel_id, $user_id, $page, $limit ) {
418 $funnel_orders = [];
419
420 $total_orders = wc_get_orders( [
421 'customer_id' => $user_id,
422 'meta_key' => 'sellkit_funnel_id', // phpcs:ignore
423 'meta_value' => $funnel_id, // phpcs:ignore
424 'meta_compare' => '=',
425 'limit' => -1,
426 ] );
427
428 $orders = wc_get_orders( [
429 'customer_id' => $user_id,
430 'meta_key' => 'sellkit_funnel_id', // phpcs:ignore
431 'meta_value' => $funnel_id, // phpcs:ignore
432 'meta_compare' => '=',
433 'limit' => $limit,
434 'paged' => $page,
435 'return' => 'objects'
436 ] );
437
438 foreach ( $orders as $order ) {
439 $products = [];
440
441 foreach ( $order->get_items() as $order_item ) {
442 $data = $order_item->get_data();
443
444 if ( ! array_key_exists( 'product_id', $data ) ) {
445 continue;
446 }
447
448 $product = wc_get_product( $data['product_id'] );
449
450 if ( empty( $product ) ) {
451 continue;
452 }
453
454 $products[] = [
455 'id' => $data['product_id'],
456 'name' => $data['name'],
457 'quantity' => $data['quantity'],
458 'order_price' => floatval( $data['total'] / $data['quantity'] ),
459 'regular_price' => floatval( $product->get_regular_price() ),
460 'image_src' => wp_get_attachment_image_src( $product->get_image_id() ),
461 ];
462 }
463
464 $funnel_orders[] = [
465 'order_number' => $order->get_order_number(),
466 'order_date' => $order->get_date_created()->date( 'Y/m/d g:i A' ),
467 'order_revenue' => $order->get_total() - $order->get_total_tax(),
468 'products' => $products,
469 ];
470 }
471
472 return [
473 'orders' => $funnel_orders,
474 'total' => count( $total_orders ),
475 ];
476 }
477 }
478
479 Sellkit_Custom_Tables::get_instance();
480