PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.6.2
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.6.2
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 1.6.2, at includes/admin/class-custom-tables.php

469 lines 13.7 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
141 $post->customer = ! empty( $customer_email ) ? $customer_email : '';
142 $post->usage_limit = ! empty( $usage_limit ) ? $usage_limit : '';
143 $post->usage_count = ! empty( $usage_count ) ? $usage_count : '';
144 $post->created_at = date_i18n( 'Y/m/d h:i A', strtotime( $post->post_date ) );
145
146 if ( ! empty( $expiry_date ) ) {
147 $post->expiry_date = round( ( get_post_meta( $post->ID, 'date_expires', true ) - time() ) / 86400 );
148 }
149
150 $coupons[] = $post;
151 }
152
153 wp_send_json_success( [
154 'coupons' => $coupons,
155 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
156 'total' => $query->found_posts,
157 ] );
158 }
159
160 /**
161 * Gets contacts.
162 *
163 * @since 1.5.0
164 */
165 public function get_contacts() {
166 check_ajax_referer( 'sellkit', 'nonce' );
167
168 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
169 $funnel_id = sellkit_htmlspecialchars( INPUT_GET, 'funnel_id' );
170
171 if ( empty( $page ) ) {
172 $page = 1;
173 }
174
175 $page_index = ( $page - 1 ) * self::CUSTOM_TABLE_PER_PAGE;
176 $limit = self::CUSTOM_TABLE_PER_PAGE;
177
178 global $wpdb;
179
180 $sellkit_prefix = Database::DATABASE_PREFIX;
181 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
182 $users_table = "{$wpdb->prefix}users ";
183
184 // phpcs:disable
185 $contacts = $wpdb->get_results(
186 $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
187 LEFT JOIN {$users_table} ut ON ut.ID = ct.user_id
188 where ct.funnel_id = %d
189 group by ct.user_id
190 order by ct.id desc limit %d , %d;", $funnel_id, $page_index, $limit ), ARRAY_A );
191
192 $total_contacts = $wpdb->get_results(
193 $wpdb->prepare( "SELECT count(*) as total_contacts FROM {$contact_table} where funnel_id = %d;", $funnel_id ), ARRAY_A );
194 $total_contacts_num = ! empty( $total_contacts[0]['total_contacts'] ) ? $total_contacts[0]['total_contacts'] : '';
195 // phpcs:enable
196
197 wp_send_json_success( [
198 'contacts' => $contacts,
199 'total' => intval( $total_contacts_num ),
200 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
201 ] );
202 }
203
204 /**
205 * Gets contacts.
206 *
207 * @since 1.5.0
208 */
209 public function get_history() {
210 check_ajax_referer( 'sellkit', 'nonce' );
211
212 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
213 $funnel_id = sellkit_htmlspecialchars( INPUT_GET, 'funnel_id' );
214 $contact_id = sellkit_htmlspecialchars( INPUT_GET, 'contact_id' );
215 $user_id = $this->get_user_id_by_contact_table( $contact_id );
216
217 if ( empty( $user_id ) ) {
218 wp_send_json_error( esc_html__( 'Something went wrong.', 'sellkit' ) );
219 }
220
221 if ( empty( $page ) ) {
222 $page = 1;
223 }
224
225 $page_index = ( $page - 1 ) * self::CUSTOM_TABLE_PER_PAGE;
226 $limit = self::CUSTOM_TABLE_PER_PAGE;
227
228 global $wpdb;
229
230 $sellkit_prefix = Database::DATABASE_PREFIX;
231 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
232 $users_table = "{$wpdb->prefix}users ";
233
234 // phpcs:disable
235 $contacts = $wpdb->get_results(
236 $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
237 LEFT JOIN {$users_table} ut ON ut.ID = ct.user_id
238 where ct.funnel_id = %d and ct.user_id = %d
239 order by ct.id desc limit %d , %d;", $funnel_id, $user_id, $page_index, $limit ), ARRAY_A );
240
241 $total_contacts = $wpdb->get_results(
242 $wpdb->prepare( "SELECT count(*) as total_contacts FROM {$contact_table} where funnel_id = %d;", $funnel_id ), ARRAY_A );
243 $total_contacts_num = ! empty( $total_contacts[0]['total_contacts'] ) ? $total_contacts[0]['total_contacts'] : '';
244 // phpcs:enable
245
246 wp_send_json_success( [
247 'contacts' => $contacts,
248 'total' => intval( $total_contacts_num ),
249 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
250 ] );
251 }
252
253 /**
254 * Delete a single contact.
255 *
256 * @since 1.5.0
257 */
258 public function delete_contact() {
259 check_ajax_referer( 'sellkit', 'nonce' );
260
261 $entry_id = sellkit_htmlspecialchars( INPUT_GET, 'entry_id' );
262
263 global $wpdb;
264
265 $sellkit_prefix = Database::DATABASE_PREFIX;
266 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
267
268 // phpcs:disable
269 $delete_result = $wpdb->delete( $contact_table, [ 'id' => intval( $entry_id ) ] );
270 // phpcs:enable
271
272 if ( ! $delete_result ) {
273 wp_send_json_error();
274 }
275
276 wp_send_json_success();
277 }
278
279 /**
280 * Gets contact details.
281 *
282 * @since 1.5.0
283 */
284 public function get_contact_details() {
285 check_ajax_referer( 'sellkit', 'nonce' );
286
287 $contact_id = sellkit_htmlspecialchars( INPUT_GET, 'contact_id' );
288
289 global $wpdb;
290
291 $sellkit_prefix = Database::DATABASE_PREFIX;
292 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
293 $contact_segmentation = "{$wpdb->prefix}{$sellkit_prefix}contact_segmentation";
294 $users_table = "{$wpdb->prefix}users ";
295
296 // phpcs:disable
297 $contact_details = $wpdb->get_results(
298 $wpdb->prepare( "SELECT ct.*, ut.user_email, ut.display_name, cs.* FROM {$contact_table} AS ct
299 LEFT JOIN {$users_table} ut ON ut.ID = ct.user_id
300 LEFT JOIN {$contact_segmentation} cs ON ut.user_email = cs.email
301 WHERE ct.id = %d limit 1;", $contact_id ), ARRAY_A );
302 // phpcs:enable
303
304 if ( empty( $contact_details[0] ) || ! is_array( $contact_details[0] ) ) {
305 wp_send_json_error( esc_html__( 'Something went wrong.', 'sellkit' ) );
306 }
307
308 $user_id = $contact_details[0]['user_id'];
309
310 wp_send_json_success( [
311 'user_details' => $contact_details[0],
312 'user_meta' => array_merge( get_user_meta( $user_id ), [ 'user_role' => get_userdata( $user_id )->roles ] ),
313 ] );
314 }
315
316 /**
317 * Gets funnel orders.
318 *
319 * @since 1.5.0
320 */
321 public function get_funnel_orders() {
322 check_ajax_referer( 'sellkit', 'nonce' );
323
324 $contact_id = sellkit_htmlspecialchars( INPUT_GET, 'contact_id' );
325 $funnel_id = sellkit_htmlspecialchars( INPUT_GET, 'funnel_id' );
326 $page_index = sellkit_htmlspecialchars( INPUT_GET, 'page' );
327 $limit = self::CUSTOM_TABLE_PER_PAGE;
328 $user_id = $this->get_user_id_by_contact_table( $contact_id );
329
330 if ( empty( $user_id ) ) {
331 wp_send_json_error( esc_html__( 'Something went wrong.', 'sellkit' ) );
332 }
333
334 $contact_orders = $this->get_contact_order_details( $funnel_id, $user_id, $page_index, $limit );
335
336 wp_send_json_success( [
337 'user_orders' => $contact_orders['orders'],
338 'total' => intval( $contact_orders['total'] ),
339 'max_item_num' => self::CUSTOM_TABLE_PER_PAGE,
340 ] );
341 }
342
343 /**
344 * Gets funnel id by contact table.
345 *
346 * @since 1.5.0
347 * @param string $contact_id Contact Id.
348 */
349 public function get_user_id_by_contact_table( $contact_id ) {
350 global $wpdb;
351
352 $sellkit_prefix = Database::DATABASE_PREFIX;
353 $contact_table = "{$wpdb->prefix}{$sellkit_prefix}funnel_contact";
354
355 // phpcs:disable
356 $contact_details = $wpdb->get_results(
357 $wpdb->prepare( "SELECT ct.user_id FROM {$contact_table} AS ct
358 WHERE ct.id = %d limit 1;", $contact_id ), ARRAY_A );
359 // phpcs:enable
360
361 if ( empty( $contact_details[0] ) || ! is_array( $contact_details[0] ) ) {
362 return false;
363 }
364
365 return $contact_details[0]['user_id'];
366 }
367
368 /**
369 * Saves contact details.
370 *
371 * @since 1.5.0
372 */
373 public function save_contact_details() {
374 check_ajax_referer( 'sellkit', 'nonce' );
375
376 $fields = sellkit_post( 'fields' );
377 $first_name = ! empty( $fields['contacts_detail_first_name'] ) ? sanitize_text_field( $fields['contacts_detail_first_name'] ) : '';
378 $last_name = ! empty( $fields['contacts_detail_last_name'] ) ? sanitize_text_field( $fields['contacts_detail_last_name'] ) : '';
379 $user_id = filter_input( INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT );
380
381 $result = wp_update_user( [
382 'ID' => $user_id,
383 'first_name' => $first_name,
384 'last_name' => $last_name,
385 ] );
386
387 if ( is_wp_error( $result ) ) {
388 wp_send_json_error( $result->get_error_message() );
389 }
390
391 wp_send_json_success( esc_html__( 'The details have been updated.', 'sellkit' ) );
392 }
393
394 /**
395 * Get order details of a contact ID related to a given funnel ID.
396 *
397 * @param int $funnel_id ID of the funnel.
398 * @param int $user_id Equals user ID of WordPress, customer ID of woocommerce and contact ID of sellkit.
399 * @param int $page Page number.
400 * @param int $limit Page limitation.
401 * @return array Order details with a custom structure which is parsed in frontend.
402 *
403 * @since 1.5.0
404 * @access private
405 */
406 private function get_contact_order_details( $funnel_id, $user_id, $page, $limit ) {
407 $funnel_orders = [];
408
409 $total_orders = wc_get_orders( [
410 'customer_id' => $user_id,
411 'meta_key' => 'sellkit_funnel_id', // phpcs:ignore
412 'meta_value' => $funnel_id, // phpcs:ignore
413 'meta_compare' => '=',
414 'limit' => -1,
415 ] );
416
417 $orders = wc_get_orders( [
418 'customer_id' => $user_id,
419 'meta_key' => 'sellkit_funnel_id', // phpcs:ignore
420 'meta_value' => $funnel_id, // phpcs:ignore
421 'meta_compare' => '=',
422 'limit' => $limit,
423 'paged' => $page,
424 'return' => 'objects'
425 ] );
426
427 foreach ( $orders as $order ) {
428 $products = [];
429
430 foreach ( $order->get_items() as $order_item ) {
431 $data = $order_item->get_data();
432
433 if ( ! array_key_exists( 'product_id', $data ) ) {
434 continue;
435 }
436
437 $product = wc_get_product( $data['product_id'] );
438
439 if ( empty( $product ) ) {
440 continue;
441 }
442
443 $products[] = [
444 'id' => $data['product_id'],
445 'name' => $data['name'],
446 'quantity' => $data['quantity'],
447 'order_price' => floatval( $data['total'] / $data['quantity'] ),
448 'regular_price' => floatval( $product->get_regular_price() ),
449 'image_src' => wp_get_attachment_image_src( $product->get_image_id() ),
450 ];
451 }
452
453 $funnel_orders[] = [
454 'order_number' => $order->get_order_number(),
455 'order_date' => $order->get_date_created()->date( 'Y/m/d g:i A' ),
456 'order_revenue' => $order->get_total() - $order->get_total_discount() - $order->get_total_tax(),
457 'products' => $products,
458 ];
459 }
460
461 return [
462 'orders' => $funnel_orders,
463 'total' => count( $total_orders ),
464 ];
465 }
466 }
467
468 Sellkit_Custom_Tables::get_instance();
469