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

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