PluginProbe
Easy Appointments / 4.0
Easy Appointments v4.0
4.0.2.1 4.0.2 4.0.1 3.12.27 3.12.28 3.12.29 4.0 3.12.26 3.12.25 trunk 2.0.0 2.1.0 2.1.1 2.1.3 2.1.4 2.10.0 2.2.0 2.2.3 2.2.4 2.3.0 2.3.1 2.3.11 2.3.2 2.3.3 2.3.4 All 79 releases
easy-appointments / src / admin.php

admin.php in Easy Appointments 4.0, at src/admin.php

1,558 lines 56.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // If this file is called directly, abort.
4 if (!defined('WPINC')) {
5 die;
6 }
7
8 /**
9 * Admin panel
10 */
11 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound
12 class EAAdminPanel
13 {
14 protected $compatibility_mode;
15
16 /**
17 * @var EAOptions
18 */
19 protected $options;
20
21 /**
22 * @var EALogic
23 */
24 protected $logic;
25
26 /**
27 * @var EADBModels
28 */
29 protected $models;
30
31 /**
32 * @var EADateTime
33 */
34 protected $datetime;
35
36 /**
37 * @var array
38 */
39 protected $customers = [];
40
41 /**
42 * @var string
43 */
44 protected $search = '';
45
46 /**
47 * @var int
48 */
49 protected $paged = 1;
50
51 /**
52 * @var int
53 */
54 protected $total_pages = 1;
55
56 /**
57 * EAAdminPanel constructor.
58 * @param EAOptions $options
59 * @param EALogic $logic
60 * @param EADBModels $models
61 * @param EADateTime $datetime
62 */
63 function __construct($options, $logic, $models, $datetime)
64 {
65 $this->options = $options;
66 $this->logic = $logic;
67 $this->models = $models;
68 $this->datetime = $datetime;
69 }
70
71 /**
72 * Init action callbacks
73 */
74 public function init()
75 {
76 // Hook for adding admin menus
77 add_action('admin_menu', array($this, 'add_menu_pages'));
78 add_action('admin_menu', array($this, 'my_booking_menu'));
79
80 // Init action
81 add_action('admin_init', array($this, 'init_scripts'));
82 add_action('admin_init', array($this, 'easy_ea_init_polylang_register_strings'));
83 //add_action( 'admin_enqueue_scripts', array( $this, 'init' ) );
84 }
85
86 function easy_ea_register_option_strings() {
87 if ( function_exists( 'pll_register_string' ) ) {
88 $options = array(
89 'trans.service' => 'Service',
90 'trans.location' => 'Location',
91 'trans.worker' => 'Worker',
92 'trans.service_option' => 'Select Service',
93 'trans.location_option' => 'Select Location',
94 'trans.worker_option' => 'Select Worker',
95 'trans.done_message' => 'Done',
96 'trans.submit_button_text' => 'Submit',
97 'trans.create_new_booking' => 'Create New Booking',
98 'pending.subject.email' => 'New Reservation #id#',
99 'pending.subject.visitor.email' => 'Reservation #id#',
100 'gdpr.label' => 'By using this form you agree with the storage and handling of your data by this website.',
101 'gdpr.message' => 'You need to accept the privacy checkbox',
102 );
103
104 foreach ( $options as $key => $value ) {
105 $my_string = $this->options->get_option_value($key, $value);
106 if ( ! empty( $my_string ) ) {
107 $this->easy_ea_polylang_register_strings( $my_string );
108 }
109 }
110 }
111
112 }
113
114
115
116 function easy_ea_polylang_register_strings( $my_string ) {
117 if ( function_exists( 'pll_register_string' ) ) {
118 pll_register_string(
119 'ea_label_' . md5( $my_string ), // unique key
120 $my_string,
121 'Easy Appointments'
122 );
123 }
124 }
125
126 public function easy_ea_init_polylang_register_strings() {
127 $this->easy_ea_register_option_strings();
128 $rows = $this->models->get_all_rows("ea_meta_fields", array(), array('position' => 'ASC'));
129 $rows = apply_filters( 'easy_ea_form_rows', $rows);
130 foreach ( $rows as $row ) {
131 if ( ! empty( $row->label ) ) {
132 $this->easy_ea_polylang_register_strings( $row->label );
133 if ( function_exists( 'pll__' ) ) {
134 $row->label = esc_html( pll__( $row->label ) );
135 } else {
136 $row->label = esc_html( $row->label );
137 }
138 }
139 }
140 }
141 public function my_booking_menu() {
142
143 if (!is_user_logged_in()) {
144 return;
145 }
146 if (current_user_can('manage_options')) {
147 return;
148 }
149
150 if (!empty($this->options->get_option_value('fullcalendar.my_booking'))) {
151
152 add_menu_page(
153 esc_html__('My Bookings', 'easy-appointments'),
154 esc_html__('My Bookings', 'easy-appointments'),
155 'read',
156 'my-bookings',
157 array($this, 'render_my_bookings_page'),
158 'dashicons-calendar-alt',
159 30
160 );
161 }
162 }
163
164 public function render_my_bookings_page() {
165 global $wpdb;
166
167 $current_user = wp_get_current_user();
168
169 if (!$current_user || !$current_user->ID) {
170 echo '<div class="wrap"><p>' . esc_html__('User not found.', 'easy-appointments') . '</p></div>';
171 return;
172 }
173
174 $user_id = (int) $current_user->ID;
175
176 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only filter parameter.
177 $filter = isset( $_GET['filter'] ) ? sanitize_key( wp_unslash( $_GET['filter'] ) ) : 'upcoming';
178
179 if ( ! in_array( $filter, array( 'upcoming', 'past' ), true ) ) {
180 $filter = 'upcoming';
181 }
182
183 $today = current_time('Y-m-d');
184
185 // ===== PAGINATION =====
186 $per_page = 10;
187 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only pagination parameter.
188 $paged = isset( $_GET['paged'] ) ? max( 1, absint( wp_unslash( $_GET['paged'] ) ) ) : 1;
189 $offset = ( $paged - 1 ) * $per_page;
190
191 $cache_key = 'ea_booking_total_' . md5( $user_id . '|' . $filter . '|' . $today );
192
193 $total = wp_cache_get( $cache_key, 'easy_appointments' );
194
195 if ( false === $total ) {
196 if ( 'past' === $filter ) {
197 $sql = $wpdb->prepare(
198 "SELECT COUNT(*)
199 FROM {$wpdb->prefix}ea_appointments a
200 WHERE a.user = %d
201 AND a.date < %s",
202 $user_id,
203 $today
204 );
205 } else {
206 $sql = $wpdb->prepare(
207 "SELECT COUNT(*)
208 FROM {$wpdb->prefix}ea_appointments a
209 WHERE a.user = %d
210 AND a.date >= %s",
211 $user_id,
212 $today
213 );
214 }
215 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared -- Querying plugin custom table.
216 $total = (int) $wpdb->get_var( $sql );
217
218 wp_cache_set( $cache_key, $total, 'easy_appointments', HOUR_IN_SECONDS );
219 }
220
221 $total_pages = ceil($total / $per_page);
222
223 // ===== FETCH DATA =====
224 if ( 'past' === $filter ) {
225
226 $sql = $wpdb->prepare(
227 "SELECT
228 a.id,
229 a.date,
230 a.start,
231 a.end,
232 a.status,
233 s.name AS service_name,
234 l.name AS location_name,
235 st.name AS staff_name
236 FROM {$wpdb->prefix}ea_appointments a
237 LEFT JOIN {$wpdb->prefix}ea_services s ON s.id = a.service
238 LEFT JOIN {$wpdb->prefix}ea_locations l ON l.id = a.location
239 LEFT JOIN {$wpdb->prefix}ea_staff st ON st.id = a.worker
240 WHERE a.user = %d
241 AND a.date < %s
242 ORDER BY a.date DESC
243 LIMIT %d OFFSET %d",
244 $user_id,
245 $today,
246 $per_page,
247 $offset
248 );
249
250 } else {
251
252 $sql = $wpdb->prepare(
253 "SELECT
254 a.id,
255 a.date,
256 a.start,
257 a.end,
258 a.status,
259 s.name AS service_name,
260 l.name AS location_name,
261 st.name AS staff_name
262 FROM {$wpdb->prefix}ea_appointments a
263 LEFT JOIN {$wpdb->prefix}ea_services s ON s.id = a.service
264 LEFT JOIN {$wpdb->prefix}ea_locations l ON l.id = a.location
265 LEFT JOIN {$wpdb->prefix}ea_staff st ON st.id = a.worker
266 WHERE a.user = %d
267 AND a.date >= %s
268 ORDER BY a.date ASC
269 LIMIT %d OFFSET %d",
270 $user_id,
271 $today,
272 $per_page,
273 $offset
274 );
275 }
276 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared -- Querying plugin custom table.
277 $appointments = $wpdb->get_results( $sql );
278
279 echo '<div class="wrap">';
280 echo '<h1>' . esc_html__('My Bookings', 'easy-appointments') . '</h1>';
281
282 // ===== FILTER BUTTONS =====
283 echo '<div style="margin-bottom:15px;">';
284 echo '<a class="button ' . ($filter === 'upcoming' ? 'button-primary' : '') . '" href="?page=my-bookings&filter=upcoming">' . esc_html__('Upcoming', 'easy-appointments') . '</a> ';
285 echo '<a class="button ' . ($filter === 'past' ? 'button-primary' : '') . '" href="?page=my-bookings&filter=past">' . esc_html__('Past', 'easy-appointments') . '</a>';
286 echo '</div>';
287
288
289
290 echo '<table class="widefat striped">';
291 echo '<thead>
292 <tr>
293 <th>' . esc_html__('Date', 'easy-appointments') . '</th>
294 <th>' . esc_html__('Time', 'easy-appointments') . '</th>
295 <th>' . esc_html__('Service', 'easy-appointments') . '</th>
296 <th>' . esc_html__('Location', 'easy-appointments') . '</th>
297 <th>' . esc_html__('Employee', 'easy-appointments') . '</th>
298 <th>' . esc_html__('Status', 'easy-appointments') . '</th>
299 </tr>
300 </thead>
301 <tbody>';
302
303 if (empty($appointments)) {
304 echo '<tr>
305 <td colspan="6">' . esc_html__('No bookings found.', 'easy-appointments') . '</td>';
306 echo '</tr>';
307 echo '</tbody></table>';
308 return;
309 }
310
311 foreach ($appointments as $a) {
312 echo '<tr>
313 <td>' . esc_html($a->date) . '</td>
314 <td>' . esc_html($a->start . ' - ' . $a->end) . '</td>
315 <td>' . esc_html($a->service_name ?: '-') . '</td>
316 <td>' . esc_html($a->location_name ?: '-') . '</td>
317 <td>' . esc_html($a->staff_name ?: '-') . '</td>
318 <td>' . esc_html(ucfirst($a->status)) . '</td>
319 </tr>';
320 }
321
322 echo '</tbody></table>';
323 if ($total_pages > 1) {
324 echo '<div class="tablenav"><div class="tablenav-pages">';
325
326 for ($i = 1; $i <= $total_pages; $i++) {
327 $class = ( $i == $paged ) ? 'button button-primary' : 'button';
328
329 $url = add_query_arg(
330 array(
331 'page' => 'my-bookings',
332 'filter' => $filter,
333 'paged' => absint( $i ),
334 ),
335 admin_url( 'admin.php' )
336 );
337
338 echo '<a class="' . esc_attr( $class ) . '" href="' . esc_url( $url ) . '">' . esc_html( $i ) . '</a> ';
339 }
340
341 echo '</div></div>';
342 }
343
344 echo '</div>';
345 }
346
347
348
349
350 public function handle_update_customer_ajax() {
351 if ( ! current_user_can('manage_options') ) {
352 wp_send_json_error(['message' => 'Unauthorized'], 403);
353 }
354 global $wpdb;
355 check_ajax_referer('ea_customer_edit', 'ea_nonce');
356
357 $table = $wpdb->prefix . 'ea_customers';
358 if ( ! isset( $_POST['id'] ) ) {
359 wp_send_json_error(
360 array( 'message' => esc_html__( 'Missing ID.', 'easy-appointments' ) ),
361 400
362 );
363 }
364
365 $id = intval( wp_unslash( $_POST['id'] ) );
366 $data = array(
367 'name' => isset( $_POST['name'] )
368 ? sanitize_text_field( wp_unslash( $_POST['name'] ) )
369 : '',
370
371 'email' => isset( $_POST['email'] )
372 ? sanitize_email( wp_unslash( $_POST['email'] ) )
373 : '',
374
375 'mobile' => isset( $_POST['mobile'] )
376 ? sanitize_text_field( wp_unslash( $_POST['mobile'] ) )
377 : '',
378
379 'address' => isset( $_POST['address'] )
380 ? sanitize_text_field( wp_unslash( $_POST['address'] ) )
381 : '',
382 );
383
384 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
385 $updated = $wpdb->update($table, $data, ['id' => $id]);
386 if ($updated !== false) {
387 wp_send_json_success();
388 }
389 wp_send_json_error();
390 }
391
392 public function handle_insert_customer_ajax() {
393 if ( ! current_user_can('manage_options') ) {
394 wp_send_json_error(['message' => 'Unauthorized'], 403);
395 }
396 check_ajax_referer('ea_customer_edit', 'ea_nonce');
397
398 $name = isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : '';
399 $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '';
400 $mobile = isset($_POST['mobile']) ? sanitize_text_field(wp_unslash($_POST['mobile'])) : '';
401 $address = isset($_POST['address']) ? sanitize_textarea_field(wp_unslash($_POST['address'])) : '';
402
403
404 global $wpdb;
405 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
406 $inserted = $wpdb->insert("{$wpdb->prefix}ea_customers", [
407 'name' => $name,
408 'email' => $email,
409 'mobile' => $mobile,
410 'address' => $address,
411 ]);
412
413 if ($inserted) {
414 wp_send_json_success();
415 } else {
416 wp_send_json_error();
417 }
418 }
419
420
421 /**
422 * Init of admin page
423 */
424 public function init_scripts()
425 {
426 // admin panel script
427 wp_register_script(
428 'ea-compatibility-mode',
429 EA_PLUGIN_URL . 'js/backbone.sync.fix.js',
430 array('backbone'),
431 EASY_APPOINTMENTS_VERSION,
432 true
433 );
434
435 // admin panel script
436 wp_register_script(
437 'time-picker-i18n',
438 EA_PLUGIN_URL . 'js/libs/jquery-ui-timepicker-addon-i18n.js',
439 array('jquery', 'time-picker'),
440 EASY_APPOINTMENTS_VERSION,
441 true
442 );
443
444 // admin panel script
445 wp_register_script(
446 'time-picker',
447 EA_PLUGIN_URL . 'js/libs/jquery-ui-timepicker-addon.js',
448 array('jquery', 'jquery-ui-datepicker'),
449 EASY_APPOINTMENTS_VERSION,
450 true
451 );
452
453 // admin panel script
454 wp_register_script(
455 'jquery-chosen',
456 EA_PLUGIN_URL . 'js/libs/chosen.jquery.min.js',
457 array('jquery'),
458 EASY_APPOINTMENTS_VERSION,
459 true
460 );
461
462 // vacation panel script
463 wp_register_script(
464 'ea-admin-bundle',
465 EA_PLUGIN_URL . 'js/bundle.js',
466 array('jquery', 'wp-api', 'wp-i18n'),
467 EASY_APPOINTMENTS_VERSION,
468 true
469 );
470
471 // vacation style
472 wp_register_style(
473 'ea-admin-bundle-css',
474 EA_PLUGIN_URL . 'css/theme/main.css',
475 array(),
476 EASY_APPOINTMENTS_VERSION
477 );
478
479 // admin panel script
480 wp_register_script(
481 'ea-settings',
482 EA_PLUGIN_URL . 'js/admin.prod.js',
483 array(
484 'jquery',
485 'moment',
486 'jquery-ui-datepicker',
487 'ea-datepicker-localization',
488 'time-picker',
489 'backbone',
490 'underscore',
491 'jquery-ui-sortable',
492 'jquery-chosen',
493 'wp-api',
494 'thickbox'
495 ),
496 EASY_APPOINTMENTS_VERSION,
497 true
498 );
499
500 // appointments panel script
501 wp_register_script(
502 'ea-appointments',
503 EA_PLUGIN_URL . 'js/settings.prod.js',
504 array(
505 'jquery',
506 'moment',
507 'jquery-ui-datepicker',
508 'ea-datepicker-localization',
509 'time-picker',
510 'backbone',
511 'wp-api',
512 'underscore'
513 ),
514 EASY_APPOINTMENTS_VERSION,
515 true
516 );
517
518 // report panel script
519 wp_register_script(
520 'ea-report',
521 EA_PLUGIN_URL . 'js/report.prod.js',
522 array('jquery', 'time-picker', 'ea-datepicker-localization', 'backbone', 'underscore', 'wp-api'),
523 EASY_APPOINTMENTS_VERSION,
524 true
525 );
526
527 wp_register_script(
528 'ea-datepicker-localization',
529 EA_PLUGIN_URL . 'js/libs/jquery-ui-i18n.min.js',
530 array('jquery'),
531 EASY_APPOINTMENTS_VERSION,
532 true
533 );
534
535 wp_register_script(
536 'ea-tinymce',
537 EA_PLUGIN_URL . 'js/libs/mce.plugin.code.min.js',
538 array('tinymce_js'),
539 EASY_APPOINTMENTS_VERSION,
540 true
541 );
542
543 // admin style
544 wp_register_style(
545 'ea-admin-css',
546 EA_PLUGIN_URL . 'css/admin.css',
547 array(),
548 EASY_APPOINTMENTS_VERSION
549 );
550
551 // admin style
552 wp_register_style(
553 'jquery-chosen',
554 EA_PLUGIN_URL . 'css/chosen.min.css',
555 array(),
556 EASY_APPOINTMENTS_VERSION
557 );
558
559
560 // report style
561 wp_register_style(
562 'ea-report-css',
563 EA_PLUGIN_URL . 'css/report.css',
564 array(),
565 EASY_APPOINTMENTS_VERSION
566 );
567
568 // admin style
569 wp_register_style(
570 'ea-admin-awesome-css',
571 EA_PLUGIN_URL . 'css/font-awesome.css',
572 array(),
573 EASY_APPOINTMENTS_VERSION
574 );
575
576 // admin style
577 wp_register_style(
578 'time-picker',
579 EA_PLUGIN_URL . 'css/jquery-ui-timepicker-addon.css',
580 array(),
581 EASY_APPOINTMENTS_VERSION
582 );
583
584 wp_register_style(
585 'jquery-style',
586 EA_PLUGIN_URL . 'css/jquery-ui.css',
587 array(),
588 EASY_APPOINTMENTS_VERSION
589 );
590
591 // custom fonts
592 wp_register_style(
593 'ea-admin-fonts-css',
594 EA_PLUGIN_URL . 'css/fonts.css',
595 array(),
596 EASY_APPOINTMENTS_VERSION
597 );
598
599 }
600
601 public function user_capability_callback($default_capability, $menu_slug) {
602 return apply_filters('easy-appointments-user-menu-capabilities', $default_capability, $menu_slug);
603 }
604
605 /**
606 * Adds required JS
607 */
608 public function add_settings_js()
609 {
610 $this->compatibility_mode = $this->options->get_option_value('compatibility.mode', 0);
611
612 if (!empty($this->compatibility_mode)) {
613 wp_enqueue_script('ea-compatibility-mode');
614 }
615
616 // we need tinyMce for WYSIWYG editor
617 wp_enqueue_script(
618 'tinymce_js',
619 includes_url( 'js/tinymce/' ) . 'wp-tinymce.php',
620 array( 'jquery' ),
621 EASY_APPOINTMENTS_VERSION,
622 true
623 );
624 wp_enqueue_script('ea-tinymce');
625 wp_enqueue_style('ea-editor-style', includes_url('/css/editor.min.css'),array(), EASY_APPOINTMENTS_VERSION, true);
626
627 // wp_enqueue_script( 'time-picker-i18n' );
628 wp_enqueue_script('ea-settings');
629
630 wp_enqueue_style('ea-admin-css');
631 wp_enqueue_style('jquery-style');
632 wp_enqueue_style('time-picker');
633 wp_enqueue_style('ea-admin-awesome-css');
634 wp_enqueue_style('thickbox');
635 wp_enqueue_style('jquery-chosen');
636 wp_enqueue_style('ea-admin-fonts-css');
637
638 $object_name = array(
639 'ajax_url' => admin_url( 'admin-ajax.php' ),
640 'ea_security_nonce' => wp_create_nonce('ea_ajax_check_nonce'),
641 );
642 $object_name = apply_filters('easy_ea_localize_filter',$object_name,'ea_obj');
643
644 wp_localize_script('ea-settings', 'ea_obj', $object_name);
645 // style editor
646 }
647
648 /**
649 * Adds required JS
650 */
651 public function add_appointments_js()
652 {
653 $this->compatibility_mode = $this->options->get_option_value('compatibility.mode', 0);
654
655 if (!empty($this->compatibility_mode)) {
656 wp_enqueue_script('ea-compatibility-mode');
657 }
658
659 wp_enqueue_script('ea-appointments');
660 wp_enqueue_style('ea-admin-css');
661 wp_enqueue_style('jquery-style');
662 wp_enqueue_style('time-picker');
663 wp_enqueue_style('ea-admin-awesome-css');
664 }
665 /**
666 * Customer required JS
667 */
668 public function add_customer_js()
669 {
670 $this->compatibility_mode = $this->options->get_option_value('compatibility.mode', 0);
671
672 if (!empty($this->compatibility_mode)) {
673 wp_enqueue_script('ea-compatibility-mode');
674 }
675
676 wp_enqueue_script('ea-appointments');
677 wp_enqueue_style('ea-admin-css');
678 wp_enqueue_style('jquery-style');
679 wp_enqueue_style('time-picker');
680 wp_enqueue_style('ea-admin-awesome-css');
681 }
682
683 /**
684 * JS for report admin page
685 */
686 public function add_report_js()
687 {
688 if (!empty($this->compatibility_mode)) {
689 wp_enqueue_script('ea-compatibility-mode');
690 }
691
692 wp_enqueue_script('ea-report');
693 wp_enqueue_script('jquery-ui-datepicker');
694 wp_enqueue_style('ea-admin-awesome-css');
695 wp_enqueue_style('ea-report-css');
696 wp_enqueue_style('jquery-style');
697 wp_enqueue_style('ea-admin-fonts-css');
698 }
699
700 /**
701 * create menu structure
702 */
703 public function add_menu_pages()
704 {
705 // IMPORTANT: the new-ui/*.php classes (EA_Appointments_New_UI etc.)
706 // all attach their own submenus to this same top-level slug via
707 // add_submenu_page(self::PARENT_SLUG, ...), so the top-level menu
708 // itself must always be registered, in both UI modes - only the
709 // classic-only submenus below get skipped in "new" UI mode.
710 $new_ui = class_exists('EA_UI_Switcher') && EA_UI_Switcher::is_new_ui();
711
712 // top_level_menu
713 add_menu_page(
714 'Appointments',
715 'Appointments',
716 'edit_posts',
717 'easy_app_top_level',
718 null,
719 'dashicons-calendar-alt',
720 '26'
721 );
722
723 // Rename first / landing page. Always routes through
724 // top_level_appointments() - that method itself checks the UI
725 // mode and delegates to EA_Appointments_New_UI::render_page()
726 // when new UI mode is active, so this single entry point can't
727 // get out of sync with the mode.
728 $page_app_suffix = add_submenu_page(
729 'easy_app_top_level',
730 __('Appointments', 'easy-appointments'),
731 __('Appointments', 'easy-appointments'),
732 $this->user_capability_callback('edit_posts', 'easy_app_top_level'),
733 'easy_app_top_level',
734 array($this, 'top_level_appointments')
735 );
736
737 if ($new_ui) {
738 // Register Reports submenus at priority 20 so they load in the correct sequence.
739 add_action('admin_menu', array($this, 'add_reports_menu_new_ui'), 20);
740 return;
741 }
742
743 // locations page
744 $page_location_suffix = add_submenu_page(
745 'easy_app_top_level',
746 __('Locations', 'easy-appointments'),
747 '1. ' . __('Locations', 'easy-appointments'),
748 $this->user_capability_callback('manage_options', 'easy_app_locations'),
749 'easy_app_locations',
750 array($this, 'locations_page')
751 );
752
753 // services
754 $page_services_suffix = add_submenu_page(
755 'easy_app_top_level',
756 __('Services', 'easy-appointments'),
757 '2. ' . __('Services', 'easy-appointments'),
758 $this->user_capability_callback('manage_options', 'easy_app_services'),
759 'easy_app_services',
760 array($this, 'services_page')
761 );
762
763 // Workers
764 $page_worker_suffix = add_submenu_page(
765 'easy_app_top_level',
766 __('Employees', 'easy-appointments'),
767 '3. ' . __('Employees', 'easy-appointments'),
768 $this->user_capability_callback('manage_options', 'easy_app_workers'),
769 'easy_app_workers',
770 array($this, 'workers_page')
771 );
772
773 // connections
774 $page_connections_suffix = add_submenu_page(
775 'easy_app_top_level',
776 __('Connections', 'easy-appointments'),
777 '4. ' . __('Connections', 'easy-appointments'),
778 $this->user_capability_callback('manage_options', 'easy_app_connections'),
779 'easy_app_connections',
780 array($this, 'connections_page')
781 );
782
783 // Publish
784 $page_connections_suffix = add_submenu_page(
785 'easy_app_top_level',
786 __('Publish', 'easy-appointments'),
787 '5. ' . __('Publish', 'easy-appointments'),
788 $this->user_capability_callback('manage_options', 'easy_app_publish'),
789 'easy_app_publish',
790 array($this, 'publish_page')
791 );
792
793 // customer
794 $page_customer_suffix = add_submenu_page(
795 'easy_app_top_level',
796 __('Customers', 'easy-appointments'),
797 __('Customers', 'easy-appointments'),
798 'manage_options', // Ensure admin access
799 'easy_app_customer',
800 array($this, 'customer_page')
801 );
802
803
804 // settings
805 $page_settings_suffix = add_submenu_page(
806 'easy_app_top_level',
807 __('Settings', 'easy-appointments'),
808 __('Settings', 'easy-appointments'),
809 $this->user_capability_callback('manage_options', 'easy_app_settings'),
810 'easy_app_settings',
811 array($this, 'top_settings_menu')
812 );
813
814 // vacation page
815 $page_vacation_suffix = add_submenu_page(
816 'easy_app_top_level',
817 __('Tools', 'easy-appointments'),
818 __('Tools', 'easy-appointments'),
819 $this->user_capability_callback('manage_options', 'easy_app_tools'),
820 'easy_app_tools',
821 array($this, 'tools_page')
822 );
823
824 // vacation page
825 $page_vacation_suffix = add_submenu_page(
826 'easy_app_top_level',
827 __('Vacation', 'easy-appointments'),
828 __('Vacation', 'easy-appointments'),
829 $this->user_capability_callback('manage_options', 'easy_app_vacation'),
830 'easy_app_vacation',
831 array($this, 'vacation_page')
832 );
833
834 // Overview - report
835 $page_new_report_suffix = add_submenu_page(
836 'easy_app_top_level',
837 __('Reports', 'easy-appointments'),
838 __('Reports', 'easy-appointments'),
839 $this->user_capability_callback('manage_options', 'easy_app_new_reports'),
840 'easy_app_new_reports',
841 array($this, 'new_reports_page')
842 );
843
844 // Overview - report
845 $page_report_suffix = add_submenu_page(
846 'easy_app_top_level',
847 __('Reports (Legacy)', 'easy-appointments'),
848 __('Reports (Legacy)', 'easy-appointments'),
849 $this->user_capability_callback('manage_options', 'easy_app_reports'),
850 'easy_app_reports',
851 array($this, 'reports_page')
852 );
853
854 // Overview - report
855 $page_new_report_suffix = add_submenu_page(
856 'easy_app_top_level',
857 __('Help & Support', 'easy-appointments'),
858 __('Help & Support', 'easy-appointments'),
859 $this->user_capability_callback('manage_options', 'easy_app_help_suppport'),
860 'easy_app_help_suppport',
861 array($this, 'easy_app_help_support')
862 );
863 // Premium Extension
864 if (! is_plugin_active( 'easy-appointments-connect/main.php' ) ) {
865 $page_vacation_suffix = add_submenu_page(
866 'easy_app_top_level',
867 __('Premium Extensions', 'easy-appointments'),
868 '<span id="ea-premium-extension-link">'.__('Premium Extensions', 'easy-appointments').'</span>',
869 $this->user_capability_callback('manage_options', 'easy_app_vacation'),
870 'https://easy-appointments.com#buyextension'
871 );
872 }
873
874 add_action('load-' . $page_settings_suffix, array($this, 'add_settings_js'));
875 add_action('load-' . $page_app_suffix, array($this, 'add_appointments_js'));
876 add_action('load-' . $page_report_suffix, array($this, 'add_report_js'));
877 add_action('load-' . $page_customer_suffix, array($this, 'add_customer_js'));
878 }
879
880 public function easy_app_help_support()
881 {
882 // check if APS tags are on
883 if ($this->is_asp_tags_are_on()) {
884 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
885 return;
886 }
887
888 wp_enqueue_style('ea-admin-bundle-css');
889 wp_enqueue_script('ea-admin-bundle');
890
891 $settings = $this->options->get_options();
892 $settings['rest_url'] = get_rest_url();
893 $settings['rest_url_fullcalendar'] = EasyEAApiFullCalendar::get_url();
894 $settings['export_tags_list'] = $this->models->get_all_tags_for_template();
895 $settings['saved_tags_list'] = get_option('ea_excel_columns', '');
896
897 $wpurl = get_bloginfo('wpurl');
898 $url = get_bloginfo('url');
899
900 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
901 $settings['image_base'] = str_replace("/wp-content", "", content_url());
902 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
903
904 if (function_exists('wp_set_script_translations')) {
905 wp_set_script_translations('ea-admin-bundle', 'easy-appointments');
906 }
907
908 require_once EA_SRC_DIR . 'templates/help-and-support.tpl.php';
909 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
910 }
911
912 /**
913 * Content of appointments admin page
914 */
915 public function top_level_appointments()
916 {
917 // This is the plugin's main-menu landing page. Delegate straight
918 // to the New UI's Appointments screen when new UI mode is active,
919 // so the landing page always matches the currently selected mode.
920 if (
921 class_exists('EA_UI_Switcher')
922 && EA_UI_Switcher::is_new_ui()
923 && class_exists('EA_Appointments_New_UI')
924 ) {
925 EA_Appointments_New_UI::render_page();
926 return;
927 }
928
929 // check if APS tags are on
930 if ($this->is_asp_tags_are_on()) {
931 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
932 return;
933 }
934
935 $settings = $this->options->get_options();
936 $data_vacation = $this->options->get_option_value('vacations', '[]');
937
938 $settings['date_format'] = $this->datetime->convert_to_moment_format(get_option('date_format', 'F j, Y'));
939
940
941
942 wp_localize_script('ea-appointments', 'ea_settings', $settings);
943 wp_localize_script('ea-appointments', 'ea_vacations', json_decode($data_vacation));
944 // wp_localize_script('ea-appointments', 'ea_app_status', $this->logic->getStatus());
945 // Provide status list for appointments page. If EA Client Portal plugin
946 // is active and current user is Administrator or Employee, limit the
947 // statuses to only Confirmed and Cancelled (simpler dropdown for portal).
948 $statuses = $this->logic->getStatus();
949
950 if ( ! function_exists( 'is_plugin_active' ) ) {
951 if ( file_exists( ABSPATH . 'wp-admin/includes/plugin.php' ) ) {
952 include_once ABSPATH . 'wp-admin/includes/plugin.php';
953 }
954 }
955
956 if ( function_exists( 'is_plugin_active' ) && is_plugin_active( 'ea-client-portal/ea-client-portal.php' ) ) {
957 // Only limit statuses for EA Client Portal employee users.
958 if ( function_exists( 'ea_is_employee' ) && ea_is_employee() ) {
959 $statuses = array(
960 'canceled' => __('cancelled', 'easy-appointments'),
961 'confirmed' => __('confirmed', 'easy-appointments'),
962 );
963 }
964 }
965
966 wp_localize_script('ea-appointments', 'ea_app_status', apply_filters('easy_ea_client_portal_appointment_statuses', $statuses));
967
968 wp_localize_script('ea-appointments', 'ea_connections', $this->models->get_connections_combinations());
969
970 $screen = get_current_screen();
971 if ($screen) {
972 $screen->add_help_tab(array(
973 'id' => 'easyapp_settings_help'
974 , 'title' => 'Appointments manager'
975 , 'content' => '<p>Use filter for date to reduce output results for appointments. You can filter by <b>location</b>, <b>service</b>, <b>worker</b>, <b>status</b> and <b>date</b>.</p>'
976 ));
977
978 $screen->set_help_sidebar('<a href="https://easy-appointments.com/documentation/">More info!</a>');
979 }
980
981 require_once EA_SRC_DIR . 'templates/appointments.tpl.php';
982 require_once EA_SRC_DIR . 'templates/inlinedata.sorted.tpl.php';
983 }
984
985 /**
986 * Register Reports submenus for the New UI to keep reports menu in both UIs
987 */
988 public function add_reports_menu_new_ui()
989 {
990 // new reports page
991 add_submenu_page(
992 'easy_app_top_level',
993 __('Reports', 'easy-appointments'),
994 __('Reports', 'easy-appointments'),
995 $this->user_capability_callback('manage_options', 'easy_app_new_reports'),
996 'easy_app_new_reports',
997 array($this, 'new_reports_page')
998 );
999
1000 // reports page
1001 $page_report_suffix = add_submenu_page(
1002 'easy_app_top_level',
1003 __('Reports (Legacy)', 'easy-appointments'),
1004 __('Reports (Legacy)', 'easy-appointments'),
1005 $this->user_capability_callback('manage_options', 'easy_app_reports'),
1006 'easy_app_reports',
1007 array($this, 'reports_page')
1008 );
1009
1010 add_action('load-' . $page_report_suffix, array($this, 'add_report_js'));
1011 }
1012
1013 /**
1014 * Content of top menu page
1015 */
1016 public function reports_page()
1017 {
1018 // check if APS tags are on
1019 if ($this->is_asp_tags_are_on()) {
1020 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1021 return;
1022 }
1023
1024 $settings = $this->options->get_options();
1025 wp_localize_script('ea-report', 'ea_settings', $settings);
1026
1027 $screen = get_current_screen();
1028 $screen->add_help_tab(array(
1029 'id' => 'easyapp_settings_help'
1030 , 'title' => 'Time table'
1031 , 'content' => '<p>Time table report shows free slots for every location - service - worker connection on whole month</p>' .
1032 '<p>There can you see free times an how many slots are taken.</p>'
1033 ));
1034
1035 $screen->set_help_sidebar('<a href="https://easy-appointments.com/documentation/">More info!</a>');
1036
1037 require_once EA_SRC_DIR . 'templates/report.tpl.php';
1038 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1039 }
1040
1041 /**
1042 * Content of top menu page
1043 */
1044 public function top_settings_menu()
1045 {
1046 // check if APS tags are on
1047 if ($this->is_asp_tags_are_on()) {
1048 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1049 return;
1050 }
1051
1052 $settings = $this->options->get_options();
1053 $settings['rest_url'] = get_rest_url();
1054 wp_localize_script('ea-settings', 'ea_settings', $settings);
1055
1056 $screen = get_current_screen();
1057 $screen->add_help_tab(array(
1058 'id' => 'easyapp_settings_help'
1059 , 'title' => 'Settings'
1060 , 'content' => '<p>You need to define at least one location, worker and service! Without that widget won\'t work.</p>'
1061 ));
1062
1063 $screen->set_help_sidebar('<a href="https://easy-appointments.com/documentation/">More info!</a>');
1064
1065 require_once EA_SRC_DIR . 'templates/admin.tpl.php';
1066 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1067 }
1068
1069 /**
1070 * Content of top menu page
1071 */
1072 public function vacation_page()
1073 {
1074 // check if APS tags are on
1075 if ($this->is_asp_tags_are_on()) {
1076 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1077 return;
1078 }
1079
1080 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1081
1082 wp_enqueue_style('ea-admin-bundle-css');
1083 wp_enqueue_script('ea-admin-bundle');
1084
1085 $settings = $this->options->get_options();
1086 $settings['rest_url'] = get_rest_url();
1087 $settings['rest_url_vacation'] = EasyEAVacationActions::get_url();
1088
1089 $wpurl = get_bloginfo('wpurl');
1090 $url = get_bloginfo('url');
1091
1092 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
1093 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1094 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1095
1096 if (function_exists('wp_set_script_translations')) {
1097 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1098 }
1099
1100 $screen = get_current_screen();
1101 $screen->add_help_tab(array(
1102 'id' => 'easyapp_settings_help'
1103 , 'title' => 'Settings'
1104 , 'content' => '<p>You need to define at least one location, worker and service! Without that widget won\'t work.</p>'
1105 ));
1106
1107 $screen->set_help_sidebar('<a href="https://easy-appointments.com/documentation/">More info!</a>');
1108
1109 require_once EA_SRC_DIR . 'templates/vacation.tpl.php';
1110 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1111 }
1112
1113 /**
1114 * Content of top menu page
1115 */
1116 public function locations_page()
1117 {
1118 // check if APS tags are on
1119 if ($this->is_asp_tags_are_on()) {
1120 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1121 return;
1122 }
1123
1124 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1125
1126 wp_enqueue_style('ea-admin-bundle-css');
1127 wp_enqueue_script('ea-admin-bundle');
1128
1129 $settings = $this->options->get_options();
1130 $settings['rest_url'] = get_rest_url();
1131
1132 $wpurl = get_bloginfo('wpurl');
1133 $url = get_bloginfo('url');
1134
1135 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
1136 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1137 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1138
1139 if (function_exists('wp_set_script_translations')) {
1140 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1141 }
1142
1143 require_once EA_SRC_DIR . 'templates/locations.tpl.php';
1144 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1145 }
1146
1147 /**
1148 * Content of top menu page
1149 */
1150 public function workers_page()
1151 {
1152 // check if APS tags are on
1153 if ($this->is_asp_tags_are_on()) {
1154 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1155 return;
1156 }
1157
1158 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1159
1160 wp_enqueue_style('ea-admin-bundle-css');
1161 wp_enqueue_script('ea-admin-bundle');
1162
1163 $settings = $this->options->get_options();
1164 $settings['rest_url'] = get_rest_url();
1165
1166 $wpurl = get_bloginfo('wpurl');
1167 $url = get_bloginfo('url');
1168
1169 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
1170 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1171 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1172
1173 if (function_exists('wp_set_script_translations')) {
1174 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1175 }
1176
1177 require_once EA_SRC_DIR . 'templates/workers.tpl.php';
1178 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1179 }
1180
1181 /**
1182 * Content of top menu page
1183 */
1184 public function services_page()
1185 {
1186 // check if APS tags are on
1187 if ($this->is_asp_tags_are_on()) {
1188 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1189 return;
1190 }
1191
1192 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1193
1194 wp_enqueue_style('ea-admin-bundle-css');
1195 wp_enqueue_script('ea-admin-bundle');
1196 wp_enqueue_editor();
1197
1198 $settings = $this->options->get_options();
1199 $settings['rest_url'] = get_rest_url();
1200
1201 $wpurl = get_bloginfo('wpurl');
1202 $url = get_bloginfo('url');
1203
1204 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
1205 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1206 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1207
1208 if (function_exists('wp_set_script_translations')) {
1209 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1210 }
1211
1212 require_once EA_SRC_DIR . 'templates/services.tpl.php';
1213 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1214 }
1215
1216 /**
1217 * Publish page
1218 */
1219 public function publish_page()
1220 {
1221 // check if APS tags are on
1222 if ($this->is_asp_tags_are_on()) {
1223 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1224 return;
1225 }
1226
1227 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1228
1229 wp_enqueue_style('ea-admin-bundle-css');
1230 wp_enqueue_script('ea-admin-bundle');
1231
1232 $settings = $this->options->get_options();
1233 $settings['rest_url'] = get_rest_url();
1234 $settings['rest_url_clear_log'] = EasyEALogActions::clear_error_url();
1235
1236 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1237 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1238
1239 if (function_exists('wp_set_script_translations')) {
1240 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1241 }
1242
1243 require_once EA_SRC_DIR . 'templates/publish.tpl.php';
1244 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1245 }
1246
1247 /**
1248 * Content of top menu page
1249 */
1250 public function connections_page()
1251 {
1252 // check if APS tags are on
1253 if ($this->is_asp_tags_are_on()) {
1254 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1255 return;
1256 }
1257
1258 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1259
1260 wp_enqueue_style('ea-admin-bundle-css');
1261 wp_enqueue_script('ea-admin-bundle');
1262
1263 $settings = $this->options->get_options();
1264 $settings['rest_url'] = get_rest_url();
1265 $settings['time_format'] = $this->datetime->convert_to_moment_format(get_option('time_format', 'H:i'));
1266 $settings['date_format'] = $this->datetime->convert_to_moment_format(get_option('date_format', 'F j, Y'));
1267
1268 $wpurl = get_bloginfo('wpurl');
1269 $url = get_bloginfo('url');
1270
1271 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
1272 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1273 $settings['rest_url_extend_connections'] = EasyEALogActions::extend_connection_url();
1274
1275 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1276
1277 if (function_exists('wp_set_script_translations')) {
1278 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1279 }
1280
1281 require_once EA_SRC_DIR . 'templates/connections.tpl.php';
1282 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1283 }
1284
1285 /**
1286 * Content of customer
1287 */
1288 public function customer_page() {
1289 global $wpdb;
1290
1291 // ASP tag check
1292 if ($this->is_asp_tags_are_on()) {
1293 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1294 return;
1295 }
1296
1297 // Table name
1298 $table = $wpdb->prefix . 'ea_customers';
1299
1300 // Pagination
1301 $per_page = 10;
1302 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1303 $paged = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
1304 $offset = ($paged - 1) * $per_page;
1305
1306 // Search
1307 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1308 $search = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
1309 $search_sql = '';
1310 $search_params = [];
1311
1312 if (!empty($search)) {
1313 $search_sql = "WHERE name LIKE %s OR email LIKE %s OR mobile LIKE %s";
1314 $like = '%' . $wpdb->esc_like($search) . '%';
1315 $search_params = [$like, $like, $like];
1316 }
1317
1318 // Total count
1319 $total_sql = "SELECT COUNT(*) FROM $table " . ($search_sql ? $search_sql : '');
1320 if (!empty($search_sql)) {
1321 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1322 $total_customers = $wpdb->get_var($wpdb->prepare($total_sql, ...$search_params));
1323 } else {
1324 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1325 $total_customers = $wpdb->get_var($total_sql);
1326 }
1327
1328 // Fetch paginated data
1329 $query_sql = "SELECT * FROM $table " . ($search_sql ? $search_sql : '') . " ORDER BY id DESC LIMIT %d OFFSET %d";
1330 if (!empty($search_sql)) {
1331 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1332 $customers = $wpdb->get_results($wpdb->prepare($query_sql, ...array_merge($search_params, [$per_page, $offset])));
1333 } else {
1334 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1335 $customers = $wpdb->get_results($wpdb->prepare($query_sql, $per_page, $offset));
1336 }
1337
1338 // Calculate total pages
1339 $total_pages = ceil($total_customers / $per_page);
1340
1341 // Make available to template
1342 $this->customers = $customers;
1343 $this->search = $search;
1344 $this->paged = $paged;
1345 $this->total_pages = $total_pages;
1346
1347 // Enqueue styles/scripts
1348 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1349 wp_enqueue_style('ea-admin-bundle-css');
1350 wp_enqueue_script('ea-admin-bundle');
1351
1352 $settings = $this->options->get_options();
1353 $settings['rest_url'] = get_rest_url();
1354 $settings['time_format'] = $this->datetime->convert_to_moment_format(get_option('time_format', 'H:i'));
1355 $settings['date_format'] = $this->datetime->convert_to_moment_format(get_option('date_format', 'F j, Y'));
1356
1357 $wpurl = get_bloginfo('wpurl');
1358 $url = get_bloginfo('url');
1359 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1360 $settings['rest_url_extend_connections'] = EasyEALogActions::extend_connection_url();
1361
1362 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1363
1364 if (function_exists('wp_set_script_translations')) {
1365 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1366 }
1367
1368 // Load template
1369 require_once EA_SRC_DIR . 'templates/customers.tpl.php';
1370 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1371 }
1372
1373
1374
1375
1376 /**
1377 * Tools page
1378 */
1379 public function tools_page()
1380 {
1381 // check if APS tags are on
1382 if ($this->is_asp_tags_are_on()) {
1383 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1384 return;
1385 }
1386
1387 // load_plugin_textdomain('easy-appointments', false, EA_PLUGIN_DIR . 'languages/');
1388
1389 wp_enqueue_style('ea-admin-bundle-css');
1390 wp_enqueue_script('ea-admin-bundle');
1391
1392 $settings = $this->options->get_options();
1393 $settings['rest_url'] = get_rest_url();
1394 $settings['rest_url_clear_log'] = EasyEALogActions::clear_error_url();
1395
1396 $wpurl = get_bloginfo('wpurl');
1397 $url = get_bloginfo('url');
1398
1399 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
1400 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1401 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1402
1403 if (function_exists('wp_set_script_translations')) {
1404 wp_set_script_translations('ea-admin-bundle', 'easy-appointments', EA_PLUGIN_DIR . 'languages');
1405 }
1406
1407 require_once EA_SRC_DIR . 'templates/tools.tpl.php';
1408 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1409 }
1410
1411 /**
1412 * Tools page
1413 */
1414 public function new_reports_page()
1415 {
1416 // check if APS tags are on
1417 if ($this->is_asp_tags_are_on()) {
1418 require_once EA_SRC_DIR . 'templates/asp_tag_message.tpl.php';
1419 return;
1420 }
1421
1422 wp_enqueue_style('ea-admin-bundle-css');
1423 wp_enqueue_script('ea-admin-bundle');
1424
1425 $settings = $this->options->get_options();
1426 $settings['rest_url'] = get_rest_url();
1427 $settings['rest_url_fullcalendar'] = EasyEAApiFullCalendar::get_url();
1428 $settings['export_tags_list'] = $this->models->get_all_tags_for_template();
1429 $settings['saved_tags_list'] = get_option('ea_excel_columns', '');
1430
1431 $wpurl = get_bloginfo('wpurl');
1432 $url = get_bloginfo('url');
1433
1434 // $settings['image_base'] = $wpurl === $url ? '' : $wpurl;
1435 $settings['image_base'] = str_replace("/wp-content", "", content_url());
1436 wp_localize_script('ea-admin-bundle', 'ea_settings', $settings);
1437
1438 if (function_exists('wp_set_script_translations')) {
1439 wp_set_script_translations('ea-admin-bundle', 'easy-appointments');
1440 }
1441
1442 require_once EA_SRC_DIR . 'templates/reports.tpl.php';
1443 require_once EA_SRC_DIR . 'templates/inlinedata.tpl.php';
1444 }
1445
1446 /**
1447 * We need to check if asp tags are turned on
1448 */
1449 public function is_asp_tags_are_on()
1450 {
1451 $aps_tags = ini_get('asp_tags');
1452
1453 if (!empty($aps_tags)) {
1454 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
1455 if (ini_set('asp_tags', '0') === false) {
1456 return true;
1457 }
1458 }
1459
1460 return false;
1461 }
1462
1463
1464
1465
1466 }
1467
1468 function easy_ea_newsletter_form(){
1469
1470 $hide_form = get_option('ea_hide_newsletter');
1471
1472 // Newsletter marker. Set this to false once newsletter subscription is displayed.
1473 $ea_newsletter = true;
1474
1475 if ( $ea_newsletter === true && $hide_form !== 'yes') { ?>
1476 <div class="ea-newsletter-wrapper">
1477 <div class="plugin-card plugin-card-ea-newsletter" style="margin :10px; background: #2271b1 url('<?php echo esc_url( plugin_dir_url( __DIR__ ) . 'img/email.png'); ?>') no-repeat right top;">
1478
1479 <div class="plugin-card-top" style="min-height: 135px; color: white;">
1480 <span class="dashicons dashicons-dismiss ea_newsletter_hide" style="float: right;cursor: pointer;"></span>
1481 <span style="clear:both;"></span>
1482 <div class="name column-name" style="margin: 0px 10px;">
1483 <h3 style="color:white;"><?php esc_html_e( 'Easy Appointments Newsletter', 'easy-appointments' ); ?></h3>
1484 </div>
1485 <div class="desc column-description" style="margin: 0px 10px; color:white;">
1486 <p style="margin-left:0px;"><?php esc_html_e( 'Learn more about easy appointments and get latest updates about plugin', 'easy-appointments' ); ?></p>
1487 </div>
1488
1489 <div class="ea-newsletter-form" style="margin: 18px 10px 0px;">
1490
1491 <form method="post" action="https://ea.com/newsletter/" target="_blank" id="ea_newsletter">
1492 <fieldset>
1493 <input name="newsletter-email" value="<?php $user = wp_get_current_user(); echo esc_attr( $user->user_email ); ?>" placeholder="<?php esc_html_e( 'Enter your email', 'easy-appointments' ); ?>" style="width: 60%; margin-left: 0px;" type="email">
1494 <input name="source" value="ea-plugin" type="hidden">
1495 <input type="submit" class="button" value="<?php esc_html_e( 'Subscribe', 'easy-appointments' ); ?>" style="background: linear-gradient(to right, #c6ccd1, #bdd0d3) !important !important; box-shadow: unset;">
1496 <span class="ea_newsletter_hide" style="box-shadow: unset;cursor: pointer;margin-left: 10px; color:white;">
1497 <?php esc_html_e( 'No thanks', 'easy-appointments' ); ?>
1498 </span>
1499 <small style="display:block; margin-top:8px; color:white;"><?php esc_html_e( 'we\'ll share our <code>root</code> password before we share your email with anyone else.', 'easy-appointments' ); ?></small>
1500
1501 </fieldset>
1502 </form>
1503
1504 </div>
1505
1506 </div>
1507
1508 </div>
1509 </div>
1510 <?php }
1511 // Set newsletter marker to false
1512 $ea_newsletter = false;
1513 }
1514
1515 function easy_ea_newsletter_submit(){
1516
1517 if (isset( $_REQUEST['ea_security_nonce'] ) && current_user_can('manage_options') && (wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['ea_security_nonce'] ) ), 'ea_ajax_check_nonce' ) )){
1518 global $current_user;
1519 $api_url = 'http://magazine3.company/wp-json/api/central/email/subscribe';
1520 $email = "";
1521 if ( isset($_POST['email']) ) {
1522 $email = sanitize_email( wp_unslash( $_POST['email'] ) );
1523 }
1524 $api_params = array(
1525 'name' => sanitize_text_field($current_user->display_name),
1526 'email'=> $email,
1527 'website'=> sanitize_url( get_site_url() ),
1528 'type'=> 'easyappointments'
1529 );
1530 $response = wp_remote_post( $api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
1531 if ( !is_wp_error( $response ) ) {
1532 $response = wp_remote_retrieve_body( $response );
1533 echo wp_json_encode(array('status'=>200, 'message'=>esc_html__('Submitted ','easy-appointments'), 'response'=> $response));
1534 }else{
1535 echo wp_json_encode(array('status'=>500, 'message'=>esc_html__('No response from API','easy-appointments')));
1536 }
1537 }
1538 else{
1539 echo wp_json_encode(array('status'=>403, 'message'=>esc_html__('Unauthorized Request','easy-appointments')));
1540 }
1541 die;
1542 }
1543 add_action( 'wp_ajax_easy_ea_newsletter_submit', 'easy_ea_newsletter_submit' );
1544
1545 function easy_ea_newsletter_hide_form(){
1546 if (isset( $_REQUEST['ea_security_nonce'] ) && current_user_can( 'manage_options') && (wp_verify_nonce( sanitize_text_field( wp_unslash($_REQUEST['ea_security_nonce'] ) ), 'ea_ajax_check_nonce' ) )){
1547 $hide_newsletter = get_option('ea_hide_newsletter');
1548 if($hide_newsletter == false){
1549 add_option( 'ea_hide_newsletter', 'no');
1550 }
1551 update_option( 'ea_hide_newsletter', 'yes' , false);
1552 echo wp_json_encode(array('status'=>200, 'message'=>esc_html__('Submitted ','easy-appointments')));
1553 }else{
1554 echo wp_json_encode(array('status'=>403, 'message'=>esc_html__('Unauthorized Request','easy-appointments')));
1555 }
1556 die;
1557 }
1558 add_action( 'wp_ajax_easy_ea_newsletter_hide_form', 'easy_ea_newsletter_hide_form' );