PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.4.3
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.4.3
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.4.3, at includes/admin/customers/class-wpsc-customers.php

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