PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.5.4
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.5.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
← All changes | includes/class-wpsc-functions.php +1488 -1814 2.3.1 → 3.5.4 View file →
@@ -1,1848 +1,1522 @@
1 1 <?php
2 2 if ( ! defined( 'ABSPATH' ) ) {
3 - exit; // Exit if accessed directly
3 + exit; // Exit if accessed directly!
4 4 }
5 5
6 6 if ( ! class_exists( 'WPSC_Functions' ) ) :
7 -
8 - final class WPSC_Functions {
9 -
10 - // Return custom field types. Developers, please make sure hooked custom field type index should start from 51. 1-50 is reserved for core product.
11 - function get_custom_field_types(){
12 - $custom_field_types = array(
13 - 1 => array(
14 - 'label' => __('Text Field','supportcandy'),
15 - 'has_options' => 0,
16 - 'allow_ticket_list' => 1,
17 - 'allow_ticket_filter' => 1,
18 - 'allow_orderby' => 1,
19 - 'ticket_filter_type' => 'string'
20 - ),
21 - 2 => array(
22 - 'label' => __('Drop Down','supportcandy'),
23 - 'has_options' => 1,
24 - 'allow_ticket_list' => 1,
25 - 'allow_ticket_filter' => 1,
26 - 'allow_orderby' => 1,
27 - 'ticket_filter_type' => 'string'
28 - ),
29 - 3 => array(
30 - 'label' => __('Checkbox','supportcandy'),
31 - 'has_options' => 1,
32 - 'allow_ticket_list' => 1,
33 - 'allow_ticket_filter' => 1,
34 - 'allow_orderby' => 1,
35 - 'ticket_filter_type' => 'string'
36 - ),
37 - 4 => array(
38 - 'label' => __('Radio Button','supportcandy'),
39 - 'has_options' => 1,
40 - 'allow_ticket_list' => 1,
41 - 'allow_ticket_filter' => 1,
42 - 'allow_orderby' => 1,
43 - 'ticket_filter_type' => 'string'
44 - ),
45 - 5 => array(
46 - 'label' => __('Textarea','supportcandy'),
47 - 'has_options' => 0,
48 - 'allow_ticket_list' => 0,
49 - 'allow_ticket_filter' => 0,
50 - 'allow_orderby' => 1,
51 - 'ticket_filter_type' => 'string'
52 - ),
53 - 6 => array(
54 - 'label' => __('Date','supportcandy'),
55 - 'has_options' => 0,
56 - 'allow_ticket_list' => 1,
57 - 'allow_ticket_filter' => 1,
58 - 'allow_orderby' => 1,
59 - 'ticket_filter_type' => 'date'
60 - ),
61 - 7 => array(
62 - 'label' => __('URL','supportcandy'),
63 - 'has_options' => 0,
64 - 'allow_ticket_list' => 0,
65 - 'allow_ticket_filter' => 1,
66 - 'allow_orderby' => 0,
67 - 'ticket_filter_type' => 'string'
68 - ),
69 - 8 => array(
70 - 'label' => __('Email','supportcandy'),
71 - 'has_options' => 0,
72 - 'allow_ticket_list' => 1,
73 - 'allow_ticket_filter' => 1,
74 - 'allow_orderby' => 1,
75 - 'ticket_filter_type' => 'string'
76 - ),
77 - 9 => array(
78 - 'label' => __('Number Only','supportcandy'),
79 - 'has_options' => 0,
80 - 'allow_ticket_list' => 1,
81 - 'allow_ticket_filter' => 1,
82 - 'allow_orderby' => 1,
83 - 'ticket_filter_type' => 'number'
84 - ),
85 - 10 => array(
86 - 'label' => __('File Attachment','supportcandy'),
87 - 'has_options' => 0,
88 - 'allow_ticket_list' => 0,
89 - 'allow_ticket_filter' => 0,
90 - 'allow_orderby' => 0,
91 - 'ticket_filter_type' => 'string'
92 - ),
93 - 18 => array(
94 - 'label' => __('Date Time','supportcandy'),
95 - 'has_options' => 0,
96 - 'allow_ticket_list' => 1,
97 - 'allow_ticket_filter' => 1,
98 - 'allow_orderby' => 1,
99 - 'ticket_filter_type' => 'datetime'
100 - ),
101 - 21 => array(
102 - 'label' => __('Time','supportcandy'),
103 - 'has_options' => 0,
104 - 'allow_ticket_list' => 1,
105 - 'allow_ticket_filter' => 1,
106 - 'allow_orderby' => 1,
107 - 'ticket_filter_type' => 'time'
108 - ),
109 - 22 => array(
110 - 'label' => __('HTML','supportcandy'),
111 - 'has_options' => 0,
112 - 'allow_ticket_list' => 0,
113 - 'allow_ticket_filter' => 0,
114 - 'allow_orderby' => 0,
115 - 'ticket_filter_type' => 'string'
116 - ),
117 - );
118 - return apply_filters('wpsc_custom_field_types',$custom_field_types);
119 - }
120 -
121 - // Calender date format to datetime conversion so that it can be compared in query
122 - function calenderDateFormatToDateTime($date){
123 - if (!$date) return '';
124 - $datetime = explode(' ',$date);
125 - $calender_format = get_option('wpsc_calender_date_format');
126 - $y = ''; $m = ''; $d = '';
127 - $calender_format = explode('-',$calender_format);
128 - $date = explode('-',$date);
129 - foreach ($calender_format as $key => $value) {
130 - switch ($value) {
131 - case 'dd':
132 - $d = $date[$key];
133 - break;
134 -
135 - case 'mm':
136 - $m = $date[$key];
137 - break;
138 -
139 - case 'yy':
140 - $y = $date[$key];
141 - break;
142 - }
143 - }
144 - if (!$y||!$m||!$d) {
145 - return '';
146 - }
147 - if(array_key_exists('1',$datetime)){
148 - return $y.'-'.$m.'-'.$d;
149 - } else{
150 - return $y.'-'.$m.'-'.$d.' 00:00:00';
151 - }
152 - }
153 -
154 - // Calender date format to datetime conversion so that it can be compared in query
155 - function datetimeToCalenderFormat($datetime){
156 - if(!$datetime) return '';
157 - $calender_format = get_option('wpsc_calender_date_format');
158 - $calender_format = explode('-',$calender_format);
159 - $arr = array();
160 - foreach ($calender_format as $key => $value) {
161 - switch ($value) {
162 - case 'dd':
163 - $arr[]='d';
164 - break;
165 - case 'mm':
166 - $arr[]='m';
167 - break;
168 - case 'yy':
169 - $arr[]='Y';
170 - break;
171 - }
172 - }
173 - $d_format = implode('-',$arr);
174 - $date=date_create($datetime);
175 - return date_format($date, $d_format);
176 - }
177 -
178 - // Get current agent permissions.
179 - function get_current_agent_permissions(){
180 - global $current_user;
181 - if (is_super_admin($current_user->ID) && is_multisite()) {
182 - return $this->get_all_permission_array();
183 - }
184 - $role_id = get_user_option('wpsc_agent_role');
185 - $agent_role = get_option('wpsc_agent_role');
186 - return $agent_role[$role_id];
187 - }
188 -
189 - // Allow all permission response
190 - function get_all_permission_array(){
191 - $agent_role = get_option('wpsc_agent_role');
192 - $permissions = array();
193 - foreach ($agent_role[1] as $key => $value) {
194 - if ($key=='label') continue;
195 - $permissions[$key] = 1;
196 - }
197 - return $permissions;
198 - }
199 -
200 - // Get default ticket filter labels
201 - function get_ticket_filter_labels(){
202 - $labels = array(
203 - 'all' => array(
204 - 'label' => __('All Tickets','supportcandy'),
205 - 'has_badge' => 0,
206 - 'visibility' => 'both',
207 - ),
208 - 'unresolved_agent' => array(
209 - 'label' => __('Unresolved','supportcandy'),
210 - 'has_badge' => 1,
211 - 'visibility' => 'agent',
212 - ),
213 - 'unresolved_customer' => array(
214 - 'label' => __('Unresolved','supportcandy'),
215 - 'has_badge' => 0,
216 - 'visibility' => 'customer',
217 - ),
218 - 'unassigned' => array(
219 - 'label' => __('Unassigned','supportcandy'),
220 - 'has_badge' => 0,
221 - 'visibility' => 'agent',
222 - ),
223 - 'mine' => array(
224 - 'label' => __('Mine','supportcandy'),
225 - 'has_badge' => 0,
226 - 'visibility' => 'agent',
227 - ),
228 - 'closed' => array(
229 - 'label' => __('Closed','supportcandy'),
230 - 'has_badge' => 0,
231 - 'visibility' => 'both',
232 - ),
233 - 'deleted' => array(
234 - 'label' => __('Deleted','supportcandy'),
235 - 'has_badge' => 0,
236 - 'visibility' => 'agent',
237 - ),
238 - );
239 -
240 - return apply_filters('ticket_filter_labels',$labels);
241 - }
242 -
243 - // Get default user filter
244 - function get_default_filter(){
245 - global $current_user;
246 - if ($current_user->has_cap('wpsc_agent')) {
247 - $order_key = get_option('wpsc_tl_agent_orderby');
248 - $order = get_option('wpsc_tl_agent_orderby_order');
249 - } else {
250 - $order_key = get_option('wpsc_tl_customer_orderby');
251 - $order = get_option('wpsc_tl_customer_orderby_order');
252 - }
253 - // check current user has default filter is set or not
254 - $blog_id = get_current_blog_id();
255 - $default_filter = get_user_meta($current_user->ID,$blog_id.'_wpsc_user_default_filter',true);
256 - $default_filter = ( $current_user->has_cap('wpsc_agent') && strlen($default_filter) )? $default_filter: 'all';
257 - if(is_numeric($default_filter) && ((int)$default_filter) >= 0 ){
258 - $saved_filters = get_user_meta($current_user->ID, $blog_id.'_wpsc_filter',true);
259 - $saved_filters = $saved_filters ? $saved_filters : array();
260 - $filter = $saved_filters[$default_filter];
261 - }else {
262 - $filter = array(
263 - 'label' => $default_filter,
264 - 'query' => $this->get_default_filter_query($default_filter),
265 - 'orderby' => $order_key,
266 - 'order' => $order,
267 - 'page' => 1,
268 - 'custom_filter' => array(
269 - 's' => '',
270 - )
271 - );
272 - }
273 7
274 - return $filter;
275 - }
276 -
277 - // Get current user filter
278 - function get_current_filter(){
279 - $filter = isset($_COOKIE['wpsc_ticket_filter']) ? $_COOKIE['wpsc_ticket_filter'] : '';
280 - if (!$filter) {
281 - $filter = $this->get_default_filter();
282 - } else {
283 - $filter = json_decode(stripslashes($filter),true);
284 - }
285 - return $filter;
286 - }
287 -
288 - // Return default filter query
289 - function get_default_filter_query( $label_key ){
290 -
291 - global $current_user;
292 -
293 - $query = array();
8 + final class WPSC_Functions {
294 9
295 - switch ($label_key) {
296 - case 'all':
297 - case 'deleted':
298 - $query = apply_filters('wpsc_filter_label_all', $query, $label_key);
299 - break;
300 -
301 - case 'unresolved_agent':
302 - $unresolved_agent = get_option('wpsc_tl_agent_unresolve_statuses');
303 - $query[] = array(
304 - 'key' => 'ticket_status',
305 - 'value' => $unresolved_agent,
306 - 'compare' => 'IN'
307 - );
308 - $query = apply_filters('wpsc_filter_label_unresolved_agent', $query, $label_key);
309 - break;
310 -
311 - case 'unresolved_customer':
312 - $unresolved_customer = get_option('wpsc_tl_customer_unresolve_statuses');
313 - $query[] = array(
314 - 'key' => 'ticket_status',
315 - 'value' => $unresolved_customer,
316 - 'compare' => 'IN'
317 - );
318 - $query = apply_filters('wpsc_filter_label_unresolved_customer', $query, $label_key);
319 - break;
320 -
321 - case 'unassigned':
322 - $close_status = get_option( 'wpsc_close_ticket_group');
323 -
324 - $query[] = array(
325 - 'relation' => 'AND',
326 - array(
327 - 'key' => 'ticket_status',
328 - 'value' => $close_status,
329 - 'compare' => 'NOT IN',
330 - ),
331 - array(
332 - 'key' => 'assigned_agent',
333 - 'value' => 0,
334 - 'compare' => '='
335 - )
336 - );
10 + /**
11 + * Referance classes. Used to provide objects on runtime.
12 + *
13 + * @var string
14 + */
15 + public static $ref_classes;
337 16
338 - $query = apply_filters('wpsc_filter_label_unassigned', $query, $label_key);
339 - break;
340 -
341 - case 'mine':
342 - $agents = get_terms([
343 - 'taxonomy' => 'wpsc_agents',
344 - 'hide_empty' => false,
345 - 'meta_query' => array(
346 - 'relation' => 'AND',
347 - array(
348 - 'key' => 'user_id',
349 - 'value' => $current_user->ID,
350 - 'compare' => '='
351 - )
352 - ),
353 - ]);
354 -
355 - $close_status = get_option( 'wpsc_close_ticket_group');
356 -
357 - if($agents){
358 - $query[] = array(
359 - 'relation' => 'AND',
360 - array(
361 - 'key' => 'ticket_status',
362 - 'value' => $close_status,
363 - 'compare' => 'NOT IN',
364 - )
365 - );
366 - }
367 -
368 - $query = apply_filters('wpsc_filter_label_mine', $query, $label_key);
369 - break;
17 + /**
18 + * Initialize class
19 + */
20 + public static function init() {
370 21
371 - case 'closed':
372 - $close_status = get_option( 'wpsc_close_ticket_group');
373 - $query[] = array(
374 - 'key' => 'ticket_status',
375 - 'value' => $close_status,
376 - 'compare' => '=',
377 - 'compare' => 'IN'
378 - );
379 - $query = apply_filters('wpsc_filter_label_closed', $query, $label_key);
380 - break;
381 -
382 - default:
383 - $query = apply_filters('wpsc_filter_label_default', $query, $label_key );
384 - break;
385 - }
386 - return $query;
387 -
388 - }
389 -
390 - // Get sort type for current orderby field
391 - function get_field_sort_type($field_slug){
392 - $term = get_term_by( 'slug', $field_slug, 'wpsc_ticket_custom_fields');
393 - $ticket_filter_type = get_term_meta($term->term_id,'wpsc_ticket_filter_type',true);
394 - switch ($ticket_filter_type) {
395 - case 'number':
396 - $sort_type = 'meta_value_num';
397 - break;
398 -
399 - case 'date':
400 - case 'datetime':
401 - case 'string':
402 - $sort_type = 'meta_value';
403 - break;
404 - }
405 - return apply_filters( 'wpsc_field_sort_type', $sort_type, $ticket_filter_type, $term );
406 - }
407 -
408 - // Get post status
409 - function get_post_status($filter){
410 - $post_status = $filter['label'] == 'deleted' ? 'trash' : 'publish';
411 - return apply_filters( 'wpsc_post_status', $post_status, $filter );
412 - }
413 -
414 - // Array sanitization
415 - function sanitize_array($array) {
416 - foreach ( $array as $key => $value ) {
417 - if ( is_array( $value ) ) {
418 - $value = $this->sanitize_array($value);
419 - }
420 - else {
421 - $value = sanitize_text_field( $value );
422 - }
423 - }
424 - return $array;
425 - }
426 -
427 - // Get label for ticket field in filter using slug & value
428 - function get_tf_value_filter_label($field_slug,$val){
429 - switch ($field_slug) {
430 -
431 - case 'ticket_status':
432 -
433 - $term = get_term_by('id',$val,'wpsc_statuses');
434 - return $term? $term->name : '';
435 - break;
436 -
437 - case 'ticket_category':
438 -
439 - $term = get_term_by('id',$val,'wpsc_categories');
440 - return $term? $term->name : '';
441 - break;
442 -
443 - case 'ticket_priority':
444 -
445 - $term = get_term_by('id',$val,'wpsc_priorities');
446 - return $term? $term->name : '';
447 - break;
448 -
449 - case 'ticket_widget':
450 -
451 - $term = get_term_by('id',$val,'wpsc_ticket_widget');
452 - return $term? $term->name : '';
453 - break;
454 -
455 - case 'assigned_agent':
456 - case 'agent_created':
457 -
458 - if($val==0) return __('None');
459 - $term = get_term_by('id',$val,'wpsc_agents');
460 - if($term){
461 - $label = get_term_meta($term->term_id,'label',true);
462 - return $label;
463 - } else {
464 - return '';
465 - }
466 - break;
467 -
468 - case 'user_type':
469 -
470 - if ($val == "user") {
471 - $label = __('User','supportcandy');
472 - return $label;
473 - } elseif ($val == "guest") {
474 - $label = __('Guest','supportcandy');
475 - return $label;
476 - }
477 -
478 - break;
479 -
480 - default:
481 -
482 - $val = apply_filters('wpsc_filter_val_label',$val,$field_slug);
483 -
484 - return $val;
485 - break;
486 - }
487 - }
488 -
489 - // get time ago format for datetime
490 - function time_elapsed_string($datetime) {
491 - $now = new DateTime;
492 - $ago = new DateTime($datetime);
493 - $diff = $now->diff($ago);
22 + // Load ref classes.
23 + add_action( 'init', array( __CLASS__, 'load_ref_classes' ), 1 );
494 24
495 - $diff->w = floor($diff->d / 7);
496 - $diff->d -= $diff->w * 7;
25 + // Refresh paid customer option when plugins state changes.
26 + add_action( 'activated_plugin', array( __CLASS__, 'update_paid_customer_status_option' ) );
27 + add_action( 'deactivated_plugin', array( __CLASS__, 'update_paid_customer_status_option' ), 99 );
28 + }
497 29
498 - $string = array(
499 - 'y' => __('years','supportcandy'),
500 - 'm' => __('months','supportcandy'),
501 - 'w' => __('weeks','supportcandy'),
502 - 'd' => __('days','supportcandy'),
503 - 'h' => __('hours','supportcandy'),
504 - 'i' => __('minutes','supportcandy'),
505 - 's' => __('seconds','supportcandy'),
506 - );
507 - foreach ($string as $k => &$v) {
508 - if ($diff->$k) {
509 - $v = $diff->$k . ' ' . $v;
510 - } else {
511 - unset($string[$k]);
512 - }
513 - }
30 + /**
31 + * Load ref classes
32 + */
33 + public static function load_ref_classes() {
514 34
515 - $string = array_slice($string, 0, 1);
516 - if($string){
517 - $string = implode(' ', $string);
518 - $string = explode(' ', $string);
519 - $digit = $string[0];
520 - $unit = $string[1];
521 - return sprintf(__("%d %s ago",'supportcandy'),$digit,$unit);
522 - }else if(!$datetime){
523 - return '';
524 - }else {
525 - return __('just now','supportcandy');
526 - }
527 -
528 - }
529 -
530 - function time_elapsed_timestamp($datetime){
531 - $timestamp = '';
532 - if($datetime){
533 - $wpsc_thread_date_time_format = get_option('wpsc_thread_date_time_format');
534 - $timestamp = date_i18n( $wpsc_thread_date_time_format, strtotime( get_date_from_gmt($datetime, 'Y-m-d H:i:s') ) );
535 - }
536 - return $timestamp;
537 - }
538 -
539 - function assign_agent($ticket_id, $agents){
540 - global $wpscfunction,$wpdb;
541 - $prev_assigned = $wpscfunction->get_ticket_meta($ticket_id,'assigned_agent');
542 -
543 - $wpscfunction->delete_ticket_meta($ticket_id,'prev_assigned_agent');
35 + self::$ref_classes = apply_filters( 'wpsc_load_ref_classes', array() );
36 + }
544 37
545 - foreach($prev_assigned as $assign_agent){
546 - $wpscfunction->add_ticket_meta($ticket_id,'prev_assigned_agent',$assign_agent);
547 - }
38 + /**
39 + * Return an object for ref class
40 + *
41 + * @param string $ref_class - reference class.
42 + * @param string $value - value.
43 + * @return object
44 + */
45 + public static function get_object( $ref_class, $value ) {
548 46
549 - $wpscfunction->delete_ticket_meta($ticket_id,'assigned_agent');
550 - if($agents){
551 - foreach($agents as $agent){
552 - $wpscfunction->add_ticket_meta($ticket_id,'assigned_agent',$agent);
553 - }
554 - }
555 - else{
556 - $wpscfunction->add_ticket_meta($ticket_id,'assigned_agent',0);
557 - }
558 - do_action('wpsc_set_assign_agent', $ticket_id, $agents, $prev_assigned);
559 - }
560 -
561 - function change_status($ticket_id,$status_id){
562 - global $wpscfunction,$wpdb;
563 - $prev_status = $wpscfunction->get_ticket_fields($ticket_id,'ticket_status');
564 - $values=array(
565 - 'ticket_status'=>$status_id
566 - );
567 - $wpdb->update($wpdb->prefix.'wpsc_ticket', $values, array('id'=>$ticket_id));
568 -
569 - $wpsc_close_ticket_status = get_option('wpsc_close_ticket_status');
570 - if ($wpsc_close_ticket_status == $status_id){
571 - $add_close_date = $wpscfunction->get_ticket_meta($ticket_id, 'date_closed');
572 - if(!$add_close_date){
573 - $wpscfunction->add_ticket_meta($ticket_id, 'date_closed', date("Y-m-d H:i:s"));
574 - }
575 - else {
576 - $wpscfunction->update_ticket_meta($ticket_id, 'date_closed',array('meta_value' => date("Y-m-d H:i:s")));
577 - }
578 - }else{
579 - $wpscfunction->delete_ticket_meta($ticket_id ,'date_closed');
580 - }
581 -
582 - do_action('wpsc_set_change_status', $ticket_id, $status_id, $prev_status);
583 -
584 - }
585 -
586 - function change_category($ticket_id,$category_id){
587 - global $wpscfunction,$wpdb;
588 - $prev_cat = $wpscfunction->get_ticket_fields($ticket_id,'ticket_category');
589 - $values = array(
590 - 'ticket_category'=>$category_id
591 - );
592 - $wpdb->update($wpdb->prefix.'wpsc_ticket', $values, array('id' =>$ticket_id));
593 - do_action('wpsc_set_change_category',$ticket_id,$category_id,$prev_cat);
594 - }
595 -
596 - function change_priority($ticket_id,$priority_id){
597 - global $wpscfunction,$wpdb;
598 - $prev_priority = $wpscfunction->get_ticket_fields($ticket_id,'ticket_priority');
599 - $values=array(
600 - 'ticket_priority'=>$priority_id
601 - );
602 - $wpdb->update($wpdb->prefix.'wpsc_ticket', $values, array('id' =>$ticket_id));
603 - do_action('wpsc_set_change_priority', $ticket_id, $priority_id, $prev_priority);
604 - }
605 -
606 - function change_raised_by($ticket_id,$name,$email){
607 - global $wpscfunction,$wpdb;
608 - $prev_name = $wpscfunction->get_ticket_fields($ticket_id,'customer_name');
609 - $values = array(
610 - 'customer_name'=> $name,
611 - 'customer_email' => $email
612 - );
613 - $wpdb->update($wpdb->prefix.'wpsc_ticket', $values, array('customer_name'=>$prev_name,'id'=>$ticket_id));
614 - do_action('wpsc_set_change_raised_by', $ticket_id, $name, $email,$prev_name);
615 - }
616 -
617 - /**
618 - * Change ticket custom field
619 - */
620 - function change_field( $ticket_id, $field_slug, $field_val ){
621 -
622 - global $wpscfunction, $wpdb;
623 -
624 - if ( $field_val === '' ) {
625 -
626 - $prev_field_val = $wpscfunction->get_ticket_meta($ticket_id,$field_slug);
627 - $wpscfunction->delete_ticket_meta($ticket_id,$field_slug);
628 -
629 - } else if( is_array($field_val) ){
630 -
631 - $prev_field_val = $wpscfunction->get_ticket_meta($ticket_id,$field_slug);
632 - $wpscfunction->delete_ticket_meta($ticket_id,$field_slug);
633 - foreach ($field_val as $value) {
634 - $wpscfunction->add_ticket_meta($ticket_id,$field_slug,$value);
635 - }
636 -
637 - } else {
638 -
639 - $term = get_term_by('slug',$field_slug,'wpsc_ticket_custom_fields');
640 - $wpsc_tf_type = get_term_meta( $term->term_id, 'wpsc_tf_type',true);
641 - $prev_field_val = $wpscfunction->get_ticket_meta($ticket_id,$field_slug,true);
642 -
643 - $values = array(
644 - 'meta_value' => $field_val,
645 - );
646 -
647 - $ticket_field = $wpdb->get_var("SELECT meta_key FROM {$wpdb->prefix}wpsc_ticketmeta WHERE ticket_id='$ticket_id' AND meta_key = '$field_slug'");
648 -
649 - if(!$ticket_field){
650 - $wpdb->insert( $wpdb->prefix . 'wpsc_ticketmeta',
651 - array(
652 - 'ticket_id' => $ticket_id,
653 - 'meta_key' => $field_slug,
654 - 'meta_value' => $field_val
655 - ));
656 - }
657 -
658 - $wpscfunction->update_ticket_meta($ticket_id,$field_slug,$values);
659 -
660 - }
661 -
662 - do_action( 'wpsc_set_change_fields', $ticket_id, $field_slug, $field_val, $prev_field_val );
663 -
664 - }
665 -
666 - function delete_tickets($ticket_id){
667 - global $wpdb;
668 -
669 - $values = array(
670 - 'active' => '0'
671 - );
672 - $wpdb->update($wpdb->prefix.'wpsc_ticket',$values,array('id'=>$ticket_id));
673 - do_action('wpsc_set_delete_ticket',$ticket_id);
674 - }
675 -
676 - // Get post id for ticket id
677 - function get_ticket_post_id($ticket_id){
678 - $posts = get_posts(array(
679 - 'post_type' => 'wpsc_ticket',
680 - 'post_status' => array('publish','trash'),
681 - 'meta_query' => array(
682 - 'relation' => 'AND',
683 - array(
684 - 'key' => 'ticket_id',
685 - 'value' => $ticket_id,
686 - 'compare' => '='
687 - ),
688 - ),
689 - ));
690 - $ticket_post = count($posts) ? $posts[0] : array();
691 - $post_id = $ticket_post ? $ticket_post->ID : 0;
692 - return $post_id;
693 - }
694 -
695 - // Get status name by status id
696 - function get_status_name($status_id){
697 - $wpsc_custom_status_localize = get_option('wpsc_custom_status_localize');
698 - return $wpsc_custom_status_localize['custom_status_'.$status_id];
699 - }
700 -
701 - // Get category name by category id
702 - function get_category_name($category_id){
703 - $wpsc_custom_category_localize = get_option('wpsc_custom_category_localize');
704 - return $wpsc_custom_category_localize['custom_category_'.$category_id];
705 - }
706 -
707 - // Get priority name by category id
708 - function get_priority_name($priority_id){
709 - $wpsc_custom_priority_localize = get_option('wpsc_custom_priority_localize');
710 - return $wpsc_custom_priority_localize['custom_priority_'.$priority_id];
711 - }
712 -
713 - // Get ticket_widget name by ticket_widget id
714 - function get_ticket_widget_name($ticket_widget_id){
715 - $ticket_widget = get_term_by('id',$ticket_widget_id,'wpsc_ticket_widget');
716 - return $ticket_widget->name;
717 - }
718 -
719 - // Get ticket description
720 - function get_ticket_description($ticket_id){
721 - $threads = get_posts(array(
722 - 'post_type' => 'wpsc_ticket_thread',
723 - 'post_status' => 'publish',
724 - 'meta_query' => array(
725 - 'relation' => 'AND',
726 - array(
727 - 'key' => 'thread_type',
728 - 'value' => 'report',
729 - 'compare' => '='
730 - ),
731 - array(
732 - 'key' => 'ticket_id',
733 - 'value' => $ticket_id,
734 - 'compare' => '='
735 - ),
736 - ),
737 - ));
738 - $description = $threads ? $threads[0]->post_content : '';
739 - $thread_id = $threads ? $threads[0]->ID : 0;
740 - $ticket_report = array();
741 -
742 - if ($thread_id) {
743 - $ticket_report = array(
744 - 'description' => $description,
745 - 'thread_id' => $thread_id,
746 - );
747 - } else {
748 - $ticket_report = array(
749 - 'description' => $description,
750 - );
751 - }
752 - return $ticket_report;
753 - }
754 -
755 - // Get last reply
756 - function get_last_reply($ticket_id){
757 - $threads = get_posts(array(
758 - 'post_type' => 'wpsc_ticket_thread',
759 - 'post_status' => 'publish',
760 - 'posts_per_page' => '1',
761 - 'orderby' => 'date',
762 - 'order' => 'DESC',
763 - 'meta_query' => array(
764 - 'relation' => 'AND',
765 - array(
766 - 'key' => 'ticket_id',
767 - 'value' => $ticket_id,
768 - 'compare' => '='
769 - ),
770 - array(
771 - 'key' => 'thread_type',
772 - 'value' => 'reply',
773 - 'compare' => '='
774 - ),
775 - ),
776 - ));
777 - $thread_id = $threads ? $threads[0]->ID : 0;
778 - if ($thread_id) {
779 - $last_reply = array(
780 - 'user_name' => get_post_meta($thread_id,'customer_name',true),
781 - 'user_email' => get_post_meta($thread_id,'customer_email',true),
782 - 'description' => $threads[0]->post_content,
783 - 'thread_id' => $thread_id,
784 - );
785 - } else {
786 - $last_reply = array(
787 - 'user_name' => '',
788 - 'user_email' => '',
789 - 'description' => '',
790 - 'thread_id' => $thread_id
791 - );
792 - }
793 - return $last_reply;
794 - }
795 -
796 - // Get last note
797 - function get_last_note($ticket_id){
798 - $threads = get_posts(array(
799 - 'post_type' => 'wpsc_ticket_thread',
800 - 'post_status' => 'publish',
801 - 'posts_per_page' => '1',
802 - 'orderby' => 'date',
803 - 'order' => 'DESC',
804 - 'meta_query' => array(
805 - 'relation' => 'AND',
806 - array(
807 - 'key' => 'ticket_id',
808 - 'value' => $ticket_id,
809 - 'compare' => '='
810 - ),
811 - array(
812 - 'key' => 'thread_type',
813 - 'value' => 'note',
814 - 'compare' => '='
815 - ),
816 - ),
817 - ));
818 - $thread_id = $threads ? $threads[0]->ID : 0;
819 - if ($thread_id) {
820 - $last_note = array(
821 - 'user_name' => get_post_meta($thread_id,'customer_name',true),
822 - 'user_email' => get_post_meta($thread_id,'customer_email',true),
823 - 'description' => $threads[0]->post_content,
824 - 'thread_id' => $thread_id,
825 - );
826 - } else {
827 - $last_note = array(
828 - 'user_name' => '',
829 - 'user_email' => '',
830 - 'description' => '',
831 - 'thread_id' => $thread_id
832 - );
833 - }
834 - return $last_note;
835 - }
836 -
837 - // Get Ticket History
838 - function get_ticket_history($ticket_id){
839 - include WPSC_ABSPATH . 'includes/functions/get_ticket_history.php';
840 - return $ticket_history;
841 - }
842 -
843 - // Get assigned_agent names
844 - function get_assigned_agent_names($ticket_id){
845 - global $wpscfunction;
846 - $assigned_agents = $wpscfunction->get_ticket_meta($ticket_id, 'assigned_agent');
847 - $agent_names = array();
848 - foreach ($assigned_agents as $agent_id) {
849 - $agent_names[] = $this->get_agent_name($agent_id);
850 - }
851 - return implode(', ', $agent_names);
852 - }
853 -
854 - // Get assigned_agent names
855 - function get_assigned_agent_emails($ticket_id){
856 - global $wpscfunction;
857 - $assigned_agents = $wpscfunction->get_ticket_meta($ticket_id,'assigned_agent');
858 - $agent_emails = array();
859 - foreach ($assigned_agents as $agent_id) {
860 - $user_id = get_term_meta($agent_id,'user_id',true);
861 - if($user_id){
862 - $user = get_user_by('id',$user_id);
863 - $agent_emails[] = $user->user_email;
864 - }
865 - }
866 - return apply_filters( 'wpsc_get_assigned_agent_emails', $agent_emails ,$ticket_id);
867 - }
868 -
869 - // Get agent name by id
870 - function get_agent_name($agent_id){
871 - if($agent_id){
872 - return get_term_meta($agent_id,'label', true);
873 - } else {
874 - return __('None','supportcandy');
875 - }
876 - }
877 -
878 - // Submit ticket
879 - function create_ticket($args){
880 - include WPSC_ABSPATH . 'includes/functions/create_ticket.php';
881 - return $ticket_id;
882 - }
883 -
884 - // Submit clone ticket ticket
885 - function create_clone_ticket($args){
886 - include WPSC_ABSPATH . 'includes/functions/create_clone_ticket.php';
887 - return $ticket_id;
888 - }
889 -
890 - // Submit ticket thread
891 - function submit_ticket_thread($args){
892 - global $wpdb;
893 - $thread_id = wp_insert_post(
894 - array(
895 - 'post_type' => 'wpsc_ticket_thread',
896 - 'post_content' => $args['reply_body'],
897 - 'post_status' => 'publish',
898 - )
899 - );
900 - add_post_meta( $thread_id, 'ticket_id', $args['ticket_id'] );
901 - add_post_meta( $thread_id, 'thread_type', $args['thread_type'] );
902 - if(isset($args['reply_source'])){
903 - add_post_meta( $thread_id, 'reply_source', $args['reply_source'] );
904 - }
905 - $customer_name = isset($args['customer_name']) ? $args['customer_name'] : '';
906 - add_post_meta( $thread_id, 'customer_name', $customer_name );
907 - $customer_email = isset($args['customer_email']) ? $args['customer_email'] : '';
908 - add_post_meta( $thread_id, 'customer_email', $customer_email );
909 - $attachments = isset($args['attachments']) ? $args['attachments'] : array();
910 - add_post_meta( $thread_id, 'attachments', $attachments );
911 -
912 - if(isset($args['ip_address'])){
913 - add_post_meta( $thread_id, 'ip_address', $args['ip_address'] );
914 - }
915 -
916 - if(isset($args['os'])){
917 - add_post_meta($thread_id,'os',$args['os']);
918 - }
919 -
920 - if(isset($args['browser'])){
921 - add_post_meta($thread_id,'browser',$args['browser']);
922 - }
923 -
924 - if (isset($args['user_seen'])) {
925 - add_post_meta($thread_id,'user_seen',$args['user_seen']);
926 - }
927 -
928 - $ticket_id = isset($args['ticket_id']) ? $args['ticket_id'] : 0;
929 - $values= array(
930 - 'date_updated' => date("Y-m-d H:i:s"),
931 - 'historyId' => $thread_id,
932 - );
933 - $wpdb->update($wpdb->prefix.'wpsc_ticket',$values,array('id'=>$ticket_id));
934 -
935 - do_action('wpsc_after_submit_thread_request',$args,$thread_id);
47 + $object = null;
936 48
937 - return $thread_id;
938 - }
939 -
940 - // Submit ticket thread
941 - function submit_cloned_ticket_thread($args){
942 - global $wpdb;
943 - $thread_id = wp_insert_post(
944 - array(
945 - 'post_type' => 'wpsc_ticket_thread',
946 - 'post_content' => $args['reply_body'],
947 - 'post_status' => 'publish',
948 - 'post_date' => $args['create_time'],
949 - )
950 - );
951 - add_post_meta( $thread_id, 'ticket_id', $args['ticket_id'] );
952 - add_post_meta( $thread_id, 'thread_type', $args['thread_type'] );
953 - $customer_name = isset($args['customer_name']) ? $args['customer_name'] : '';
954 - add_post_meta( $thread_id, 'customer_name', $customer_name );
955 - $customer_email = isset($args['customer_email']) ? $args['customer_email'] : '';
956 - add_post_meta( $thread_id, 'customer_email', $customer_email );
957 - $attachments = isset($args['attachments']) ? $args['attachments'] : array();
958 - add_post_meta( $thread_id, 'attachments', $attachments );
959 -
960 - if(isset($args['reply_source'])){
961 - add_post_meta( $thread_id, 'reply_source', $args['reply_source'] );
962 - }
963 -
964 - if(isset($args['ip_address'])){
965 - add_post_meta( $thread_id, 'ip_address', $args['ip_address'] );
966 - }
967 -
968 - if(isset($args['os'])){
969 - add_post_meta($thread_id,'os',$args['os']);
970 - }
971 -
972 - if(isset($args['browser'])){
973 - add_post_meta($thread_id,'browser',$args['browser']);
974 - }
975 -
976 - $ticket_id = isset($args['ticket_id']) ? $args['ticket_id'] : 0;
977 - $values= array(
978 - 'date_updated' => date("Y-m-d H:i:s"),
979 - 'historyId' => $thread_id,
980 - );
981 - $wpdb->update($wpdb->prefix.'wpsc_ticket',$values,array('id'=>$ticket_id));
982 - return $thread_id;
983 - }
984 -
985 - // Replace macros
986 - function replace_macro($str,$ticket_id){
987 - include WPSC_ABSPATH . 'includes/functions/replace_macro.php';
988 - return $str;
989 - }
990 -
991 - // Get user agent id
992 - function get_current_user_agent_id(){
993 - global $current_user;
994 - $agents = get_terms([
995 - 'taxonomy' => 'wpsc_agents',
996 - 'hide_empty' => false,
997 - 'meta_query' => array(
998 - 'relation' => 'AND',
999 - array(
1000 - 'key' => 'user_id',
1001 - 'value' => $current_user->ID,
1002 - 'compare' => '='
1003 - )
1004 - ),
1005 - ]);
1006 - if($agents){
1007 - return $agents[0]->term_id;
1008 - } else {
1009 - return 0;
1010 - }
1011 - }
1012 -
1013 - // Check agent permission for wpsc functionality
1014 - function agent_has_permission( $permission, $ticket_id=0 ){
1015 - global $current_user,$wpscfunction;
1016 - $current_agent_id = $this->get_current_user_agent_id();
1017 - if(!$current_agent_id) return false;
1018 - if(!$current_user->has_cap('wpsc_agent')) return false;
1019 - $role_id = get_user_option( 'wpsc_agent_role', $current_user->ID );
1020 - $agent_roles = get_option('wpsc_agent_role');
1021 - $permissions = $agent_roles[$role_id];
1022 - $response = false;
1023 - if ($ticket_id) {
1024 - $assigned_agents = $wpscfunction->get_ticket_meta($ticket_id,'assigned_agent');
1025 - switch ($permission) {
1026 - case 'view_unassigned':
1027 - case 'assign_unassigned':
1028 - case 'reply_unassigned':
1029 - case 'cng_tkt_sts_unassigned':
1030 - case 'cng_tkt_field_unassigned':
1031 - case 'cng_tkt_ao_unassigned':
1032 - case 'cng_tkt_rb_unassigned':
1033 - case 'delete_unassigned':
1034 - case 'view_unassigned_private_note':
1035 - case 'view_unassigned_log':
1036 - case 'edit_delete_unassigned':
1037 - $response = ($permissions[$permission] && in_array(0,$assigned_agents)) ? true : false;
1038 - break;
1039 -
1040 - case 'view_assigned_me':
1041 - case 'assign_assigned_me':
1042 - case 'reply_assigned_me':
1043 - case 'cng_tkt_sts_assigned_me':
1044 - case 'cng_tkt_field_assigned_me':
1045 - case 'cng_tkt_ao_assigned_me':
1046 - case 'cng_tkt_rb_assigned_me':
1047 - case 'delete_assigned_me':
1048 - case 'view_assigned_me_private_note':
1049 - case 'view_assigned_me_log':
1050 - case 'edit_delete_assigned_me':
1051 - $response = ($permissions[$permission] && in_array($current_agent_id,$assigned_agents)) ? true : false;
1052 - break;
1053 -
1054 - case 'view_assigned_others':
1055 - case 'assign_assigned_others':
1056 - case 'reply_assigned_others':
1057 - case 'cng_tkt_sts_assigned_others':
1058 - case 'cng_tkt_field_assigned_others':
1059 - case 'cng_tkt_ao_assigned_others':
1060 - case 'cng_tkt_rb_assigned_others':
1061 - case 'delete_assigned_others':
1062 - case 'view_assigned_others_private_note':
1063 - case 'view_assigned_others_log':
1064 - case 'edit_delete_assigned_others':
1065 - $response = ($permissions[$permission] && !in_array($current_agent_id,$assigned_agents) && !in_array(0,$assigned_agents)) ? true : false;
1066 - break;
1067 - }
1068 - } else {
1069 - $response = ($permissions[$permission]) ? true : false;
1070 - }
1071 - return apply_filters( 'wpsc_agent_has_permission', $response, $permission, $ticket_id );
1072 - }
1073 -
1074 - // User permissions
1075 - function has_permission( $permission, $ticket_id=0 ){
49 + switch ( $ref_class ) {
1076 50
1077 - global $wpscfunction, $current_user;
1078 -
1079 - if(!$current_user->ID) return false;
1080 -
1081 - if(is_super_admin($current_user->ID) && is_multisite()) return true;
1082 -
1083 - $ticket = $wpscfunction->get_ticket($ticket_id);
1084 - $customer_email = $ticket_id ? strtolower($ticket['customer_email']) : '';
1085 - $wpsc_ticket_public_mode = get_option('wpsc_ticket_public_mode');
1086 - $response = false;
1087 - switch ($permission) {
1088 - case 'view_ticket':
1089 - $response = $customer_email == strtolower($current_user->user_email) || $this->agent_has_permission( 'view_unassigned', $ticket_id ) || $this->agent_has_permission( 'view_assigned_me', $ticket_id ) || $this->agent_has_permission( 'view_assigned_others', $ticket_id ) ? true : false;
1090 - break;
1091 -
1092 - case 'assign_agent':
1093 - $response = $this->agent_has_permission( 'assign_unassigned', $ticket_id ) || $this->agent_has_permission( 'assign_assigned_me', $ticket_id ) || $this->agent_has_permission( 'assign_assigned_others', $ticket_id ) ? true : false;
1094 - break;
1095 -
1096 - case 'reply_ticket':
1097 - $response = $customer_email == strtolower($current_user->user_email) || $this->agent_has_permission( 'reply_unassigned', $ticket_id ) || $this->agent_has_permission( 'reply_assigned_me', $ticket_id ) || $this->agent_has_permission( 'reply_assigned_others', $ticket_id ) || (!$current_user->has_cap('wpsc_agent') && $wpsc_ticket_public_mode) ? true : false;
1098 - break;
1099 -
1100 - case 'add_note':
1101 - $response = $this->agent_has_permission( 'view_unassigned_private_note', $ticket_id ) || $this->agent_has_permission( 'view_assigned_me_private_note', $ticket_id ) || $this->agent_has_permission( 'view_assigned_others_private_note', $ticket_id ) ? true : false;
1102 - break;
1103 -
1104 - case 'change_status':
1105 - $response = $this->agent_has_permission( 'cng_tkt_sts_unassigned', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_sts_assigned_me', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_sts_assigned_others', $ticket_id ) ? true : false;
1106 - break;
1107 -
1108 - case 'change_ticket_fields':
1109 - $response = $this->agent_has_permission( 'cng_tkt_field_unassigned', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_field_assigned_me', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_field_assigned_others', $ticket_id ) ? true : false;
1110 - break;
1111 -
1112 - case 'change_agentonly_fields':
1113 - $response = $this->agent_has_permission( 'cng_tkt_ao_unassigned', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_ao_assigned_me', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_ao_assigned_others', $ticket_id ) ? true : false;
1114 - break;
1115 -
1116 - case 'change_raised_by':
1117 - $response = $this->agent_has_permission( 'cng_tkt_rb_unassigned', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_rb_assigned_me', $ticket_id ) || $this->agent_has_permission( 'cng_tkt_rb_assigned_others', $ticket_id ) ? true : false;
1118 - break;
1119 -
1120 - case 'delete_ticket':
1121 - $response = $this->agent_has_permission( 'delete_unassigned', $ticket_id ) || $this->agent_has_permission( 'delete_assigned_me', $ticket_id ) || $this->agent_has_permission( 'delete_assigned_others', $ticket_id ) ? true : false;
1122 - break;
1123 -
1124 - case 'view_note':
1125 - $response = $this->agent_has_permission( 'view_unassigned_private_note', $ticket_id ) || $this->agent_has_permission( 'view_assigned_me_private_note', $ticket_id ) || $this->agent_has_permission( 'view_assigned_others_private_note', $ticket_id ) ? true : false;
1126 - break;
1127 -
1128 - case 'view_log':
1129 - $response = $this->agent_has_permission( 'view_unassigned_log', $ticket_id ) || $this->agent_has_permission( 'view_assigned_me_log', $ticket_id ) || $this->agent_has_permission( 'view_assigned_others_log', $ticket_id ) ? true : false;
1130 - break;
1131 -
1132 - case 'edit_delete_ticket' :
1133 - $response = $this->agent_has_permission('edit_delete_unassigned' ,$ticket_id) || $this->agent_has_permission('edit_delete_assigned_me', $ticket_id) || $this->agent_has_permission('edit_delete_assigned_others', $ticket_id) ? true : false;
1134 - break;
1135 - }
1136 - return apply_filters( 'wpsc_has_permission', $response, $ticket_id, $permission );
1137 - }
1138 -
1139 - // Random string
1140 - function getRandomString($length = 8) {
1141 - $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
1142 - $string = '';
1143 - for ($i = 0; $i < $length; $i++) {
1144 - $string .= $characters[mt_rand(0, strlen($characters) - 1)];
1145 - }
1146 - return $string;
1147 - }
1148 -
1149 - // Email Notification types
1150 - function get_email_notification_types(){
1151 - $notification_types = array(
1152 - 'new_ticket' => __('New Ticket','supportcandy'),
1153 - 'ticket_reply' => __('Ticket Reply','supportcandy'),
1154 - 'change_status' => __('Change Ticket Status','supportcandy'),
1155 - 'assign_agent' => __('Assign Agent','supportcandy'),
1156 - 'delete_ticket' => __('Delete Ticket','supportcandy'),
1157 - 'private_note' => __('Private Note','supportcandy'),
1158 - 'change_category' => __('Change Ticket Category','supportcandy'),
1159 - 'change_priority' => __('Change Ticket Priority','supportcandy')
1160 - );
1161 - return apply_filters('wpsc_en_types',$notification_types);
1162 - }
1163 -
1164 - // Get Field value by value id
1165 - function get_field_val_by_field_id($field_id,$val){
1166 - include WPSC_ABSPATH . 'includes/functions/get_field_val_by_valId.php';
1167 - return $val;
1168 - }
1169 -
1170 - // get condition field options
1171 - function get_condition_field_options(){
1172 - include WPSC_ABSPATH . 'includes/functions/get_condition_field_options.php';
1173 - return $fields;
1174 - }
1175 -
1176 - // check conditions
1177 - function check_ticket_conditions($conditions,$ticket_id){
1178 - include WPSC_ABSPATH . 'includes/functions/check_ticket_conditions.php';
1179 - return $flag;
1180 - }
1181 -
1182 - // show ad banner on dashboard interface if no add-on is installed.
1183 - function display_ad_banner(){
1184 - include WPSC_ABSPATH . 'includes/functions/display_ad_banner.php';
1185 - }
1186 -
1187 - function get_ticket($ticket_id){
1188 - global $wpdb;
1189 - $ticket_data = array();
1190 - $ticket = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}wpsc_ticket WHERE id='$ticket_id' ");
1191 - if( $ticket ){
1192 - $ticket_data = json_decode(json_encode($ticket), true);
1193 - }
1194 - return $ticket_data;
1195 - }
1196 -
1197 - function get_ticket_fields($ticket_id,$select_field){
1198 -
1199 - global $wpdb;
1200 - $ticket_field_value = '';
1201 - if (apply_filters('wpsc_get_select_field',true,$ticket_id,$select_field)) {
1202 - $get_ticket_field_value = $wpdb->get_var(" SELECT $select_field FROM {$wpdb->prefix}wpsc_ticket WHERE id='$ticket_id' ");
1203 - $ticket_field_value = $get_ticket_field_value ? $get_ticket_field_value : '';
1204 - }
1205 - return stripslashes($ticket_field_value);
1206 - }
1207 -
1208 - /**
1209 - * Get ticket meta
1210 - */
1211 - function get_ticket_meta( $ticket_id, $meta_key, $flag = false ){
1212 -
1213 - global $wpdb;
1214 - if($flag){
1215 -
1216 - $get_meta = $wpdb->get_var("SELECT meta_value FROM {$wpdb->prefix}wpsc_ticketmeta WHERE ticket_id= '$ticket_id' AND meta_key = '$meta_key' ");
1217 - $ticket_meta = stripslashes($get_meta) ? stripslashes($get_meta) : '';
1218 -
1219 - } else {
1220 -
1221 - $ticket_meta = array();
1222 - $results = $wpdb->get_results("SELECT meta_value FROM {$wpdb->prefix}wpsc_ticketmeta WHERE ticket_id= '$ticket_id' AND meta_key = '$meta_key'");
1223 - if( $results ){
1224 - foreach ($results as $result) {
1225 - $ticket_meta[]= stripslashes($result->meta_value);
1226 - }
1227 - }
1228 - }
1229 - return $ticket_meta;
1230 - }
1231 -
1232 - /**
1233 - * Get assigned agents. If not, return empty array
1234 - */
1235 - function get_assigned_agents($ticket_id){
1236 - $assigned_agents = $this->get_ticket_meta($ticket_id,'assigned_agent');
1237 - if ( isset($assigned_agents[0]) && $assigned_agents[0] == 0 ) {
1238 - $assigned_agents = array();
1239 - }
1240 - return $assigned_agents;
1241 - }
1242 -
1243 - /**
1244 - * Get status of ticket whether it is active or deleted
1245 - */
1246 - function get_ticket_status($ticket_id){
1247 - global $wpdb;
1248 - $ticket_status = $wpdb->get_var("SELECT active FROM {$wpdb->prefix}wpsc_ticket WHERE id='$ticket_id' ");
1249 - return intval($ticket_status);
1250 - }
1251 -
1252 - /**
1253 - * Adds ticketmeta for ticket
1254 - */
1255 - function add_ticket_meta($ticket_id ,$meta_key ,$meta_value){
1256 - global $wpdb;
1257 - $wpdb->insert(
1258 - $wpdb->prefix . 'wpsc_ticketmeta',
1259 - array(
1260 - 'ticket_id' => $ticket_id,
1261 - 'meta_key' => $meta_key,
1262 - 'meta_value' => $meta_value
1263 - ));
1264 - }
1265 -
1266 - /**
1267 - * Update ticket meta for ticket
1268 - */
1269 - function update_ticket_meta($ticket_id ,$meta_key ,$meta_value){
1270 - global $wpdb;
1271 - $wpdb->update($wpdb->prefix.'wpsc_ticketmeta', $meta_value, array('ticket_id'=>$ticket_id,'meta_key' => $meta_key));
1272 - }
1273 -
1274 - function delete_ticket_meta($ticket_id ,$meta_key){
1275 - global $wpdb;
1276 - $wpdb->delete( $wpdb->prefix.'wpsc_ticketmeta', array( 'ticket_id' => $ticket_id,'meta_key'=>$meta_key) );
1277 - }
1278 -
1279 - /**
1280 - * Get SQL Query depending on paramenters passed for ticket list
1281 - */
1282 - public function get_sql_query( $select_str , $meta_query, $search = false, $orderby = false, $order = false, $no_of_tickets = false, $current_page = false ){
1283 - include WPSC_ABSPATH . 'includes/functions/get_sql_query.php';
1284 - return $sql;
1285 - }
1286 -
1287 - /**
1288 - * Get all field array which saved in ticketmeta table
1289 - */
1290 -
1291 - function get_all_meta_keys(){
1292 -
1293 - $c_fields = get_terms([
1294 - 'taxonomy' => 'wpsc_ticket_custom_fields',
1295 - 'hide_empty' => false,
1296 - 'orderby' => 'meta_value_num',
1297 - 'meta_key' => 'wpsc_tf_load_order',
1298 - 'order' => 'ASC',
1299 - 'meta_query' => array(
1300 - array(
1301 - 'key' => 'agentonly',
1302 - 'value' => array(0,1),
1303 - 'compare' => 'IN'
1304 - )
1305 - ),
1306 - ]);
1307 -
1308 - $meta_key = array();
1309 -
1310 - if( $c_fields ) {
1311 -
1312 - foreach ($c_fields as $field) {
1313 -
1314 - $wpsc_tf_type = get_term_meta( $field->term_id, 'wpsc_tf_type',true);
1315 -
1316 - if(!$wpsc_tf_type) continue;
1317 -
1318 - $meta_key[] = $field->slug;
1319 -
1320 - }
1321 -
1322 - }
1323 -
1324 - $meta_key[] = 'assigned_agent';
1325 - $meta_key[] = 'date_closed';
1326 - $meta_key[] = 'last_reply_by';
1327 - $meta_key[] = 'last_reply_on';
1328 - return apply_filters( 'wpsc_get_all_meta_keys', $meta_key );
1329 -
1330 - }
1331 -
1332 - /**
1333 - * Create a ticket
1334 - */
1335 - public function create_new_ticket($values){
1336 - global $wpdb;
1337 - $wpdb->insert($wpdb->prefix . 'wpsc_ticket', $values);
1338 - $ticket_id = $wpdb->insert_id;
1339 - return $ticket_id;
1340 - }
1341 -
1342 - /**
1343 - * Get status term ids
1344 - */
1345 - function get_statuses(){
1346 - $status_ids = array();
1347 - $statuses = get_terms([
1348 - 'taxonomy' => 'wpsc_statuses',
1349 - 'hide_empty' => false,
1350 - 'orderby' => 'meta_value_num',
1351 - 'order' => 'ASC',
1352 - 'meta_query' => array('order_clause' => array('key' => 'wpsc_status_load_order')),
1353 - ]);
1354 - foreach ($statuses as $status) {
1355 - $status_ids[] = $status->term_id;
1356 - }
1357 - return $status_ids;
1358 - }
1359 -
1360 - /**
1361 - * Get priority term ids
1362 - */
1363 - function get_priorities(){
1364 - $priority_ids = array();
1365 - $priorities = get_terms([
1366 - 'taxonomy' => 'wpsc_priorities',
1367 - 'hide_empty' => false,
1368 - 'orderby' => 'meta_value_num',
1369 - 'order' => 'ASC',
1370 - 'meta_query' => array('order_clause' => array('key' => 'wpsc_priority_load_order')),
1371 - ]);
1372 - foreach ($priorities as $priority) {
1373 - $priority_ids[] = $priority->term_id;
1374 - }
1375 - return $priority_ids;
1376 - }
1377 -
1378 - /**
1379 - * Get category term ids
1380 - */
1381 - function get_categories(){
1382 - $category_ids = array();
1383 - $categories = get_terms([
1384 - 'taxonomy' => 'wpsc_categories',
1385 - 'hide_empty' => false,
1386 - 'orderby' => 'meta_value_num',
1387 - 'order' => 'ASC',
1388 - 'meta_query' => array('order_clause' => array('key' => 'wpsc_category_load_order')),
1389 - ]);
1390 - foreach ($categories as $category) {
1391 - $category_ids[] = $category->term_id;
1392 - }
1393 - return $category_ids;
1394 - }
1395 -
1396 - /**
1397 - * Get Unresolved Label COUNT
1398 - */
1399 -
1400 - function get_label_count_unresolved(){
1401 -
1402 - global $wpdb, $current_user, $wpscfunction;
1403 -
1404 - $label_counts = array();
1405 -
1406 - // Get user meta history
1407 - $label_count_history = get_option( 'wpsc_label_count_history' );
1408 - $label_count_last_history = get_user_meta( $current_user->ID, 'wpsc_'.get_current_blog_id().'_label_count_last_history', true );
1409 -
1410 - if( $label_count_history && $label_count_history == $label_count_last_history ){
1411 - $label_counts = get_user_meta( $current_user->ID, 'wpsc_'.get_current_blog_id().'_label_counts', true );
1412 - $filter_count_flag = false;
1413 - }
1414 -
1415 - $all_labels = $this->get_ticket_filter_labels();
1416 -
1417 - // Initialize meta query
1418 - $meta_query = array(
1419 - 'relation' => 'AND',
1420 - );
1421 -
1422 - // Initialie restrictions. Everyone should able to see their own tickets.
1423 - $restrict_rules = array(
1424 - 'relation' => 'OR',
1425 - array(
1426 - 'key' => 'customer_email',
1427 - 'value' => $current_user->user_email,
1428 - 'compare' => '='
1429 - ),
1430 - );
1431 -
1432 - if ($current_user->has_cap('wpsc_agent')) {
1433 -
1434 - $agent_permissions = $this->get_current_agent_permissions();
1435 -
1436 - $agents = get_terms([
1437 - 'taxonomy' => 'wpsc_agents',
1438 - 'hide_empty' => false,
1439 - 'meta_query' => array(
1440 - 'relation' => 'AND',
1441 - array(
1442 - 'key' => 'user_id',
1443 - 'value' => $current_user->ID,
1444 - 'compare' => '='
1445 - )
1446 - ),
1447 - ]);
1448 -
1449 - if(!$agents) die();
1450 - $current_agent = $agents[0];
1451 -
1452 - if ($agent_permissions['view_unassigned']) {
1453 - $restrict_rules[] = array(
1454 - 'key' => 'assigned_agent',
1455 - 'value' => 0,
1456 - 'compare' => '='
1457 - );
1458 - }
1459 -
1460 - if ($agent_permissions['view_assigned_me']) {
1461 - $restrict_rules[] = array(
1462 - 'key' => 'assigned_agent',
1463 - 'value' => $current_agent->term_id,
1464 - 'compare' => '='
1465 - );
1466 - }
1467 -
1468 - if ($agent_permissions['view_assigned_others']) {
1469 - $restrict_rules[] = array(
1470 - 'key' => 'assigned_agent',
1471 - 'value' => array(0,$current_agent->term_id),
1472 - 'compare' => 'NOT IN'
1473 - );
1474 - }
1475 -
1476 - $restrict_rules = apply_filters('wpsc_tl_agent_restrict_rules',$restrict_rules);
1477 -
1478 - } else {
1479 - $restrict_rules = apply_filters('wpsc_tl_customer_restrict_rules',$restrict_rules);
1480 - }
1481 -
1482 - $meta_query[] = $restrict_rules;
1483 -
1484 - $labels = array();
1485 -
1486 - foreach ($all_labels as $key => $label) {
1487 -
1488 - if( $label['has_badge'] ){
1489 -
1490 - switch ($key) {
1491 -
1492 - case 'unresolved_agent':
1493 - $unresolved_agent = get_option('wpsc_tl_agent_unresolve_statuses');
1494 - $unresolved_agent_rules = array(
1495 - 'relation' => 'OR',
1496 - );
1497 - if($unresolved_agent){
1498 - $unresolved_agent_rules[] = array(
1499 - 'key' => 'ticket_status',
1500 - 'value' => $unresolved_agent,
1501 - 'compare' => 'IN'
1502 - );
1503 - }
1504 - $meta_query[] = apply_filters('wpsc_unresolved_agent_label_count', $unresolved_agent_rules, $key);
1505 - break;
1506 -
1507 - default:
1508 - $meta_query = apply_filters('wpsc_filter_after_label_default', $meta_query, $key );
1509 - break;
1510 -
1511 - }
1512 -
1513 - $sql = $wpscfunction->get_sql_query( 'COUNT(DISTINCT t.id)', $meta_query );
1514 - $ticket_count = $wpdb->get_var($sql);
1515 - $labels[$key] = $ticket_count;
1516 - }
1517 - }
1518 -
1519 - if(!$label_count_history){
1520 - $label_count_history = 1;
1521 - update_option( 'wpsc_label_count_history', $label_count_history );
1522 - }
1523 -
1524 - update_user_meta( $current_user->ID, 'wpsc_'.get_current_blog_id().'_label_count_last_history', $label_count_history );
1525 - update_user_meta( $current_user->ID, 'wpsc_'.get_current_blog_id().'_label_counts', $labels );
1526 -
1527 - $label_counts = $labels;
1528 -
1529 - }
1530 -
1531 - /**
1532 - * Check string
1533 - */
1534 - public function check_str_is_non_english($string){
1535 - $flag = true;
1536 - if(preg_match('/[^\x00-\x7F]+/' ,$string)){
1537 - $flag = false;
1538 - }
1539 - return $flag;
1540 - }
1541 -
1542 - /**
1543 - * Load conditions UI. Will be used to show conditions in setting.
1544 - * @param [String] $id (required) CSS id for the element. It must be ubique for each element.
1545 - * @param array $conditions (optional) Existing conditions to load
1546 - * @return [type] Void
1547 - */
1548 - public function load_conditions_ui( $id, $conditions = '' ){
1549 - include WPSC_ABSPATH . 'includes/functions/conditions/load_conditions_ui.php';
1550 - }
1551 -
1552 - /**
1553 - * Print options html for a condition options for a given key
1554 - * @param Mixed $key key for getting options.
1555 - * @return [type] Void
1556 - */
1557 - public function get_condition_options($key){
1558 - include WPSC_ABSPATH . 'includes/functions/conditions/get_condition_options.php';
1559 - return $options;
1560 - }
1561 -
1562 - /**
1563 - * Check whether given category available or not
1564 - * @return boolean
1565 - */
1566 - public function is_category( $cat_id ){
1567 - $term = get_term_by( 'id', $cat_id, 'wpsc_categories' );
1568 - return $term ? true : false;
1569 - }
1570 -
1571 - /**
1572 - * Check whether given priority available or not
1573 - * @return boolean
1574 - */
1575 - public function is_priority( $priority_id ){
1576 - $term = get_term_by( 'id', $priority_id, 'wpsc_priorities' );
1577 - return $term ? true : false;
1578 - }
1579 -
1580 - /**
1581 - * Check whether given status available or not
1582 - * @return boolean
1583 - */
1584 - public function is_status( $status_id ){
1585 - $term = get_term_by( 'id', $status_id, 'wpsc_statuses' );
1586 - return $term ? true : false;
1587 - }
1588 -
1589 - /**
1590 - * Check whether given custom field option available or not
1591 - * @return boolean
1592 - */
1593 - public function is_cf_option( $field_id, $option ){
1594 - $options = get_term_meta( $field_id, 'wpsc_tf_options', true);
1595 - $options = is_array($options) ? $options : array();
1596 - $options = isset($options[0]) && $options[0] ? $options : array();
1597 - return in_array($option,$options) ? true : false;
1598 - }
1599 -
1600 - /**
1601 - * Check whether given slug is custom field slug
1602 - */
1603 - public function is_cf_slug($slug){
1604 - $term = get_term_by( 'slug', $slug, 'wpsc_ticket_custom_fields' );
1605 - return $term ? true : false;
1606 - }
1607 -
1608 - /**
1609 - * Check whether given agent is present or not
1610 - */
1611 - public function is_agent($agents){
1612 - if(!$agents) return false;
1613 - foreach ($agents as $agent) {
1614 - $term = get_term_by( 'id' , $agent , 'wpsc_agents' );
1615 - if(!$term){
1616 - return false;
1617 - }
1618 - }
1619 - return true;
1620 - }
1621 -
1622 - /**
1623 - * Check whether given ticket is present and active or not
1624 - */
1625 - public function is_ticket($ticket_id){
1626 - global $wpdb;
1627 -
1628 - $ticket_exists = $wpdb->get_var("SELECT IF( EXISTS( SELECT * FROM {$wpdb->prefix}wpsc_ticket WHERE id = $ticket_id AND active = 1), 1, 0)");
1629 - return $ticket_exists ? true : false;
1630 - }
1631 -
1632 - /**
1633 - * Add extra users for ticket
1634 - * @param [type] $ticket_id
1635 - * @param [type] $extra_ticket_users
1636 - */
1637 - function add_extra_users($ticket_id,$extra_ticket_users){
1638 - global $wpscfunction,$wpdb;
1639 - $unwanted_emails = array();
51 + case 'wp_user':
52 + $object = $value ? get_user_by( 'ID', $value ) : null;
53 + break;
1640 54
1641 - $ticket = $wpscfunction->get_ticket($ticket_id);
1642 - $unwanted_emails[] = $ticket['customer_email'];
55 + case 'datetime':
56 + $object = $value && $value !== '0000-00-00 00:00:00' ? DateTime::createFromFormat( 'Y-m-d H:i:s', $value ) : '';
57 + break;
1643 58
1644 - $from_email = get_option('wpsc_en_from_email','');
1645 - if($from_email) $unwanted_emails[] = $from_email;
59 + case 'dateinterval':
60 + $object = $value ? new DateInterval( $value ) : new DateInterval( 'PT0M' );
61 + break;
1646 62
1647 - $reply_to = get_option('wpsc_en_reply_to','');
1648 - if($reply_to) $unwanted_emails[] = $reply_to;
63 + case 'wpsc_cft':
64 + $object = isset( self::$ref_classes[ $value ] ) ? self::$ref_classes[ $value ]['class'] : null;
65 + break;
1649 66
1650 - $extra_ticket_users = array_diff($extra_ticket_users, $unwanted_emails);
1651 -
1652 - $prev_users = $wpscfunction->get_ticket_meta($ticket_id,'extra_ticket_users');
1653 -
1654 - //delete prev emails
1655 - if($prev_users){
1656 - $wpscfunction->delete_ticket_meta($ticket_id,'extra_ticket_users');
1657 - }
1658 -
1659 - //add again all emails
1660 - if($extra_ticket_users){
1661 - foreach($extra_ticket_users as $user){
1662 - $wpscfunction->add_ticket_meta($ticket_id,'extra_ticket_users',$user);
1663 - }
1664 - }
1665 -
1666 - do_action('wpsc_set_add_extra_users', $ticket_id, $extra_ticket_users, $prev_users);
1667 - }
1668 -
1669 - function get_os(){
1670 - $user_agent = $_SERVER['HTTP_USER_AGENT'];
1671 - $os_platform = "Not Found";
1672 - $os_array = array(
1673 - '/windows nt 10/i' => 'Windows 10',
1674 - '/windows nt 6.3/i' => 'Windows 8.1',
1675 - '/windows nt 6.2/i' => 'Windows 8',
1676 - '/windows nt 6.1/i' => 'Windows 7',
1677 - '/windows nt 6.0/i' => 'Windows Vista',
1678 - '/windows nt 5.2/i' => 'Windows Server 2003/XP x64',
1679 - '/windows nt 5.1/i' => 'Windows XP',
1680 - '/windows xp/i' => 'Windows XP',
1681 - '/windows nt 5.0/i' => 'Windows 2000',
1682 - '/windows me/i' => 'Windows ME',
1683 - '/win98/i' => 'Windows 98',
1684 - '/win95/i' => 'Windows 95',
1685 - '/win16/i' => 'Windows 3.11',
1686 - '/macintosh|mac os x/i' => 'Mac OS X',
1687 - '/mac_powerpc/i' => 'Mac OS 9',
1688 - '/linux/i' => 'Linux',
1689 - '/ubuntu/i' => 'Ubuntu',
1690 - '/iphone/i' => 'iPhone',
1691 - '/ipod/i' => 'iPod',
1692 - '/ipad/i' => 'iPad',
1693 - '/android/i' => 'Android',
1694 - '/blackberry/i' => 'BlackBerry',
1695 - '/webos/i' => 'Mobile'
1696 - );
1697 - foreach ( $os_array as $regex => $value ) {
1698 - if ( preg_match($regex, $user_agent ) ) {
1699 - $os_platform = $value;
1700 - }
1701 - }
1702 -
1703 - return $os_platform;
1704 - }
1705 -
1706 - function get_browser(){
1707 - $user_agent = $_SERVER['HTTP_USER_AGENT'];
1708 - $browser = "Not Found";
1709 - $browser_array = array(
1710 - '/msie/i' => 'Internet Explorer',
1711 - '/firefox/i' => 'Mozilla Firefox',
1712 - '/safari/i' => 'Safari',
1713 - '/chrome/i' => 'Google Chrome',
1714 - '/edge/i' => 'Edge',
1715 - '/opera/i' => 'Opera',
1716 - '/netscape/i' => 'Netscape',
1717 - '/maxthon/i' => 'Maxthon',
1718 - '/konqueror/i' => 'Konqueror',
1719 - '/SamsungBrowser/' => 'Samsung Browser'
1720 - );
1721 - foreach ( $browser_array as $regex => $value ) {
67 + case 'wpsc_customer':
68 + if ( $value && ! is_object( $object ) && isset( self::$ref_classes[ $ref_class ] ) ) {
69 + $class = self::$ref_classes[ $ref_class ]['class'];
70 + $object = new $class( $value );
71 + } else {
72 + $object = WPSC_Customer::get_anonymous_customer();
73 + }
74 + break;
1722 75
1723 - if ( preg_match( $regex, $user_agent ) ) {
1724 - $browser = $value;
1725 - }
1726 - }
1727 - return $browser;
1728 - }
1729 -
1730 - //Ticket all threads
1731 - function get_ticket_history_all($ticket_id){
1732 - include WPSC_ABSPATH . 'includes/functions/get_ticket_history_all.php';
1733 - return $ticket_history_all;
1734 - }
1735 -
1736 - // All ticket threads with note
1737 - function get_ticket_history_all_with_notes($ticket_id){
1738 - include WPSC_ABSPATH . 'includes/functions/get_ticket_history_all_with_notes.php';
1739 - return $ticket_history_all_with_notes;
1740 - }
1741 -
1742 - // ticket all notes
1743 - function ticket_notes_history($ticket_id){
1744 - include WPSC_ABSPATH . 'includes/functions/get_ticket_notes_history.php';
1745 - return $ticket_notes_history;
1746 - }
76 + case 'wpsc_ticket':
77 + if ( $value && isset( self::$ref_classes[ $ref_class ] ) ) {
78 + $class = self::$ref_classes[ $ref_class ]['class'];
79 + $object = new $class( $value );
80 + // A ticket referenced from another record (a todo, a thread, a timer log, ...)
81 + // may have since been archived - archived tickets are moved out of the live
82 + // tickets table entirely, so the lookup above resolves to an empty object. Fall
83 + // back to the archived-ticket table rather than silently returning a blank
84 + // ticket (blank id, blank subject, blank link) to every caller.
85 + if ( ! $object->id ) {
86 + $object = new WPSC_Archive_Ticket( $value );
87 + }
88 + }
89 + break;
1747 90
1748 - function get_previously_assigned_agents_names($ticket_id){
1749 - global $wpscfunction;
1750 - $prev_assigned_agents = $wpscfunction->get_ticket_meta($ticket_id, 'prev_assigned_agent');
1751 - $agent_names = array();
1752 - foreach ($prev_assigned_agents as $agent_id) {
1753 - $agent_names[] = $this->get_agent_name($agent_id);
1754 - }
1755 - return implode(', ', $agent_names);
1756 - }
91 + default:
92 + $object = apply_filters( 'wpsc_fun_get_object', $value, $ref_class );
93 + if ( ! is_object( $object ) && isset( self::$ref_classes[ $ref_class ] ) ) {
94 + $class = self::$ref_classes[ $ref_class ]['class'];
95 + $object = new $class( $value );
96 + }
97 + }
1757 98
1758 - function get_previously_assigned_agents($ticket_id){
1759 - global $wpscfunction;
1760 - $prev_assigned_agents = $wpscfunction->get_ticket_meta($ticket_id,'prev_assigned_agent');
1761 - $agent_emails = array();
1762 - foreach ($prev_assigned_agents as $agent_id) {
1763 - $user_id = get_term_meta($agent_id,'user_id',true);
1764 - if($user_id){
1765 - $user = get_user_by('id',$user_id);
1766 - $agent_emails[] = $user->user_email;
1767 - }
1768 - }
1769 - return apply_filters( 'wpsc_get_prev_assigned_agent_emails',$agent_emails, $prev_assigned_agents, $ticket_id);
1770 - }
99 + return $object ? $object : $value;
100 + }
1771 101
1772 - function rich_editing_status($user){
1773 - $status = get_user_meta($user->ID,'rich_editing',true);
1774 - return filter_var($status, FILTER_VALIDATE_BOOLEAN);
1775 - }
1776 -
1777 - function check_rtl(){
1778 - $rtl_locale = array('ar','ary','ckb','haz','he_IL','fa_IR','ps','ur','ug_CN');
1779 - if(in_array(get_locale(),$rtl_locale)){
1780 - return 'rtl';
1781 - }else{
1782 - return 'ltr';
1783 - }
1784 - }
1785 -
1786 - //All ticket history with log threads
1787 - function get_ticket_history_all_with_logs($ticket_id){
1788 - include WPSC_ABSPATH . 'includes/functions/get_ticket_history_all_with_logs.php';
1789 - return $ticket_history_all_with_logs;
1790 - }
102 + /**
103 + * Return value to be saved in model db for an abject
104 + *
105 + * @param string $ref_class - reference class.
106 + * @param string $value - value.
107 + * @return object
108 + */
109 + public static function set_object( $ref_class, $value ) {
1791 110
1792 - //All ticket history with notes and log threads
1793 - function get_ticket_history_all_with_notes_and_logs($ticket_id){
1794 - include WPSC_ABSPATH . 'includes/functions/get_ticket_history_all_with_notes_and_logs.php';
1795 - return $ticket_history_all_with_notes_and_logs;
1796 - }
111 + $save_val = '';
112 + switch ( $ref_class ) {
1797 113
1798 - //Ticket history notes with log threads
1799 - function get_ticket_notes_history_with_logs($ticket_id){
1800 - include WPSC_ABSPATH . 'includes/functions/get_ticket_notes_history_with_logs.php';
1801 - return $ticket_notes_history_with_logs;
1802 - }
114 + case 'wp_user':
115 + $save_val = $value->ID;
116 + break;
1803 117
1804 - function get_ticket_id_range(){
1805 - $ticket_length = get_option('wpsc_rt_id_length');
1806 - $start = 0;
1807 - for ($i = 1; $i <= $ticket_length; $i++) {
1808 - $start = ($start * 10) + 1;
1809 - }
118 + case 'datetime':
119 + $save_val = $value->format( 'Y-m-d H:i:s' );
120 + break;
1810 121
1811 - $end = 0;
1812 - for ($i = 1; $i <= $ticket_length; $i++) {
1813 - $end = ($end * 10) + 9;
1814 - }
1815 -
1816 - return array('start_id' => $start, 'end_id'=>$end);
1817 - }
1818 -
1819 - /**
1820 - * Convert date from WP timezone date to UTC equivalant date
1821 - *
1822 - * @param String $date_str
1823 - * @return DateTime
1824 - */
1825 - public static function get_utc_date_str($date_str) {
122 + case 'dateinterval':
123 + $save_val = self::date_interval_to_string( $value );
124 + break;
1826 125
1827 - $tz = wp_timezone();
1828 - $date = DateTime::createFromFormat('Y-m-d H:i:s', $date_str, $tz);
1829 - $date->setTimezone(new DateTimeZone('+0000'));
1830 - return $date->format('Y-m-d H:i:s');
1831 - }
126 + default:
127 + if ( isset( self::$ref_classes[ $ref_class ] ) ) {
128 + $key = self::$ref_classes[ $ref_class ]['save-key'];
129 + $save_val = $value->$key;
130 + }
131 + }
1832 132
1833 - public function remove_emoji($string) {
133 + return $save_val ? $save_val : $value;
134 + }
1834 135
1835 - $symbols = "\x{1F100}-\x{1F1FF}" // Enclosed Alphanumeric Supplement
1836 - ."\x{1F300}-\x{1F5FF}" // Miscellaneous Symbols and Pictographs
1837 - ."\x{1F600}-\x{1F64F}" //Emoticons
1838 - ."\x{1F680}-\x{1F6FF}" // Transport And Map Symbols
1839 - ."\x{1F900}-\x{1F9FF}" // Supplemental Symbols and Pictographs
1840 - ."\x{2600}-\x{26FF}" // Miscellaneous Symbols
1841 - ."\x{2700}-\x{27BF}"; // Dingbats
136 + /**
137 + * Return search string given in model filters array
138 + *
139 + * @param array $filter - filter array.
140 + * @return string
141 + */
142 + public static function get_filter_search_str( $filter ) {
1842 143
1843 - return preg_replace('/['. $symbols . ']+/u', '', $string);
1844 - }
1845 -}
144 + return isset( $filter['search'] ) ? addslashes( trim( $filter['search'] ) ) : '';
145 + }
146 +
147 + /**
148 + * Parse user filter for models which has static schema
149 + *
150 + * @param string $class_name - Class name of the model.
151 + * @param array $filters - User filters array.
152 + * @return string
153 + */
154 + public static function parse_user_filters( $class_name, $filters ) {
155 +
156 + global $wpdb;
157 +
158 + // Invalid filter.
159 + if ( ! isset( $filters['relation'] ) || count( $filters ) < 2 ) {
160 + return '1=1';
161 + }
162 +
163 + $relation = $filters['relation'];
164 + $filter_str = array();
165 +
166 + foreach ( $filters as $key => $filter ) {
167 +
168 + // Skip if current element is relation indicator.
169 + if ( $key === 'relation' ) {
170 + continue;
171 + }
172 +
173 + // Invalid filter if it is not an array.
174 + if ( ! is_array( $filter ) ) {
175 + return '1=1';
176 + }
177 +
178 + // Call recursively if there is multi-layer filter detected.
179 + if ( isset( $filter['relation'] ) ) {
180 + $filter_str[] = self::parse_user_filters( $class_name, $filter );
181 + continue;
182 + }
183 +
184 + // Invalid filter if it does not contain slug, compare and val indexes.
185 + $slug = isset( $filter['slug'] ) ? self::sanitize_sql_key( $filter['slug'] ) : false;
186 + $compare = isset( $filter['compare'] ) ? $filter['compare'] : false;
187 + $val = isset( $filter['val'] ) || $filter['val'] == null ? $filter['val'] : false;
188 + if ( ! $slug || ! $compare || $val === false ) {
189 + return '1=1';
190 + }
191 +
192 + // custom filter.
193 + if ( $slug === 'custom_query' ) {
194 +
195 + $filter_str[] = $val;
196 +
197 + } else {
198 + switch ( $compare ) {
199 +
200 + case '<':
201 + case '=':
202 + case '>':
203 + case '<=':
204 + case '>=':
205 + if ( $class_name::$schema[ $slug ]['has_multiple_val'] ) {
206 + $filter_str[] = '1=1';
207 + break;
208 + }
209 + $filter_str[] = $slug . ' ' . $compare . ' \'' . esc_sql( $val ) . '\'';
210 + break;
211 +
212 + case 'BETWEEN':
213 + $filter_str[] = $slug . ' BETWEEN \'' . esc_sql( $val[0] ) . '\' AND \'' . esc_sql( $val[1] ) . '\'';
214 + break;
215 +
216 + case 'IN':
217 + if ( $class_name::$schema[ $slug ]['has_multiple_val'] ) {
218 +
219 + $rlike = array();
220 + foreach ( $val as $match ) {
221 +
222 + $rlike[] = $slug . ' RLIKE \'(^|[|])' . esc_sql( $match ) . '($|[|])\'';
223 + }
224 + $filter_str[] = '( ' . implode( ' OR ', $rlike ) . ' )';
225 +
226 + } else {
227 +
228 + $filter_str[] = $slug . ' IN ( \'' . implode( '\', \'', esc_sql( $val ) ) . '\' )';
229 + }
230 + break;
231 +
232 + case 'NOT IN':
233 + if ( $class_name::$schema[ $slug ]['has_multiple_val'] ) {
234 +
235 + $rlike = array();
236 + foreach ( $val as $match ) {
237 +
238 + $rlike[] = $slug . ' NOT RLIKE \'(^|[|])' . esc_sql( $match ) . '($|[|])\'';
239 + }
240 + $filter_str[] = '( ' . implode( ' OR ', $rlike ) . ' )';
241 +
242 + } else {
243 +
244 + $filter_str[] = $slug . ' NOT IN ( \'' . implode( '\', \'', esc_sql( $val ) ) . '\' )';
245 + }
246 + break;
247 +
248 + case 'IS':
249 + $filter_str[] = $slug . ' IS NULL';
250 + break;
251 +
252 + case 'IS NOT':
253 + $filter_str[] = $slug . ' IS NOT NULL';
254 + break;
255 +
256 + case 'LIKE':
257 + $filter_str[] = $slug . ' ' . $compare . ' \'%' . esc_sql( $wpdb->esc_like( $val ) ) . '%\'';
258 + break;
259 + }
260 + }
261 + }
262 +
263 + return count( $filter_str ) > 1 ?
264 + '( ' . implode( ' ' . $relation . ' ', $filter_str ) . ' )' :
265 + $filter_str[0];
266 + }
267 +
268 + /**
269 + * Get order for find method of models
270 + *
271 + * @param array $filter - filter array.
272 + * @return string
273 + */
274 + public static function parse_order( $filter ) {
275 +
276 + $orderby = isset( $filter['orderby'] ) && $filter['orderby'] ?
277 + $filter['orderby'] : '';
278 +
279 + if ( ! $orderby ) {
280 + return '';
281 + }
282 +
283 + $order = isset( $filter['order'] ) && $filter['order'] && in_array( $filter['order'], array( 'ASC', 'DESC' ) ) ?
284 + $filter['order'] : 'ASC';
285 +
286 + $orderby_slug = isset( $filter['orderby_slug'] ) && $filter['orderby_slug'] ? $filter['orderby_slug'] : '';
287 + $cf = WPSC_Custom_Field::get_cf_by_slug( $orderby_slug );
288 +
289 + if ( $cf && $cf->type::$slug == 'cf_number' ) {
290 +
291 + return 'ORDER BY CAST(' . $orderby . ' AS SIGNED ) ' . $order . ' ';
292 + } else {
293 +
294 + return 'ORDER BY ' . $orderby . ' ' . $order . ' ';
295 + }
296 + }
297 +
298 + /**
299 + * Get order for find method of models
300 + *
301 + * @param array $filter - filter array.
302 + * @return string
303 + */
304 + public static function parse_limit( $filter ) {
305 +
306 + $items_per_page = isset( $filter['items_per_page'] ) ?
307 + intval( $filter['items_per_page'] ) : 0;
308 +
309 + if ( $items_per_page == 0 ) {
310 + return '';
311 + }
312 +
313 + $page_no = isset( $filter['page_no'] ) && is_numeric( $filter['page_no'] ) ?
314 + intval( $filter['page_no'] ) : 1;
315 +
316 + $offset = ( $page_no - 1 ) * $items_per_page;
317 +
318 + return 'LIMIT ' . $offset . ', ' . $items_per_page;
319 + }
320 +
321 + /**
322 + * Calculate total pages, has_next_page, results, etc. for models
323 + *
324 + * @param string $results - page result.
325 + * @param int $total_items - total page items.
326 + * @param array $filter - filter items.
327 + * @return array
328 + */
329 + public static function parse_response( $results, int $total_items, $filter ) {
330 +
331 + $items_per_page = isset( $filter['items_per_page'] ) ?
332 + intval( $filter['items_per_page'] ) : 0;
333 +
334 + if ( ! $items_per_page ) {
335 + return array(
336 + 'total_items' => $total_items,
337 + 'results' => $results,
338 + );
339 + }
340 +
341 + $page_no = isset( $filter['page_no'] ) && is_numeric( $filter['page_no'] ) ?
342 + intval( $filter['page_no'] ) : 1;
343 +
344 + $total_pages = ceil( $total_items / $items_per_page );
345 +
346 + $has_next_page = $page_no < $total_pages ? true : false;
347 +
348 + return array(
349 + 'total_items' => $total_items,
350 + 'items_per_page' => $items_per_page,
351 + 'current_page' => $page_no,
352 + 'total_pages' => $total_pages,
353 + 'has_next_page' => $has_next_page,
354 + 'results' => $results,
355 + );
356 + }
357 +
358 + /**
359 + * Check whether current page is supportcandy page or not
360 + * Used for loading framework.
361 + * Pages like dashboard pages and where wpsc shortcode is present are considered true.
362 + *
363 + * @return boolean
364 + */
365 + public static function is_wpsc_page() {
366 +
367 + if ( is_admin() ) {
368 +
369 + return isset( $_REQUEST['page'] ) && preg_match( '/wpsc-/', $_REQUEST['page'] ) ? true : false; // phpcs:ignore
370 +
371 + } else {
372 +
373 + return true;
374 + }
375 + }
376 +
377 + /**
378 + * Check whether current use is site admin or not
379 + *
380 + * @return boolean
381 + */
382 + public static function is_site_admin() {
383 +
384 + global $current_user;
385 + return $current_user && $current_user->ID && $current_user->has_cap( 'manage_options' ) ? true : false;
386 + }
387 +
388 + /**
389 + * Get default filter auto-increament number
390 + *
391 + * @return integer
392 + */
393 + public static function get_tl_df_auto_increament() {
394 +
395 + $index = intval( get_option( 'wpsc-tl-df-auto-increament', 0 ) );
396 + update_option( 'wpsc-tl-df-auto-increament', ++$index );
397 + return $index;
398 + }
399 +
400 + /**
401 + * Get user custom filter auto-increament number
402 + *
403 + * @return integer
404 + */
405 + public static function get_tl_cf_auto_increament() {
406 +
407 + global $current_user;
408 + $index = intval( get_user_meta( $current_user->ID, get_current_blog_id() . '-wpsc-tl-cf-auto-increament', true ) );
409 + update_user_meta( $current_user->ID, get_current_blog_id() . '-wpsc-tl-cf-auto-increament', ++$index );
410 + return $index;
411 + }
412 +
413 + /**
414 + * Return css classes string as per size
415 + *
416 + * @param WPSC_custom_field $cf - custom field.
417 + * @param WPSC_TFF $tff - ticket form field.
418 + * @return string
419 + */
420 + public static function get_tff_classes( $cf, $tff ) {
421 +
422 + $classes = 'wpsc-tff ' . $cf->slug . ' wpsc-xs-12 ';
423 + switch ( $tff['width'] ) {
424 + case '1/3':
425 + $classes .= 'wpsc-sm-4 wpsc-md-4 wpsc-lg-4 ';
426 + break;
427 +
428 + case 'half':
429 + $classes .= 'wpsc-sm-6 wpsc-md-6 wpsc-lg-6 ';
430 + break;
431 +
432 + case 'full':
433 + $classes .= 'wpsc-sm-12 wpsc-md-12 wpsc-lg-12 ';
434 + break;
435 + }
436 + $classes .= $tff['is-required'] ? 'required ' : '';
437 + $visibility = WPSC_TFF::get_visibility( $tff, true );
438 + $classes .= $visibility ? 'wpsc-hidden conditional' : 'wpsc-visible';
439 +
440 + return $classes;
441 + }
442 +
443 + /**
444 + * Sort an array with key
445 + *
446 + * @param array $array_name - macro array.
447 + * @param array $on - title.
448 + * @param array $order - SORT_ASC.
449 + * @return array
450 + */
451 + public static function array_sort( $array_name, $on, $order = SORT_ASC ) {
452 +
453 + $new_array = array();
454 + $sortable_array = array();
455 +
456 + if ( count( $array_name ) > 0 ) {
457 + foreach ( $array_name as $k => $v ) {
458 + if ( is_array( $v ) ) {
459 + foreach ( $v as $k2 => $v2 ) {
460 + if ( $k2 == $on ) {
461 + $sortable_array[ $k ] = $v2;
462 + }
463 + }
464 + } else {
465 + $sortable_array[ $k ] = $v;
466 + }
467 + }
468 + switch ( $order ) {
469 + case SORT_ASC:
470 + asort( $sortable_array );
471 + break;
472 + case SORT_DESC:
473 + arsort( $sortable_array );
474 + break;
475 + }
476 + foreach ( $sortable_array as $k => $v ) {
477 + $new_array[ $k ] = $array_name[ $k ];
478 + }
479 + }
480 + return $new_array;
481 + }
482 +
483 + /**
484 + * Convert date from WP timezone date to UTC equivalant date
485 + *
486 + * @param string $date_str - date to UTC equivalant date.
487 + * @return DateTime
488 + */
489 + public static function get_utc_date_str( $date_str ) {
490 +
491 + $tz = wp_timezone();
492 + $date = DateTime::createFromFormat( 'Y-m-d H:i:s', $date_str, $tz );
493 + $date->setTimezone( new DateTimeZone( '+0000' ) );
494 + return $date->format( 'Y-m-d H:i:s' );
495 + }
496 +
497 + /**
498 + * Check whether given date is valid or not
499 + *
500 + * @param string $date - date string.
501 + * @param string $format - date format.
502 + * @return boolean
503 + */
504 + public static function is_valid_date( $date, $format = 'Y-m-d' ) {
505 + if ( preg_match( '/^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}(:\d{2})?$/', $date ) ) {
506 + return self::is_valid_datetime( $date );
507 + }
508 + $d = DateTime::createFromFormat( $format, $date );
509 + return $d && $d->format( $format ) === $date;
510 + }
511 +
512 + /**
513 + * Check whether given datetime is valid or not
514 + *
515 + * @param string $datetime - datetime string.
516 + * @return boolean
517 + */
518 + public static function is_valid_datetime( $datetime ) {
519 +
520 + if ( ! is_string( $datetime ) ) {
521 + return false;
522 + }
523 + if ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $datetime ) ) {
524 + return self::is_valid_date( $datetime );
525 + }
526 + $datetime = trim( $datetime );
527 + $formats = array(
528 + 'Y-m-d H:i',
529 + 'Y-m-d H:i:s',
530 + );
531 +
532 + foreach ( $formats as $format ) {
533 + $dt = DateTime::createFromFormat( $format, $datetime );
534 + if (
535 + $dt !== false &&
536 + $dt->format( $format ) === $datetime
537 + ) {
538 + return true;
539 + }
540 + }
541 + return false;
542 + }
543 +
544 + /**
545 + * Check whether given time is valid or not
546 + *
547 + * @param string $time - time string.
548 + * @return boolean
549 + */
550 + public static function is_valid_time( $time ) {
551 + if ( ! is_string( $time ) ) {
552 + return false;
553 + }
554 +
555 + // Accept HH:MM or HH:MM:SS (24-hour).
556 + return (bool) preg_match(
557 + '/^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/',
558 + $time
559 + );
560 + }
561 +
562 + /**
563 + * Normalize date string to UTC date string
564 + *
565 + * @param string $date - date string.
566 + * @param boolean $end_of_day - end of day flag.
567 + * @return string|false
568 + */
569 + public static function normalize_date( $date, $end_of_day = false ) {
570 + if ( ! is_string( $date ) ) {
571 + return false;
572 + }
573 +
574 + $date = trim( $date );
575 +
576 + $formats = array(
577 + 'Y-m-d H:i:s',
578 + 'Y-m-d',
579 + );
580 +
581 + foreach ( $formats as $format ) {
582 + $dt = DateTime::createFromFormat( $format, $date );
583 + if ( $dt instanceof DateTime ) {
584 + if ( $format === 'Y-m-d' ) {
585 + $dt->setTime(
586 + $end_of_day ? 23 : 0,
587 + $end_of_day ? 59 : 0,
588 + $end_of_day ? 59 : 0
589 + );
590 + }
591 + return self::get_utc_date_str( $dt->format( 'Y-m-d H:i:s' ) );
592 + }
593 + }
594 +
595 + return false;
596 + }
597 +
598 + /**
599 + * Return SQL BETWEEN string
600 + *
601 + * @param string $column - column name.
602 + * @param string $from - from value.
603 + * @param string $to - to value.
604 + * @return string
605 + */
606 + public static function sql_between( $column, $from, $to ) {
607 + return sprintf(
608 + "%s BETWEEN '%s' AND '%s'",
609 + $column,
610 + esc_sql( $from ),
611 + esc_sql( $to )
612 + );
613 + }
614 +
615 +
616 + /**
617 + * Get new ticket url
618 + *
619 + * @return string
620 + */
621 + public static function get_new_ticket_url() {
622 +
623 + $page_settings = get_option( 'wpsc-gs-page-settings' );
624 + $url = '';
625 +
626 + if ( $page_settings['new-ticket-page'] == 'default' && $page_settings['support-page'] ) {
627 +
628 + $url = get_permalink( $page_settings['support-page'] );
629 + $url = add_query_arg( array( 'wpsc-section' => 'new-ticket' ), $url );
630 +
631 + } elseif ( $page_settings['new-ticket-page'] == 'custom' && $page_settings['new-ticket-url'] ) {
632 +
633 + $url = $page_settings['new-ticket-url'];
634 + }
635 +
636 + return apply_filters( 'wpsc_get_new_ticket_url', $url );
637 + }
638 +
639 + /**
640 + * Load package for third-party php library without composer
641 + *
642 + * @param string $dir - directory path of package.
643 + * @return void
644 + */
645 + public static function load_library( $dir ) {
646 +
647 + $composer = json_decode( file_get_contents( "$dir/composer.json" ), 1 ); // phpcs:ignore
648 + $namespaces = $composer['autoload']['psr-4'];
649 +
650 + // Foreach namespace specified in the composer, load the given classes.
651 + foreach ( $namespaces as $namespace => $classpaths ) {
652 + if ( ! is_array( $classpaths ) ) {
653 + $classpaths = array( $classpaths );
654 + }
655 + spl_autoload_register(
656 + function ( $classname ) use ( $namespace, $classpaths, $dir ) {
657 + // Check if the namespace matches the class we are looking for.
658 + if ( preg_match( '#^' . preg_quote( $namespace, '/' ) . '#', $classname ) ) {
659 + // Remove the namespace from the file path since it's psr4.
660 + $classname = str_replace( $namespace, '', $classname );
661 + $filename = preg_replace( '#\\\\#', '/', $classname ) . '.php';
662 + foreach ( $classpaths as $classpath ) {
663 + $fullpath = $dir . '/' . $classpath . "/$filename";
664 + if ( file_exists( $fullpath ) ) {
665 + include_once $fullpath;
666 + }
667 + }
668 + }
669 + }
670 + );
671 + }
672 + }
673 +
674 + /**
675 + * Create a random string
676 + *
677 + * @param integer $length - random strig lenght.
678 + * @return string
679 + */
680 + public static function get_random_string( $length = 8 ) {
681 +
682 + $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
683 + $string = '';
684 + for ( $i = 0; $i < $length; $i++ ) {
685 + $string .= $characters[ wp_rand( 0, strlen( $characters ) - 1 ) ];
686 + }
687 + return $string;
688 + }
689 +
690 + /**
691 + * Perform sum of date intervals
692 + *
693 + * @param array $arr - date interval array.
694 + * @return DateInterval
695 + */
696 + public static function date_interval_sum( $arr ) {
697 +
698 + $response = $arr[0];
699 + $arrau_count = count( $arr );
700 + for ( $i = 1; $i < $arrau_count; $i++ ) {
701 + $today = new DateTime();
702 + $sum_today = clone $today;
703 + $sum_today->add( $response );
704 + $sum_today->add( $arr[ $i ] );
705 + $response = $today->diff( $sum_today );
706 + }
707 + return $response;
708 + }
709 +
710 + /**
711 + * Return string representation of date interval
712 + *
713 + * @param DateInterval $diff - date interval.
714 + * @return string
715 + */
716 + public static function date_interval_to_string( $diff ) {
717 +
718 + $str = 'P';
719 +
720 + if ( $diff->days ) {
721 +
722 + $str .= $diff->format( '%aD' );
723 +
724 + } elseif ( $diff->d ) {
725 +
726 + $str .= $diff->format( '%dD' );
727 +
728 + }
729 +
730 + if ( $diff->h || $diff->i ) {
731 +
732 + $str .= 'T';
733 + $str .= $diff->h ? $diff->format( '%hH' ) : '';
734 + $str .= $diff->i ? $diff->format( '%iM' ) : '';
735 + }
736 +
737 + if ( $str === 'P' ) {
738 + $str = 'PT0M';
739 + }
740 +
741 + return $str;
742 + }
743 +
744 + /**
745 + * Return readable time interval so that we can print this on user interface.
746 + *
747 + * @param DateInterval $diff - time interval.
748 + * @return string
749 + */
750 + public static function date_interval_to_readable( $diff ) {
751 +
752 + $arr = array();
753 +
754 + // days.
755 + if ( $diff->days ) {
756 +
757 + $arr[] = sprintf(
758 + /* translators: %d: number of days */
759 + __( '%dd', 'supportcandy' ),
760 + $diff->format( '%a' )
761 + );
762 +
763 + } elseif ( $diff->d ) {
764 +
765 + $arr[] = sprintf(
766 + /* translators: %d: number of days */
767 + __( '%dd', 'supportcandy' ),
768 + $diff->format( '%d' )
769 + );
770 +
771 + }
772 +
773 + // hours.
774 + if ( $diff->h ) {
775 + $arr[] = sprintf(
776 + /* translators: %d: number of hours */
777 + __( '%dh', 'supportcandy' ),
778 + $diff->format( '%h' )
779 + );
780 + }
781 +
782 + // minutes.
783 + if ( $diff->i ) {
784 + $arr[] = sprintf(
785 + /* translators: %d: number of minutes */
786 + __( '%dm', 'supportcandy' ),
787 + $diff->format( '%i' )
788 + );
789 + }
790 +
791 + return $arr ? implode( ' ', $arr ) : '0m';
792 + }
793 +
794 + /**
795 + * Return time interval object from readable string (usually comes from user interface)
796 + *
797 + * @param string $str - string to date format.
798 + * @return DateInterval
799 + */
800 + public static function readable_to_date_interval( $str ) {
801 +
802 + // remove spaces in between.
803 + $str = str_replace( ' ', '', $str );
804 +
805 + // invalid if not given.
806 + if ( ! $str ) {
807 + return false;
808 + }
809 +
810 + // validate format.
811 + $flag = preg_match( '/^(\d*d)?(\d*h)?(\d*m)?$/', $str, $matches );
812 + if ( ! $flag ) {
813 + return false;
814 + }
815 +
816 + // build interval string.
817 + $str = 'P';
818 + $str .= $matches[1] ? strtoupper( $matches[1] ) : '';
819 + if ( $matches[2] || $matches[3] ) {
820 + $str .= 'T';
821 + $str .= $matches[2] ? strtoupper( $matches[2] ) : '';
822 + $str .= $matches[3] ? strtoupper( $matches[3] ) : '';
823 + }
824 +
825 + // return dateinterval object.
826 + return new DateInterval( $str );
827 + }
828 +
829 + /**
830 + * Return time ago string for highest unit. For example, if difference is 2hr 30min 34sec then return 2 hour ago.
831 + *
832 + * @param DateInterval $diff - date interval object.
833 + * @return string
834 + */
835 + public static function date_interval_highest_unit_ago( $diff ) {
836 +
837 + // return years if any.
838 + if ( $diff->y ) {
839 + return sprintf(
840 + /* translators: %d: number of years */
841 + __( '%d years ago', 'supportcandy' ),
842 + intval( $diff->format( '%y' ) )
843 + );
844 + }
845 +
846 + // return months if any.
847 + if ( $diff->m ) {
848 + return sprintf(
849 + /* translators: %d: number of months */
850 + __( '%d months ago', 'supportcandy' ),
851 + intval( $diff->format( '%m' ) )
852 + );
853 + }
854 +
855 + // return days if any.
856 + $days = $diff->days ? intval( $diff->format( '%a' ) ) : intval( $diff->format( '%d' ) );
857 + if ( $days ) {
858 + return sprintf(
859 + /* translators: %d: number of days */
860 + __( '%d days ago', 'supportcandy' ),
861 + $days
862 + );
863 + }
864 +
865 + // return hours if any.
866 + if ( $diff->h ) {
867 + return sprintf(
868 + /* translators: %d: number of hours */
869 + __( '%d hours ago', 'supportcandy' ),
870 + intval( $diff->format( '%h' ) )
871 + );
872 + }
873 +
874 + // return minutes if any.
875 + if ( $diff->i ) {
876 + return sprintf(
877 + /* translators: %d: number of minutes */
878 + __( '%d minutes ago', 'supportcandy' ),
879 + intval( $diff->format( '%i' ) )
880 + );
881 + }
882 +
883 + // return seconds if any.
884 + if ( $diff->s ) {
885 + return sprintf(
886 + /* translators: %d: number of seconds */
887 + __( '%d seconds ago', 'supportcandy' ),
888 + intval( $diff->format( '%s' ) )
889 + );
890 + }
891 +
892 + return __( 'Just now', 'supportcandy' );
893 + }
894 +
895 + /**
896 + * Return day name
897 + *
898 + * @param int $day - week days.
899 + * @return string
900 + */
901 + public static function get_day_name( $day ) {
902 +
903 + $days = array(
904 + 1 => wpsc__( 'Monday' ),
905 + 2 => wpsc__( 'Tuesday' ),
906 + 3 => wpsc__( 'Wednesday' ),
907 + 4 => wpsc__( 'Thursday' ),
908 + 5 => wpsc__( 'Friday' ),
909 + 6 => wpsc__( 'Saturday' ),
910 + 7 => wpsc__( 'Sunday' ),
911 + );
912 + return isset( $days[ $day ] ) ? $days[ $day ] : '';
913 + }
914 +
915 + /**
916 + * Return month name
917 + *
918 + * @param int $month - month names.
919 + * @return string
920 + */
921 + public static function get_month_name( $month ) {
922 +
923 + $months = array(
924 + 1 => wpsc__( 'January' ),
925 + 2 => wpsc__( 'February' ),
926 + 3 => wpsc__( 'March' ),
927 + 4 => wpsc__( 'April' ),
928 + 5 => wpsc__( 'May' ),
929 + 6 => wpsc__( 'June' ),
930 + 7 => wpsc__( 'July' ),
931 + 8 => wpsc__( 'August' ),
932 + 9 => wpsc__( 'September' ),
933 + 10 => wpsc__( 'October' ),
934 + 11 => wpsc__( 'November' ),
935 + 12 => wpsc__( 'December' ),
936 + );
937 + return isset( $months[ $month ] ) ? $months[ $month ] : '';
938 + }
939 +
940 + /**
941 + * Sanitize SQL key to allow only possible lowercase keys with joins.
942 + *
943 + * @param string $key - key to sanitize.
944 + * @return string
945 + */
946 + public static function sanitize_sql_key( $key ) {
947 +
948 + $sanitized_key = '';
949 +
950 + if ( is_scalar( $key ) ) {
951 + $key = strtolower( $key );
952 + if ( preg_match( '/^([a-z]{1,2}\.)?[a-z0-9_]+$/', $key ) ) {
953 + $sanitized_key = $key;
954 + }
955 + }
956 +
957 + return $sanitized_key;
958 + }
959 +
960 + /**
961 + * Sanitize date string e.g. "2022-12-25" and return with datetime format
962 + *
963 + * @param string $date - date string to be sanitized.
964 + * @return string
965 + */
966 + public static function sanitize_date( $date ) {
967 +
968 + if ( ! $date ) {
969 + return $date;
970 + }
971 +
972 + if ( ! preg_match( '/\d{4}-\d{2}-\d{2}/', $date ) ) {
973 + return '';
974 + }
975 +
976 + $format = 'Y-m-d';
977 + $d = DateTime::createFromFormat( $format, $date );
978 + return $d && $d->format( $format ) == $date ? $date . ' 00:00:00' : '';
979 + }
980 +
981 + /**
982 + * Sanitize date string e.g. "2022-12-25 12:00:00"
983 + *
984 + * @param string $date - date string to be sanitized.
985 + * @return string
986 + */
987 + public static function sanitize_datetime( $date ) {
988 +
989 + if ( ! $date ) {
990 + return $date;
991 + }
992 +
993 + if ( ! preg_match( '/\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}/', $date ) ) {
994 + return '';
995 + }
996 +
997 + $format = 'Y-m-d H:i';
998 + $d = DateTime::createFromFormat( $format, $date );
999 + return $d && $d->format( $format ) == $date ? $date . ':00' : '';
1000 + }
1001 +
1002 + /**
1003 + * Sanitize time string e.g. "12:31"
1004 + *
1005 + * @param string $time - time string to be sanitized.
1006 + * @return string
1007 + */
1008 + public static function sanitize_time( $time ) {
1009 +
1010 + if ( ! $time ) {
1011 + return $time;
1012 + }
1013 +
1014 + if ( ! preg_match( '/(\d{2}):(\d{2})/', $time, $matches ) ) {
1015 + return '';
1016 + }
1017 +
1018 + return intval( $matches[1] ) < 24 && intval( $matches[2] ) < 60 ? $time : '';
1019 + }
1020 +
1021 + /**
1022 + * Sanitiize email string
1023 + *
1024 + * @param string $email - email string to be sanitized.
1025 + * @return string
1026 + */
1027 + public static function sanitize_email( $email ) {
1028 +
1029 + return filter_var( $email, FILTER_VALIDATE_EMAIL ) ? $email : '';
1030 + }
1031 +
1032 + /**
1033 + * Sanitiize url string
1034 + *
1035 + * @param string $url - email string to be sanitized.
1036 + * @return string
1037 + */
1038 + public static function sanitize_url( $url ) {
1039 +
1040 + return filter_var( $url, FILTER_VALIDATE_URL ) ? $url : '';
1041 + }
1042 +
1043 + /**
1044 + * Sanitize attachment id came as user input
1045 + *
1046 + * @param integer $id - attachment id.
1047 + * @return integer|boolean
1048 + */
1049 + public static function sanitize_attachment( $id ) {
1050 +
1051 + if ( ! $id ) {
1052 + return false;
1053 + }
1054 +
1055 + $attachment = new WPSC_Attachment( $id );
1056 + return $attachment->id ? $id : false;
1057 + }
1058 +
1059 + /**
1060 + * Sanitize option id provided by user
1061 + *
1062 + * @param integer $id - option id.
1063 + * @param WPSC_Custom_Field $cf - custom field object.
1064 + * @param array $options - array of option objects.
1065 + * @return integer|boolean
1066 + */
1067 + public static function sanitize_option( $id, $cf, $options ) {
1068 +
1069 + $option = new WPSC_Option( $id );
1070 + $options = array_filter(
1071 + array_map(
1072 + fn( $option ) => $option->id ? $option->id : false,
1073 + $options
1074 + )
1075 + );
1076 + return $option->id && in_array( $option->id, $options ) ? $id : false;
1077 + }
1078 +
1079 + /**
1080 + * Get current langauge iso code. Use for datepicker library.
1081 + *
1082 + * @return string
1083 + */
1084 + public static function get_locale_iso() {
1085 +
1086 + $locale = substr( get_locale(), 0, 2 );
1087 + if ( $locale == 'el' ) {
1088 + $locale = 'gr';
1089 + }
1090 + return $locale;
1091 + }
1092 +
1093 + /**
1094 + * Get anonymous customer id.
1095 + *
1096 + * @return object
1097 + */
1098 + public static function anonymous_customer() {
1099 +
1100 + global $wpdb;
1101 + $id = get_option( 'wpsc-anonymous-user-id' );
1102 + if ( ! $id ) {
1103 +
1104 + // add anonymuos customer to customer table.
1105 + $success = $wpdb->insert(
1106 + $wpdb->prefix . 'psmsc_customers',
1107 + array(
1108 + 'name' => 'Anonymous',
1109 + 'email' => '[email protected]',
1110 + )
1111 + );
1112 + if ( ! $success ) {
1113 + return false;
1114 + }
1115 +
1116 + // Store anonymous customer ID in option.
1117 + $id = $wpdb->insert_id;
1118 + update_option( 'wpsc-anonymous-user-id', $id );
1119 + }
1120 +
1121 + $anonymous = new WPSC_Customer( $id );
1122 + return $anonymous;
1123 + }
1124 +
1125 + /**
1126 + * Calculate date range
1127 + *
1128 + * @param string $date - date string.
1129 + * @return array
1130 + */
1131 + public static function get_dashboard_date_range( $date ) {
1132 +
1133 + $today = new DateTime();
1134 + switch ( $date ) {
1135 + case 'today':
1136 + // Start of today at 00:00:00.
1137 + $today_start = clone $today;
1138 + $today_start->setTime( 0, 0, 0 );
1139 + // End of today with the current time.
1140 + $today_end = clone $today;
1141 + return array( $today_start->format( 'Y-m-d H:i:s' ), $today_end->format( 'Y-m-d H:i:s' ) );
1142 +
1143 + case 'yesterday':
1144 + // Start of yesterday at 00:00:00.
1145 + $yesterday_start = clone $today;
1146 + $yesterday_start->modify( '-1 day' )->setTime( 0, 0, 0 );
1147 + // End of yesterday at 23:59:59.
1148 + $yesterday_end = clone $yesterday_start;
1149 + $yesterday_end->setTime( 23, 59, 59 );
1150 + return array( $yesterday_start->format( 'Y-m-d H:i:s' ), $yesterday_end->format( 'Y-m-d H:i:s' ) );
1151 +
1152 + case 'last-7':
1153 + // Calculate last 7 days from today's date.
1154 + $last7_days_start = clone $today;
1155 + $last7_days_start->modify( '-6 days' )->setTime( 0, 0, 0 );
1156 + $last7_days_end = clone $today;
1157 + $last7_days_end->setTime( 23, 59, 59 );
1158 + return array( $last7_days_start->format( 'Y-m-d H:i:s' ), $last7_days_end->format( 'Y-m-d H:i:s' ) );
1159 +
1160 + case 'this-week':
1161 + // Calculate this week's start and end (Sunday to Saturday).
1162 + $week_start = clone $today;
1163 + $week_start->modify( 'last Sunday' )->setTime( 0, 0, 0 );
1164 + $week_end = clone $week_start;
1165 + $week_end->modify( 'next Saturday' )->setTime( 23, 59, 59 );
1166 + return array( $week_start->format( 'Y-m-d H:i:s' ), $week_end->format( 'Y-m-d H:i:s' ) );
1167 +
1168 + case 'last-week':
1169 + // Calculate last week's start and end (Sunday to Saturday).
1170 + $last_week_start = clone $today;
1171 + $last_week_start->modify( 'last Sunday' )->sub( new DateInterval( 'P7D' ) )->setTime( 0, 0, 0 );
1172 + $last_week_end = clone $last_week_start;
1173 + $last_week_end->modify( 'next Saturday' )->setTime( 23, 59, 59 );
1174 + return array( $last_week_start->format( 'Y-m-d H:i:s' ), $last_week_end->format( 'Y-m-d H:i:s' ) );
1175 +
1176 + case 'last-30-days':
1177 + // Calculate last 30 days from today's date.
1178 + $last30_days_start = clone $today;
1179 + $last30_days_start->modify( '-29 days' )->setTime( 0, 0, 0 );
1180 + return array( $last30_days_start->format( 'Y-m-d H:i:s' ), $today->format( 'Y-m-d H:i:s' ) );
1181 +
1182 + case 'this-month':
1183 + // Calculate this month's start and end date.
1184 + $start_month = clone $today;
1185 + $start_month->modify( 'first day of this month' )->setTime( 0, 0, 0 );
1186 + $end_month = clone $today;
1187 + $end_month->setTime( 23, 59, 59 );
1188 + return array( $start_month->format( 'Y-m-d H:i:s' ), $end_month->format( 'Y-m-d H:i:s' ) );
1189 +
1190 + case 'this-quarter':
1191 + // Calculate this quarter's start and end date.
1192 + $month = (int) $today->format( 'n' );
1193 + $start_quarter = clone $today;
1194 + $start_quarter->setDate( $today->format( 'Y' ), floor( ( $month - 1 ) / 3 ) * 3 + 1, 1 )->setTime( 0, 0, 0 );
1195 + return array( $start_quarter->format( 'Y-m-d H:i:s' ), $today->format( 'Y-m-d H:i:s' ) );
1196 +
1197 + case 'this-year':
1198 + // Calculate this year's start date to today.
1199 + $start_year = clone $today;
1200 + $start_year->setDate( $today->format( 'Y' ), 1, 1 )->setTime( 0, 0, 0 );
1201 + return array( $start_year->format( 'Y-m-d H:i:s' ), $today->format( 'Y-m-d H:i:s' ) );
1202 +
1203 + case 'last-month':
1204 + // Calculate last month's start and end date.
1205 + $last_month_start = clone $today;
1206 + $last_month_start->modify( 'first day of last month' )->setTime( 0, 0, 0 );
1207 + $last_month_end = clone $today;
1208 + $last_month_end->modify( 'last day of last month' )->setTime( 23, 59, 59 );
1209 + return array( $last_month_start->format( 'Y-m-d H:i:s' ), $last_month_end->format( 'Y-m-d H:i:s' ) );
1210 +
1211 + case 'last-quarter':
1212 + // Last quarter: from the first to the last day of the previous quarter.
1213 + $current_month = (int) $today->format( 'n' );
1214 +
1215 + // Calculate the first month of the previous quarter.
1216 + $last_quarter_start_month = 3 * ( floor( ( $current_month - 1 ) / 3 ) ) - 2;
1217 + if ( $last_quarter_start_month <= 0 ) {
1218 + // If the calculated month is 0 or negative, it means we are in Q1, so the last quarter is Q4 of the previous year.
1219 + $last_quarter_start_month += 12;
1220 + $start_last_quarter = ( clone $today )->setDate( $today->format( 'Y' ) - 1, $last_quarter_start_month, 1 )->setTime( 0, 0, 0 );
1221 + } else {
1222 + $start_last_quarter = ( clone $today )->setDate( $today->format( 'Y' ), $last_quarter_start_month, 1 )->setTime( 0, 0, 0 );
1223 + }
1224 +
1225 + // Calculate the end of the last quarter.
1226 + $end_last_quarter = clone $start_last_quarter;
1227 + $end_last_quarter->modify( '+2 months' )->modify( 'last day of this month' )->setTime( 23, 59, 59 );
1228 +
1229 + return array( $start_last_quarter->format( 'Y-m-d H:i:s' ), $end_last_quarter->format( 'Y-m-d H:i:s' ) );
1230 +
1231 + case 'last-year':
1232 + // Calculate last year's start and end date.
1233 + $start_last_year = clone $today;
1234 + $start_last_year->setDate( $today->format( 'Y' ) - 1, 1, 1 )->setTime( 0, 0, 0 );
1235 + $end_last_year = clone $start_last_year;
1236 + $end_last_year->setDate( $today->format( 'Y' ) - 1, 12, 31 )->setTime( 23, 59, 59 );
1237 + return array( $start_last_year->format( 'Y-m-d H:i:s' ), $end_last_year->format( 'Y-m-d H:i:s' ) );
1238 + }
1239 + }
1240 +
1241 + /**
1242 + * Generate random colors.
1243 + *
1244 + * @return string
1245 + */
1246 + public static function generate_random_color() {
1247 + $min_luminance = 0.7; // Adjust this value based on your preference.
1248 +
1249 + do {
1250 + $color = wp_rand( 0x000000, 0xFFFFFF );
1251 + $red = ( $color >> 16 ) & 0xFF;
1252 + $green = ( $color >> 8 ) & 0xFF;
1253 + $blue = $color & 0xFF;
1254 +
1255 + // Calculate luminance (brightness).
1256 + $luminance = ( 0.299 * $red + 0.587 * $green + 0.114 * $blue ) / 255;
1257 +
1258 + } while ( $luminance < $min_luminance );
1259 +
1260 + return '#' . dechex( $color );
1261 + }
1262 +
1263 + /**
1264 + * Get ticket url depending on view using ticket id.
1265 + *
1266 + * @param int $ticket_id - ticket id.
1267 + * @param string $view - view - frontend/backend.
1268 + * @return string
1269 + */
1270 + public static function get_ticket_url( $ticket_id, $view ) {
1271 +
1272 + $ticket_id = absint( $ticket_id );
1273 + $view = (int) $view;
1274 + $url = '';
1275 +
1276 + if ( ! $ticket_id ) {
1277 + return $url;
1278 + }
1279 +
1280 + $page_settings = get_option( 'wpsc-gs-page-settings', array() );
1281 +
1282 + // Detect ticket type.
1283 + $is_archive = false;
1284 + $ticket = new WPSC_Ticket( $ticket_id );
1285 + if ( ! $ticket->id ) {
1286 + $ticket = new WPSC_Archive_Ticket( $ticket_id );
1287 + if ( ! $ticket->id ) {
1288 + return $url;
1289 + }
1290 + $is_archive = true;
1291 + }
1292 +
1293 + $type = $is_archive
1294 + ? 'wpsc-archive-tickets&section=archive-ticket-list'
1295 + : 'wpsc-tickets&section=ticket-list';
1296 +
1297 + $admin_url = admin_url( 'admin.php?page=' . $type . '&id=' . $ticket_id );
1298 +
1299 + // Backend view always wins.
1300 + if ( $view === 0 || $is_archive ) {
1301 + return apply_filters( 'wpsc_get_ticket_url_by_view', $admin_url, $ticket_id, $view );
1302 + }
1303 +
1304 + // Frontend view (normal tickets only).
1305 + if ( $view === 1 ) {
1306 +
1307 + $ticket_url_page = $page_settings['ticket-url-page'] ?? '';
1308 + $support_page = absint( $page_settings['support-page'] ?? 0 );
1309 + $open_page = absint( $page_settings['open-ticket-page'] ?? 0 );
1310 +
1311 + if ( $ticket_url_page === 'support-page' && $support_page ) {
1312 +
1313 + $url = add_query_arg(
1314 + array(
1315 + 'wpsc-section' => 'ticket-list',
1316 + 'ticket-id' => $ticket_id,
1317 + ),
1318 + get_permalink( $support_page )
1319 + );
1320 +
1321 + } elseif ( $ticket_url_page === 'open-ticket-page' && $open_page && $ticket->auth_code ) {
1322 +
1323 + $url = add_query_arg(
1324 + array(
1325 + 'ticket-id' => $ticket_id,
1326 + 'auth-code' => $ticket->auth_code,
1327 + ),
1328 + get_permalink( $open_page )
1329 + );
1330 + }
1331 + }
1332 +
1333 + if ( ! $url ) {
1334 + $url = $admin_url;
1335 + }
1336 +
1337 + return apply_filters( 'wpsc_get_ticket_url_by_view', $url, $ticket_id, $view );
1338 + }
1339 +
1340 + /**
1341 + * Get unique, non-empty closed statuses from merged settings.
1342 + *
1343 + * Merges advanced and general settings, filters out empty values,
1344 + * ensures uniqueness, and returns an indexed array.
1345 + *
1346 + * @return array Unique, non-empty closed statuses.
1347 + */
1348 + public static function get_closed_statuses() {
1349 +
1350 + $tl_ms_advance_settings = get_option( 'wpsc-tl-ms-advanced' );
1351 + $general_settings = get_option( 'wpsc-gs-general' );
1352 +
1353 + // Merge, filter non-empty, get unique values, and convert all to string.
1354 + $closed_statuses = array_unique(
1355 + array_filter(
1356 + array_merge(
1357 + $tl_ms_advance_settings['closed-ticket-statuses'],
1358 + (array) $general_settings['close-ticket-status']
1359 + ),
1360 + function ( $statuses ) {
1361 + return ! empty( $statuses );
1362 + }
1363 + )
1364 + );
1365 + return array_map( 'strval', $closed_statuses ); // Ensure indexed array.
1366 + }
1367 +
1368 + /**
1369 + * Check whether any SupportCandy addon is active.
1370 + *
1371 + * @return bool
1372 + */
1373 + public static function is_paid_customer() {
1374 +
1375 + $cache_key = 'wpsc_is_paid_customer';
1376 + $cached_status = get_option( $cache_key, null );
1377 +
1378 + if ( null !== $cached_status ) {
1379 + return (bool) $cached_status;
1380 + }
1381 +
1382 + return self::update_paid_customer_status_option();
1383 + }
1384 +
1385 + /**
1386 + * Update the paid customer status option based on active addons.
1387 + *
1388 + * @param string $plugin - Optional plugin path to exclude from check (used during activation/deactivation).
1389 + * @return bool Updated paid customer status.
1390 + */
1391 + public static function update_paid_customer_status_option( $plugin = '' ) {
1392 + $cache_key = 'wpsc_is_paid_customer';
1393 +
1394 + $addon_plugins = array(
1395 + 'wpsc-agentgroup/wpsc-agentgroup.php',
1396 + 'wpsc-assign-agent-rules/wpsc-assign-agent-rules.php',
1397 + 'wpsc-automatic-close-ticket/wpsc-automatic-close-ticket.php',
1398 + 'wpsc-canned-reply/wpsc-canned-reply.php',
1399 + 'wpsc-edd/wpsc-edd.php',
1400 + 'wpsc-email-marketing-tools/wpsc-email-marketing-tools-integration.php',
1401 + 'wpsc-email-piping/wpsc-email-piping.php',
1402 + 'wpsc-export-ticket/wpsc-export-ticket.php',
1403 + 'wpsc-gravity-forms/wpsc-gravity-form-integration.php',
1404 + 'wpsc-lms/wpsc-lms.php',
1405 + 'wpsc-pressapps-knowledge-base/wpsc-pressapps-knowledge-base.php',
1406 + 'wpsc-print-ticket/wpsc-print-ticket.php',
1407 + 'wpsc-private-credentials/wpsc_private_credentials.php',
1408 + 'wpsc-productivity-suite/wpsc-productivity-suite.php',
1409 + 'wpsc-reports/wpsc-reports.php',
1410 + 'wpsc-satisfaction-survey/wpsc-satisfaction-survey.php',
1411 + 'wpsc-schedule-tickets/wpsc-schedule-tickets.php',
1412 + 'wpsc-sla/wpsc-sla.php',
1413 + 'wpsc-slack/wpsc-slack.php',
1414 + 'wpsc-timer/wpsc-timer.php',
1415 + 'wpsc-ultimate-faq/wpsc-ultimate-faq.php',
1416 + 'wpsc-usergroup/wpsc-usergroup.php',
1417 + 'wpsc-webhooks/wpsc-webhooks.php',
1418 + 'wpsc-woocommerce/wpsc-woocommerce.php',
1419 + 'wpsc-workflows/wpsc-workflows.php',
1420 + );
1421 +
1422 + $active_plugins = (array) get_option( 'active_plugins', array() );
1423 +
1424 + if ( current_filter() === 'deactivated_plugin' && ! empty( $plugin ) ) {
1425 + $active_plugins = array_diff( $active_plugins, array( $plugin ) );
1426 + }
1427 +
1428 + if ( is_multisite() ) {
1429 + $active_network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
1430 + $active_plugins = array_merge( $active_plugins, array_keys( $active_network_plugins ) );
1431 + }
1432 +
1433 + $is_paid_customer = ! empty( array_intersect( $addon_plugins, $active_plugins ) );
1434 + update_option( $cache_key, $is_paid_customer ? 1 : 0 );
1435 + return (bool) $is_paid_customer;
1436 + }
1437 +
1438 + /**
1439 + * Whether SupportCandy front-end scripts/styles should load on the current page,
1440 + * based on Settings -> General -> Page settings -> Load scripts.
1441 + *
1442 + * Translation aware: if the current page is a WPML or Polylang translation of a
1443 + * page selected in the 'Custom' list, scripts still load - the settings screen can
1444 + * only ever store the ID of the page in the language active while saving.
1445 + *
1446 + * @return bool
1447 + */
1448 + public static function is_load_scripts_page() {
1449 +
1450 + $page_settings = get_option( 'wpsc-gs-page-settings' );
1451 +
1452 + $load = true;
1453 +
1454 + if ( isset( $page_settings['load-scripts'] ) && $page_settings['load-scripts'] === 'custom' ) {
1455 +
1456 + $current_id = get_the_id();
1457 + $pages = isset( $page_settings['load-script-pages'] ) ? (array) $page_settings['load-script-pages'] : array();
1458 +
1459 + $load = $current_id && self::page_id_in_pages_or_translations( $current_id, $pages );
1460 + }
1461 +
1462 + return (bool) apply_filters( 'wpsc_load_frontend_scripts', $load, $page_settings );
1463 + }
1464 +
1465 + /**
1466 + * Check if given post id matches (directly or via translation) any of the given page ids.
1467 + *
1468 + * @param int $current_id current post id.
1469 + * @param array $page_ids selected page ids from settings.
1470 + * @return bool
1471 + */
1472 + private static function page_id_in_pages_or_translations( $current_id, $page_ids ) {
1473 +
1474 + if ( in_array( $current_id, $page_ids ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
1475 + return true;
1476 + }
1477 +
1478 + foreach ( $page_ids as $page_id ) {
1479 +
1480 + // WPML.
1481 + if ( has_filter( 'wpml_object_id' ) ) {
1482 + $translated_id = apply_filters( 'wpml_object_id', $page_id, 'page', false );
1483 + if ( $translated_id && (int) $translated_id === (int) $current_id ) {
1484 + return true;
1485 + }
1486 + }
1487 +
1488 + // Polylang.
1489 + if ( function_exists( 'pll_get_post_translations' ) ) {
1490 + $translations = pll_get_post_translations( $page_id );
1491 + if ( in_array( $current_id, $translations ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
1492 + return true;
1493 + }
1494 + }
1495 + }
1496 +
1497 + return false;
1498 + }
1499 +
1500 + /**
1501 + * Get current active language code, if a multilingual plugin is active.
1502 + *
1503 + * @return string|null
1504 + */
1505 + public static function get_current_language_code() {
1506 +
1507 + if ( has_filter( 'wpml_current_language' ) ) {
1508 + $lang = apply_filters( 'wpml_current_language', null );
1509 + return $lang ? $lang : null;
1510 + }
1511 +
1512 + if ( function_exists( 'pll_current_language' ) ) {
1513 + $lang = pll_current_language();
1514 + return $lang ? $lang : null;
1515 + }
1516 +
1517 + return null;
1518 + }
1519 + }
1846 1520 endif;
1847 1521
1848 -$GLOBALS['wpscfunction'] = new WPSC_Functions();
1522 +WPSC_Functions::init();