PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.54
Timetics – Appointment Booking Calendar & Scheduling v1.0.54
1.0.61 1.0.60 1.0.59 1.0.58 1.0.57 1.0.56 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.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 All 62 releases
timetics / bootstrap.php

bootstrap.php in Timetics – Appointment Booking Calendar & Scheduling 1.0.54, at bootstrap.php

509 lines 16.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Bootstrap Class
4 *
5 * @package Timetics
6 */
7 namespace Timetics;
8
9 defined( 'ABSPATH' ) || exit;
10
11 /**
12 * Bootstrap class.
13 *
14 * @since 1.0.0
15 */
16 final class Bootstrap {
17 /**
18 * @var Bootstrap The Actual Timetics instance
19 * @since 1.0.0
20 */
21 private static $instance;
22
23
24 private $file;
25 public $version;
26 private $has_pro;
27
28 /**
29 * Throw Error While Trying To Clone Object
30 *
31 * @since 1.0.0
32 * @return void
33 */
34 public function __clone() {
35 _doing_it_wrong( __FUNCTION__, esc_html__( 'Cloning is forbidden.', 'timetics' ), '1.0.0' );
36 }
37
38 /**
39 * Disabling Un-serialization Of This Class
40 */
41 public function __wakeup() {
42 _doing_it_wrong( __FUNCTION__, esc_html__( 'Unserializing instances of this class is forbidden.', 'timetics' ), '1.0.0' );
43 }
44
45 /**
46 * The actual TimeTics instance
47 *
48 * @since 1.0.0
49 * @param string $file
50 * @return void
51 */
52 public static function instantiate( $file = '' ) {
53
54 // Return if already instantiated
55 if ( self::instantiated() ) {
56 return self::$instance;
57 }
58
59 self::prepare_instance( $file );
60
61 self::$instance->initialize_constants();
62 self::$instance->define_tables();
63 self::$instance->include_files();
64 self::$instance->initialize_components();
65
66 return self::$instance;
67 }
68
69 /**
70 * Return If The Main Class has Already Been Instantiated Or Not
71 *
72 * @since 1.0.0
73 * @return boolean
74 */
75 private static function instantiated() {
76 if ( ( null !== self::$instance ) && ( self::$instance instanceof Bootstrap ) ) {
77 return true;
78 }
79
80 return false;
81 }
82
83 /**
84 * Prepare Singleton Instance
85 *
86 * @since 1.0.0
87 * @param string $file
88 * @return void
89 */
90 private static function prepare_instance( $file = '' ) {
91 self::$instance = new self();
92 self::$instance->file = $file;
93 self::$instance->version = \Timetics::get_version();
94 }
95
96 /**
97 * Assets Directory URL
98 *
99 * @since 1.0.0
100 * @return void
101 */
102 public function get_assets_url() {
103 return trailingslashit( TIMETICS_PLUGIN_URL . 'assets' );
104 }
105
106 /**
107 * Assets Directory Path
108 *
109 * @since 1.0.0
110 * @return void
111 */
112 public function get_assets_dir() {
113 return trailingslashit( TIMETICS_PLUGIN_DIR . 'assets' );
114 }
115
116 /**
117 * Plugin Directory URL
118 *
119 * @return void
120 */
121 public function get_plugin_url() {
122 return trailingslashit( plugin_dir_url( TIMETICS_PLUGIN_FILE ) );
123 }
124
125 /**
126 * Plugin Directory Path
127 *
128 * @return void
129 */
130 public function get_plugin_dir() {
131 return \Timetics::get_plugin_dir();
132 }
133
134 /**
135 * Plugin Basename
136 *
137 * @return void
138 */
139 public function get_plugin_basename() {
140 return plugin_basename( TIMETICS_PLUGIN_FILE );
141 }
142
143 /**
144 * Setup Plugin Constants
145 *
146 * @since 1.0.0
147 * @return void
148 */
149 private function initialize_constants() {
150 // Plugin Version
151 self::$instance->define( 'TIMETICS_VERSION', \Timetics::get_version() );
152
153 // Plugin Main File
154 self::$instance->define( 'TIMETICS_PLUGIN_FILE', $this->file );
155
156 // Plugin File Basename
157 self::$instance->define( 'TIMETICS_PLUGIN_BASE', $this->get_plugin_basename() );
158
159 // Plugin Main Directory Path
160 self::$instance->define( 'TIMETICS_PLUGIN_DIR', $this->get_plugin_dir() );
161
162 // Plugin Main Directory URL
163 self::$instance->define( 'TIMETICS_PLUGIN_URL', $this->get_plugin_url() );
164
165 // Plugin Assets Directory URL
166 self::$instance->define( 'TIMETICS_ASSETS_URL', $this->get_assets_url() );
167
168 // Plugin Assets Directory Path
169 self::$instance->define( 'TIMETICS_ASSETS_DIR', $this->get_assets_dir() );
170
171
172 }
173
174 /**
175 * Define constant if not already set.
176 *
177 * @since 1.0.0
178 * @param string $timetics_constant_name Constant name.
179 * @param string|bool $value Constant value.
180 */
181 private function define( $timetics_constant_name, $value ) {
182 if ( ! defined( $timetics_constant_name ) ) {
183 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.VariableConstantNameFound -- Constant name is dynamic but prefixed by caller
184 define( $timetics_constant_name, $value );
185 }
186 }
187
188 /**
189 * Define DB Tables Required For This Plugin
190 *
191 * @since 1.0.0
192 * @return void
193 */
194 private function define_tables() {
195 // To Be Implemented
196 }
197
198 /**
199 * Include All Required Files
200 *
201 * @since 1.0.0
202 * @return void
203 */
204 private function include_files() {
205 // require_once TIMETICS_PLUGIN_DIR . 'includes/post-types.php';
206 // require_once TIMETICS_PLUGIN_DIR . 'includes/widgets/manifest.php';
207 // require_once TIMETICS_PLUGIN_DIR . 'includes/template-functions.php';
208 // require_once TIMETICS_PLUGIN_DIR . 'includes/shortcodes.php';
209 // require_once TIMETICS_PLUGIN_DIR . 'includes/install.php';
210
211 /**
212 * Core helpers.
213 */
214 require_once TIMETICS_PLUGIN_DIR . 'utils/global-helper.php';
215 require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/CalendarSyncFacade.php';
216 require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/CalendarSyncFactory.php';
217 require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/CalendarSyncInterface.php';
218 require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/GoogleCalendarSync.php';
219 }
220
221 /**
222 * Initialize All Components
223 *
224 * @since 1.0.0
225 * @return void
226 */
227 private function initialize_components() {
228
229 // Register scripts and styles first
230 if ( $this->is_request( 'admin' ) ) {
231 add_action( 'admin_enqueue_scripts', [ $this, 'admin_scripts' ] );
232 add_action( 'admin_footer', [ $this, 'admin_helpscout_beacon' ] );
233 }
234
235 if ( $this->is_request( 'frontend' ) ) {
236 add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
237 }
238
239 // Register admin menu
240 Core\Admin\Menu::instance()->init();
241 Core\Base::instance()->init();
242 Core\Services\Hooks::instance()->init();
243 Base\Custom_Endpoint::instance()->init();
244
245 global $current_screen;
246 $this->has_pro = class_exists('TimeticsPro');
247
248 $this->handle_buy_pro_module();
249
250 if ( function_exists('WC') ) {
251 Core\Integrations\Woocommerce\Hooks::instance()->init();
252 }
253 }
254
255 /**
256 * demo url for set pro button
257 *
258 * @return void
259 */
260 public function demo_url(){
261 return "https://arraytics.com/timetics/";
262 }
263
264 /**
265 * Register scripts and styles for admin
266 *
267 * @return void
268 */
269 public function admin_scripts( $handle ) {
270
271 if('plugins.php' === $handle){
272
273 wp_register_script( 'timetics-feedback-modal', TIMETICS_ASSETS_URL . 'js/feedback-modal.js', [ 'wp-plugins', 'wp-i18n', 'wp-element', 'wp-dom', 'wp-data' ], TIMETICS_VERSION, true );
274 wp_enqueue_script( 'timetics-feedback-modal', TIMETICS_ASSETS_URL . 'js/feedback-modal.js', [], TIMETICS_VERSION, true );
275 wp_register_style( 'timetics-feedback-modal', TIMETICS_ASSETS_URL . 'css/feedback-modal.css', [], TIMETICS_VERSION, 'all' );
276 wp_enqueue_style( 'timetics-feedback-modal', TIMETICS_ASSETS_URL . 'css/feedback-modal.css', [], TIMETICS_VERSION, 'all' );
277
278 $feedback_obj = array(
279 'site_url' => site_url(),
280 'admin_email' => get_option( 'admin_email' )
281 );
282
283 wp_localize_script( 'timetics-feedback-modal', 'timetics_feedback', $feedback_obj );
284
285 }
286
287 if ( 'toplevel_page_timetics' !== $handle) {
288 return;
289 }
290 global $wp_locale;
291
292 wp_enqueue_media();
293 wp_enqueue_style( 'wp-color-picker' );
294 wp_enqueue_style( 'timetics-admin-style', TIMETICS_ASSETS_URL . 'css/admin.css', [], TIMETICS_VERSION, 'all' );
295 wp_enqueue_style( 'timetics-vendor', TIMETICS_ASSETS_URL . 'css/vendor.css', [], TIMETICS_VERSION, 'all' );
296 wp_enqueue_script( 'timetics-flatpickr-scripts', TIMETICS_ASSETS_URL . 'js/vendors/flatpickr.js', [ 'wp-plugins', 'wp-i18n', 'wp-element', 'wp-dom', 'wp-data' ], TIMETICS_VERSION, true );
297 wp_enqueue_script( 'timetics-packages', TIMETICS_ASSETS_URL . 'js/packages.js', [ 'timetics-flatpickr-scripts' ], TIMETICS_VERSION, true );
298
299 $calendar_locale = timetics_get_option('calendar_locale');
300 if (!empty($calendar_locale)) {
301 wp_enqueue_script( 'calendar-locale', TIMETICS_ASSETS_URL . "js/local/{$calendar_locale}.js", [ 'jquery', 'wp-plugins', 'wp-i18n', 'wp-element', 'wp-dom', 'wp-data' ], TIMETICS_VERSION, true );
302 }
303
304 wp_enqueue_script( 'timetics-dashboard-scripts', TIMETICS_ASSETS_URL . 'js/dashboard.js', [ 'wp-plugins', 'wp-i18n', 'wp-element', 'wp-dom', 'wp-data', 'wp-color-picker' ], TIMETICS_VERSION, true );
305
306
307 $localize_obj = array(
308 'site_url' => site_url(),
309 'admin_url' => admin_url(),
310 'nonce' => wp_create_nonce( 'wp_rest' ),
311 'timezone' => timetics_get_timezone_list(),
312 'stripe_pub_key' => timetics_get_option( 'stripe_pub_key' ),
313 'date_format' => get_option( 'date_format' ),
314 'date_format_string' => date_i18n( get_option( 'date_format' ) ),
315 'time_format' => get_option( 'time_format' ),
316 'time_format_string' => date_i18n( get_option( 'time_format' ) ),
317 'start_of_week' => get_option( 'start_of_week', 0 ),
318
319 'default_timezone' => timetics_get_default_timezone(),
320 'currency_list' => timetics_get_currencies(),
321 'current_user_id' => get_current_user_id(),
322 'timeticsPro' => class_exists('TimeticsPro') ? true : false,
323 'demo_url' => $this->demo_url(),
324 'current_user' => timetics_get_current_user(),
325 );
326
327 $localize_obj = apply_filters( 'timetics_admin_localize_data', $localize_obj );
328
329 wp_localize_script( 'timetics-dashboard-scripts', 'timetics', $localize_obj );
330 }
331
332 /**
333 * Register scripts and styles for frontend
334 *
335 * @return void
336 */
337 public function frontend_scripts() {
338
339 wp_register_style( 'timetics-vendor', TIMETICS_ASSETS_URL . 'css/vendor.css', [], TIMETICS_VERSION, 'all' );
340 wp_register_style( 'timetics-frontend', TIMETICS_ASSETS_URL . 'css/frontend.css', [], TIMETICS_VERSION, 'all' );
341
342 wp_register_script( 'timetics-flatpickr-scripts', TIMETICS_ASSETS_URL . 'js/vendors/flatpickr.js', [ 'wp-plugins', 'wp-i18n', 'wp-element', 'wp-dom', 'wp-data' ], TIMETICS_VERSION, true );
343 wp_enqueue_script( 'timetics-packages', TIMETICS_ASSETS_URL . 'js/packages.js', [ 'timetics-flatpickr-scripts' ], TIMETICS_VERSION, true );
344
345 wp_register_script( 'timetics-frontend-scripts', TIMETICS_ASSETS_URL . 'js/frontend.js', [ 'jquery', 'wp-plugins', 'wp-i18n', 'wp-element', 'wp-dom', 'wp-data' ], TIMETICS_VERSION, true );
346
347 $calendar_locale = timetics_get_option('calendar_locale');
348 if (!empty($calendar_locale)) {
349 wp_register_script( 'calendar-locale', "https://npmcdn.com/flatpickr/dist/l10n/{$calendar_locale}.js", [ 'jquery', 'wp-plugins', 'wp-i18n', 'wp-element', 'wp-dom', 'wp-data' ], TIMETICS_VERSION, true );
350 }
351
352 // load text domain
353 wp_set_script_translations( 'timetics-frontend-scripts', 'timetics', TIMETICS_PLUGIN_DIR . 'languages/' );
354
355 global $wp_locale;
356
357 $stripe_pub_key = timetics_get_option( 'stripe_pub_key' );
358 $stripe_secret_key = timetics_get_option( 'stripe_secret_key' );
359 $stripe_configure = $stripe_pub_key && $stripe_secret_key;
360
361 $localize_obj = array(
362 'site_url' => site_url(),
363 'nonce' => wp_create_nonce( 'wp_rest' ),
364 'date_format' => get_option( 'date_format' ),
365 'time_format' => get_option( 'time_format' ),
366 'stripe_pub_key' => $stripe_pub_key,
367 'currency' => apply_filters( 'timetics_currency', timetics_get_option( 'currency', 'USD' ) ),
368 'stripe_configure' => $stripe_configure,
369 'current_user_id' => get_current_user_id(),
370 'start_of_week' => get_option( 'start_of_week', 0 ),
371 'currency_list' => timetics_get_currencies(),
372 'locale_name' => strtolower( str_replace( '_', '-', get_locale() ) )
373
374 );
375
376 $localize_obj = apply_filters( 'timetics_frontned_localize_data', $localize_obj );
377
378 wp_localize_script( 'timetics-frontend-scripts', 'timetics', $localize_obj );
379 }
380
381 /**
382 * What type of request
383 *
384 * @param string $type admin,frontend, ajax, cron
385 * @return boolean
386 */
387 private function is_request( $type ) {
388 switch ( $type ) {
389 case 'admin':
390 return is_admin();
391 case 'ajax':
392 return defined( 'DOING_AJAX' );
393 case 'cron':
394 return defined( 'DOING_CRON' );
395 case 'frontend':
396 return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' ) && ! $this->is_rest_api_request();
397 }
398 }
399
400 /**
401 * Returns if the request is non-legacy REST API request.
402 *
403 * @return boolean
404 */
405 private function is_rest_api_request() {
406 $server_request = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : false;
407
408 if ( ! $server_request ) {
409 return false;
410 }
411
412 $rest_prefix = trailingslashit( rest_get_url_prefix() );
413 $is_rest_request = ( false !== strpos( $server_request, $rest_prefix ) );
414
415 return apply_filters( 'timetics_is_rest_api_request', $is_rest_request );
416 }
417
418
419 /**
420 * Show buy-pro menu if pro plugin not active
421 *
422 * @return void
423 */
424 public function handle_buy_pro_module() {
425 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only page parameter check, no form processing
426 $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
427
428
429 if ( 'timetics' !== $page ) {
430 return;
431 }
432
433
434 /**
435 * Show banner (codename: jhanda)
436 */
437 $filter_string = 'timetics,timetics-free-only';
438
439 if( $this->has_pro ) {
440
441 $filter_string .= ',timetics-pro';
442 $filter_string = str_replace(',timetics-free-only', '', $filter_string);
443
444 }
445
446
447 \Wpmet\Libs\Banner::instance('timetics')
448 ->is_test(true)
449 ->set_filter(ltrim($filter_string, ','))
450 ->set_api_url('https://banner.themefunction.com/public/jhanda')
451 ->set_plugin_screens('timetics')
452 ->set_plugin_screens('toplevel_page_timetics')
453 ->call();
454 // show get-help and upgrade-to-premium menu.
455 // $this->handle_get_help_and_upgrade_menu();
456 }
457
458 /**
459 * Add HelpScout script to admin footer
460 *
461 * @return void
462 */
463 public function admin_helpscout_beacon() {
464 $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
465 $is_timetics_screen = false;
466
467 if ( $screen ) {
468 $screen_id = isset( $screen->id ) ? $screen->id : '';
469
470 // Check: only load on Timetics top-level admin page
471 if ( 'toplevel_page_timetics' === $screen_id ) {
472 $is_timetics_screen = true;
473 }
474 }
475
476 // Allow overriding detection via filter.
477 $is_timetics_screen = apply_filters( 'timetics_is_admin_screen', $is_timetics_screen, $screen );
478
479 if ( ! $is_timetics_screen ) {
480 return;
481 }
482 ?>
483 <script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)a();else if(e.attachEvent)e.attachEvent("onload",a);else e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});</script>
484 <script type="text/javascript">
485 window.Beacon('config', {
486 color: "#0060e5",
487 });
488 window.Beacon('init', '4be24aa2-ee50-483c-a90c-db4216664d65');
489 window.Beacon('on', 'ready', function(){
490 window.Beacon('show');
491 });
492
493 </script>
494 <?php
495 }
496
497 }
498
499 /**
500 * Returns The Instance Of Timetics.
501 * The main function that is responsible for returning Timetics instance.
502 *
503 * @since 1.0.0
504 * @return Timetics
505 */
506 function timetics() {
507 return Bootstrap::instantiate();
508 }
509