PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.3.9
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.3.9
3.5.4 3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / includes / admin / customers / class-wpsc-customers.php

class-wpsc-customers.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.3.9, at includes/admin/customers/class-wpsc-customers.php

1,120 lines 35.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_Customers' ) ) :
7
8 final class WPSC_Customers {
9
10 /**
11 * Initialize the class
12 *
13 * @return void
14 */
15 public static function init() {
16
17 // get customer list.
18 add_action( 'wp_ajax_wpsc_get_customer_list', array( __CLASS__, 'get_customer_list' ) );
19
20 // view customer info.
21 add_action( 'wp_ajax_wpsc_view_customer_info', array( __CLASS__, 'view_customer_info' ) );
22
23 // edit customer info.
24 add_action( 'wp_ajax_wpsc_get_edit_customer_info', array( __CLASS__, 'get_edit_customer_info' ) );
25 add_action( 'wp_ajax_wpsc_set_edit_customer_info', array( __CLASS__, 'set_edit_customer_info' ) );
26
27 // view customer logs.
28 add_action( 'wp_ajax_wpsc_view_customer_logs', array( __CLASS__, 'view_customer_logs' ) );
29
30 // delete customer logs.
31 add_action( 'wp_ajax_wpsc_delete_customer', array( __CLASS__, 'delete_customer_info' ) );
32
33 // calculate customer ticket count.
34 add_action( 'wpsc_create_new_ticket', array( __CLASS__, 'customer_ticket_count' ) );
35 add_action( 'wpsc_delete_ticket', array( __CLASS__, 'customer_ticket_count' ) );
36 add_action( 'wpsc_ticket_restore', array( __CLASS__, 'customer_ticket_count' ) );
37 add_action( 'wpsc_change_raised_by', array( __CLASS__, 'customer_ticket_count' ), 200, 4 );
38
39 // view customer profile info.
40 add_action( 'wp_ajax_wpsc_view_customer_detailed_info', array( __CLASS__, 'view_customer_detailed_info' ) );
41
42 // Get customer recent activities.
43 add_action( 'wp_ajax_wpsc_upw_get_recent_activities', array( __CLASS__, 'get_upw_recent_activities' ) );
44 add_action( 'wp_ajax_nopriv_wpsc_upw_get_recent_activities', array( __CLASS__, 'get_upw_recent_activities' ) );
45 }
46
47 /**
48 * Admin submenu layout
49 *
50 * @return void
51 */
52 public static function layout() {
53
54 $types = apply_filters(
55 'wpsc_customer_type_filter',
56 array(
57 'all' => esc_attr__( 'All Users', 'supportcandy' ),
58 'customer_with_tickets' => esc_attr__( 'Users has tickets', 'supportcandy' ),
59 )
60 );
61
62 ?>
63 <div class="wrap">
64 <hr class="wp-header-end">
65 <div id="wpsc-container">
66 <div class="wpsc-setting-header">
67 <h2><?php esc_attr_e( 'Customers', 'supportcandy' ); ?></h2>
68 </div>
69 <div class="wpsc-setting-section-body">
70 <div class="wpsc-feedback-filter-container">
71 <div class="wpsc-filter-container">
72 <div class="wpsc-filter-item" style="min-width: 200px;">
73 <select name="wpsc-cust-list-filter" id="wpsc-cust-list-filter">
74 <?php
75 foreach ( $types as $key => $type ) {
76 $selected = 'selected="selected"';
77 ?>
78 <option <?php echo esc_attr( $selected ); ?> value="<?php echo esc_attr( $key ); ?>"><?php echo esc_attr( $type ); ?></option>
79 <?php
80 }
81 ?>
82 </select>
83 </div>
84 <div class="wpsc-filter-item" style="min-width: 250px;">
85 <input type="text" id="wpsc-cust-filter-search" placeholder="<?php esc_attr_e( 'Search...', 'supportcandy' ); ?>">
86 </div>
87 </div>
88 </div>
89 <?php
90 self::load_customer_list();
91 WPSC_Tickets::load_html_snippets();
92 ?>
93 </div>
94 </div>
95 </div>
96 <?php
97 }
98
99 /**
100 * List customer list
101 *
102 * @return void
103 */
104 public static function load_customer_list() {
105
106 ?>
107 <div id="wpsc-customer-list">
108 <table class="wpsc_customer_list wpsc-setting-tbl">
109 <thead>
110 <tr>
111 <th><?php esc_attr_e( 'Name', 'supportcandy' ); ?></th>
112 <th><?php esc_attr_e( 'Email address', 'supportcandy' ); ?></th>
113 <th><?php esc_attr_e( 'User Type', 'supportcandy' ); ?></th>
114 <th><?php esc_attr_e( 'Number of tickets', 'supportcandy' ); ?></th>
115 <th><?php esc_attr_e( 'Actions', 'supportcandy' ); ?></th>
116 </tr>
117 </thead>
118 </table>
119 </div>
120 <script>
121 function load_customer_list(custType) {
122
123 jQuery('.wpsc_customer_list').dataTable({
124 processing: true,
125 serverSide: true,
126 serverMethod: 'post',
127 ajax: {
128 url: supportcandy.ajax_url,
129 data: {
130 'action': 'wpsc_get_customer_list',
131 'cust_type': custType,
132 '_ajax_nonce': '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_customer_list' ) ); ?>'
133 }
134 },
135 'columns': [
136 { data: 'name' },
137 { data: 'email' },
138 { data: 'type' },
139 { data: 'tickets' },
140 { data: 'actions' },
141 ],
142 'bDestroy': true,
143 'searching': true,
144 'ordering': false,
145 'bLengthChange': false,
146 pageLength: 20,
147 columnDefs: [
148 { targets: '_all', className: 'dt-left' },
149 ],
150 language: supportcandy.translations.datatables
151 });
152 }
153
154 jQuery(document).ready(function() {
155
156 load_customer_list('customer_with_tickets');
157
158 jQuery('#wpsc-cust-filter-search').on('keyup', function() {
159 var searchTerm = jQuery(this).val();
160 jQuery('table.wpsc_customer_list').DataTable().search(searchTerm).draw();
161 });
162
163 jQuery('#wpsc-cust-list-filter').on('change', function(){
164 var custType = jQuery(this).val();
165 load_customer_list(custType);
166 });
167 });
168
169 <?php do_action( 'wpsc_js_customer_list_functions' ); ?>
170 </script>
171 <?php
172 }
173
174 /**
175 * Get list of all customers
176 *
177 * @return void
178 */
179 public static function get_customer_list() {
180
181 if ( check_ajax_referer( 'wpsc_get_customer_list', '_ajax_nonce', false ) != 1 ) {
182 wp_send_json_error( 'Unauthorized request!', 401 );
183 }
184
185 if ( ! WPSC_Functions::is_site_admin() ) {
186 wp_send_json_error( 'Unauthorized request!', 401 );
187 }
188
189 $search = isset( $_POST['search'] ) && isset( $_POST['search']['value'] ) ? sanitize_text_field( wp_unslash( $_POST['search']['value'] ) ) : '';
190 $draw = isset( $_POST['draw'] ) ? intval( $_POST['draw'] ) : 1;
191 $start = isset( $_POST['start'] ) ? intval( $_POST['start'] ) : 1;
192 $rowperpage = isset( $_POST['length'] ) ? intval( $_POST['length'] ) : 20;
193 $page_no = ( $start / $rowperpage ) + 1;
194 $cust_type = isset( $_POST['cust_type'] ) ? sanitize_text_field( wp_unslash( $_POST['cust_type'] ) ) : 'customer_with_tickets';
195
196 $args = array(
197 'search' => $search,
198 'items_per_page' => $rowperpage,
199 'page_no' => $page_no,
200 'orderby' => 'ticket_count',
201 'order' => 'DESC',
202 'meta_query' => array(
203 'relation' => 'AND',
204 ),
205 );
206
207 if ( $cust_type == 'customer_with_tickets' ) {
208
209 $args['meta_query'][] = array(
210 'slug' => 'ticket_count',
211 'compare' => '>',
212 'val' => 0,
213 );
214 }
215
216 if ( $cust_type == 'all' ) {
217
218 $args['meta_query'][] = array();
219 }
220
221 $args = apply_filters( 'wpsc_get_customer_list_filters', $args, $cust_type );
222 $response = WPSC_Customer::find( $args );
223
224 $customers = $response['results'];
225
226 $data = array();
227 foreach ( $customers as $customer ) {
228
229 $agent = WPSC_Agent::get_by_customer( $customer );
230 ob_start();
231 ?>
232 <a href="javascript:wpsc_view_customer_info(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_info' ) ); ?>')" class="wpsc-link">
233 <?php esc_attr_e( 'View', 'supportcandy' ); ?>
234 </a> |
235 <a href="javascript:wpsc_get_edit_customer_info(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_customer_info' ) ); ?>')" class="wpsc-link">
236 <?php esc_attr_e( 'Edit', 'supportcandy' ); ?>
237 </a> |
238 <a href="javascript:wpsc_view_customer_logs(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_logs' ) ); ?>')" class="wpsc-link">
239 <?php esc_attr_e( 'Logs', 'supportcandy' ); ?>
240 </a>
241 <?php
242 if ( ! $agent->id || ( $agent->role != 1 ) ) {
243 ?>
244 | <a href="javascript:wpsc_delete_customer(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer' ) ); ?>')" class="wpsc-link">
245 <?php esc_attr_e( 'Delete', 'supportcandy' ); ?>
246 </a>
247 <?php
248 }
249 ?>
250 <?php
251 $actions = ob_get_clean();
252
253 $data[] = array(
254 'name' => '<a class="wpsc-link" href="javascript:wpsc_view_customer_detailed_info( ' . $customer->id . ', \'' . wp_create_nonce( 'wpsc_view_customer_detailed_info' ) . '\' )">' . $customer->name . '<a>',
255 'email' => $customer->email,
256 'type' => ! is_object( $customer->user ) ? esc_attr__( 'Guest', 'supportcandy' ) : esc_attr__( 'Registered', 'supportcandy' ),
257 'tickets' => $customer->ticket_count,
258 'actions' => $actions,
259 );
260 }
261
262 $response = array(
263 'draw' => intval( $draw ),
264 'iTotalRecords' => $response['total_items'],
265 'iTotalDisplayRecords' => $response['total_items'],
266 'data' => $data,
267 );
268
269 wp_send_json( $response );
270 }
271
272 /**
273 * View customer info
274 *
275 * @return void
276 */
277 public static function view_customer_info() {
278
279 if ( check_ajax_referer( 'wpsc_view_customer_info', '_ajax_nonce', false ) != 1 ) {
280 wp_send_json_error( 'Unauthorised request!', 401 );
281 }
282
283 if ( ! WPSC_Functions::is_site_admin() ) {
284 wp_send_json_error( 'Unauthorised request!', 401 );
285 }
286
287 $customer_id = isset( $_POST['customer_id'] ) ? intval( $_POST['customer_id'] ) : 0;
288 if ( ! $customer_id ) {
289 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
290 }
291
292 $customer = new WPSC_Customer( $customer_id );
293 if ( ! $customer->id ) {
294 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
295 }
296
297 $title = esc_attr__( 'Customer info', 'supportcandy' );
298 $unique_id = uniqid();
299
300 ob_start();
301 ?>
302 <div class="wpsc-thread-info">
303
304 <div style="width: 100%;">
305 <table class="wpsc-setting-tbl <?php echo esc_attr( $unique_id ); ?>" style="margin-bottom: 15px;">
306 <thead>
307 <tr>
308 <th><?php esc_attr_e( 'Field', 'supportcandy' ); ?></th>
309 <th><?php esc_attr_e( 'Value', 'supportcandy' ); ?></th>
310 </tr>
311 </thead>
312 <tbody>
313 <tr>
314 <td><?php esc_attr_e( 'Name', 'supportcandy' ); ?>:</td>
315 <td><?php echo esc_attr( $customer->name ); ?></td>
316 </tr>
317 <tr>
318 <td><?php esc_attr_e( 'Email Address', 'supportcandy' ); ?>:</td>
319 <td><?php echo esc_attr( $customer->email ); ?></td>
320 </tr>
321 <?php
322 foreach ( WPSC_Custom_Field::$custom_fields as $cf ) :
323 if ( $cf->field !== 'customer' || in_array( $cf->slug, WPSC_DF_Customer::$ignore_customer_info_cft ) ) {
324 continue;
325 }
326 ?>
327 <tr>
328 <td><?php echo esc_attr( $cf->name ); ?>:</td>
329 <td><?php $cf->type::print_widget_customer_field_val( $cf, $customer ); ?></td>
330 </tr>
331 <?php
332 endforeach;
333 ?>
334 </tbody>
335 </table>
336 <script>
337 jQuery('.<?php echo esc_attr( $unique_id ); ?>').DataTable({
338 searching: false,
339 paging: false,
340 ordering: false,
341 info: false
342 });
343 </script>
344 </div>
345 <?php do_action( 'wpsc_view_customer_info', $customer ); ?>
346 </div>
347 <?php
348 $body = ob_get_clean();
349
350 ob_start();
351
352 ?>
353 <button class="wpsc-button small primary" onclick="wpsc_get_edit_customer_info(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_customer_info' ) ); ?>');">
354 <?php esc_attr_e( 'Edit Info', 'supportcandy' ); ?>
355 </button>
356 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
357 <?php esc_attr_e( 'Close', 'supportcandy' ); ?>
358 </button>
359 <?php
360 do_action( 'wpsc_view_customer_info_footer', $customer );
361 $footer = ob_get_clean();
362
363 $response = array(
364 'title' => $title,
365 'body' => $body,
366 'footer' => $footer,
367 );
368 wp_send_json( $response );
369 }
370
371 /**
372 * Get edit customer info
373 *
374 * @return void
375 */
376 public static function get_edit_customer_info() {
377
378 if ( check_ajax_referer( 'wpsc_get_edit_customer_info', '_ajax_nonce', false ) != 1 ) {
379 wp_send_json_error( 'Unauthorised request!', 401 );
380 }
381
382 if ( ! WPSC_Functions::is_site_admin() ) {
383 wp_send_json_error( 'Unauthorised request!', 401 );
384 }
385
386 $customer_id = isset( $_POST['customer_id'] ) ? intval( $_POST['customer_id'] ) : 0;
387 if ( ! $customer_id ) {
388 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
389 }
390
391 $customer = new WPSC_Customer( $customer_id );
392 if ( ! $customer->id ) {
393 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
394 }
395
396 $title = esc_attr__( 'Edit customer info', 'supportcandy' );
397 ob_start();
398 ?>
399 <form action="#" onsubmit="return false;" class="frm-edit-customer-info">
400 <?php
401
402 $cf = WPSC_Custom_Field::get_cf_by_slug( 'name' )
403 ?>
404 <div class="wpsc-tff">
405 <div class="wpsc-tff-label">
406 <span class="name"><?php echo esc_attr( $cf->name ); ?></span>
407 </div>
408 <span class="extra-info"><?php echo esc_attr( $cf->extra_info ); ?></span>
409 <input
410 type="text"
411 name="<?php echo esc_attr( $cf->slug ); ?>"
412 value="<?php echo esc_attr( $customer->name ); ?>"
413 placeholder="<?php echo esc_attr( $cf->placeholder_text ); ?>"
414 autocomplete="off"/>
415 </div>
416 <?php
417 foreach ( WPSC_Custom_Field::$custom_fields as $cf ) {
418 if ( $cf->field !== 'customer' || in_array( $cf->slug, WPSC_DF_Customer::$ignore_customer_info_cft ) ) {
419 continue;
420 }
421 $properties = array(
422 'is-required' => 0,
423 'width' => 'full',
424 'visibility' => '',
425 );
426 echo $cf->type::print_edit_customer_info( $cf, $customer, $properties ); // phpcs:ignore
427 }
428 do_action( 'wpsc_get_edit_customer_info_body', $customer );
429 ?>
430 <input type="hidden" name="action" value="wpsc_set_edit_customer_info"/>
431 <input type="hidden" name="id" value="<?php echo esc_attr( $customer->id ); ?>">
432 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_edit_customer_info' ) ); ?>">
433 </form>
434 <?php
435 do_action( 'wpsc_get_edit_customer_info_footer', $customer );
436 $body = ob_get_clean();
437
438 ob_start();
439 ?>
440 <button class="wpsc-button small primary" onclick="wpsc_set_edit_customer_info(this, <?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_info' ) ); ?>');">
441 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
442 </button>
443 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
444 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
445 </button>
446 <?php
447 $footer = ob_get_clean();
448
449 $response = array(
450 'title' => $title,
451 'body' => $body,
452 'footer' => $footer,
453 );
454 wp_send_json( $response );
455 }
456
457 /**
458 * Save customer info
459 *
460 * @return void
461 */
462 public static function set_edit_customer_info() {
463
464 if ( check_ajax_referer( 'wpsc_set_edit_customer_info', '_ajax_nonce', false ) != 1 ) {
465 wp_send_json_error( 'Unauthorised request!', 401 );
466 }
467
468 if ( ! WPSC_Functions::is_site_admin() ) {
469 wp_send_json_error( 'Unauthorised request!', 401 );
470 }
471
472 $customer_id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
473 if ( ! $customer_id ) {
474 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
475 }
476
477 $customer = new WPSC_Customer( $customer_id );
478 if ( ! $customer->id ) {
479 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
480 }
481
482 $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
483 if ( ! $name ) {
484 wp_send_json_error( new WP_Error( '002', 'Bad request!' ), 400 );
485 }
486
487 if ( $customer->name != $name ) {
488 $customer->name = $name;
489 $customer->save();
490 // Update WP User if available.
491 if ( $customer->user ) {
492 wp_update_user(
493 array(
494 'ID' => $customer->user->ID,
495 'display_name' => $name,
496 )
497 );
498 }
499 }
500
501 $cfs = array();
502 foreach ( WPSC_Custom_Field::$custom_fields as $cf ) {
503
504 if ( $cf->field !== 'customer' || $cf->type::$is_default ) {
505 continue;
506 }
507 $cfs[ $cf->type::$slug ][] = $cf;
508 }
509
510 foreach ( $cfs as $slug => $fields ) {
511 WPSC_Functions::$ref_classes[ $slug ]['class']::set_create_ticket_data( array( 'customer' => $customer->id ), $cfs, true );
512 }
513 $response = array(
514 'customer_id' => $customer->id,
515 'nonce' => wp_create_nonce( 'wpsc_view_customer_detailed_info' ),
516 );
517 wp_send_json( $response );
518 }
519
520 /**
521 * View customer logs
522 *
523 * @return void
524 */
525 public static function view_customer_logs() {
526
527 if ( check_ajax_referer( 'wpsc_view_customer_logs', '_ajax_nonce', false ) != 1 ) {
528 wp_send_json_error( 'Unauthorised request!', 401 );
529 }
530
531 if ( ! WPSC_Functions::is_site_admin() ) {
532 wp_send_json_error( 'Unauthorised request!', 401 );
533 }
534
535 $customer_id = isset( $_POST['customer_id'] ) ? intval( $_POST['customer_id'] ) : 0;
536 if ( ! $customer_id ) {
537 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
538 }
539
540 $customer = new WPSC_Customer( $customer_id );
541 if ( ! $customer->id ) {
542 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
543 }
544
545 $title = esc_attr__( 'Customer logs', 'supportcandy' );
546 $unique_id = uniqid();
547
548 ob_start();
549 $logs = WPSC_Log::find(
550 array(
551 'meta_query' => array(
552 'relation' => 'AND',
553 array(
554 'slug' => 'type',
555 'compare' => '=',
556 'val' => 'customer',
557 ),
558 array(
559 'slug' => 'ref_id',
560 'compare' => '=',
561 'val' => $customer->id,
562 ),
563 ),
564 )
565 )['results'];
566 ?>
567 <div style="width: 100%;">
568 <?php
569 foreach ( $logs as $log ) {
570 self::print_log( $log );
571 }
572 ?>
573 </div>
574 <?php
575
576 do_action( 'wpsc_view_customer_info', $customer );
577
578 $body = ob_get_clean();
579
580 ob_start();
581 ?>
582 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
583 <?php esc_attr_e( 'Close', 'supportcandy' ); ?>
584 </button>
585 <?php
586 do_action( 'wpsc_view_customer_logs_footer', $customer );
587 $footer = ob_get_clean();
588
589 $response = array(
590 'title' => $title,
591 'body' => $body,
592 'footer' => $footer,
593 );
594 wp_send_json( $response );
595 }
596
597 /**
598 * Print customer log
599 *
600 * @param WPSC_Log $log - log object.
601 * @return void
602 */
603 public static function print_log( $log ) {
604
605 $advanced = get_option( 'wpsc-ms-advanced-settings', array() );
606 $now = new DateTime();
607 $date = $log->date_created->setTimezone( wp_timezone() );
608 $time_date_str = $date->format( $advanced['thread-date-format'] );
609 $time_diff_str = WPSC_Functions::date_interval_highest_unit_ago( $date->diff( $now ) );
610 $title = $advanced['thread-date-display-as'] == 'date' ? $time_diff_str : $time_date_str;
611 $time_str = $advanced['thread-date-display-as'] == 'date' ? $time_date_str : $time_diff_str;
612
613 $body = json_decode( $log->body );
614 $customer = new WPSC_Customer( $log->modified_by );
615
616 $cf = WPSC_Custom_Field::get_cf_by_slug( $body->slug );
617 if ( ! $cf ) {
618 return;
619 }
620 ?>
621 <div class="wpsc-thread log">
622 <div class="thread-avatar">
623 <?php
624 if ( $log->modified_by ) {
625 echo get_avatar( $customer->email, 32 );
626 } else {
627 WPSC_Icons::get( 'system' );
628 }
629 ?>
630 </div>
631 <div class="thread-body">
632 <div class="thread-header">
633 <div class="user-info">
634 <div>
635 <?php
636 if ( $log->modified_by ) {
637 printf(
638 /* translators: %1$s: User Name, %2$s: Field Name */
639 esc_attr__( '%1$s changed the %2$s', 'supportcandy' ),
640 '<strong>' . esc_attr( $customer->name ) . '</strong>',
641 '<strong>' . esc_attr( $cf->name ) . '</strong>'
642 );
643 } else {
644 printf(
645 /* translators: %1$s: Field Name */
646 esc_attr__( 'The %1$s has been changed', 'supportcandy' ),
647 '<strong>' . esc_attr( $cf->name ) . '</strong>'
648 );
649 }
650
651 ?>
652 </div>
653 <span class="thread-time" title="<?php echo esc_attr( $title ); ?>"><?php echo esc_attr( $time_str ); ?></span>
654 </div>
655 </div>
656 <div class="wpsc-log-diff">
657 <div class="lhs"><?php $cf->type::print_val( $cf, $body->prev ); ?></div>
658 <div class="transform-icon">
659 <?php
660 if ( is_rtl() ) {
661 WPSC_Icons::get( 'arrow-left' );
662 } else {
663 WPSC_Icons::get( 'arrow-right' );
664 }
665 ?>
666 </div>
667 <div class="rhs"><?php $cf->type::print_val( $cf, $body->new ); ?></div>
668 </div>
669 </div>
670 </div>
671 <?php
672 }
673
674 /**
675 * Count customer tickets after create/delete/restore ticket
676 *
677 * @param WPSC_Ticket $ticket - ticket object.
678 * @return void
679 */
680 public static function customer_ticket_count( $ticket ) {
681
682 $ticket->customer->update_ticket_count();
683 }
684
685 /**
686 * Delete customer from.
687 *
688 * @return void
689 */
690 public static function delete_customer_info() {
691
692 if ( check_ajax_referer( 'wpsc_delete_customer', '_ajax_nonce', false ) != 1 ) {
693 wp_send_json_error( 'Unauthorised request!', 401 );
694 }
695
696 if ( ! WPSC_Functions::is_site_admin() ) {
697 wp_send_json_error( 'Unauthorised request!', 401 );
698 }
699
700 $customer_id = isset( $_POST['customer_id'] ) ? intval( $_POST['customer_id'] ) : 0;
701 if ( ! $customer_id ) {
702 wp_send_json_error( 'Bad Request', 400 );
703 }
704
705 $customer = new WPSC_Customer( $customer_id );
706 if ( ! $customer->id ) {
707 wp_send_json_error( 'Bad request', 400 );
708 }
709
710 // Make agent as a anonymous customer.
711 $agent = WPSC_Agent::get_by_customer( $customer );
712 if ( $agent->id ) {
713
714 if ( $agent->role == 1 ) {
715 wp_send_json_error( 'Unauthorised request!', 401 );
716 }
717
718 $agent->customer = WPSC_Functions::anonymous_customer();
719 $agent->is_active = 0;
720 $agent->save();
721
722 // Remove agent capability.
723 if ( $agent->has_cap( 'backend-access' ) ) {
724 $agent->user->remove_cap( 'wpsc_agent' );
725 }
726
727 do_action( 'wpsc_delete_agent', $agent );
728 }
729
730 self::delete_customer_tickets( $customer_id );
731
732 WPSC_Customer::destroy( $customer );
733 do_action( 'wpsc_delete_customer', $customer );
734 wp_die();
735 }
736
737 /**
738 * Delete customer tickets
739 *
740 * @param int $customer_id - customer_id.
741 * @return void
742 */
743 public static function delete_customer_tickets( $customer_id ) {
744
745 global $wpdb;
746
747 // Delete threads if records is exists.
748 $td_sql = "DELETE thrd FROM {$wpdb->prefix}psmsc_threads AS thrd LEFT JOIN {$wpdb->prefix}psmsc_tickets AS t ON thrd.ticket = t.id WHERE t.customer = $customer_id";
749 $wpdb->query( $td_sql );
750
751 // is active 0 attachment if records is exists.
752 $td_sql = "UPDATE {$wpdb->prefix}psmsc_attachments AS att LEFT JOIN {$wpdb->prefix}psmsc_tickets AS t ON att.ticket_id = t.id SET att.is_active = 0 WHERE t.customer = $customer_id";
753 $wpdb->query( $td_sql );
754
755 // Delete sla log records if log records is exists.
756 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}psmsc_sla_logs'" ) ) {
757 $sl_sql = "DELETE sl FROM {$wpdb->prefix}psmsc_sla_logs AS sl LEFT JOIN {$wpdb->prefix}psmsc_tickets AS t ON sl.ticket = t.id WHERE t.customer = $customer_id";
758 $wpdb->query( $sl_sql );
759 }
760
761 // Delete timer log records if log records is exists.
762 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}psmsc_timer_logs'" ) ) {
763 $tl_sql = "DELETE tl FROM {$wpdb->prefix}psmsc_timer_logs AS tl LEFT JOIN {$wpdb->prefix}psmsc_tickets AS t ON tl.ticket = t.id WHERE t.customer = $customer_id";
764 $wpdb->query( $tl_sql );
765 }
766
767 // Delete tickets if ticket records is exists.
768 $td_sql = "DELETE FROM {$wpdb->prefix}psmsc_tickets WHERE customer = $customer_id";
769 $wpdb->query( $td_sql );
770 }
771
772 /**
773 * Get customer profile details
774 *
775 * @return void
776 */
777 public static function view_customer_detailed_info() {
778
779 if ( check_ajax_referer( 'wpsc_view_customer_detailed_info', '_ajax_nonce', false ) != 1 ) {
780 wp_send_json_error( 'Unauthorised request!', 401 );
781 }
782
783 $customer_id = isset( $_POST['customer_id'] ) ? intval( $_POST['customer_id'] ) : 0;
784 if ( ! $customer_id ) {
785 wp_send_json_error( 'Bad Request', 400 );
786 }
787
788 $customer = new WPSC_Customer( $customer_id );
789 if ( ! $customer->id ) {
790 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
791 }
792 $agent = WPSC_Agent::get_by_customer( $customer );
793 ?>
794 <!-- User profile starts -->
795 <div class="wpsc-back-button">
796 <a class="wpsc-link" onclick="location.reload()"><?php esc_attr_e( 'Back', 'supportcandy' ); ?></a>
797 <?php
798 if ( ! $agent->id || ( $agent->role != 1 ) ) {
799 ?>
800 | <a href="javascript:wpsc_delete_customer(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_customer' ) ); ?>')" class="wpsc-link">
801 <?php esc_attr_e( 'Delete', 'supportcandy' ); ?>
802 </a>
803 <?php
804 }
805 ?>
806 </div>
807 <div class="wpsc-up-section">
808 <main>
809 <div class="wpsc-up-container">
810 <div class="wpsc-up-picture img">
811 <?php echo get_avatar( $customer->email, 50 ); ?>
812 </div>
813 <div class="wpsc-up-info">
814 <div class="wpsc-up-name"><?php echo esc_attr( $customer->name ); ?></div>
815 <div class="wpsc-up-email"><?php echo esc_attr( $customer->email ); ?></div>
816 </div>
817 </div>
818 <!-- Tabs -->
819 <div class="wpsc-up-tab">
820 <?php do_action( 'wpsc_add_before_up_tab' ); ?>
821 <label class="wpsc-profile-tab active" data-toggle-target="wpsc-up-tickets"><?php esc_attr_e( 'Tickets', 'supportcandy' ); ?></label>
822 <label class="wpsc-profile-tab" data-toggle-target="wpsc-up-cf"><?php esc_attr_e( 'Custom fields', 'supportcandy' ); ?></label>
823 <label class="wpsc-profile-tab" data-toggle-target="wpsc-up-other"><?php esc_attr_e( 'Other', 'supportcandy' ); ?></label>
824 <?php do_action( 'wpsc_add_after_up_tab' ); ?>
825 </div>
826
827 <!-- Tab Content -->
828 <section>
829 <?php do_action( 'wpsc_add_before_up_tab_content' ); ?>
830 <div class="wpsc-up-content wpsc-up-tickets active">
831 <?php self::get_customers_ticket_list( $customer ); ?>
832 </div>
833 <div class="wpsc-up-content wpsc-up-cf">
834 <?php self::get_customers_customer_fields( $customer ); ?>
835 </div>
836 <div class="wpsc-up-content wpsc-up-other">
837 <?php self::get_customers_other_info( $customer ); ?>
838 </div>
839 <?php do_action( 'wpsc_add_after_up_tab_content' ); ?>
840 </section>
841 </main>
842 </div>
843 <!-- User profile ends -->
844
845 <script>
846 jQuery('.wpsc-profile-tab').on('click', function(event) {
847
848 event.preventDefault();
849 if ( jQuery(this).hasClass('active') ) return;
850
851 jQuery(this).toggleClass('active');
852 var temp = jQuery(this).data('toggle-target');
853 jQuery('.wpsc-up-content').removeClass('active').filter('.'+temp).addClass('active');
854 jQuery('.wpsc-profile-tab').not(this).removeClass('active');
855 });
856 </script>
857 <?php
858 wp_die();
859 }
860
861 /**
862 * Get customer's individual tickets
863 *
864 * @param int $customer - customer id.
865 * @return void
866 */
867 public static function get_customers_ticket_list( $customer ) {
868
869 $list_items = get_option( 'wpsc-ctl-list-items' );
870 ?>
871 <table class="my-profile-ticket-list wpsc-setting-tbl">
872 <thead>
873 <tr>
874 <?php
875 foreach ( $list_items as $slug ) :
876 $cf = WPSC_Custom_Field::get_cf_by_slug( $slug );
877 if ( ! $cf ) {
878 continue;
879 }
880 ?>
881 <th style="min-width: <?php echo esc_attr( $cf->tl_width ); ?>px;"><?php echo esc_attr( $cf->name ); ?></th>
882 <?php
883 endforeach;
884 ?>
885 </tr>
886 </thead>
887 <tbody>
888 <?php
889 $filters = array(
890 'items_per_page' => 0,
891 'orderby' => 'id',
892 'order' => 'DESC',
893 'meta_query' => array(
894 'relation' => 'AND',
895 array(
896 'slug' => 'customer',
897 'compare' => '=',
898 'val' => $customer->id,
899 ),
900 ),
901 );
902 $tickets = WPSC_Ticket::find( $filters )['results'];
903 if ( $tickets ) {
904 foreach ( $tickets as $ticket ) {
905 ?>
906 <tr>
907 <?php
908 foreach ( $list_items as $slug ) {
909 $cf = WPSC_Custom_Field::get_cf_by_slug( $slug );
910 if ( ! $cf ) {
911 continue;
912 }
913 ?>
914 <td onmouseover="link=true;">
915 <?php
916 if ( in_array( $cf->field, array( 'ticket', 'agentonly' ) ) ) {
917 $cf->type::print_tl_ticket_field_val( $cf, $ticket );
918 } else {
919 $cf->type::print_tl_customer_field_val( $cf, $ticket->customer );
920 }
921 ?>
922 </td>
923 <?php
924 }
925 ?>
926 </tr>
927 <?php
928 }
929 }
930 ?>
931 </tbody>
932 </table>
933 <script>
934 jQuery(document).ready(function() {
935
936 jQuery('.my-profile-ticket-list').dataTable({
937 'bDestroy': true,
938 'searching': false,
939 'ordering': false,
940 'bLengthChange': false,
941 pageLength: 10,
942 columnDefs: [
943 { targets: '_all', className: 'dt-left' },
944 ],
945 language: supportcandy.translations.datatables
946 });
947 });
948 </script>
949 <?php
950 }
951
952 /**
953 * Get customer's custom fields
954 *
955 * @param int $customer - customer id.
956 * @return void
957 */
958 public static function get_customers_customer_fields( $customer ) {
959 ?>
960 <form action="#" onsubmit="return false;" class="frm-edit-customer-info">
961 <?php
962 $cf = WPSC_Custom_Field::get_cf_by_slug( 'name' );
963 foreach ( WPSC_Custom_Field::$custom_fields as $cf ) {
964 if ( $cf->field !== 'customer' || in_array( $cf->slug, WPSC_DF_Customer::$ignore_customer_info_cft ) ) {
965 continue;
966 }
967 $properties = array(
968 'is-required' => 0,
969 'width' => 'full',
970 'visibility' => '',
971 );
972 echo $cf->type::print_edit_customer_info( $cf, $customer, $properties ); // phpcs:ignore
973 }
974 do_action( 'wpsc_get_edit_customer_info_body', $customer );
975 ?>
976 <input type="hidden" name="action" value="wpsc_set_edit_customer_info"/>
977 <input type="hidden" name="id" value="<?php echo esc_attr( $customer->id ); ?>">
978 <input type="hidden" name="name" value="<?php echo esc_attr( $customer->name ); ?>">
979 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_edit_customer_info' ) ); ?>">
980 </form>
981 <button class="wpsc-button small primary" onclick="wpsc_set_edit_customer_info(this, <?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_info' ) ); ?>');">
982 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
983 </button>
984 <button class="wpsc-button small secondary" onclick="wpsc_view_customer_logs(<?php echo esc_attr( $customer->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_view_customer_logs' ) ); ?>')">
985 <?php esc_attr_e( 'View logs', 'supportcandy' ); ?>
986 </button>
987 <?php
988 }
989
990 /**
991 * Get customer's other info
992 *
993 * @param int $customer - customer id.
994 * @return void
995 */
996 public static function get_customers_other_info( $customer ) {
997
998 do_action( 'wpsc_user_profile_widgets_before', $customer );
999 ?>
1000 <div class="wpsc-xs-6 wpsc-sm-6 wpsc-md-6 wpsc-lg-6">
1001 <div class="wpsc-it-widget wpsc-itw-add-rec">
1002 <div class="wpsc-widget-header">
1003 <h2><?php echo esc_attr__( 'Recent Activities', 'supportcandy' ); ?></h2>
1004 <span>
1005 <div class="info-list-item">
1006 <div class="info-label">
1007 <a href="<?php echo esc_url_raw( admin_url( 'admin.php?page=wpsc-recent-activities&cid=' . $customer->id ) ); ?>" target="__blank"><?php echo esc_attr__( 'View All', 'supportcandy' ); ?></a>
1008 </div>
1009 </div>
1010 </span>
1011 </div>
1012 <div class="wpsc-widget-body wpsc-widget-scroller">
1013 <div class="info-list-item">
1014 <div class="info-val fullwidth">
1015 <div id="wpsc-upw-recent-activities"></div>
1016 </div>
1017 </div>
1018 </div>
1019 </div>
1020 </div>
1021 <script>
1022 wpsc_upw_get_recent_activities();
1023 function wpsc_upw_get_recent_activities() {
1024 jQuery('#wpsc-upw-recent-activities').html( supportcandy.loader_html );
1025 var data = { action: 'wpsc_upw_get_recent_activities', view: supportcandy.is_frontend, _ajax_nonce: supportcandy.nonce, customer_id: <?php echo esc_attr( $customer->id ); ?> };
1026 jQuery.post(
1027 supportcandy.ajax_url,
1028 data,
1029 function (response) {
1030 jQuery('#wpsc-upw-recent-activities').html(response.html);
1031 }
1032 );
1033 }
1034 </script>
1035 <?php
1036 do_action( 'wpsc_user_profile_widgets_after', $customer );
1037 }
1038
1039 /**
1040 * Get customer recent activities
1041 *
1042 * @return void
1043 */
1044 public static function get_upw_recent_activities() {
1045
1046 if ( check_ajax_referer( 'general', '_ajax_nonce', false ) != 1 ) {
1047 wp_send_json_error( 'Unauthorised request!', 401 );
1048 }
1049
1050 if ( ! WPSC_Functions::is_site_admin() ) {
1051 wp_send_json_error( new WP_Error( '004', 'Unauthorized!' ), 401 );
1052 }
1053
1054 $view = isset( $_POST['view'] ) ? sanitize_text_field( wp_unslash( $_POST['view'] ) ) : '0';
1055
1056 $customer_id = isset( $_POST['customer_id'] ) ? intval( $_POST['customer_id'] ) : 0;
1057 if ( ! $customer_id ) {
1058 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1059 }
1060
1061 $customer = new WPSC_Customer( $customer_id );
1062 if ( ! $customer->id ) {
1063 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
1064 }
1065
1066 $logs = WPSC_RA_Logs::get_activity_logs( 10, 1, $customer_id );
1067 $now = new DateTime();
1068 ob_start();
1069 ?>
1070 <div class="wpsc-widget-list-section">
1071 <?php
1072 if ( $logs['total_items'] ) {
1073 foreach ( $logs['results'] as $log ) {
1074
1075 $url = WPSC_Functions::get_ticket_url( $log->ticket->id, $view );
1076 $time_ago = WPSC_Functions::date_interval_highest_unit_ago( $log->date_created->diff( $now ) );
1077
1078 if ( $log->type == 'report' ) {
1079 ?>
1080 <div class="wpsc-widget-list"><?php echo esc_attr( $log->customer->name ) . ' ' . esc_attr__( 'created a ticket', 'supportcandy' ); ?> <a href="<?php echo esc_attr( $url ); ?>" target="_blank">#<?php echo esc_attr( $log->ticket->id ) . ' ' . esc_attr( $log->ticket->subject ); ?></a><?php echo esc_attr( ' (' . $time_ago . ')' ); ?></div>
1081 <?php
1082 } elseif ( $log->type == 'reply' ) {
1083 ?>
1084 <div class="wpsc-widget-list"><?php echo esc_attr( $log->customer->name ) . ' ' . esc_attr__( 'replied to ticket', 'supportcandy' ); ?> <a href="<?php echo esc_attr( $url ); ?>" target="_blank">#<?php echo esc_attr( $log->ticket->id ); ?></a><?php echo esc_attr( ' (' . $time_ago . ')' ); ?></div>
1085 <?php
1086 } elseif ( $log->type == 'note' ) {
1087 ?>
1088 <div class="wpsc-widget-list"><?php echo esc_attr( $log->customer->name ) . ' ' . esc_attr__( 'added a note to ticket', 'supportcandy' ); ?> <a href="<?php echo esc_attr( $url ); ?>" target="_blank">#<?php echo esc_attr( $log->ticket->id ); ?></a><?php echo esc_attr( ' (' . $time_ago . ')' ); ?></div>
1089 <?php
1090 } elseif ( $log->type == 'log' ) {
1091 if ( ! $log->customer ) {
1092 continue;
1093 }
1094 $body = json_decode( $log->body );
1095 $is_json = ( json_last_error() == JSON_ERROR_NONE ) ? true : false;
1096 if ( $is_json ) {
1097 $cf = WPSC_Custom_Field::get_cf_by_slug( $body->slug );
1098 if ( ! $cf ) {
1099 continue;
1100 }
1101 ?>
1102 <div class="wpsc-widget-list"><?php echo wp_kses_post( $cf->type::print_activity( $cf, $log, $body, '0' ) ); ?><?php echo esc_attr( ' (' . $time_ago . ')' ); ?></div>
1103 <?php
1104 }
1105 }
1106 }
1107 } else {
1108 echo esc_attr__( 'Record not found!', 'supportcandy' );
1109 }
1110 ?>
1111 </div>
1112 <?php
1113 $table = ob_get_clean();
1114 wp_send_json( array( 'html' => $table ) );
1115 }
1116 }
1117 endif;
1118
1119 WPSC_Customers::init();
1120