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

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

998 lines 23.7 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 $success = $wpdb->delete(
315 $wpdb->prefix . 'psmsc_threads',
316 array( 'ticket' => $ticket->id )
317 );
318 if ( ! $success ) {
319 return false;
320 }
321
322 // Finally delete ticket.
323 $success = $wpdb->delete(
324 $wpdb->prefix . 'psmsc_tickets',
325 array( 'id' => $ticket->id )
326 );
327 if ( ! $success ) {
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 $filter_str[] = $cf ? $cf->type::parse_filter( $cf, $compare, $val ) : '1=1';
551 }
552 }
553
554 return count( $filter_str ) > 1 ?
555 '(' . implode( ' ' . $relation . ' ', $filter_str ) . ')' :
556 $filter_str[0];
557 }
558
559 /**
560 * Load current class to reference classes
561 *
562 * @param array $classes - Associative array of class names indexed by its slug.
563 * @return array
564 */
565 public static function load_ref_class( $classes ) {
566
567 $classes['wpsc_ticket'] = array(
568 'class' => __CLASS__,
569 'save-key' => 'id',
570 );
571 return $classes;
572 }
573
574 /**
575 * Return array of thread objects for current ticket
576 *
577 * @param integer $page_no - current page.
578 * @param integer $items_per_page - number of records per page.
579 * @param array $types - thread types: reply, log, etc.
580 * @param string $orderby - orderby slug.
581 * @param string $order - order flag.
582 * @return array
583 */
584 public function get_threads( $page_no = 1, $items_per_page = 0, $types = array(), $orderby = 'date_created', $order = 'DESC' ) {
585
586 $args = array(
587 'meta_query' => array(
588 'relation' => 'AND',
589 array(
590 'slug' => 'ticket',
591 'compare' => '=',
592 'val' => $this->id,
593 ),
594 ),
595 'items_per_page' => $items_per_page,
596 'page_no' => $page_no,
597 'orderby' => $orderby,
598 'order' => $order,
599 );
600
601 if ( $types ) {
602 $args['meta_query'][] = array(
603 'slug' => 'type',
604 'compare' => 'IN',
605 'val' => $types,
606 );
607 }
608
609 return WPSC_Thread::find( $args )['results'];
610 }
611
612 /**
613 * Return last reply of the ticket.
614 *
615 * @return WPSC_Thread|boolean
616 */
617 public function get_last_reply() {
618
619 $filters = array(
620 'meta_query' => array(
621 'relation' => 'AND',
622 array(
623 'slug' => 'ticket',
624 'compare' => '=',
625 'val' => $this->id,
626 ),
627 array(
628 'slug' => 'type',
629 'compare' => 'IN',
630 'val' => array( 'reply', 'report' ),
631 ),
632 array(
633 'slug' => 'is_active',
634 'compare' => '=',
635 'val' => '1',
636 ),
637 ),
638 'orderby' => 'id',
639 'order' => 'DESC',
640 'items_per_page' => 1,
641 );
642 $threads = WPSC_Thread::find( $filters );
643
644 return isset( $threads['results'][0] ) ? $threads['results'][0] : false;
645 }
646
647 /**
648 * Return last note of the ticket.
649 *
650 * @return WPSC_Thread|boolean
651 */
652 public function get_last_note() {
653
654 $filters = array(
655 'meta_query' => array(
656 'relation' => 'AND',
657 array(
658 'slug' => 'ticket',
659 'compare' => '=',
660 'val' => $this->id,
661 ),
662 array(
663 'slug' => 'type',
664 'compare' => '=',
665 'val' => 'note',
666 ),
667 array(
668 'slug' => 'is_active',
669 'compare' => '=',
670 'val' => '1',
671 ),
672 ),
673 'orderby' => 'id',
674 'order' => 'DESC',
675 'items_per_page' => 1,
676 );
677 $threads = WPSC_Thread::find( $filters );
678
679 return isset( $threads['results'][0] ) ? $threads['results'][0] : false;
680 }
681
682 /**
683 * Return array of agents allowed to view this ticket
684 */
685 public function get_current_read_permission_agents() {
686
687 $agents = array();
688 $agent_roles = get_option( 'wpsc-agent-roles' );
689
690 // check customer whether he is an agent.
691 if ( $this->customer->user ) {
692 $agent = WPSC_Agent::get_by_user_id( $this->customer->user->ID );
693 if ( $agent->id && $agent->is_active ) {
694 $agents[] = $agent;
695 }
696 }
697
698 // unassigned.
699 if ( ! $this->assigned_agent ) {
700
701 $applicable_roles = array();
702 foreach ( $agent_roles as $key => $role ) {
703 if ( $role['caps']['view-unassigned'] ) {
704 $applicable_roles[] = $key;
705 }
706 }
707 $temp_agents = WPSC_Agent::find(
708 array(
709 'items_per_page' => 0,
710 'meta_query' => array(
711 'relation' => 'AND',
712 array(
713 'slug' => 'role',
714 'compare' => 'IN',
715 'val' => $applicable_roles,
716 ),
717 array(
718 'slug' => 'is_active',
719 'compare' => '=',
720 'val' => 1,
721 ),
722 array(
723 'slug' => 'is_agentgroup',
724 'compare' => '=',
725 'val' => 0,
726 ),
727 ),
728 )
729 )['results'];
730 if ( $temp_agents ) {
731 $agents = array_merge( $agents, $temp_agents );
732 }
733 } else { // assigned to agents.
734
735 // assign to me.
736 foreach ( $this->assigned_agent as $agent ) {
737
738 if ( $agent->is_agentgroup ) {
739 continue;
740 }
741 if ( $agent_roles[ $agent->role ]['caps']['view-assigned-me'] ) {
742 $agents[] = $agent;
743 }
744 }
745
746 // assign to other.
747 $applicable_roles = array();
748 foreach ( $agent_roles as $key => $role ) {
749 if ( $role['caps']['view-assigned-others'] ) {
750 $applicable_roles[] = $key;
751 }
752 }
753 $temp_agents = WPSC_Agent::find(
754 array(
755 'items_per_page' => 0,
756 'meta_query' => array(
757 'relation' => 'AND',
758 array(
759 'slug' => 'role',
760 'compare' => 'IN',
761 'val' => $applicable_roles,
762 ),
763 array(
764 'slug' => 'is_active',
765 'compare' => '=',
766 'val' => 1,
767 ),
768 array(
769 'slug' => 'is_agentgroup',
770 'compare' => '=',
771 'val' => 0,
772 ),
773 ),
774 )
775 )['results'];
776 if ( $temp_agents ) {
777 $agents = array_merge( $agents, $temp_agents );
778 }
779
780 // filter for agentgroups.
781 $agents = apply_filters( 'wpsc_get_current_read_permission_agents', $agents, $this );
782 }
783
784 $temp_agents = array();
785 foreach ( $agents as $agent ) {
786 if ( ! isset( $temp_agents[ $agent->id ] ) ) {
787 $temp_agents[ $agent->id ] = $agent;
788 }
789 }
790
791 return $temp_agents;
792 }
793
794 /**
795 * Return agents associated to this ticket previously with read permission
796 *
797 * @param array $prev - array of agent objects.
798 * @return array
799 */
800 public function get_prev_read_permission_agents( $prev ) {
801
802 $agents = array();
803 $agent_roles = get_option( 'wpsc-agent-roles' );
804
805 // unassigned.
806 if ( ! $prev ) {
807
808 $applicable_roles = array();
809 foreach ( $agent_roles as $key => $role ) {
810 if ( $role['caps']['view-unassigned'] ) {
811 $applicable_roles[] = $key;
812 }
813 }
814 $temp_agents = WPSC_Agent::find(
815 array(
816 'items_per_page' => 0,
817 'meta_query' => array(
818 'relation' => 'AND',
819 array(
820 'slug' => 'role',
821 'compare' => 'IN',
822 'val' => $applicable_roles,
823 ),
824 array(
825 'slug' => 'is_active',
826 'compare' => '=',
827 'val' => 1,
828 ),
829 array(
830 'slug' => 'is_agentgroup',
831 'compare' => '=',
832 'val' => 0,
833 ),
834 ),
835 )
836 )['results'];
837 if ( $temp_agents ) {
838 $agents = array_merge( $agents, $temp_agents );
839 }
840 } else {
841
842 // assign to me.
843 foreach ( $prev as $agent ) {
844 if ( $agent->is_agentgroup ) {
845 continue;
846 }
847 if ( $agent_roles[ $agent->role ]['caps']['view-assigned-me'] ) {
848 $agents[] = $agent;
849 }
850 }
851
852 // assign to other.
853 $applicable_roles = array();
854 foreach ( $agent_roles as $key => $role ) {
855 if ( $role['caps']['view-assigned-others'] ) {
856 $applicable_roles[] = $key;
857 }
858 }
859 $temp_agents = WPSC_Agent::find(
860 array(
861 'items_per_page' => 0,
862 'meta_query' => array(
863 'relation' => 'AND',
864 array(
865 'slug' => 'role',
866 'compare' => 'IN',
867 'val' => $applicable_roles,
868 ),
869 array(
870 'slug' => 'is_active',
871 'compare' => '=',
872 'val' => 1,
873 ),
874 array(
875 'slug' => 'is_agentgroup',
876 'compare' => '=',
877 'val' => 0,
878 ),
879 ),
880 )
881 )['results'];
882 if ( $temp_agents ) {
883 $agents = array_merge( $agents, $temp_agents );
884 }
885
886 // filter for agentgroups.
887 $agents = apply_filters( 'wpsc_get_prev_read_permission_agents', $agents, $this );
888 }
889
890 $temp_agents = array();
891 foreach ( $agents as $agent ) {
892 if ( ! isset( $temp_agents[ $agent->id ] ) ) {
893 $temp_agents[ $agent->id ] = $agent;
894 }
895 }
896
897 return $temp_agents;
898 }
899
900 /**
901 * Get ticket id range
902 *
903 * @return array start id and end id of random number
904 */
905 public static function get_ticket_id_range() {
906
907 $ad_settings = get_option( 'wpsc-ms-advanced-settings' );
908 $length = $ad_settings['random-id-length'];
909
910 $start = '1';
911 for ( $i = 1; $i < $length; $i++ ) {
912 $start .= '0';
913 }
914
915 $end = '9';
916 for ( $i = 1; $i < $length; $i++ ) {
917 $end .= '9';
918 }
919
920 return array(
921 'start_range' => intval( $start ),
922 'end_range' => intval( $end ),
923 );
924 }
925
926 /**
927 * Get ticket url
928 */
929 public function get_url() {
930
931 $page_settings = get_option( 'wpsc-gs-page-settings' );
932 $ticket_url = '';
933
934 if ( ! $this->auth_code ) {
935 $this->auth_code = WPSC_Functions::get_random_string();
936 $this->save();
937 }
938
939 // support page.
940 if ( $page_settings['ticket-url-page'] == 'support-page' && $page_settings['support-page'] ) {
941 $url = get_permalink( $page_settings['support-page'] );
942 $ticket_url = add_query_arg(
943 array(
944 'wpsc-section' => 'ticket-list',
945 'ticket-id' => $this->id,
946 'auth-code' => $this->auth_code,
947 ),
948 $url
949 );
950 }
951
952 // open ticket page.
953 if ( $page_settings['ticket-url-page'] == 'open-ticket-page' && $page_settings['open-ticket-page'] ) {
954 $url = get_permalink( $page_settings['open-ticket-page'] );
955 $ticket_url = add_query_arg(
956 array(
957 'ticket-id' => $this->id,
958 'auth-code' => $this->auth_code,
959 ),
960 $url
961 );
962 }
963
964 return apply_filters( 'wpsc_get_ticket_url', $ticket_url, $this );
965 }
966
967 /**
968 * Get description thread model object
969 *
970 * @return WPSC_Thread
971 */
972 public function get_description_thread() {
973
974 $results = WPSC_Thread::find(
975 array(
976 'meta_query' => array(
977 'relation' => 'AND',
978 array(
979 'slug' => 'ticket',
980 'compare' => '=',
981 'val' => $this->id,
982 ),
983 array(
984 'slug' => 'type',
985 'compare' => '=',
986 'val' => 'report',
987 ),
988 ),
989 )
990 )['results'];
991
992 return $results ? $results[0] : false;
993 }
994 }
995 endif;
996
997 WPSC_Ticket::init();
998