PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.64
Timetics – Appointment Booking Calendar & Scheduling v1.0.64
1.0.64 1.0.62 1.0.63 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 All 65 releases
← All changes | timetics.php +194 -75 1.0.1 → 1.0.64 View file →
@@ -1,11 +1,11 @@
1 1 <?php
2 2
3 3 /**
4 - * Plugin Name: Timetics
4 + * Plugin Name: Timetics - Appointment Booking Calendar & Scheduling System
5 5 * Plugin URI: https://arraytics.com/timetics/
6 6 * Description: Schedule, Appointment and Seat Booking plugin.
7 - * Version: 1.0.1
7 + * Version: 1.0.64
8 8 * Requires at least: 5.2
9 9 * Requires PHP: 7.3
10 10 * Author: Arraytics
11 11 * Author URI: https://arraytics.com/
@@ -29,13 +29,13 @@
29 29 *
30 30 * @package Timetics
31 31 * @category Core
32 32 * @author Arraytics
33 - * @version 1.0.0
33 + * @version 1.0.10
34 34 */
35 35
36 36 // Exit if accessed directly.
37 -defined('ABSPATH') || exit;
37 +defined( 'ABSPATH' ) || exit;
38 38
39 39 /**
40 40 * The Main Plugin Requirements Checker
41 41 *
@@ -40,10 +40,9 @@
40 40 * The Main Plugin Requirements Checker
41 41 *
42 42 * @since 1.0.0
43 43 */
44 -final class Timetics
45 -{
44 +final class Timetics {
46 45
47 46 /**
48 47 * Static Property To Hold Singleton Instance
49 48 *
@@ -51,8 +50,17 @@
51 50 */
52 51 private static $instance;
53 52
54 53 /**
54 + * Plugin Current Production Version
55 + *
56 + * @return string
57 + */
58 + public static function get_version() {
59 + return '1.0.64';
60 + }
61 +
62 + /**
55 63 * Requirements Array
56 64 *
57 65 * @since 1.0.0
58 66 * @var array
@@ -80,11 +88,10 @@
80 88 * Singleton Instance
81 89 *
82 90 * @return Timetics
83 91 */
84 - public static function get_instance()
85 - {
86 - if (null === self::$instance) {
92 + public static function get_instance() {
93 + if ( null === self::$instance ) {
87 94 self::$instance = new self();
88 95 }
89 96
90 97 return self::$instance;
@@ -94,12 +101,11 @@
94 101 * Setup Plugin Requirements
95 102 *
96 103 * @since 1.0.0
97 104 */
98 - private function __construct()
99 - {
105 + private function __construct() {
100 106 // Always load translation.
101 - add_action('plugins_loaded', array($this, 'load_text_domain'));
107 + add_action( 'init', array( $this, 'load_text_domain' ) );
102 108
103 109 // Initialize plugin functionalities or quit.
104 110 $this->requirements_met() ? $this->initialize_modules() : $this->quit();
105 111 }
@@ -109,15 +115,32 @@
109 115 *
110 116 * @since 1.0
111 117 * @return void
112 118 */
113 - public function load_text_domain()
114 - {
115 - $locale = apply_filters('plugin_locale', get_user_locale(), 'timetics');
119 + public function load_text_domain() {
120 + $locale = determine_locale();
121 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress core localization hook.
122 + $locale = apply_filters( 'plugin_locale', $locale, 'timetics' );
123 + $locale = apply_filters( 'timetics_plugin_locale', $locale, 'timetics' );
116 124
117 - unload_textdomain('timetics');
118 - load_textdomain('timetics', WP_LANG_DIR . '/timetics/timetics-' . $locale . '.mo');
119 - load_plugin_textdomain('timetics', false, self::get_plugin_dir() . 'languages/');
125 + $mofile = 'timetics-' . $locale . '.mo';
126 +
127 + // Loco "Custom" location.
128 + if ( file_exists( WP_LANG_DIR . '/loco/plugins/' . $mofile ) ) {
129 + load_textdomain( 'timetics', WP_LANG_DIR . '/loco/plugins/' . $mofile );
130 + }
131 +
132 + // Loco "System" location.
133 + if ( file_exists( WP_LANG_DIR . '/plugins/' . $mofile ) ) {
134 + load_textdomain( 'timetics', WP_LANG_DIR . '/plugins/' . $mofile );
135 + }
136 +
137 + // Bundled translations remain available while WordPress loads language
138 + // packs for this text domain automatically.
139 + $bundled_mofile = plugin_dir_path( __FILE__ ) . 'languages/' . $mofile;
140 + if ( file_exists( $bundled_mofile ) ) {
141 + load_textdomain( 'timetics', $bundled_mofile );
142 + }
120 143 }
121 144
122 145 /**
123 146 * Initialize Plugin Modules
@@ -124,28 +147,34 @@
124 147 *
125 148 * @since 1.0.0
126 149 * @return void
127 150 */
128 - private function initialize_modules()
129 - {
130 - require_once dirname(__FILE__) . '/autoloader.php';
131 - require_once dirname(__FILE__) . '/core/settings/settings.php';
151 + private function initialize_modules() {
152 + require_once dirname( __FILE__ ) . '/autoloader.php';
153 + require_once dirname( __FILE__ ) . '/core/settings/settings.php';
132 154
133 - require_once dirname(__FILE__) . '/utils/global-helper.php';
155 + require_once dirname( __FILE__ ) . '/utils/global-helper.php';
134 156
157 + // block for showing banner.
158 + require_once plugin_dir_path( __FILE__ ) . '/utils/notice/notice.php';
159 + require_once plugin_dir_path( __FILE__ ) . '/utils/banner/banner.php';
160 +
135 161 // Include the bootstrap file if not loaded.
136 - if (!class_exists('Timetics\Bootstrap')) {
162 + if ( ! class_exists( 'Timetics\Bootstrap' ) ) {
137 163 require_once self::get_plugin_dir() . 'bootstrap.php';
138 164 }
139 165
166 + // init notice class.
167 + \Oxaim\Libs\Notice::init();
168 +
140 169 // Initialize the bootstraper if exists.
141 - if (class_exists('Timetics\Bootstrap')) {
170 + if ( class_exists( 'Timetics\Bootstrap' ) ) {
142 171
143 172 // Initialize all modules through plugins_loaded.
144 - add_action('plugins_loaded', array($this, 'init'));
173 + add_action( 'plugins_loaded', array( $this, 'init' ) );
145 174
146 - register_activation_hook(self::get_plugin_file(), array($this, 'activate'));
147 - register_deactivation_hook(self::get_plugin_file(), array($this, 'deactivate'));
175 + register_activation_hook( self::get_plugin_file(), array( $this, 'activate' ) );
176 + register_deactivation_hook( self::get_plugin_file(), array( $this, 'deactivate' ) );
148 177 }
149 178 }
150 179
151 180 /**
@@ -152,17 +181,16 @@
152 181 * Check If All Requirements Are Fulfilled
153 182 *
154 183 * @return boolean
155 184 */
156 - private function requirements_met()
157 - {
185 + private function requirements_met() {
158 186 $this->prepare_requirement_versions();
159 187
160 188 $passed = true;
161 - $to_meet = wp_list_pluck($this->requirements, 'met');
189 + $to_meet = wp_list_pluck( $this->requirements, 'met' );
162 190
163 - foreach ($to_meet as $met) {
164 - if (empty($met)) {
191 + foreach ( $to_meet as $met ) {
192 + if ( empty( $met ) ) {
165 193 $passed = false;
166 194 continue;
167 195 }
168 196 }
@@ -176,26 +204,25 @@
176 204 * @since 1.0.0
177 205 *
178 206 * @return void
179 207 */
180 - private function prepare_requirement_versions()
181 - {
182 - foreach ($this->requirements as $dependency => $config) {
183 - switch ($dependency) {
184 - case 'php':
185 - $version = phpversion();
186 - break;
187 - case 'wp':
188 - $version = get_bloginfo('version');
189 - break;
190 - default:
191 - $version = false;
208 + private function prepare_requirement_versions() {
209 + foreach ( $this->requirements as $dependency => $config ) {
210 + switch ( $dependency ) {
211 + case 'php':
212 + $version = phpversion();
213 + break;
214 + case 'wp':
215 + $version = get_bloginfo( 'version' );
216 + break;
217 + default:
218 + $version = false;
192 219 }
193 220
194 - if (!empty($version)) {
221 + if ( ! empty( $version ) ) {
195 222 $this->requirements[$dependency]['current'] = $version;
196 223 $this->requirements[$dependency]['checked'] = true;
197 - $this->requirements[$dependency]['met'] = version_compare($version, $config['minimum'], '>=');
224 + $this->requirements[$dependency]['met'] = version_compare( $version, $config['minimum'], '>=' );
198 225 }
199 226 }
200 227 }
201 228
@@ -205,11 +232,66 @@
205 232 * @since 1.0.0
206 233 *
207 234 * @return void
208 235 */
209 - public function init()
210 - {
211 - Timetics\Bootstrap::instantiate(self::get_plugin_file());
236 + public function init() {
237 + Timetics\Bootstrap::instantiate( self::get_plugin_file() );
238 +
239 + // Add autoload from composer for integrating uninstallation form
240 + if (file_exists(plugin_dir_path( __FILE__ ) . '/vendor/autoload.php')) {
241 + require_once plugin_dir_path( __FILE__ ) . '/vendor/autoload.php';
242 + }
243 +
244 + if (class_exists('UninstallerForm\UninstallerForm') && is_callable(['\UninstallerForm\UninstallerForm', 'init'])) {
245 +
246 + $reflection = new ReflectionMethod('\UninstallerForm\UninstallerForm', 'init');
247 +
248 + // Maximum number of parameters allowed
249 + $totalParams = $reflection->getNumberOfParameters();
250 +
251 + if($totalParams === 6) {
252 + add_filter( 'rest_request_before_callbacks', function( $response, $handler, $request ) {
253 + if ( $request->get_route() === '/timetics/v1/feedback' ) {
254 + $params = $request->get_json_params();
255 +
256 + if ( empty( $params['email'] ) ) {
257 + $params['email'] = get_option( 'admin_email' );
258 + $request->set_body( wp_json_encode( $params ) );
259 + }
260 + }
261 + return $response;
262 + }, 10, 3 );
263 +
264 + \UninstallerForm\UninstallerForm::init(
265 + 'Timetics', // Plugin name
266 + 'timetics', // Plugin Slug
267 + __FILE__,
268 + 'timetics', // Text Domain Name
269 + 'timetics-feedback-modal', // plugins-admin-script-handler
270 + 'https://arraytics.com/?fluentcrm=1&route=contact&hash=13cce8a6-c038-4997-91e7-4a2326cc1124'
271 + );
272 + } else {
273 + add_filter( 'rest_request_before_callbacks', function( $response, $handler, $request ) {
274 + if ( $request->get_route() === '/timetics/v1/feedback' ) {
275 + $params = $request->get_json_params();
276 +
277 + if ( empty( $params['email'] ) ) {
278 + $params['email'] = get_option( 'admin_email' );
279 + $request->set_body( wp_json_encode( $params ) );
280 + }
281 + }
282 + return $response;
283 + }, 10, 3 );
284 +
285 + \UninstallerForm\UninstallerForm::init(
286 + 'Timetics', // Plugin name
287 + 'timetics', // Plugin Slug
288 + __FILE__,
289 + 'timetics', // Text Domain Name
290 + 'timetics-feedback-modal'
291 + );
292 + }
293 + }
212 294 }
213 295
214 296 /**
215 297 * Called Only Once While Activation
@@ -215,15 +297,38 @@
215 297 * Called Only Once While Activation
216 298 *
217 299 * @return void
218 300 */
219 - public function activate()
220 - {
301 + public function activate() {
221 302 // Insert new role.
222 303 Timetics\Base\Role::instance()->init();
223 304
224 305 // Update default settings.
225 306 timetics_update_default_settings();
307 +
308 + // Register cron
309 + timetics_register_cron();
310 +
311 + // Create new woocommerce product category for timetics meeting
312 + timetics_add_woocommerce_product_cat();
313 +
314 + // Force rewrite-rule flush on activation; the maybe_flush_rules guard handles subsequent upgrades.
315 + delete_option( 'timetics_rewrite_version' );
316 +
317 + // Update option for onboard settings.
318 + $timetics_onboard_setup = get_option( 'timetics_onboard_setup' );
319 +
320 + $timetics_demo_data = get_option( 'timetics_demo_data' );
321 +
322 + if ( ! $timetics_demo_data ) {
323 + $dummy_data_generator = new Timetics\Core\DummyData\Dummy_Data_Generator();
324 + $dummy_data_generator->generate();
325 + update_option( 'timetics_demo_data', true );
326 + }
327 +
328 + if ( ! $timetics_onboard_setup ) {
329 + update_option( 'timetics_onboard_settings', true );
330 + }
226 331 }
227 332
228 333 /**
229 334 * Called Only Once While Deactivation
@@ -229,10 +334,10 @@
229 334 * Called Only Once While Deactivation
230 335 *
231 336 * @return void
232 337 */
233 - public function deactivate()
234 - {
338 + public function deactivate() {
339 + wp_clear_scheduled_hook( 'timetics_cleanup_unpaid_bookings' );
235 340 }
236 341
237 342 /**
238 343 * Quit Plugin Execution
@@ -238,11 +343,10 @@
238 343 * Quit Plugin Execution
239 344 *
240 345 * @return void
241 346 */
242 - private function quit()
243 - {
244 - add_action('admin_head', array($this, 'show_plugin_requirements_not_met_notice'));
347 + private function quit() {
348 + add_action( 'admin_head', array( $this, 'show_plugin_requirements_not_met_notice' ) );
245 349 }
246 350
247 351 /**
248 352 * Show Error Notice For Missing Requirements
@@ -248,30 +352,18 @@
248 352 * Show Error Notice For Missing Requirements
249 353 *
250 354 * @return void
251 355 */
252 - public function show_plugin_requirements_not_met_notice()
253 - {
254 - printf('<div>Minimum requirements for Timetics are not met. Please update requirements to continue.</div>');
356 + public function show_plugin_requirements_not_met_notice() {
357 + printf( '<div>Minimum requirements for Timetics are not met. Please update requirements to continue.</div>' );
255 358 }
256 359
257 360 /**
258 - * Plugin Current Production Version
259 - *
260 - * @return string
261 - */
262 - public static function get_version()
263 - {
264 - return '1.0.0';
265 - }
266 -
267 - /**
268 361 * Plugin Main File
269 362 *
270 363 * @return string
271 364 */
272 - public static function get_plugin_file()
273 - {
365 + public static function get_plugin_file() {
274 366 return __FILE__;
275 367 }
276 368
277 369 /**
@@ -278,11 +370,38 @@
278 370 * Plugin Base Directory Path
279 371 *
280 372 * @return string
281 373 */
282 - public static function get_plugin_dir()
283 - {
284 - return trailingslashit(plugin_dir_path(self::get_plugin_file()));
374 + public static function get_plugin_dir() {
375 + return trailingslashit( plugin_dir_path( self::get_plugin_file() ) );
285 376 }
286 377 }
378 +
379 +/**
380 + * Add a "Go Pro" action link on the Plugins page.
381 + * Hidden when the pro plugin already exists.
382 + */
383 +if ( ! function_exists( 'timetics_add_go_pro_action_link' ) ) {
384 + function timetics_add_go_pro_action_link( $links ) {
385 + if ( ! function_exists( 'get_plugins' ) ) {
386 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
387 + }
388 +
389 + foreach ( get_plugins() as $plugin ) {
390 + if ( isset( $plugin['TextDomain'] ) && 'timetics-pro' === $plugin['TextDomain'] ) {
391 + return $links;
392 + }
393 + }
394 +
395 + $go_pro = sprintf(
396 + '<a href="%1$s" target="_blank" rel="noopener noreferrer" style="color:#e8364c;font-weight:600;">%2$s</a>',
397 + esc_url( 'https://arraytics.com/timetics/pricing/' ),
398 + esc_html__( 'Go Pro', 'timetics' )
399 + );
400 +
401 + $links[] = $go_pro;
402 + return $links;
403 + }
404 +}
405 +add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'timetics_add_go_pro_action_link' );
287 406
288 407 Timetics::get_instance();