PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.19
Booktics – Appointment Booking Calendar for Service Businesses v1.0.19
1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 All 27 releases
booktics / utils / global-helper.php

global-helper.php in Booktics – Appointment Booking Calendar for Service Businesses 1.0.19, at utils/global-helper.php

922 lines 28.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' ) ) exit;
3 /**
4 * Get timezone list.
5 *
6 * @return array
7 * @since 1.0.0
8 */
9 if ( ! function_exists( 'booktics_get_timezone_list' ) ) {
10 function booktics_get_timezone_list() {
11 $tzlist = wp_timezone_choice( 'UTC' );
12 $doc = new DOMDocument();
13 $doc->loadHTML( $tzlist );
14
15 $elements = $doc->getElementsByTagName( 'option' );
16 $timezones = array();
17
18 if ( ! empty( $elements ) ) {
19 foreach ( $elements as $element ) {
20 $data = array(
21 'value' => $element->getAttribute( 'value' ),
22 'name' => $element->textContent,
23 // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
24 );
25
26 $timezones[] = $data;
27 }
28 }
29
30 return $timezones;
31 }
32 }
33
34 if ( ! function_exists( 'booktics_get_auth_redirect_uri' ) ) {
35 /**
36 * Get auth redirect uri
37 *
38 * @param string $auth
39 *
40 * @return string
41 */
42 function booktics_get_auth_redirect_uri( $auth = '' ) {
43 return site_url( 'booktics-integration/' . $auth );
44 }
45 }
46
47
48 if ( ! function_exists( 'booktics_get_google_auth' ) ) {
49 /**
50 * Get google auth
51 *
52 * @param integer $user_id
53 *
54 * @return array
55 */
56 function booktics_get_google_auth( $user_id = 0 ) {
57 return get_user_meta( $user_id, 'booktics_google_auth', true );
58 }
59 }
60
61 if ( ! function_exists( 'booktics_get_posts' ) ) {
62 /**
63 * Get posts with date range
64 *
65 * @param array $args
66 *
67 * @return WP_Query
68 */
69 function booktics_get_posts( $args = array() ) {
70 $defaults = array(
71 'post_type' => 'post',
72 'post_status' => 'publish',
73 'nopaging' => true,
74 'date_range' => '',
75 );
76
77 $args = wp_parse_args( $args, $defaults );
78
79 // Date range found.
80 if ( $args['date_range'] ) {
81 $from_date = $args['date_range']['start'];
82 $to_date = $args['date_range']['end'];
83
84 $args['date_query'] = array(
85 'relation' => 'AND',
86 array(
87 'before' => array(
88 'year' => gmdate( 'Y', strtotime( $to_date ) ),
89 'month' => gmdate( 'm', strtotime( $to_date ) ),
90 'day' => gmdate( 'd', strtotime( $to_date ) ),
91 ),
92 'after' => array(
93 'year' => gmdate( 'Y', strtotime( $from_date ) ),
94 'month' => gmdate( 'm', strtotime( $from_date ) ),
95 'day' => gmdate( 'd', strtotime( $from_date ) ),
96 ),
97 'inclusive' => true,
98 ),
99 );
100 }
101
102 // The Query
103 $posts = new WP_Query( $args );
104
105 return $posts;
106 }
107 }
108
109 if ( ! function_exists( 'booktics_count_posts()' ) ) {
110 /**
111 * Count post with date range or without date range
112 *
113 * @param array $args Required query params
114 *
115 * @return integer
116 */
117 function booktics_count_posts( $args = array() ) {
118 $posts = booktics_get_posts( $args );
119
120 return $posts->post_count;
121 }
122 }
123
124 if ( ! function_exists( 'booktics_count_users' ) ) {
125 /**
126 * Count user by role and date range
127 *
128 * @param array $args Required query params
129 *
130 * @return integer
131 */
132 function booktics_count_users( $args = array() ) {
133 $defaults = array(
134 'role' => '',
135 'date_range' => '',
136 'count_total' => true,
137 );
138
139 $args = wp_parse_args( $args, $defaults );
140
141 // Date range found.
142 if ( $args['date_range'] ) {
143 $from_date = $args['date_range']['start'];
144 $to_date = $args['date_range']['end'];
145
146 $args['date_query'] = array(
147 'relation' => 'AND',
148 array(
149 'before' => array(
150 'year' => gmdate( 'Y', strtotime( $to_date ) ),
151 'month' => gmdate( 'm', strtotime( $to_date ) ),
152 'day' => gmdate( 'd', strtotime( $to_date ) ),
153 ),
154 'after' => array(
155 'year' => gmdate( 'Y', strtotime( $from_date ) ),
156 'month' => gmdate( 'm', strtotime( $from_date ) ),
157 'day' => gmdate( 'd', strtotime( $from_date ) ),
158 ),
159 'inclusive' => true,
160 ),
161 );
162 }
163
164 // The Query
165 $user_query = new WP_User_Query( $args );
166
167 // Return total users.
168 return $user_query->total_users;
169 }
170 }
171
172
173 if ( ! function_exists( 'booktics_get_default_timezone' ) ) {
174 /**
175 * Get default timezone
176 *
177 * @return string
178 */
179 function booktics_get_default_timezone() {
180 $timezone = get_option( 'timezone_string' );
181
182 return $timezone;
183 }
184 }
185
186 if ( ! function_exists( 'booktics_get_currencies' ) ) {
187 /**
188 * Get currency list
189 *
190 * @return array
191 */
192 function booktics_get_currencies() {
193 $currencies = require_once __DIR__ . '/currency.php';
194
195 return $currencies;
196 }
197 }
198
199 if ( ! function_exists( 'booktics_update_default_settings' ) ) {
200
201 /**
202 * Update default settings
203 *
204 * @return void
205 */
206 function booktics_update_default_settings() {
207 $settings = array(
208 'google_auth_redirect_uri' => booktics_get_auth_redirect_uri( 'google-auth' ),
209 'default_booking_status' => 'pending',
210 'currency' => 'USD',
211 'primary_color' => '#3161F1',
212 'secondary_color' => '#6188ff',
213 );
214
215 $settings = apply_filters( 'booktics_default_settings', $settings );
216
217 foreach ( $settings as $key => $value ) {
218 booktics_update_option( $key, $value );
219 }
220 }
221 }
222
223 if ( ! function_exists( 'booktics_get_post_status' ) ) {
224
225 /**
226 * Get post status
227 *
228 * @return array
229 */
230 function booktics_get_post_status() {
231 return array(
232 'approved',
233 'pending',
234 'cancel',
235 'completed',
236 );
237 }
238 }
239
240 if ( ! function_exists( 'booktics_replace_placeholder' ) ) {
241 /**
242 * Replace string with placeholder
243 *
244 * @param array $placeholders
245 * @param string $text
246 *
247 * @return string
248 */
249 function booktics_replace_placeholder( $text, $placeholders = array() ) {
250
251 if ( ! $placeholders ) {
252 return $text;
253 }
254
255 foreach ( $placeholders as $placeholder => $replace_with ) {
256 $text = str_replace( $placeholder, $replace_with, $text );
257 }
258
259 return $text;
260 }
261 }
262
263 if ( ! function_exists( 'booktics_register_cron' ) ) {
264 /**
265 * Register booktics cron
266 *
267 * @return void
268 */
269 function booktics_register_cron() {
270 wp_schedule_event( time(), 'daily', 'booktics_booking_clear_schedule' );
271 }
272 }
273
274 if ( ! function_exists( 'booktics_is_woocommerce_active' ) ) {
275
276 /**
277 * Check woocommerce is active or not
278 *
279 * @return bool
280 */
281 function booktics_is_woocommerce_active() {
282
283 if ( function_exists( 'WC' ) && booktics_get_option( 'wc_integration' ) ) {
284 return true;
285 }
286
287 return false;
288 }
289 }
290
291 if ( ! function_exists( 'booktics_add_woocommerce_product_cat' ) ) {
292 /**
293 * Add woocommerce product category
294 *
295 * @return void
296 */
297 function booktics_add_woocommerce_product_cat() {
298 $category_name = __( 'Booktics Meeting', 'booktics' );
299
300 // Prepare category arguments
301 $category_args = array(
302 'taxonomy' => 'product_cat',
303 'cat_name' => $category_name,
304 'category_description' => __( 'Booktics meeting', 'booktics' ),
305 'slug' => 'booktics-meeting',
306 );
307
308 // Insert the category
309 wp_insert_term( $category_args['cat_name'], $category_args['taxonomy'], $category_args );
310 }
311 }
312
313 if ( ! function_exists( 'booktics_is_valid_timezone' ) ) {
314 /**
315 * Check a timezone is valid or not
316 *
317 * @param string $timezone
318 *
319 * @return bool
320 */
321 function booktics_is_valid_timezone( $timezone ) {
322 try {
323 new DateTimeZone( $timezone );
324 } catch ( Exception $e ) {
325 return false;
326 }
327
328 return true;
329 }
330 }
331
332 if ( ! function_exists( 'booktics_datetime' ) ) {
333
334 /**
335 * Booktics date time with timezone
336 *
337 * @param int | string $date
338 * @param string $timezone
339 *
340 * @return string
341 */
342 function booktics_datetime( $format, $date, $timezone = '' ) {
343 $date = is_int( $date ) ? gmdate( 'Y-m-d g:ia', $date ) : $date;
344
345 if ( ! $timezone ) {
346 $timezone = 'UTC';
347 }
348
349 // Create a DateTime object with the provided timestamp and time zone
350 $datetime = new \DateTime( $date, new \DateTimeZone( $timezone ) );
351
352 // Get the converted timestamp
353 return $datetime->format( $format );
354 }
355 }
356
357 if ( ! function_exists( 'booktics_convert_timezone' ) ) {
358
359 /**
360 * Convert date and time from timezone to another timezone
361 *
362 * @param string $format
363 * @param string $date_time
364 * @param string $from
365 * @param string $to
366 *
367 * @return \DateTime
368 */
369 function booktics_convert_timezone( $date_time_string, $from, $to ) {
370
371 if ( empty( $from ) || empty( $to ) ) {
372 return new DateTime( $date_time_string );
373 }
374
375 $date_time_string = is_int( $date_time_string ) ? gmdate( 'Y-m-d g:ia', $date_time_string ) : gmdate( 'Y-m-d g:ia', strtotime( $date_time_string ) );
376
377 $datetime = new DateTime( $date_time_string, new DateTimeZone( $from ) );
378 $datetime->setTimezone( new DateTimeZone( $to ) );
379
380 return $datetime;
381 }
382 }
383
384 if ( ! function_exists( 'booktics_generate_username' ) ) {
385 /**
386 * Generate unique username
387 *
388 * @param string $email
389 *
390 * @return string
391 */
392 function booktics_generate_username( $email ) {
393 $username = strtok( $email, '@' );
394
395 if ( username_exists( $username ) ) {
396 $username = $username . wp_rand( 10, 100 );
397 }
398
399 return $username;
400 }
401 }
402
403 if ( ! function_exists( 'booktics_is_json' ) ) {
404 /**
405 * Check a string is valid json or not
406 *
407 * @param string $json_string
408 *
409 * @return bool
410 */
411 function booktics_is_json( $json_string ) {
412 if ( ! is_string( $json_string ) ) {
413 return false;
414 }
415
416 $data = json_decode( $json_string, true );
417
418 return $data !== null && json_last_error() === JSON_ERROR_NONE;
419 }
420 }
421
422
423 if ( ! function_exists( 'booktics_get_current_user' ) ) {
424 /**
425 * Get current user data
426 *
427 * @return array
428 */
429 function booktics_get_current_user() {
430 $user_id = get_current_user_id();
431 $user = get_userdata( $user_id );
432
433 $user_data = array(
434 'id' => $user->ID,
435 'username' => $user->user_login,
436 'email' => $user->user_email,
437 'roles' => $user->roles,
438 );
439
440 return $user_data;
441 }
442 }
443
444 if ( ! function_exists( 'booktics_validate' ) ) {
445 /**
446 * Validate user input
447 *
448 * @param array $request
449 * @param array $rules
450 *
451 * @return bool | WP_Error
452 */
453 function booktics_validate( $request, $rules ) {
454 $validator = new \Booktics\Validation\Validator( $request );
455
456 $validator->set_rules( $rules );
457
458 if ( ! $validator->validate() ) {
459 return $validator->get_error();
460 }
461
462 return true;
463 }
464 }
465
466 if ( ! function_exists( 'booktics_snake_case' ) ) {
467 /**
468 * Convert a string to snake_case.
469 *
470 * @param string $string
471 *
472 * @return string
473 */
474 function booktics_snake_case( string $string ): string {
475 $string = preg_replace( '/([a-z])([A-Z])/', '$1_$2', $string );
476
477 return strtolower( str_replace( array( '-', ' ' ), '_', $string ) );
478 }
479 }
480
481 if ( ! function_exists( 'booktics_kebab_case' ) ) {
482 /**
483 * Convert a string to kebab-case.
484 *
485 * @param string $string
486 *
487 * @return string
488 */
489 function booktics_kebab_case( string $string ): string {
490 $string = preg_replace( '/([a-z])([A-Z])/', '$1-$2', $string );
491
492 return strtolower( str_replace( array( '_', ' ' ), '-', $string ) );
493 }
494 }
495
496 if ( ! function_exists( 'booktics_camel_case' ) ) {
497 /**
498 * Convert a string to camelCase.
499 *
500 * @param string $string
501 *
502 * @return string
503 */
504 function booktics_camel_case( string $string ): string {
505 $string = str_replace( array( '-', '_' ), ' ', strtolower( $string ) );
506 $string = ucwords( $string );
507 $string = str_replace( ' ', '', $string );
508
509 return lcfirst( $string );
510 }
511 }
512
513 if ( ! function_exists( 'booktics_pascal_case' ) ) {
514 /**
515 * Convert a string to PascalCase.
516 *
517 * @param string $string
518 *
519 * @return string
520 */
521 function booktics_pascal_case( string $string ): string {
522 $string = str_replace( array( '-', '_' ), ' ', strtolower( $string ) );
523 $string = ucwords( $string );
524
525 return str_replace( ' ', '', $string );
526 }
527 }
528
529 if ( ! function_exists( 'booktics_date_range_loop' ) ) {
530 /**
531 * Make date range iterable array
532 *
533 * @param $start
534 * @param $end
535 * @param $step
536 * @param $format
537 *
538 * @return array
539 * @throws Exception
540 */
541 function booktics_date_range_loop( $start, $end, $step = '+1 day', $format = 'Y-m-d' ) {
542 $dates = array();
543
544 $current_date = new DateTime( $start );
545 $end_date = new DateTime( $end );
546
547 while ( $current_date <= $end_date ) {
548 $dates[] = $current_date->format( $format );
549 $current_date->modify( $step );
550 }
551
552 return $dates;
553 }
554
555 if ( ! function_exists( 'booktics_get_option' ) ) {
556 /**
557 * Get option for Booktics
558 *
559 * @param string $key Option key
560 * @param mixed $default Default value to return if option doesn't exist
561 *
562 * @return mixed
563 */
564 function booktics_get_option( $key = '', $default = false ) {
565 return \Booktics\Settings\Settings::get( $key, $default );
566 }
567 }
568
569 if ( ! function_exists( 'booktics_update_option' ) ) {
570 /**
571 * Update Booktics option
572 *
573 * @param string $key Option key
574 * @param mixed $value Option value
575 *
576 * @return void
577 */
578 function booktics_update_option( $key, $value ) {
579 \Booktics\Settings\Settings::update( $key, $value );
580 }
581 }
582 }
583
584 if ( ! function_exists( 'booktics_is_pro_active' ) ) {
585 /**
586 * Check Booktics Pro plugin activate or deactivate
587 *
588 * @return bool
589 */
590 function booktics_is_pro_active(): bool {
591 return is_plugin_active( 'booktics-pro/booktics-pro.php' );
592 }
593 }
594
595 if ( ! function_exists( 'booktics_extension' ) ) {
596 /**
597 * Get Booktics extension object from tools-sdk
598 */
599 function booktics_extension() {
600 return ( new \Arraytics\ToolsSdk\Extension( 'booktics_available_modules', booktics_modules_list() ) );
601 }
602 }
603
604 if ( ! function_exists( 'booktics_get_enabled_modules' ) ) {
605 /**
606 * Get enabled modules
607 *
608 * @return array
609 */
610 function booktics_get_enabled_modules(): array {
611 $modules = get_option( 'booktics_available_modules', array() );
612
613 if ( empty( $modules ) || ! is_array( $modules ) ) {
614 return array();
615 }
616
617 $enabled = array();
618
619 foreach ( $modules as $module_slug => $module_data ) {
620 if ( is_array( $module_data ) && isset( $module_data['status'] ) && $module_data['status'] === 'on' ) {
621 $enabled[] = $module_slug;
622 } elseif ( is_string( $module_data ) && $module_data === 'on' ) {
623 $enabled[] = $module_slug;
624 }
625 }
626
627 return $enabled;
628 }
629
630 if ( ! function_exists( 'get_booktics_modules_list' ) ) {
631 /**
632 * Get Booktics modules list
633 *
634 * @return array
635 */
636 function booktics_modules_list(): array {
637 $modules_list = array(
638 'stripe' => array(
639 'name' => 'stripe',
640 'slug' => 'stripe',
641 'type' => 'module',
642 'upgrade' => true,
643 'upgrade_link' => 'https://themewinter.com/purchase-history',
644 'status' => 'off',
645 'is_pro' => false,
646 'title' => __( 'Stripe', 'booktics' ),
647 'description' => __( 'It allows you to use stripe payment.', 'booktics' ),
648 'icon' => \Booktics\Extensions\Extension_Icon::get( 'stripe-addon' ),
649 'notice' => '',
650 'demo_link' => 'https://support.themewinter.com/docs/plugins/plugin-docs/integration/booktics-stripe',
651 'settings_link' => '',
652 'doc_link' => 'https://docs.arraytics.com/docs/booktics/payment-type/how-to-configure-the-stripe-in-booktics/',
653 ),
654 'fluentcrm' => array(
655 'name' => 'fluentcrm',
656 'slug' => 'fluentcrm',
657 'type' => 'module',
658 'upgrade' => true,
659 'upgrade_link' => 'https://themewinter.com/purchase-history',
660 'status' => 'off',
661 'is_pro' => false,
662 'title' => __( 'FluentCRM', 'booktics' ),
663 'description' => __( 'It allows you to use FluentCRM.', 'booktics' ),
664 'icon' => \Booktics\Extensions\Extension_Icon::get( 'booktics-fluentcrm-addon' ),
665 'notice' => '',
666 'demo_link' => 'https://support.themewinter.com/docs/plugins/plugin-docs/integration/booktics-fluentcrm',
667 'settings_link' => '',
668 'doc_link' => 'https://support.themewinter.com/docs/plugins/plugin-docs/integration/booktics-google-calendar',
669 ),
670 'google-calendar' => array(
671 'name' => 'google-calendar',
672 'slug' => 'google-calendar',
673 'type' => 'module',
674 'upgrade' => true,
675 'upgrade_link' => 'https://themewinter.com/purchase-history',
676 'status' => 'off',
677 'is_pro' => false,
678 'title' => __( 'Booktics Google Calendar', 'booktics' ),
679 'description' => __( 'It allows you to use google calendar.', 'booktics' ),
680 'icon' => \Booktics\Extensions\Extension_Icon::get( 'booktics-google-calendar' ),
681 'notice' => '',
682 'demo_link' => 'https://support.themewinter.com/docs/plugins/plugin-docs/integration/booktics-google-calendar',
683 'settings_link' => '',
684 'doc_link' => 'https://docs.arraytics.com/docs/booktics/integration/how-to-integrate-google-calendar-with-booktics/',
685 ),
686 'outlook-calendar' => array(
687 'name' => 'outlook-calendar',
688 'slug' => 'outlook-calendar',
689 'type' => 'module',
690 'upgrade' => true,
691 'upgrade_link' => 'https://themewinter.com/purchase-history',
692 'status' => 'off',
693 'is_pro' => true,
694 'title' => __( 'Booktics Outlook Calendar', 'booktics' ),
695 'description' => __( 'It allows you to use outlook calendar.', 'booktics' ),
696 'icon' => \Booktics\Extensions\Extension_Icon::get( 'booktics-outlook-calendar' ),
697 'notice' => '',
698 'demo_link' => 'https://support.themewinter.com/docs/plugins/plugin-docs/integration/booktics-outlook-calendar-addon',
699 'settings_link' => '',
700 'doc_link' => 'https://docs.arraytics.com/docs/booktics/integration/how-to-integrate-outlook-calendar-with-booktics/',
701 ),
702 'paypal' => array(
703 'name' => 'paypal',
704 'slug' => 'paypal',
705 'type' => 'module',
706 'upgrade' => true,
707 'upgrade_link' => 'https://themewinter.com/purchase-history',
708 'status' => 'off',
709 'is_pro' => true,
710 'title' => __( 'PayPal', 'booktics' ),
711 'description' => __( 'It allows you to use PayPal.', 'booktics' ),
712 'icon' => \Booktics\Extensions\Extension_Icon::get( 'booktics-paypal-addon' ),
713 'notice' => '',
714 'demo_link' => 'https://support.themewinter.com/docs/plugins/plugin-docs/integration/booktics-paypal-addon',
715 'settings_link' => '',
716 'doc_link' => 'https://docs.arraytics.com/docs/booktics/payment-type/how-to-configure-the-paypal-in-booktics-pro/',
717 ),
718 );
719
720 return $modules_list;
721 }
722 }
723 }
724
725 if ( ! function_exists( 'booktics_get_multisite_table_name' ) ) {
726 /**
727 * Get multisite-safe table name
728 *
729 * @param string $table_name
730 *
731 * @return string
732 */
733 function booktics_get_table_name( $table_name ) {
734 global $wpdb;
735 $prefix = $wpdb->prefix;
736 if ( strpos( $table_name, $prefix ) === 0 ) {
737 return $table_name;
738 }
739 return $wpdb->prefix . $table_name;
740 }
741 }
742
743 if ( ! function_exists( 'booktics_handle_conflicting_plugins' ) ) {
744 /**
745 * Deactivate conflicting plugins if active and check if they exist.
746 */
747 function booktics_handle_conflicting_plugins() {
748 // Avoid during AJAX or REST requests
749 if ( wp_doing_ajax() || defined( 'REST_REQUEST' ) ) {
750 return;
751 }
752
753 // Only proceed if user is logged in and can manage plugins
754 if ( ! is_user_logged_in() || ! current_user_can( 'activate_plugins' ) ) {
755 return;
756 }
757
758 // Prevent running repeatedly on every page load using a transient
759 if ( get_transient( 'booktics_conflict_check_done' ) ) {
760 return;
761 }
762
763 $conflicting_plugins = array(
764 'booktics-google-calendar-addon/booktics-google-calendar.php',
765 'booktics-outlook-calendar-addon/booktics-outlook-calendar-addon.php',
766 'booktics-paypal-addon/booktics-paypal-addon.php',
767 'booktics-stripe-addon/booktics_stripe.php',
768 'booktics-fluentcrm-addon/booktics-fluentcrm-addon.php',
769 );
770
771 $active_plugins = get_option( 'active_plugins', array() );
772 $deactivated_list = array();
773
774 foreach ( $conflicting_plugins as $plugin_file ) {
775 $plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file;
776
777 if ( file_exists( $plugin_path ) ) {
778 if ( in_array( $plugin_file, $active_plugins, true ) ) {
779 deactivate_plugins( $plugin_file );
780 $plugin_data = get_plugin_data( $plugin_path );
781 $deactivated_list[] = $plugin_data['Name'];
782 }
783 }
784 }
785
786 if ( ! empty( $deactivated_list ) ) {
787 // Store data in transient for 1 minute to show notice once
788 set_transient( 'booktics_deactivated_plugins_notice', $deactivated_list, MINUTE_IN_SECONDS );
789 }
790
791 // Set the conflict check as done (even if nothing was deactivated)
792 set_transient( 'booktics_conflict_check_done', true, MINUTE_IN_SECONDS );
793 }
794 }
795
796 if ( ! function_exists( 'booktics_show_conflict_deactivation_notice' ) ) {
797 /**
798 * Show a one-time admin notice for deactivated conflicting plugins.
799 */
800 function booktics_show_conflict_deactivation_notice() {
801 if ( ! current_user_can( 'activate_plugins' ) ) {
802 return;
803 }
804
805 $deactivated_list = get_transient( 'booktics_deactivated_plugins_notice' );
806
807 if ( ! empty( $deactivated_list ) ) {
808 delete_transient( 'booktics_deactivated_plugins_notice' );
809
810 $plugin_names = implode( ', ', array_map( 'esc_html', $deactivated_list ) );
811 ?>
812 <div class="notice notice-warning is-dismissible">
813 <p>
814 <?php echo esc_html__( 'No need for addons! The following addon plugins have been added as modules in Booktics:', 'booktics' ); ?>
815 <strong><?php echo esc_html( $plugin_names ); ?></strong>
816 <br><?php echo esc_html__( 'Please deactivate and remove these plugins to avoid future issues. Don\'t worry, it will not affect your existing data and the features will remain the same.', 'booktics' ); ?>
817 </p>
818 </div>
819 <?php
820 }
821 }
822 }
823
824 if ( ! function_exists( 'booktics_time_to_gmt' ) ) {
825 /**
826 * Convert time from site timezone to GMT/UTC
827 *
828 * @param string $time Time string (e.g., "9:00 AM", "09:00:00")
829 * @param string|int $context_date Date context (Y-m-d or 0 for regular schedules)
830 * @return string Time in H:i:s format (GMT/UTC)
831 * @since 1.0.15
832 */
833 function booktics_time_to_gmt( string $time, $context_date = 0 ): string {
834 // Skip '0' placeholder for holidays
835 if ( $time === '0' || $time === 0 ) {
836 return '0';
837 }
838
839 // For regular schedules (context_date = 0), use current date as context
840 // For custom schedules, use the actual date for DST-aware conversion
841 $date = ( $context_date === 0 || $context_date === '0' || empty( $context_date ) )
842 ? gmdate( 'Y-m-d' )
843 : $context_date;
844
845 $timestamp = strtotime( $time );
846 if ( $timestamp === false ) {
847 return $time;
848 }
849 $formatted_time = gmdate( 'H:i:s', $timestamp );
850 $datetime_string = $date . ' ' . $formatted_time;
851
852 $gmt_datetime = get_gmt_from_date( $datetime_string );
853
854 // Extract and return only the time part
855 return gmdate( 'H:i:s', strtotime( $gmt_datetime ) );
856 }
857 }
858
859 if ( ! function_exists( 'booktics_is_admin_or_team_member' ) ) {
860 /**
861 * Check if the current user is an admin or a Booktics team member.
862 *
863 * @return bool
864 * @since 1.0.16
865 */
866 function booktics_is_admin_or_team_member() {
867 if ( current_user_can( 'manage_options' ) ) {
868 return true;
869 }
870 if ( is_user_logged_in() ) {
871 $roles = (array) wp_get_current_user()->roles;
872 if ( in_array( 'booktics_team_member', $roles, true ) ) {
873 return true;
874 }
875 }
876 return false;
877 }
878 }
879
880 if ( ! function_exists( 'booktics_is_team_member' ) ) {
881 function booktics_is_team_member() {
882 if ( is_user_logged_in() ) {
883 $roles = (array) wp_get_current_user()->roles;
884 if ( in_array( 'booktics_team_member', $roles, true ) ) {
885 return true;
886 }
887 }
888 return false;
889 }
890 }
891
892 if ( ! function_exists( 'booktics_time_from_gmt' ) ) {
893 /**
894 * Convert time from GMT/UTC to site timezone
895 *
896 * @param string $time Time string in UTC (e.g., "14:00:00")
897 * @param string|int $context_date Date context (Y-m-d or 0 for regular schedules)
898 * @return string Time in H:i:s format (site timezone)
899 * @since 1.0.15
900 */
901 function booktics_time_from_gmt( string $time, $context_date = 0 ): string {
902 // Skip '0' placeholder for holidays
903 if ( $time === '0' || $time === 0 ) {
904 return '0';
905 }
906
907 $date = ( $context_date === 0 || $context_date === '0' || empty( $context_date ) )
908 ? gmdate( 'Y-m-d' )
909 : $context_date;
910
911 $timestamp = strtotime( $time );
912 if ( $timestamp === false ) {
913 return $time;
914 }
915 $formatted_time = gmdate( 'H:i:s', $timestamp );
916 $gmt_datetime_string = $date . ' ' . $formatted_time;
917
918 $local_datetime = get_date_from_gmt( $gmt_datetime_string );
919
920 return gmdate( 'H:i:s', strtotime( $local_datetime ) );
921 }
922 }