PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / trunk
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent vtrunk
3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / includes / models / class-wpsc-holiday.php

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

701 lines 17.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_Holiday' ) ) :
7
8 final class WPSC_Holiday {
9
10 /**
11 * Object data in key => val pair.
12 *
13 * @var array
14 */
15 private $data = array();
16
17 /**
18 * Set whether or not current object properties modified
19 *
20 * @var boolean
21 */
22 private $is_modified = false;
23
24 /**
25 * Schema for this model
26 *
27 * @var array
28 */
29 public static $schema = array();
30
31 /**
32 * Prevent fields to modify
33 *
34 * @var array
35 */
36 public static $prevent_modify = array();
37
38 /**
39 * DB object caching
40 *
41 * @var array
42 */
43 private static $cache = array();
44
45 /**
46 * Initialize this class
47 *
48 * @return void
49 */
50 public static function init() {
51
52 // Apply schema for this model.
53 add_action( 'init', array( __CLASS__, 'apply_schema' ), 2 );
54
55 // Get object of this class.
56 add_filter( 'wpsc_load_ref_classes', array( __CLASS__, 'load_ref_class' ) );
57
58 // Settings section.
59 add_action( 'wp_ajax_wpsc_get_holidays', array( __CLASS__, 'get_holidays' ) );
60 add_action( 'wp_ajax_wpsc_get_company_holiday_actions', array( __CLASS__, 'get_company_holiday_actions' ) );
61 add_action( 'wp_ajax_wpsc_set_company_holiday_actions', array( __CLASS__, 'set_company_holiday_actions' ) );
62 }
63
64 /**
65 * Apply schema for this model
66 *
67 * @return void
68 */
69 public static function apply_schema() {
70
71 $schema = array(
72 'id' => array(
73 'has_ref' => false,
74 'ref_class' => '',
75 'has_multiple_val' => false,
76 ),
77 'agent' => array(
78 'has_ref' => true,
79 'ref_class' => 'wpsc_agent',
80 'has_multiple_val' => false,
81 ),
82 'holiday' => array(
83 'has_ref' => true,
84 'ref_class' => 'datetime',
85 'has_multiple_val' => false,
86 ),
87 'is_recurring' => array(
88 'has_ref' => false,
89 'ref_class' => '',
90 'has_multiple_val' => false,
91 ),
92 );
93 self::$schema = apply_filters( 'wpsc_holidays_schema', $schema );
94
95 // Prevent modify.
96 $prevent_modify = array( 'id' );
97 self::$prevent_modify = apply_filters( 'wpsc_holidays_prevent_modify', $prevent_modify );
98 }
99
100 /**
101 * Model constructor
102 *
103 * @param int $id - Optional. Data record id to retrive object for.
104 */
105 public function __construct( $id = 0 ) {
106
107 global $wpdb;
108
109 $id = intval( $id );
110
111 if ( isset( self::$cache[ $id ] ) ) {
112 $this->data = self::$cache[ $id ]->data;
113 return;
114 }
115
116 if ( $id > 0 ) {
117
118 $holiday = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}psmsc_holidays WHERE id = " . $id, ARRAY_A );
119 if ( ! is_array( $holiday ) ) {
120 return;
121 }
122
123 foreach ( $holiday as $key => $val ) {
124 $this->data[ $key ] = $val !== null ? $val : '';
125 }
126
127 self::$cache[ $id ] = $this;
128 }
129 }
130
131 /**
132 * Magic get function to use with object arrow function
133 *
134 * @param string $var_name - variable name.
135 * @return mixed
136 */
137 public function __get( $var_name ) {
138
139 if ( ! isset( $this->data[ $var_name ] ) ||
140 $this->data[ $var_name ] == null ||
141 $this->data[ $var_name ] == ''
142 ) {
143 return self::$schema[ $var_name ]['has_multiple_val'] ? array() : '';
144 }
145
146 return self::$schema[ $var_name ]['has_ref'] && $this->data[ $var_name ] ?
147 WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $this->data[ $var_name ] ) :
148 $this->data[ $var_name ];
149 }
150
151 /**
152 * Magic function to use setting object field with arrow function
153 *
154 * @param string $var_name - (Required) property slug.
155 * @param mixed $value - (Required) value to set for a property.
156 * @return void
157 */
158 public function __set( $var_name, $value ) {
159
160 if (
161 ! isset( $this->data[ $var_name ] ) ||
162 in_array( $var_name, self::$prevent_modify )
163 ) {
164 return;
165 }
166
167 $data_val = is_object( $value ) ?
168 WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $value ) :
169 $value;
170
171 if ( $this->data[ $var_name ] == $data_val ) {
172 return;
173 }
174
175 $this->data[ $var_name ] = $data_val;
176 $this->is_modified = true;
177 }
178
179 /**
180 * Save changes made
181 *
182 * @return boolean
183 */
184 public function save() {
185
186 global $wpdb;
187
188 if ( ! $this->is_modified ) {
189 return true;
190 }
191
192 $data = $this->data;
193
194 unset( $data['id'] );
195 $success = $wpdb->update(
196 $wpdb->prefix . 'psmsc_holidays',
197 $data,
198 array( 'id' => $this->data['id'] )
199 );
200
201 $this->is_modified = false;
202 self::$cache[ $this->id ] = $this;
203 return $success ? true : false;
204 }
205
206 /**
207 * Insert new record
208 *
209 * @param array $data - insert data.
210 * @return WPSC_Holiday
211 */
212 public static function insert( $data ) {
213
214 global $wpdb;
215
216 $success = $wpdb->insert(
217 $wpdb->prefix . 'psmsc_holidays',
218 $data
219 );
220
221 if ( ! $success ) {
222 return false;
223 }
224
225 $working_hr = new WPSC_Holiday( $wpdb->insert_id );
226 return $working_hr;
227 }
228
229 /**
230 * Delete record of given ID
231 *
232 * @param WPSC_Holiday $holiday - holiday object.
233 * @return boolean
234 */
235 public static function destroy( $holiday ) {
236
237 global $wpdb;
238
239 $success = $wpdb->delete(
240 $wpdb->prefix . 'psmsc_holidays',
241 array( 'id' => $holiday->id )
242 );
243
244 if ( ! $success ) {
245 return false;
246 }
247
248 unset( self::$cache[ $holiday->id ] );
249 return true;
250 }
251
252 /**
253 * Set data to create new object using direct data. Used in find method
254 *
255 * @param array $data - data to set for object.
256 * @return void
257 */
258 private function set_data( $data ) {
259
260 foreach ( $data as $var_name => $val ) {
261 $this->data[ $var_name ] = $val !== null ? $val : '';
262 }
263 self::$cache[ $this->id ] = $this;
264 }
265
266 /**
267 * Find records based on given filters
268 *
269 * @param array $filter - array containing array items like search, where, orderby, order, page_no, items_per_page, etc.
270 * @param boolean $is_object - return data as array or object. Default object.
271 * @return mixed
272 */
273 public static function find( $filter = array(), $is_object = true ) {
274
275 global $wpdb;
276
277 $sql = 'SELECT * FROM ' . $wpdb->prefix . 'psmsc_holidays ';
278 $where = self::get_where( $filter );
279
280 $filter['items_per_page'] = isset( $filter['items_per_page'] ) ? $filter['items_per_page'] : 0;
281 $filter['page_no'] = isset( $filter['page_no'] ) ? $filter['page_no'] : 0;
282 $filter['orderby'] = isset( $filter['orderby'] ) ? $filter['orderby'] : 'holiday';
283 $filter['order'] = isset( $filter['order'] ) ? $filter['order'] : 'ASC';
284
285 $order = WPSC_Functions::parse_order( $filter );
286
287 $sql = $sql . $where . $order;
288 $results = $wpdb->get_results( $sql, ARRAY_A );
289
290 // total results.
291 $sql = 'SELECT count(id) FROM ' . $wpdb->prefix . 'psmsc_holidays ';
292 $total_items = $wpdb->get_var( $sql . $where );
293
294 $response = WPSC_Functions::parse_response( $results, $total_items, $filter );
295
296 // Return array.
297 if ( ! $is_object ) {
298 return $response;
299 }
300
301 // create and return array of objects.
302 $temp_results = array();
303 foreach ( $response['results'] as $working_hr ) {
304
305 $ob = new WPSC_Holiday();
306 $data = array();
307 foreach ( $working_hr as $key => $val ) {
308 $data[ $key ] = $val;
309 }
310 $ob->set_data( $data );
311 $temp_results[] = $ob;
312 }
313 $response['results'] = $temp_results;
314
315 return $response;
316 }
317
318 /**
319 * Get where for find method
320 *
321 * @param array $filter - user filter.
322 * @return array
323 */
324 private static function get_where( $filter ) {
325
326 $where = '';
327
328 // Set user defined filters.
329 $meta_query = isset( $filter['meta_query'] ) && $filter['meta_query'] ? $filter['meta_query'] : array();
330 if ( $meta_query ) {
331 $meta_query = WPSC_Functions::parse_user_filters( __CLASS__, $meta_query );
332 $where = $meta_query . ' ';
333 }
334
335 return $where ? 'WHERE ' . $where : '';
336 }
337
338 /**
339 * Load current class to reference classes
340 *
341 * @param array $classes - Associative array of class names indexed by its slug.
342 * @return array
343 */
344 public static function load_ref_class( $classes ) {
345
346 $classes['wpsc_holiday'] = array(
347 'class' => __CLASS__,
348 'save-key' => 'id',
349 );
350 return $classes;
351 }
352
353 /**
354 * Get holidays settings
355 *
356 * @return void
357 */
358 public static function get_holidays() {
359
360 if ( ! WPSC_Functions::is_site_admin() ) {
361 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
362 }
363
364 // get non-recurring holidays.
365 $non_recurring_holidays = array_map(
366 fn( $holiday ) => $holiday->holiday->format( 'Y-m-d' ),
367 self::find(
368 array(
369 'meta_query' => array(
370 'relation' => 'AND',
371 array(
372 'slug' => 'agent',
373 'compare' => '=',
374 'val' => 0,
375 ),
376 array(
377 'slug' => 'is_recurring',
378 'compare' => '=',
379 'val' => 0,
380 ),
381 ),
382 )
383 )['results']
384 );
385
386 // get recurring holidays.
387 $recurring_holidays = array_map(
388 fn( $holiday ) => $holiday->holiday->format( 'm-d' ),
389 self::find(
390 array(
391 'meta_query' => array(
392 'relation' => 'AND',
393 array(
394 'slug' => 'agent',
395 'compare' => '=',
396 'val' => 0,
397 ),
398 array(
399 'slug' => 'is_recurring',
400 'compare' => '=',
401 'val' => 1,
402 ),
403 ),
404 )
405 )['results']
406 );
407
408 $locale = explode( '_', get_locale() );?>
409
410 <div class="wpsc-dock-container">
411 <?php
412 printf(
413 /* translators: Click here to see the documentation */
414 esc_attr__( '%s to see the documentation!', 'supportcandy' ),
415 '<a href="https://supportcandy.net/docs/working-hours/" target="_blank">' . esc_attr__( 'Click here', 'supportcandy' ) . '</a>'
416 );
417 ?>
418 </div>
419 <div id="wpsc-calendar"></div>
420 <script>
421 supportcandy.temp.holidayList = {
422 'nonRecurring': <?php echo wp_json_encode( $non_recurring_holidays ); ?>,
423 'recurring': <?php echo wp_json_encode( $recurring_holidays ); ?>
424 };
425 var calendarEl = document.getElementById('wpsc-calendar');
426 var calendar = new FullCalendar.Calendar(calendarEl, {
427 initialView: 'dayGridMonth',
428 selectable: true,
429 locale: '<?php echo esc_attr( $locale[0] ); ?>',
430 dayCellDidMount: function(args) {
431
432 // non-recurring
433 var dateToCompare = args.date.toLocaleDateString('en-CA');
434 if (jQuery.inArray(dateToCompare, supportcandy.temp.holidayList.nonRecurring) != -1) {
435 jQuery(args.el).css('background-color', '#f0932b');
436 }
437
438 // recurring
439 var strArr = dateToCompare.split('-');
440 if (jQuery.inArray(strArr[1] + '-' + strArr[2], supportcandy.temp.holidayList.recurring) != -1) {
441 jQuery(args.el).css('background-color', '#eb4d4b');
442 }
443
444 },
445 select: function(info) {
446
447 var start = info.start;
448 var end = info.end;
449 end.setDate(end.getDate()-1);
450
451 var dateSelected = [];
452 do {
453 var d = start.toLocaleDateString('en-CA');
454 dateSelected.push(d);
455 start.setDate(parseInt(start.getDate())+1);
456 } while (start <= end);
457
458 wpsc_get_company_holiday_actions(dateSelected, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_company_holiday_actions' ) ); ?>');
459 }
460 }).render();
461 </script>
462 <?php
463 wp_die();
464 }
465
466 /**
467 * Get company holiday actions
468 *
469 * @return void
470 */
471 public static function get_company_holiday_actions() {
472
473 if ( check_ajax_referer( 'wpsc_get_company_holiday_actions', '_ajax_nonce', false ) != 1 ) {
474 wp_send_json_error( 'Unauthorized request!', 401 );
475 }
476
477 if ( ! WPSC_Functions::is_site_admin() ) {
478 wp_send_json_error( 'Unauthorized', 400 );
479 }
480
481 $date_selected = isset( $_POST['dateSelected'] ) ? array_filter( array_map( 'sanitize_text_field', wp_unslash( $_POST['dateSelected'] ) ) ) : array();
482 if ( ! $date_selected ) {
483 wp_send_json_error( 'Bad Request', 401 );
484 }
485
486 $title = esc_attr__( 'Add/Delete Holidays', 'supportcandy' );
487 $unique_id = uniqid( 'wpsc_' );
488
489 ob_start();
490 ?>
491 <form action="#" onsubmit="return false;" class="wpsc-frm-comp-holiday-actions">
492
493 <div class="wpsc-input-group">
494 <div class="label-container">
495 <label for=""><?php esc_attr_e( 'Action', 'supportcandy' ); ?></label>
496 </div>
497 <select class="<?php echo esc_attr( $unique_id ); ?>" name="holiday-action">
498 <option value="add"><?php esc_attr_e( 'Add new holidays', 'supportcandy' ); ?></option>
499 <option value="delete"><?php esc_attr_e( 'Delete existing holidays', 'supportcandy' ); ?></option>
500 </select>
501 </div>
502
503 <div class="wpsc-input-group is-recurring">
504 <div class="label-container">
505 <label for=""><?php esc_attr_e( 'Repeate every year', 'supportcandy' ); ?></label>
506 </div>
507 <select name="is-recurring">
508 <option value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
509 <option value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
510 </select>
511 </div>
512
513 <input type="hidden" name="action" value="wpsc_set_company_holiday_actions">
514 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_company_holiday_actions' ) ); ?>">
515
516 </form>
517 <script>
518 jQuery('.<?php echo esc_attr( $unique_id ); ?>').change(function(){
519 if (jQuery(this).val() == 'add') {
520 jQuery('.wpsc-input-group.is-recurring').show();
521 } else {
522 jQuery('.wpsc-input-group.is-recurring').hide();
523 }
524 });
525 </script>
526 <?php
527 $body = ob_get_clean();
528
529 ob_start();
530 ?>
531 <button class="wpsc-button small primary" onclick="wpsc_set_company_holiday_actions(this);">
532 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
533 </button>
534 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
535 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
536 </button>
537 <?php
538 $footer = ob_get_clean();
539
540 $response = array(
541 'title' => $title,
542 'body' => $body,
543 'footer' => $footer,
544 );
545
546 wp_send_json( $response, 200 );
547 }
548
549 /**
550 * Set company holiday actions
551 *
552 * @return void
553 */
554 public static function set_company_holiday_actions() {
555
556 if ( check_ajax_referer( 'wpsc_set_company_holiday_actions', '_ajax_nonce', false ) != 1 ) {
557 wp_send_json_error( 'Unauthorized request!', 401 );
558 }
559
560 global $wpdb;
561
562 if ( ! WPSC_Functions::is_site_admin() ) {
563 wp_send_json_error( 'Unauthorized', 400 );
564 }
565
566 $date_selected = isset( $_POST['dateSelected'] ) ? sanitize_text_field( wp_unslash( $_POST['dateSelected'] ) ) : '';
567 $date_selected = $date_selected ? array_filter( array_map( 'sanitize_text_field', explode( ',', $date_selected ) ) ) : array();
568 if ( ! $date_selected ) {
569 wp_send_json_error( 'Bad Request', 401 );
570 }
571
572 $action = isset( $_POST['holiday-action'] ) ? sanitize_text_field( wp_unslash( $_POST['holiday-action'] ) ) : '';
573 if ( ! $action ) {
574 wp_send_json_error( 'Bad Request', 401 );
575 }
576
577 $is_recurring = isset( $_POST['is-recurring'] ) ? intval( $_POST['is-recurring'] ) : '';
578 if ( ! is_numeric( $is_recurring ) ) {
579 wp_send_json_error( 'Bad Request', 401 );
580 }
581
582 foreach ( $date_selected as $date ) {
583
584 $date = new DateTime( $date . ' 00:00:00' );
585
586 // delete non-recurring record if exists.
587 $wpdb->delete(
588 $wpdb->prefix . 'psmsc_holidays',
589 array(
590 'holiday' => $date->format( 'Y-m-d H:i:s' ),
591 'agent' => 0,
592 )
593 );
594
595 // delete recurring record if exists.
596 $wpdb->query( "DELETE FROM {$wpdb->prefix}psmsc_holidays WHERE agent=0 AND DAYOFMONTH(holiday)=" . $date->format( 'd' ) . ' AND MONTH(holiday)=' . $date->format( 'm' ) . ' AND is_recurring=1' );
597
598 // add record.
599 if ( $action == 'add' ) {
600 self::insert(
601 array(
602 'agent' => 0,
603 'holiday' => $date->format( 'Y-m-d H:i:s' ),
604 'is_recurring' => $is_recurring,
605 )
606 );
607 }
608 }
609
610 // get non-recurring holidays.
611 $non_recurring_holidays = array();
612 $holidays = self::find(
613 array(
614 'meta_query' => array(
615 'relation' => 'AND',
616 array(
617 'slug' => 'agent',
618 'compare' => '=',
619 'val' => 0,
620 ),
621 array(
622 'slug' => 'is_recurring',
623 'compare' => '=',
624 'val' => 0,
625 ),
626 ),
627 )
628 )['results'];
629 foreach ( $holidays as $holiday ) {
630 $non_recurring_holidays[] = $holiday->holiday->format( 'Y-m-d' );
631 }
632
633 // get recurring holidays.
634 $recurring_holidays = array();
635 $holidays = self::find(
636 array(
637 'meta_query' => array(
638 'relation' => 'AND',
639 array(
640 'slug' => 'agent',
641 'compare' => '=',
642 'val' => 0,
643 ),
644 array(
645 'slug' => 'is_recurring',
646 'compare' => '=',
647 'val' => 1,
648 ),
649 ),
650 )
651 )['results'];
652 foreach ( $holidays as $holiday ) {
653 $recurring_holidays[] = $holiday->holiday->format( 'm-d' );
654 }
655
656 $response = array(
657 'action' => $action,
658 'is_recurring' => $is_recurring,
659 'holidayList' => array(
660 'nonRecurring' => $non_recurring_holidays,
661 'recurring' => $recurring_holidays,
662 ),
663 );
664
665 wp_send_json( $response, 200 );
666 }
667
668 /**
669 * Get holiday by date and agent id
670 *
671 * @param DateTime $date - datetime object.
672 * @param integer $agent_id - agent id.
673 * @return WPSC_Holiday
674 */
675 public static function get_holiday_by_date( $date, $agent_id = 0 ) {
676
677 $holiday = self::find(
678 array(
679 'meta_query' => array(
680 'relation' => 'AND',
681 array(
682 'slug' => 'agent',
683 'compare' => '=',
684 'val' => $agent_id,
685 ),
686 array(
687 'slug' => 'holiday',
688 'compare' => '=',
689 'val' => $date->format( 'Y-m-d H:i:s' ),
690 ),
691 ),
692 )
693 );
694
695 return $holiday['results'] ? $holiday['results'][0] : false;
696 }
697 }
698 endif;
699
700 WPSC_Holiday::init();
701