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

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

1,003 lines 28.5 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_Wh_Exception' ) ) :
7
8 final class WPSC_Wh_Exception {
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_wh_exceptions', array( __CLASS__, 'get_wh_exceptions' ) );
60 add_action( 'wp_ajax_wpsc_get_add_wh_exception', array( __CLASS__, 'get_add_wh_exception' ) );
61 add_action( 'wp_ajax_wpsc_set_add_wh_exception', array( __CLASS__, 'set_add_exception' ) );
62 add_action( 'wp_ajax_wpsc_get_edit_wh_exception', array( __CLASS__, 'get_edit_wh_exception' ) );
63 add_action( 'wp_ajax_wpsc_set_edit_wh_exception', array( __CLASS__, 'set_edit_wh_exception' ) );
64 add_action( 'wp_ajax_wpsc_delete_wh_exception', array( __CLASS__, 'delete_wh_exception' ) );
65 }
66
67 /**
68 * Apply schema for this model
69 *
70 * @return void
71 */
72 public static function apply_schema() {
73
74 $schema = array(
75 'id' => array(
76 'has_ref' => false,
77 'ref_class' => '',
78 'has_multiple_val' => false,
79 ),
80 'agent' => array(
81 'has_ref' => true,
82 'ref_class' => 'wpsc_agent',
83 'has_multiple_val' => false,
84 ),
85 'title' => array(
86 'has_ref' => false,
87 'ref_class' => '',
88 'has_multiple_val' => false,
89 ),
90 'exception_date' => array(
91 'has_ref' => true,
92 'ref_class' => 'datetime',
93 'has_multiple_val' => false,
94 ),
95 'start_time' => array(
96 'has_ref' => false,
97 'ref_class' => '',
98 'has_multiple_val' => false,
99 ),
100 'end_time' => array(
101 'has_ref' => false,
102 'ref_class' => '',
103 'has_multiple_val' => false,
104 ),
105 );
106 self::$schema = apply_filters( 'wpsc_wh_exception_schema', $schema );
107
108 // Prevent modify.
109 $prevent_modify = array( 'id' );
110 self::$prevent_modify = apply_filters( 'wpsc_wh_exception_prevent_modify', $prevent_modify );
111 }
112
113 /**
114 * Model constructor
115 *
116 * @param int $id - Optional. Data record id to retrive object for.
117 */
118 public function __construct( $id = 0 ) {
119
120 global $wpdb;
121
122 $id = intval( $id );
123
124 if ( isset( self::$cache[ $id ] ) ) {
125 $this->data = self::$cache[ $id ]->data;
126 return;
127 }
128
129 if ( $id > 0 ) {
130
131 $exception = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}psmsc_wh_exceptions WHERE id = " . $id, ARRAY_A );
132 if ( ! is_array( $exception ) ) {
133 return;
134 }
135
136 foreach ( $exception as $key => $val ) {
137 $this->data[ $key ] = $val !== null ? $val : '';
138 }
139
140 self::$cache[ $id ] = $this;
141 }
142 }
143
144 /**
145 * Magic get function to use with object arrow function
146 *
147 * @param string $var_name - variable name.
148 * @return mixed
149 */
150 public function __get( $var_name ) {
151
152 if ( ! isset( $this->data[ $var_name ] ) ||
153 $this->data[ $var_name ] == null ||
154 $this->data[ $var_name ] == ''
155 ) {
156 return self::$schema[ $var_name ]['has_multiple_val'] ? array() : '';
157 }
158
159 return self::$schema[ $var_name ]['has_ref'] && $this->data[ $var_name ] ?
160 WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $this->data[ $var_name ] ) :
161 $this->data[ $var_name ];
162 }
163
164 /**
165 * Magic function to use setting object field with arrow function
166 *
167 * @param string $var_name - (Required) property slug.
168 * @param mixed $value - (Required) value to set for a property.
169 * @return void
170 */
171 public function __set( $var_name, $value ) {
172
173 if (
174 ! isset( $this->data[ $var_name ] ) ||
175 in_array( $var_name, self::$prevent_modify )
176 ) {
177 return;
178 }
179
180 $data_val = is_object( $value ) ?
181 WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $value ) :
182 $value;
183
184 if ( $this->data[ $var_name ] == $data_val ) {
185 return;
186 }
187
188 $this->data[ $var_name ] = $data_val;
189 $this->is_modified = true;
190 }
191
192 /**
193 * Save changes made
194 *
195 * @return boolean
196 */
197 public function save() {
198
199 global $wpdb;
200
201 if ( ! $this->is_modified ) {
202 return true;
203 }
204
205 $data = $this->data;
206
207 unset( $data['id'] );
208 $success = $wpdb->update(
209 $wpdb->prefix . 'psmsc_wh_exceptions',
210 $data,
211 array( 'id' => $this->data['id'] )
212 );
213
214 $this->is_modified = false;
215 self::$cache[ $this->id ] = $this;
216 return $success ? true : false;
217 }
218
219 /**
220 * Insert new record
221 *
222 * @param array $data - insert data.
223 * @return WPSC_Wh_Exception
224 */
225 public static function insert( $data ) {
226
227 global $wpdb;
228
229 $success = $wpdb->insert(
230 $wpdb->prefix . 'psmsc_wh_exceptions',
231 $data
232 );
233
234 if ( ! $success ) {
235 return false;
236 }
237
238 $working_hr = new WPSC_Wh_Exception( $wpdb->insert_id );
239 return $working_hr;
240 }
241
242 /**
243 * Delete record from database
244 *
245 * @param WPSC_Exception $exception - exception object.
246 * @return boolean
247 */
248 public static function destroy( $exception ) {
249
250 global $wpdb;
251
252 $success = $wpdb->delete(
253 $wpdb->prefix . 'psmsc_wh_exceptions',
254 array( 'id' => $exception->id )
255 );
256 if ( ! $success ) {
257 return false;
258 }
259
260 unset( self::$cache[ $exception->id ] );
261 return true;
262 }
263
264 /**
265 * Set data to create new object using direct data. Used in find method
266 *
267 * @param array $data - data to set for object.
268 * @return void
269 */
270 private function set_data( $data ) {
271
272 foreach ( $data as $var_name => $val ) {
273 $this->data[ $var_name ] = $val !== null ? $val : '';
274 }
275 self::$cache[ $this->id ] = $this;
276 }
277
278 /**
279 * Find records based on given filters
280 *
281 * @param array $filter - array containing array items like search, where, orderby, order, page_no, items_per_page, etc.
282 * @param boolean $is_object - return data as array or object. Default object.
283 * @return mixed
284 */
285 public static function find( $filter = array(), $is_object = true ) {
286
287 global $wpdb;
288
289 $sql = 'SELECT * FROM ' . $wpdb->prefix . 'psmsc_wh_exceptions ';
290 $where = self::get_where( $filter );
291
292 $filter['items_per_page'] = isset( $filter['items_per_page'] ) ? $filter['items_per_page'] : 0;
293 $filter['page_no'] = isset( $filter['page_no'] ) ? $filter['page_no'] : 0;
294 $filter['orderby'] = isset( $filter['orderby'] ) ? $filter['orderby'] : 'exception_date';
295 $filter['order'] = isset( $filter['order'] ) ? $filter['order'] : 'ASC';
296
297 $order = WPSC_Functions::parse_order( $filter );
298
299 $sql = $sql . $where . $order;
300 $results = $wpdb->get_results( $sql, ARRAY_A );
301
302 // total results.
303 $sql = 'SELECT count(id) FROM ' . $wpdb->prefix . 'psmsc_wh_exceptions ';
304 $total_items = $wpdb->get_var( $sql . $where );
305
306 $response = WPSC_Functions::parse_response( $results, $total_items, $filter );
307
308 // Return array.
309 if ( ! $is_object ) {
310 return $response;
311 }
312
313 // create and return array of objects.
314 $temp_results = array();
315 foreach ( $response['results'] as $working_hr ) {
316
317 $ob = new WPSC_Wh_Exception();
318 $data = array();
319 foreach ( $working_hr as $key => $val ) {
320 $data[ $key ] = $val;
321 }
322 $ob->set_data( $data );
323 $temp_results[] = $ob;
324 }
325 $response['results'] = $temp_results;
326
327 return $response;
328 }
329
330 /**
331 * Get where for find method
332 *
333 * @param array $filter - user filter.
334 * @return array
335 */
336 private static function get_where( $filter ) {
337
338 $where = '';
339
340 // Set user defined filters.
341 $meta_query = isset( $filter['meta_query'] ) && $filter['meta_query'] ? $filter['meta_query'] : array();
342 if ( $meta_query ) {
343 $meta_query = WPSC_Functions::parse_user_filters( __CLASS__, $meta_query );
344 $where = $meta_query . ' ';
345 }
346
347 return $where ? 'WHERE ' . $where : '';
348 }
349
350 /**
351 * Load current class to reference classes
352 *
353 * @param array $classes - Associative array of class names indexed by its slug.
354 * @return array
355 */
356 public static function load_ref_class( $classes ) {
357
358 $classes['wpsc_wh_exception'] = array(
359 'class' => __CLASS__,
360 'save-key' => 'id',
361 );
362 return $classes;
363 }
364
365 /**
366 * Get exceptions of agent
367 *
368 * @param int $agent_id - Agent ID. Default is company.
369 * @return array
370 */
371 public static function get( $agent_id = 0 ) {
372
373 $exceptions = self::find(
374 array(
375 'meta_query' => array(
376 'relation' => 'AND',
377 array(
378 'slug' => 'agent',
379 'compare' => '=',
380 'val' => $agent_id,
381 ),
382 ),
383 )
384 );
385 $response = array();
386 foreach ( $exceptions['results'] as $key => $exceptions ) {
387 $response[ $key + 1 ] = $exceptions;
388 }
389 return $response;
390 }
391
392 /**
393 * Get exception list
394 *
395 * @return void
396 */
397 public static function get_wh_exceptions() {
398
399 if ( ! WPSC_Functions::is_site_admin() ) {
400 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
401 }
402
403 $unique_id = uniqid( 'wpsc_' );
404 $exceptions = self::find(
405 array(
406 'meta_query' => array(
407 'relation' => 'AND',
408 array(
409 'slug' => 'agent',
410 'compare' => '=',
411 'val' => 0,
412 ),
413 ),
414 )
415 )['results'];?>
416
417 <div class="wpsc-dock-container">
418 <?php
419 printf(
420 /* translators: Click here to see the documentation */
421 esc_attr__( '%s to see the documentation!', 'supportcandy' ),
422 '<a href="https://supportcandy.net/docs/working-hours/" target="_blank">' . esc_attr__( 'Click here', 'supportcandy' ) . '</a>'
423 );
424 ?>
425 </div>
426 <table class="wpsc-setting-tbl wpsc-wh-exceptions">
427 <thead>
428 <tr>
429 <th><?php esc_attr_e( 'Title', 'supportcandy' ); ?></th>
430 <th><?php esc_attr_e( 'Date', 'supportcandy' ); ?></th>
431 <th><?php esc_attr_e( 'Schedule', 'supportcandy' ); ?></th>
432 <th><?php esc_attr_e( 'Actions', 'supportcandy' ); ?></th>
433 </tr>
434 </thead>
435 <tbody>
436 <?php
437 foreach ( $exceptions as $exception ) :
438 ?>
439 <tr data-id="<?php echo esc_attr( $exception->id ); ?>">
440 <td><?php echo esc_attr( $exception->title ); ?></td>
441 <td><?php echo esc_attr( $exception->exception_date->format( 'F d, Y' ) ); ?></td>
442 <td>
443 <?php
444 $start_time = explode( ':', $exception->start_time );
445 $start_time = $start_time[0] . ':' . $start_time[1];
446 $end_time = explode( ':', $exception->end_time );
447 $end_time = $end_time[0] . ':' . $end_time[1];
448 echo esc_attr(
449 sprintf(
450 /* translators: %1$s: start time, %2$s: end time e.g. 04:00 - 05:00 */
451 esc_attr__( '%1$s - %2$s', 'supportcandy' ),
452 $start_time,
453 $end_time
454 )
455 );
456 ?>
457 </td>
458 <td>
459 <span class="wpsc-link" onclick="wpsc_get_edit_wh_exception(<?php echo esc_attr( $exception->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_wh_exception' ) ); ?>');"><?php esc_attr_e( 'Edit', 'supportcandy' ); ?></span> |
460 <span class="wpsc-link" onclick="wpsc_delete_wh_exception(<?php echo esc_attr( $exception->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_delete_wh_exception' ) ); ?>');"><?php esc_attr_e( 'Delete', 'supportcandy' ); ?></span>
461 </td>
462 </tr>
463 <?php
464 endforeach;
465 ?>
466 </tbody>
467 </table>
468 <script>
469 jQuery('table.wpsc-wh-exceptions').DataTable({
470 ordering: false,
471 pageLength: 20,
472 bLengthChange: false,
473 columnDefs: [
474 { targets: -1, searchable: false },
475 { targets: '_all', className: 'dt-left' }
476 ],
477 layout: {
478 topStart: {
479 buttons: [
480 {
481 text: '<?php esc_attr_e( 'Add new', 'supportcandy' ); ?>',
482 className: 'wpsc-button small primary',
483 action: function ( e, dt, node, config ) {
484
485 wpsc_show_modal();
486 var data = { action: 'wpsc_get_add_wh_exception' };
487 jQuery.post(supportcandy.ajax_url, data, function (response) {
488
489 // Set to modal
490 jQuery('.wpsc-modal-header').text(response.title);
491 jQuery('.wpsc-modal-body').html(response.body);
492 jQuery('.wpsc-modal-footer').html(response.footer);
493 // Display modal
494 wpsc_show_modal_inner_container();
495 });
496 }
497 }
498 ],
499 },
500 },
501 language: supportcandy.translations.datatables
502 });
503 </script>
504 <?php
505 wp_die();
506 }
507
508 /**
509 * Get add new exception
510 */
511 public static function get_add_wh_exception() {
512
513 if ( ! WPSC_Functions::is_site_admin() ) {
514 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
515 }
516
517 $title = esc_attr__( 'Add new exception', 'supportcandy' );
518 $unique_id = uniqid( 'wpsc_' );
519
520 ob_start();
521 ?>
522 <form action="#" onsubmit="return false;" class="wpsc-frm-add-exception">
523 <div class="wpsc-input-group">
524 <div class="label-container">
525 <label for=""><?php esc_attr_e( 'Title', 'supportcandy' ); ?></label>
526 <span class="required-char">*</span>
527 </div>
528 <input name="title" type="text" autocomplete="off">
529 </div>
530 <div class="wpsc-input-group">
531 <div class="label-container">
532 <label for=""><?php esc_attr_e( 'Date', 'supportcandy' ); ?></label>
533 <span class="required-char">*</span>
534 </div>
535 <input class="date exception_date <?php echo esc_attr( $unique_id ); ?>" name="exception_date" type="text" autocomplete="off">
536 </div>
537 <div class="wpsc-input-group">
538 <div class="label-container">
539 <label for=""><?php esc_attr_e( 'Schedule', 'supportcandy' ); ?></label>
540 </div>
541 <table class="wpsc-working-hrs">
542 <tr>
543 <td style="padding: 0 !important;">
544 <select class="wpsc-wh-start-time" name="start_time">
545 <?php self::get_start_time_slots( '00:00:00' ); ?>
546 </select>
547 </td>
548 <td style="text-align: center; width:45px; padding: 0 !important;">-</td>
549 <td style="padding: 0 !important;">
550 <select class="wpsc-wh-end-time" name="end_time">
551 <?php WPSC_Working_Hour::get_end_time_slots( '00:00:00', '00:15:00' ); ?>
552 </select>
553 </td>
554 </tr>
555 </table>
556 </div>
557 <script type="text/javascript">
558 var end_times = [];
559 jQuery('.date.<?php echo esc_attr( $unique_id ); ?>').flatpickr({minDate:new Date});
560 <?php
561 $current_slot = new DateTime( '2020-01-01 00:15:00' );
562 $second_last_slot = new DateTime( '2020-01-01 23:45:00' );
563 $last_slot = new DateTime( '2020-01-01 23:59:59' );
564
565 do {
566 $time = $current_slot->format( 'H:i:s' )
567 ?>
568 end_times.push({
569 val: '<?php echo esc_attr( $time ); ?>',
570 display_val: '<?php echo esc_attr( $current_slot->format( 'H:i' ) ); ?>',
571 });
572 <?php
573 if ( $current_slot == $second_last_slot ) {
574 $current_slot->add( new DateInterval( 'PT14M59S' ) );
575 } else {
576 $current_slot->add( new DateInterval( 'PT15M' ) );
577 }
578 } while ( $current_slot <= $last_slot );
579 ?>
580 supportcandy.temp = {end_times};
581
582 // Change event
583 jQuery('.wpsc-wh-start-time').change(function(){
584 var start_time = jQuery(this).val();
585 var tempArr = start_time.split(":");
586 var startDate = new Date(2020, 0, 1, tempArr[0], tempArr[1], tempArr[2]);
587 var cmbEndTime = jQuery('.wpsc-wh-end-time');
588 cmbEndTime.find('option').remove();
589 jQuery.each(supportcandy.temp.end_times, function(index, end_time){
590 var tempArr = end_time.val.split(":");
591 var endDate = new Date(2020, 0, 1, tempArr[0], tempArr[1], tempArr[2]);
592 if (startDate < endDate) {
593 var obj = document.createElement('OPTION');
594 var displayVal = document.createTextNode(end_time.display_val);
595 obj.setAttribute("value", end_time.val);
596 obj.appendChild(displayVal);
597 cmbEndTime.append(obj);
598 }
599 });
600 });
601 </script>
602 <input type="hidden" name="action" value="wpsc_set_add_wh_exception">
603 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_add_wh_exception' ) ); ?>">
604 </form>
605 <?php
606 $body = ob_get_clean();
607
608 ob_start();
609 ?>
610 <button class="wpsc-button small primary" onclick="wpsc_set_add_wh_exception(this);">
611 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
612 </button>
613 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
614 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
615 </button>
616 <?php
617 do_action( 'wpsc_get_add_priority' );
618 $footer = ob_get_clean();
619
620 $response = array(
621 'title' => $title,
622 'body' => $body,
623 'footer' => $footer,
624 );
625 wp_send_json( $response );
626 }
627
628 /**
629 * Save new holiday
630 *
631 * @return void
632 */
633 public static function set_add_exception() {
634
635 if ( check_ajax_referer( 'wpsc_set_add_wh_exception', '_ajax_nonce', false ) != 1 ) {
636 wp_send_json_error( 'Unauthorized request!', 401 );
637 }
638
639 if ( ! WPSC_Functions::is_site_admin() ) {
640 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
641 }
642
643 $title = isset( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : '';
644 if ( ! $title ) {
645 wp_send_json_error( 'Bad request', 400 );
646 }
647
648 // start date.
649 $exception_date = isset( $_POST['exception_date'] ) ? sanitize_text_field( wp_unslash( $_POST['exception_date'] ) ) : '';
650 if ( ! $exception_date ) {
651 wp_send_json_error( 'Bad request', 400 );
652 }
653 $flag = preg_match( '/\w{4}-\w{2}-\w{2}/', $exception_date );
654 if ( $flag !== 1 ) {
655 wp_send_json_error( 'Bad request', 400 );
656 }
657
658 // start time.
659 $start_time = isset( $_POST['start_time'] ) ? sanitize_text_field( wp_unslash( $_POST['start_time'] ) ) : '';
660 if ( ! $start_time ) {
661 wp_send_json_error( 'Bad request', 400 );
662 }
663 $flag = preg_match( '/\w{2}:\w{2}:00/', $start_time );
664 if ( $flag !== 1 ) {
665 wp_send_json_error( 'Bad request', 400 );
666 }
667
668 // end time.
669 $default_end_time = new DateTime( '2020-01-01 ' . $start_time );
670 $default_end_time->add( new DateInterval( 'PT15M' ) );
671 $end_time = isset( $_POST['end_time'] ) ? sanitize_text_field( wp_unslash( $_POST['end_time'] ) ) : $default_end_time->format( 'H:i:s' );
672 if ( ! $end_time ) {
673 wp_send_json_error( 'Bad request', 400 );
674 }
675 $flag = preg_match( '/\w{2}:\w{2}:00/', $end_time );
676 if ( $flag !== 1 ) {
677 wp_send_json_error( 'Bad request', 400 );
678 }
679
680 // delete existing record for the date if exists.
681 $exceptions = self::find(
682 array(
683 'meta_query' => array(
684 'relation' => 'AND',
685 array(
686 'slug' => 'agent',
687 'compare' => '=',
688 'val' => 0,
689 ),
690 array(
691 'slug' => 'exception_date',
692 'compare' => '=',
693 'val' => $exception_date . ' 00:00:00',
694 ),
695 ),
696 )
697 )['results'];
698 if ( $exceptions ) {
699 self::destroy( $exceptions[0] );
700 }
701
702 self::insert(
703 array(
704 'agent' => 0,
705 'title' => $title,
706 'exception_date' => $exception_date . ' 00:00:00',
707 'start_time' => $start_time,
708 'end_time' => $end_time,
709 )
710 );
711
712 wp_die();
713 }
714
715 /**
716 * Get edit holiday modal
717 */
718 public static function get_edit_wh_exception() {
719
720 if ( check_ajax_referer( 'wpsc_get_edit_wh_exception', '_ajax_nonce', false ) != 1 ) {
721 wp_send_json_error( 'Unauthorized request!', 401 );
722 }
723
724 if ( ! WPSC_Functions::is_site_admin() ) {
725 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
726 }
727
728 $id = isset( $_POST['exception_id'] ) ? intval( $_POST['exception_id'] ) : 0;
729 if ( ! $id ) {
730 wp_send_json_error( 'Bad request', 400 );
731 }
732
733 $exception = new WPSC_Wh_Exception( $id );
734 if ( ! $exception->id ) {
735 wp_send_json_error( 'Bad request', 400 );
736 }
737
738 $title = esc_attr__( 'Edit exception', 'supportcandy' );
739 $unique_id = uniqid( 'wpsc_' );
740
741 ob_start();
742 ?>
743 <form action="#" onsubmit="return false;" class="wpsc-frm-edit-exception">
744 <div class="wpsc-input-group">
745 <div class="label-container">
746 <label for=""><?php esc_attr_e( 'Title', 'supportcandy' ); ?></label>
747 <span class="required-char">*</span>
748 </div>
749 <input
750 name="title"
751 type="text"
752 value="<?php echo esc_attr( $exception->title ); ?>"
753 autocomplete="off">
754 </div>
755 <div class="wpsc-input-group">
756 <div class="label-container">
757 <label for=""><?php esc_attr_e( 'Date', 'supportcandy' ); ?></label>
758 <span class="required-char">*</span>
759 </div>
760 <input class="date exception_date <?php echo esc_attr( $unique_id ); ?>" value="<?php echo esc_attr( $exception->exception_date->format( 'Y-m-d' ) ); ?>" name="exception_date" type="text" autocomplete="off">
761 </div>
762 <div class="wpsc-input-group">
763 <div class="label-container">
764 <label for=""><?php esc_attr_e( 'Schedule', 'supportcandy' ); ?></label>
765 </div>
766 <table class="wpsc-working-hrs">
767 <tr>
768 <td style="padding: 0 !important;">
769 <select class="wpsc-wh-start-time" name="start_time">
770 <?php self::get_start_time_slots( $exception->start_time ); ?>
771 </select>
772 </td>
773 <td style="text-align: center; width:45px; padding: 0 !important;">-</td>
774 <td style="padding: 0 !important;">
775 <select class="wpsc-wh-end-time" name="end_time">
776 <?php WPSC_Working_Hour::get_end_time_slots( $exception->start_time, $exception->end_time ); ?>
777 </select>
778 </td>
779 </tr>
780 </table>
781 </div>
782 <script>
783 var end_times = [];
784 jQuery('.date.<?php echo esc_attr( $unique_id ); ?>').flatpickr();
785 <?php
786 $current_slot = new DateTime( '2020-01-01 00:15:00' );
787 $second_last_slot = new DateTime( '2020-01-01 23:45:00' );
788 $last_slot = new DateTime( '2020-01-01 23:59:59' );
789
790 do {
791 $time = $current_slot->format( 'H:i:s' )
792 ?>
793 end_times.push({
794 val: '<?php echo esc_attr( $time ); ?>',
795 display_val: '<?php echo esc_attr( $current_slot->format( 'H:i' ) ); ?>',
796 });
797 <?php
798 if ( $current_slot == $second_last_slot ) {
799 $current_slot->add( new DateInterval( 'PT14M59S' ) );
800 } else {
801 $current_slot->add( new DateInterval( 'PT15M' ) );
802 }
803 } while ( $current_slot <= $last_slot );
804 ?>
805 supportcandy.temp = {end_times};
806
807 // Change event
808 jQuery('.wpsc-wh-start-time').change(function(){
809 var start_time = jQuery(this).val();
810 var tempArr = start_time.split(":");
811 var startDate = new Date(2020, 0, 1, tempArr[0], tempArr[1], tempArr[2]);
812 var cmbEndTime = jQuery('.wpsc-wh-end-time');
813 cmbEndTime.find('option').remove();
814 jQuery.each(supportcandy.temp.end_times, function(index, end_time){
815 var tempArr = end_time.val.split(":");
816 var endDate = new Date(2020, 0, 1, tempArr[0], tempArr[1], tempArr[2]);
817 if (startDate < endDate) {
818 var obj = document.createElement('OPTION');
819 var displayVal = document.createTextNode(end_time.display_val);
820 obj.setAttribute("value", end_time.val);
821 obj.appendChild(displayVal);
822 cmbEndTime.append(obj);
823 }
824 });
825 });
826 </script>
827 <input type="hidden" name="action" value="wpsc_set_edit_wh_exception">
828 <input type="hidden" name="exception_id" value="<?php echo esc_attr( $exception->id ); ?>">
829 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_edit_wh_exception' ) ); ?>">
830 </form>
831 <?php
832 $body = ob_get_clean();
833
834 ob_start();
835 ?>
836 <button class="wpsc-button small primary" onclick="wpsc_set_edit_wh_exception(this);">
837 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
838 </button>
839 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
840 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
841 </button>
842 <?php
843 do_action( 'wpsc_get_add_priority' );
844 $footer = ob_get_clean();
845
846 $response = array(
847 'title' => $title,
848 'body' => $body,
849 'footer' => $footer,
850 );
851 wp_send_json( $response );
852 }
853
854 /**
855 * Set edit holiday
856 */
857 public static function set_edit_wh_exception() {
858
859 if ( check_ajax_referer( 'wpsc_set_edit_wh_exception', '_ajax_nonce', false ) != 1 ) {
860 wp_send_json_error( 'Unauthorized request!', 401 );
861 }
862
863 if ( ! WPSC_Functions::is_site_admin() ) {
864 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
865 }
866
867 $id = isset( $_POST['exception_id'] ) ? intval( $_POST['exception_id'] ) : 0;
868 if ( ! $id ) {
869 wp_send_json_error( 'Bad request', 400 );
870 }
871
872 $exception = new WPSC_Wh_Exception( $id );
873 if ( ! $exception->id ) {
874 wp_send_json_error( 'Bad request', 400 );
875 }
876
877 $title = isset( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : '';
878 if ( ! $title ) {
879 wp_send_json_error( 'Bad request', 400 );
880 }
881 $exception->title = $title;
882
883 // start date.
884 $exception_date = isset( $_POST['exception_date'] ) ? sanitize_text_field( wp_unslash( $_POST['exception_date'] ) ) : '';
885 if ( ! $exception_date ) {
886 wp_send_json_error( 'Bad request', 400 );
887 }
888 $flag = preg_match( '/\w{4}-\w{2}-\w{2}/', $exception_date );
889 if ( $flag !== 1 ) {
890 wp_send_json_error( 'Bad request', 400 );
891 }
892 $exception->exception_date = $exception_date . ' 00:00:00';
893
894 // start time.
895 $start_time = isset( $_POST['start_time'] ) ? sanitize_text_field( wp_unslash( $_POST['start_time'] ) ) : '';
896 if ( ! $start_time ) {
897 wp_send_json_error( 'Bad request', 400 );
898 }
899 $flag = preg_match( '/\w{2}:\w{2}:00/', $start_time );
900 if ( $flag !== 1 ) {
901 wp_send_json_error( 'Bad request', 400 );
902 }
903 $exception->start_time = $start_time;
904
905 // end time.
906 $default_end_time = new DateTime( '2020-01-01 ' . $start_time );
907 $default_end_time->add( new DateInterval( 'PT15M' ) );
908 $end_time = isset( $_POST['end_time'] ) ? sanitize_text_field( wp_unslash( $_POST['end_time'] ) ) : $default_end_time->format( 'H:i:s' );
909 if ( ! $end_time ) {
910 wp_send_json_error( 'Bad request', 400 );
911 }
912 $flag = preg_match( '/\w{2}:\w{2}:00/', $end_time );
913 if ( $flag !== 1 ) {
914 wp_send_json_error( 'Bad request', 400 );
915 }
916 $exception->end_time = $end_time;
917
918 $exception->save();
919 wp_die();
920 }
921
922 /**
923 * Delete holiday
924 */
925 public static function delete_wh_exception() {
926
927 if ( check_ajax_referer( 'wpsc_delete_wh_exception', '_ajax_nonce', false ) != 1 ) {
928 wp_send_json_error( 'Unauthorized request!', 401 );
929 }
930
931 if ( ! WPSC_Functions::is_site_admin() ) {
932 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
933 }
934
935 $id = isset( $_POST['exception_id'] ) ? intval( $_POST['exception_id'] ) : 0;
936 if ( ! $id ) {
937 wp_send_json_error( 'Bad request', 400 );
938 }
939
940 $exception = new WPSC_Wh_Exception( $id );
941 if ( ! $exception->id ) {
942 wp_send_json_error( 'Bad request', 400 );
943 }
944
945 self::destroy( $exception );
946 wp_die();
947 }
948
949 /**
950 * Get start time slots
951 *
952 * @param string $start_time - start time string.
953 * @return void
954 */
955 public static function get_start_time_slots( $start_time ) {
956
957 $current_slot = new DateTime( '2020-01-01 00:00:00' );
958 $last_slot = new DateTime( '2020-01-01 23:45:00' );
959 do {
960
961 $time = $current_slot->format( 'H:i:s' );
962 ?>
963 <option <?php selected( $time, $start_time ); ?> value="<?php echo esc_attr( $time ); ?>"><?php echo esc_attr( $current_slot->format( 'H:i' ) ); ?></option>
964 <?php
965 $current_slot->add( new DateInterval( 'PT15M' ) );
966
967 } while ( $current_slot <= $last_slot );
968 }
969
970 /**
971 * Get exception by date and agent id
972 *
973 * @param DateTime $date - datetime object.
974 * @param integer $agent_id - agent id.
975 * @return mixed
976 */
977 public static function get_exception_by_date( $date, $agent_id = 0 ) {
978
979 $exceptions = self::find(
980 array(
981 'meta_query' => array(
982 'relation' => 'AND',
983 array(
984 'slug' => 'agent',
985 'compare' => '=',
986 'val' => $agent_id,
987 ),
988 array(
989 'slug' => 'exception_date',
990 'compare' => '=',
991 'val' => $date->format( 'Y-m-d H:i:s' ),
992 ),
993 ),
994 )
995 );
996
997 return $exceptions['results'] ? $exceptions['results'][0] : false;
998 }
999 }
1000 endif;
1001
1002 WPSC_Wh_Exception::init();
1003