PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / trunk
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent vtrunk
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 / models / class-wpsc-ticket.php

class-wpsc-ticket.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent trunk, at includes/models/class-wpsc-ticket.php

1,022 lines 24.4 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_Ticket' ) ) :
7
8 final class WPSC_Ticket {
9
10 /**
11 * Object data in key => val pair.
12 *
13 * @var array
14 */
15 private $data = array();
16
17 /**
18 * Set whether or not current object properties modified
19 *
20 * @var boolean
21 */
22 private $is_modified = false;
23
24 /**
25 * Schema for this model
26 *
27 * @var array
28 */
29 public static $schema = array();
30
31 /**
32 * Prevent fields to modify
33 *
34 * @var array
35 */
36 public static $prevent_modify = array();
37
38 /**
39 * Initialize this class
40 *
41 * @return void
42 */
43 public static function init() {
44
45 // Apply schema for this model.
46 add_action( 'init', array( __CLASS__, 'apply_schema' ), 2 );
47
48 // Get object of this class.
49 add_filter( 'wpsc_load_ref_classes', array( __CLASS__, 'load_ref_class' ) );
50 }
51
52 /**
53 * Apply schema for this model
54 *
55 * @return void
56 */
57 public static function apply_schema() {
58
59 // start with schema item not present as custom field type.
60 $schema = array(
61 'is_active' => array(
62 'has_ref' => false,
63 'ref_class' => '',
64 'has_multiple_val' => false,
65 ),
66 'auth_code' => array(
67 'has_ref' => false,
68 'ref_class' => '',
69 'has_multiple_val' => false,
70 ),
71 'live_agents' => array(
72 'has_ref' => false,
73 'ref_class' => '',
74 'has_multiple_val' => false,
75 ),
76 'misc' => array(
77 'has_ref' => false,
78 'ref_class' => '',
79 'has_multiple_val' => false,
80 ),
81 );
82
83 foreach ( WPSC_Custom_Field::$custom_fields as $cf ) {
84
85 if ( in_array( $cf->field, array( 'ticket', 'agentonly' ) ) ) {
86 $schema[ $cf->slug ] = array(
87 'has_ref' => $cf->type::$has_ref,
88 'ref_class' => $cf->type::$ref_class,
89 'has_multiple_val' => $cf->type::$has_multiple_val,
90 );
91 }
92 }
93
94 self::$schema = apply_filters( 'wpsc_ticket_schema', $schema );
95
96 // Prevent modify.
97 $prevent_modify = array( 'id', 'description', 'agent_created', 'date_created' );
98 self::$prevent_modify = apply_filters( 'wpsc_ticket_prevent_modify', $prevent_modify );
99 }
100
101 /**
102 * Model constructor
103 *
104 * @param int $id - Optional. Data record id to retrive object for.
105 */
106 public function __construct( $id = 0 ) {
107
108 global $wpdb;
109
110 $id = intval( $id );
111
112 if ( $id > 0 ) {
113
114 $ticket = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}psmsc_tickets WHERE id = " . $id, ARRAY_A );
115 if ( ! is_array( $ticket ) ) {
116 return;
117 }
118
119 foreach ( $ticket as $key => $val ) {
120 $this->data[ $key ] = $val !== null ? $val : '';
121 }
122 }
123 }
124
125 /**
126 * Convert object into an array
127 *
128 * @return array
129 */
130 public function to_array() {
131
132 return $this->data;
133 }
134
135 /**
136 * Magic get function to use with object arrow function
137 *
138 * @param string $var_name - variable name.
139 * @return mixed
140 */
141 public function __get( $var_name ) {
142
143 if ( $var_name == 'misc' ) {
144
145 $misc_data = array();
146 if ( ( isset( $this->data['misc'] ) && ! empty( isset( $this->data['misc'] ) ) ) ) {
147 $misc_data = json_decode( $this->data['misc'], true );
148 }
149 return $misc_data;
150 }
151
152 if ( ! isset( $this->data[ $var_name ] ) ||
153 $this->data[ $var_name ] == null ||
154 $this->data[ $var_name ] == ''
155 ) {
156
157 if ( $var_name == 'customer_name' ) {
158 return $this->customer->name;
159 }
160 if ( $var_name == 'customer_email' ) {
161 return $this->customer->email_address;
162 }
163 return self::$schema[ $var_name ]['has_multiple_val'] ? array() : '';
164 }
165
166 if ( self::$schema[ $var_name ]['has_multiple_val'] ) {
167
168 $response = array();
169 $values = $this->data[ $var_name ] ? explode( '|', $this->data[ $var_name ] ) : array();
170 foreach ( $values as $val ) {
171 $response[] = self::$schema[ $var_name ]['has_ref'] ?
172 WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $val ) :
173 $val;
174 }
175 return $response;
176
177 } elseif ( ( self::$schema[ $var_name ]['has_ref'] && $this->data[ $var_name ] ) || ( self::$schema[ $var_name ]['has_ref'] && self::$schema[ $var_name ]['ref_class'] == 'wpsc_customer' ) ) {
178 return WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $this->data[ $var_name ] );
179 } else {
180 return $this->data[ $var_name ];
181 }
182 }
183
184 /**
185 * Magic function to use setting object field with arrow function
186 *
187 * @param string $var_name - (Required) property slug.
188 * @param mixed $value - (Required) value to set for a property.
189 * @return void
190 */
191 public function __set( $var_name, $value ) {
192
193 if (
194 ! isset( $this->data[ $var_name ] ) ||
195 in_array( $var_name, self::$prevent_modify )
196 ) {
197 return;
198 }
199
200 $data_val = '';
201 if ( self::$schema[ $var_name ]['has_multiple_val'] ) {
202
203 $data_vals = array_map(
204 fn( $val ) => is_object( $val ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $val ) : $val,
205 $value
206 );
207
208 $data_val = $data_vals ? implode( '|', $data_vals ) : '';
209 } else {
210 if ( $var_name == 'misc' ) {
211 $value = wp_json_encode( $value );
212 }
213 $data_val = is_object( $value ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $value ) : $value;
214 }
215
216 if ( $this->data[ $var_name ] == $data_val ) {
217 return;
218 }
219
220 $this->data[ $var_name ] = $data_val;
221 $this->is_modified = true;
222 }
223
224 /**
225 * Save changes made
226 *
227 * @return boolean
228 */
229 public function save() {
230
231 global $wpdb;
232
233 if ( ! $this->is_modified ) {
234 return true;
235 }
236
237 $data = $this->data;
238 $success = true;
239
240 if ( ! isset( $data['id'] ) ) {
241
242 $tic = self::insert( $data );
243 if ( $tic ) {
244 $this->data = $tic->data;
245 $success = true;
246 } else {
247 $success = false;
248 }
249 } else {
250
251 unset( $data['id'] );
252 $success = $wpdb->update(
253 $wpdb->prefix . 'psmsc_tickets',
254 $data,
255 array( 'id' => $this->data['id'] )
256 );
257 }
258 $this->is_modified = false;
259 return $success ? true : false;
260 }
261
262 /**
263 * Insert new record
264 *
265 * @param array $data - insert data.
266 * @return WPSC_Custom_Field
267 */
268 public static function insert( $data ) {
269
270 global $wpdb;
271
272 $ad_settings = get_option( 'wpsc-ms-advanced-settings' );
273 if ( ! isset( $data['id'] ) && $ad_settings['ticket-id-format'] === 'random' ) {
274
275 $range = self::get_ticket_id_range();
276 do {
277 $id = wp_rand( $range['start_range'], $range['end_range'] );
278 $sql = "select id from {$wpdb->prefix}psmsc_tickets where id=" . $id;
279 $result = $wpdb->get_var( $sql );
280 } while ( $result );
281 $data['id'] = $id;
282 }
283
284 // Insert ticket to DB.
285 $success = $wpdb->insert(
286 $wpdb->prefix . 'psmsc_tickets',
287 $data
288 );
289
290 if ( ! $success ) {
291 return false;
292 }
293 return new WPSC_Ticket( $wpdb->insert_id );
294 }
295
296 /**
297 * Delete record from database
298 *
299 * @param WPSC_Ticket $ticket - ticket object.
300 * @return boolean
301 */
302 public static function destroy( $ticket ) {
303
304 global $wpdb;
305
306 // Delete attachments of the ticket.
307 $success = $wpdb->update(
308 $wpdb->prefix . 'psmsc_attachments',
309 array( 'is_active' => '0' ),
310 array( 'ticket_id' => $ticket->id )
311 );
312
313 // Delete threads for the ticket.
314 $deleted_threads = $wpdb->delete(
315 $wpdb->prefix . 'psmsc_threads',
316 array( 'ticket' => $ticket->id )
317 );
318 if ( false === $deleted_threads ) {
319 return false;
320 }
321
322 // Finally delete ticket.
323 $deleted_ticket = $wpdb->delete(
324 $wpdb->prefix . 'psmsc_tickets',
325 array( 'id' => $ticket->id )
326 );
327 if ( false === $deleted_ticket ) {
328 return false;
329 }
330
331 return true;
332 }
333
334 /**
335 * Set data to create new object using direct data. Used in find method
336 *
337 * @param array $data - data to set for object.
338 * @return void
339 */
340 private function set_data( $data ) {
341
342 foreach ( $data as $var_name => $val ) {
343 $this->data[ $var_name ] = $val !== null ? $val : '';
344 }
345 }
346
347 /**
348 * Find records based on given filters
349 *
350 * @param array $filter - array containing array items like search, where, orderby, order, page_no, items_per_page, etc.
351 * @param boolean $is_object - return data as array or object. Default object.
352 * @return mixed
353 */
354 public static function find( $filter = array(), $is_object = true ) {
355
356 global $wpdb;
357
358 $filter['items_per_page'] = isset( $filter['items_per_page'] ) ? $filter['items_per_page'] : 20;
359 $filter['page_no'] = isset( $filter['page_no'] ) ? $filter['page_no'] : 1;
360 $filter['orderby'] = isset( $filter['orderby'] ) ? $filter['orderby'] : 'date_updated';
361 $filter['orderby_slug'] = $filter['orderby'];
362
363 // orderby.
364 $cf = WPSC_Custom_Field::get_cf_by_slug( $filter['orderby'] );
365 if ( ! $cf ) {
366 $cf = WPSC_Custom_Field::get_cf_by_slug( 'date_updated' );
367 }
368 $filter['orderby'] = $cf->type::get_orderby_string( $cf );
369
370 $filter['order'] = isset( $filter['order'] ) ? $filter['order'] : 'DESC';
371 $filter['is_active'] = isset( $filter['is_active'] ) ? $filter['is_active'] : 1;
372
373 $sql = 'SELECT t.* FROM ' . $wpdb->prefix . 'psmsc_tickets t ';
374 $joins = self::get_joins( $filter );
375 $where = self::get_where( $filter );
376
377 $order = WPSC_Functions::parse_order( $filter );
378 $order = apply_filters( 'wpsc_ticket_order_by', $order, $filter );
379
380 $limit = WPSC_Functions::parse_limit( $filter );
381 $group_by = 'GROUP BY t.id ';
382
383 $sql = $sql . $joins . $where . $group_by . $order . $limit;
384 $results = $wpdb->get_results( $sql, ARRAY_A );
385
386 // total results.
387 $sql = 'SELECT count(DISTINCT t.id) FROM ' . $wpdb->prefix . 'psmsc_tickets t ';
388 $total_items = $wpdb->get_var( $sql . $joins . $where );
389
390 $response = WPSC_Functions::parse_response( $results, $total_items, $filter );
391
392 // Return array.
393 if ( ! $is_object ) {
394 return $response;
395 }
396
397 // create and return array of objects.
398 $temp_results = array();
399 foreach ( $response['results'] as $ticket ) {
400
401 $ob = new WPSC_Ticket();
402 $data = array();
403 foreach ( $ticket as $key => $val ) {
404 $data[ $key ] = $val;
405 }
406 $ob->set_data( $data );
407 $temp_results[] = $ob;
408 }
409 $response['results'] = $temp_results;
410
411 return $response;
412 }
413
414 /**
415 * Return join string
416 *
417 * @param array $filter - user filter.
418 * @return string
419 */
420 private static function get_joins( $filter ) {
421
422 $joins = apply_filters( 'wpsc_ticket_joins', array(), $filter );
423 return implode( ' ', $joins ) . ' ';
424 }
425
426 /**
427 * Get where for find method
428 *
429 * @param array $filter - user filter.
430 * @return array
431 */
432 private static function get_where( $filter ) {
433
434 global $wpdb;
435
436 // Custom fields by type.
437 $cfs = array();
438 $custom_fields = WPSC_Custom_Field::$custom_fields;
439 foreach ( $custom_fields as $cf ) {
440 $cfs[ $cf->type::$slug ][] = $cf;
441 }
442
443 $where = array( '1=1' );
444
445 // Load system filters.
446 $system_query = isset( $filter['system_query'] ) ? $filter['system_query'] : array();
447 if ( $system_query ) {
448 $where[] = self::parse_filters( $system_query );
449 }
450
451 // Load meta filters.
452 $meta_query = isset( $filter['meta_query'] ) ? $filter['meta_query'] : array();
453 if ( $meta_query ) {
454 $where[] = self::parse_filters( $meta_query );
455 }
456
457 // Load search query.
458 $search = esc_sql( $wpdb->esc_like( WPSC_Functions::get_filter_search_str( $filter ) ) );
459 if ( $search ) {
460
461 $gs = get_option( 'wpsc-gs-general' );
462 $search_query = apply_filters( 'wpsc_ticket_search', array(), $filter, $cfs, $search, $gs['allowed-search-fields'] );
463 if ( $search_query ) {
464 $where[] = implode( ' OR ', $search_query );
465 }
466 }
467
468 $where = apply_filters( 'wpsc_ticket_where', $where, $filter, $cfs );
469
470 // is_active.
471 $where[] = 't.is_active=' . $filter['is_active'];
472
473 return 'WHERE (' . implode( ') AND (', $where ) . ') ';
474 }
475
476 /**
477 * Check whether slug is present in either system filters or meta query filters
478 *
479 * @param string $slug - custom field slug.
480 * @param array $filter - filter array.
481 * @return boolean
482 */
483 public static function is_filter( $slug, $filter ) {
484
485 $flag = false;
486 $search_term = '"slug":"' . $slug . '"';
487
488 if ( isset( $filter['meta_query'] ) ) {
489
490 $meta_query = wp_json_encode( $filter['meta_query'] );
491 if ( is_numeric( strpos( $meta_query, $search_term ) ) ) {
492 $flag = true;
493 }
494 }
495
496 return $flag;
497 }
498
499 /**
500 * Parse user filters for this model
501 *
502 * @param array $filters - filter array.
503 * @return string
504 */
505 private static function parse_filters( $filters ) {
506
507 // Invalid filter.
508 if ( ! isset( $filters['relation'] ) || count( $filters ) < 2 ) {
509 return '1=1';
510 }
511
512 $relation = $filters['relation'];
513 $filter_str = array();
514
515 foreach ( $filters as $key => $filter ) {
516
517 // Skip if current element is relation indicator.
518 if ( $key === 'relation' ) {
519 continue;
520 }
521
522 // Invalid filter if it is not an array.
523 if ( ! is_array( $filter ) ) {
524 return '1=1';
525 }
526
527 // Call recursively if there is multi-layer filter detected.
528 if ( isset( $filter['relation'] ) ) {
529 $filter_str[] = self::parse_filters( $filter );
530 continue;
531 }
532
533 // Invalid filter if it does not contain slug, compare and val indexes.
534 $slug = isset( $filter['slug'] ) ? WPSC_Functions::sanitize_sql_key( $filter['slug'] ) : false;
535 $compare = isset( $filter['compare'] ) ? $filter['compare'] : false;
536 $val = isset( $filter['val'] ) ? $filter['val'] : false;
537 if ( ! $slug || ! $compare || $val === false ) {
538 $filter_str[] = '1=1';
539 }
540
541 // custom filter.
542 if ( $slug === 'custom_query' ) {
543
544 $filter_str[] = $val;
545
546 } else {
547
548 // Get custom field object for the slug.
549 $cf = WPSC_Custom_Field::get_cf_by_slug( $slug );
550 if ( $cf ) {
551 $filter_str[] = $cf->type::parse_filter( $cf, $compare, $val );
552 }
553 }
554 }
555
556 return count( $filter_str ) > 1 ?
557 '(' . implode( ' ' . $relation . ' ', $filter_str ) . ')' :
558 $filter_str[0];
559 }
560
561 /**
562 * Load current class to reference classes
563 *
564 * @param array $classes - Associative array of class names indexed by its slug.
565 * @return array
566 */
567 public static function load_ref_class( $classes ) {
568
569 $classes['wpsc_ticket'] = array(
570 'class' => __CLASS__,
571 'save-key' => 'id',
572 );
573 return $classes;
574 }
575
576 /**
577 * Return array of thread objects for current ticket
578 *
579 * @param integer $page_no - current page.
580 * @param integer $items_per_page - number of records per page.
581 * @param array $types - thread types: reply, log, etc.
582 * @param string $orderby - orderby slug.
583 * @param string $order - order flag.
584 * @return array
585 */
586 public function get_threads( $page_no = 1, $items_per_page = 0, $types = array(), $orderby = 'date_created', $order = 'DESC' ) {
587
588 $args = array(
589 'meta_query' => array(
590 'relation' => 'AND',
591 array(
592 'slug' => 'ticket',
593 'compare' => '=',
594 'val' => $this->id,
595 ),
596 ),
597 'items_per_page' => $items_per_page,
598 'page_no' => $page_no,
599 'orderby' => $orderby,
600 'order' => $order,
601 );
602
603 if ( $types ) {
604 $args['meta_query'][] = array(
605 'slug' => 'type',
606 'compare' => 'IN',
607 'val' => $types,
608 );
609 }
610
611 return WPSC_Thread::find( $args )['results'];
612 }
613
614 /**
615 * Return last reply of the ticket.
616 *
617 * @return WPSC_Thread|boolean
618 */
619 public function get_last_reply() {
620
621 $filters = array(
622 'meta_query' => array(
623 'relation' => 'AND',
624 array(
625 'slug' => 'ticket',
626 'compare' => '=',
627 'val' => $this->id,
628 ),
629 array(
630 'slug' => 'type',
631 'compare' => 'IN',
632 'val' => array( 'reply', 'report' ),
633 ),
634 array(
635 'slug' => 'is_active',
636 'compare' => '=',
637 'val' => '1',
638 ),
639 ),
640 'orderby' => 'id',
641 'order' => 'DESC',
642 'items_per_page' => 1,
643 );
644 $threads = WPSC_Thread::find( $filters );
645
646 return isset( $threads['results'][0] ) ? $threads['results'][0] : false;
647 }
648
649 /**
650 * Return last note of the ticket.
651 *
652 * @return WPSC_Thread|boolean
653 */
654 public function get_last_note() {
655
656 $filters = array(
657 'meta_query' => array(
658 'relation' => 'AND',
659 array(
660 'slug' => 'ticket',
661 'compare' => '=',
662 'val' => $this->id,
663 ),
664 array(
665 'slug' => 'type',
666 'compare' => '=',
667 'val' => 'note',
668 ),
669 array(
670 'slug' => 'is_active',
671 'compare' => '=',
672 'val' => '1',
673 ),
674 ),
675 'orderby' => 'id',
676 'order' => 'DESC',
677 'items_per_page' => 1,
678 );
679 $threads = WPSC_Thread::find( $filters );
680
681 return isset( $threads['results'][0] ) ? $threads['results'][0] : false;
682 }
683
684 /**
685 * Return array of agents allowed to view this ticket
686 */
687 public function get_current_read_permission_agents() {
688
689 $agents = array();
690 $agent_roles = get_option( 'wpsc-agent-roles' );
691
692 // check customer whether he is an agent.
693 if ( $this->customer->user ) {
694 $agent = WPSC_Agent::get_by_user_id( $this->customer->user->ID );
695 if ( $agent->id && $agent->is_active ) {
696 $agents[] = $agent;
697 }
698 }
699
700 // unassigned.
701 if ( ! $this->assigned_agent ) {
702
703 $applicable_roles = array();
704 foreach ( $agent_roles as $key => $role ) {
705 if ( $role['caps']['view-unassigned'] ) {
706 $applicable_roles[] = $key;
707 }
708 }
709 $temp_agents = WPSC_Agent::find(
710 array(
711 'items_per_page' => 0,
712 'meta_query' => array(
713 'relation' => 'AND',
714 array(
715 'slug' => 'role',
716 'compare' => 'IN',
717 'val' => $applicable_roles,
718 ),
719 array(
720 'slug' => 'is_active',
721 'compare' => '=',
722 'val' => 1,
723 ),
724 array(
725 'slug' => 'is_agentgroup',
726 'compare' => '=',
727 'val' => 0,
728 ),
729 ),
730 )
731 )['results'];
732 if ( $temp_agents ) {
733 $agents = array_merge( $agents, $temp_agents );
734 }
735 } else { // assigned to agents.
736
737 // assign to me.
738 foreach ( $this->assigned_agent as $agent ) {
739
740 if ( $agent->is_agentgroup ) {
741 continue;
742 }
743 if ( $agent_roles[ $agent->role ]['caps']['view-assigned-me'] ) {
744 $agents[] = $agent;
745 }
746 }
747
748 // assign to other.
749 $applicable_roles = array();
750 foreach ( $agent_roles as $key => $role ) {
751 if ( $role['caps']['view-assigned-others'] ) {
752 $applicable_roles[] = $key;
753 }
754 }
755 $temp_agents = WPSC_Agent::find(
756 array(
757 'items_per_page' => 0,
758 'meta_query' => array(
759 'relation' => 'AND',
760 array(
761 'slug' => 'role',
762 'compare' => 'IN',
763 'val' => $applicable_roles,
764 ),
765 array(
766 'slug' => 'is_active',
767 'compare' => '=',
768 'val' => 1,
769 ),
770 array(
771 'slug' => 'is_agentgroup',
772 'compare' => '=',
773 'val' => 0,
774 ),
775 ),
776 )
777 )['results'];
778 if ( $temp_agents ) {
779 $agents = array_merge( $agents, $temp_agents );
780 }
781
782 // filter for agentgroups.
783 $agents = apply_filters( 'wpsc_get_current_read_permission_agents', $agents, $this );
784 }
785
786 $temp_agents = array();
787 foreach ( $agents as $agent ) {
788 if ( ! isset( $temp_agents[ $agent->id ] ) ) {
789 $temp_agents[ $agent->id ] = $agent;
790 }
791 }
792
793 return $temp_agents;
794 }
795
796 /**
797 * Return agents associated to this ticket previously with read permission
798 *
799 * @param array $prev - array of agent objects.
800 * @return array
801 */
802 public function get_prev_read_permission_agents( $prev ) {
803
804 $agents = array();
805 $agent_roles = get_option( 'wpsc-agent-roles' );
806
807 // unassigned.
808 if ( ! $prev ) {
809
810 $applicable_roles = array();
811 foreach ( $agent_roles as $key => $role ) {
812 if ( $role['caps']['view-unassigned'] ) {
813 $applicable_roles[] = $key;
814 }
815 }
816 $temp_agents = WPSC_Agent::find(
817 array(
818 'items_per_page' => 0,
819 'meta_query' => array(
820 'relation' => 'AND',
821 array(
822 'slug' => 'role',
823 'compare' => 'IN',
824 'val' => $applicable_roles,
825 ),
826 array(
827 'slug' => 'is_active',
828 'compare' => '=',
829 'val' => 1,
830 ),
831 array(
832 'slug' => 'is_agentgroup',
833 'compare' => '=',
834 'val' => 0,
835 ),
836 ),
837 )
838 )['results'];
839 if ( $temp_agents ) {
840 $agents = array_merge( $agents, $temp_agents );
841 }
842 } else {
843
844 // assign to me.
845 foreach ( $prev as $agent ) {
846 if ( $agent->is_agentgroup ) {
847 continue;
848 }
849 if ( $agent_roles[ $agent->role ]['caps']['view-assigned-me'] ) {
850 $agents[] = $agent;
851 }
852 }
853
854 // assign to other.
855 $applicable_roles = array();
856 foreach ( $agent_roles as $key => $role ) {
857 if ( $role['caps']['view-assigned-others'] ) {
858 $applicable_roles[] = $key;
859 }
860 }
861 $temp_agents = WPSC_Agent::find(
862 array(
863 'items_per_page' => 0,
864 'meta_query' => array(
865 'relation' => 'AND',
866 array(
867 'slug' => 'role',
868 'compare' => 'IN',
869 'val' => $applicable_roles,
870 ),
871 array(
872 'slug' => 'is_active',
873 'compare' => '=',
874 'val' => 1,
875 ),
876 array(
877 'slug' => 'is_agentgroup',
878 'compare' => '=',
879 'val' => 0,
880 ),
881 ),
882 )
883 )['results'];
884 if ( $temp_agents ) {
885 $agents = array_merge( $agents, $temp_agents );
886 }
887
888 // filter for agentgroups.
889 $agents = apply_filters( 'wpsc_get_prev_read_permission_agents', $agents, $this );
890 }
891
892 $temp_agents = array();
893 foreach ( $agents as $agent ) {
894 if ( ! isset( $temp_agents[ $agent->id ] ) ) {
895 $temp_agents[ $agent->id ] = $agent;
896 }
897 }
898
899 return $temp_agents;
900 }
901
902 /**
903 * Get ticket id range
904 *
905 * @return array start id and end id of random number
906 */
907 public static function get_ticket_id_range() {
908
909 $ad_settings = get_option( 'wpsc-ms-advanced-settings' );
910 $length = $ad_settings['random-id-length'];
911
912 $start = '1';
913 for ( $i = 1; $i < $length; $i++ ) {
914 $start .= '0';
915 }
916
917 $end = '9';
918 for ( $i = 1; $i < $length; $i++ ) {
919 $end .= '9';
920 }
921
922 return array(
923 'start_range' => intval( $start ),
924 'end_range' => intval( $end ),
925 );
926 }
927
928 /**
929 * Get ticket url
930 */
931 public function get_url() {
932
933 $page_settings = get_option( 'wpsc-gs-page-settings' );
934 $ticket_url = '';
935
936 if ( ! $this->auth_code ) {
937 $this->auth_code = WPSC_Functions::get_random_string();
938 $this->save();
939 }
940
941 // support page.
942 if ( $page_settings['ticket-url-page'] == 'support-page' && $page_settings['support-page'] ) {
943 $url = get_permalink( $page_settings['support-page'] );
944 $ticket_url = add_query_arg(
945 array(
946 'wpsc-section' => 'ticket-list',
947 'ticket-id' => $this->id,
948 'auth-code' => $this->auth_code,
949 ),
950 $url
951 );
952 }
953
954 // open ticket page.
955 if ( $page_settings['ticket-url-page'] == 'open-ticket-page' && $page_settings['open-ticket-page'] ) {
956 $url = get_permalink( $page_settings['open-ticket-page'] );
957 $ticket_url = add_query_arg(
958 array(
959 'ticket-id' => $this->id,
960 'auth-code' => $this->auth_code,
961 ),
962 $url
963 );
964 }
965
966 return apply_filters( 'wpsc_get_ticket_url', $ticket_url, $this );
967 }
968
969 /**
970 * Get description thread model object
971 *
972 * @return WPSC_Thread
973 */
974 public function get_description_thread() {
975
976 $results = WPSC_Thread::find(
977 array(
978 'meta_query' => array(
979 'relation' => 'AND',
980 array(
981 'slug' => 'ticket',
982 'compare' => '=',
983 'val' => $this->id,
984 ),
985 array(
986 'slug' => 'type',
987 'compare' => '=',
988 'val' => 'report',
989 ),
990 ),
991 )
992 )['results'];
993
994 return $results ? $results[0] : false;
995 }
996
997 /**
998 * Count tickets based on given filters
999 *
1000 * @param array $filter - array containing array items like search, where, etc.
1001 * @return int
1002 */
1003 public static function count( $filter = array() ) {
1004
1005 global $wpdb;
1006
1007 $filter['is_active'] = isset( $filter['is_active'] ) ? $filter['is_active'] : 1;
1008 $filter['orderby_slug'] = isset( $filter['orderby'] ) ? $filter['orderby'] : '';
1009
1010 $sql = 'SELECT COUNT(DISTINCT t.id) FROM ' . $wpdb->prefix . 'psmsc_tickets t ';
1011 $joins = self::get_joins( $filter );
1012 $where = self::get_where( $filter );
1013
1014 $sql = $sql . $joins . $where;
1015
1016 return (int) $wpdb->get_var( $sql );
1017 }
1018 }
1019 endif;
1020
1021 WPSC_Ticket::init();
1022