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

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