PluginProbe ʕ •ᴥ•ʔ
OttoKit: All-in-One Automation Platform / 1.1.16
OttoKit: All-in-One Automation Platform v1.1.16
1.1.31 1.1.30 1.1.29 1.1.28 1.1.27 1.1.9 trunk 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.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.47 1.0.48 1.0.49 1.0.50 1.0.51 1.0.52 1.0.53 1.0.54 1.0.55 1.0.56 1.0.57 1.0.58 1.0.59 1.0.60 1.0.61 1.0.62 1.0.63 1.0.64 1.0.65 1.0.66 1.0.67 1.0.68 1.0.69 1.0.7 1.0.70 1.0.71 1.0.72 1.0.73 1.0.74 1.0.75 1.0.76 1.0.77 1.0.78 1.0.79 1.0.8 1.0.80 1.0.81 1.0.82 1.0.83 1.0.84 1.0.85 1.0.86 1.0.87 1.0.88 1.0.89 1.0.9 1.0.90 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.20 1.1.21 1.1.22 1.1.23 1.1.24 1.1.25 1.1.26 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8
suretriggers / src / Loader.php
suretriggers / src Last commit date
Admin 10 months ago Controllers 6 months ago Integrations 6 months ago Models 9 months ago Support 1 year ago Traits 3 years ago Loader.php 6 months ago
Loader.php
939 lines
1 <?php
2 /**
3 * Loader.
4 * php version 5.6
5 *
6 * @category Loader
7 * @package SureTriggers
8 * @author BSF <username@example.com>
9 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
10 * @link https://www.brainstormforce.com/
11 * @since 1.0.0
12 */
13
14 namespace SureTriggers;
15
16 use DirectoryIterator;
17 use SureTriggers\Controllers\AuthController;
18 use SureTriggers\Controllers\AutomationController;
19 use SureTriggers\Controllers\EventController;
20 use SureTriggers\Controllers\GlobalSearchController;
21 use SureTriggers\Controllers\IntegrationsController;
22 use SureTriggers\Controllers\OptionController;
23 use SureTriggers\Controllers\RestController;
24 use SureTriggers\Controllers\RoutesController;
25 use SureTriggers\Controllers\WebhookRequestsController;
26 use SureTriggers\Controllers\SettingsController;
27 use SureTriggers\Traits\SingletonLoader;
28 use SureTriggers\Models\SaasApiToken;
29 use function add_menu_page;
30 use function add_submenu_page;
31
32 /**
33 * Loader
34 *
35 * @category Loader
36 * @package SureTriggers
37 * @author BSF <username@example.com>
38 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
39 * @link https://www.brainstormforce.com/
40 * @since 1.0.0
41 */
42 class Loader {
43
44
45
46 use SingletonLoader;
47
48 /**
49 * Constructor
50 *
51 * @since 1.0.0
52 */
53 public function __construct() {
54 register_activation_hook( SURE_TRIGGERS_FILE, [ $this, 'st_activate' ] );
55
56 $this->define_constants();
57 add_action( 'plugins_loaded', [ $this, 'load_textdomain' ] );
58 add_action( 'plugins_loaded', [ $this, 'initialize_core' ] );
59 // Admin Menu.
60 add_action( 'admin_menu', [ $this, 'admin_menu' ] );
61 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
62 add_action( 'admin_head', [ $this, 'add_admin_menu_styles' ] );
63 add_action( 'admin_init', [ $this, 'reset_plugin' ] );
64
65 add_filter( 'plugin_action_links_' . plugin_basename( SURE_TRIGGERS_FILE ), [ $this, 'add_settings_link' ] );
66 add_action( 'admin_init', [ $this, 'redirect_after_activation' ] );
67
68 add_action( 'admin_notices', [ $this, 'display_notice' ] );
69
70 add_action( 'all_admin_notices', [ $this, 'suretriggers_show_api_connection_error' ] );
71
72 add_action( 'wp_dashboard_setup', [ $this, 'add_dashboard_widgets' ] );
73
74 // Remove Webhook Requests retry cron and requests table.
75 register_uninstall_hook(
76 SURE_TRIGGERS_FILE,
77 [ WebhookRequestsController::class, 'suretriggers_remove_table_retry_cron' ]
78 );
79 }
80
81 /**
82 * Adding dashboard widget.
83 *
84 * @return void
85 */
86 public function add_dashboard_widgets() {
87 if ( isset( OptionController::$options['secret_key'] ) ) {
88 return;
89 }
90
91 wp_add_dashboard_widget(
92 'suretriggers_dashboard_widget',
93 __( 'Stop Doing It Manually!', 'suretriggers' ),
94 [ $this, 'dashboard_widget_display' ],
95 null,
96 null,
97 'side',
98 'high'
99 );
100 }
101
102 /**
103 * Dashboard widget callback.
104 *
105 * @return void
106 */
107 public function dashboard_widget_display() { ?>
108 <div>
109 <p> <?php esc_html_e( 'Automation That’s Easy Enough for Anyone.', 'suretriggers' ); ?></p>
110 <p>
111 <?php
112 esc_html_e(
113 'OttoKit connects all your tools - WooCommerce, Forms, CRM, and more, so your website runs smoothly while you focus on your business.
114 ',
115 'suretriggers'
116 );
117 ?>
118 </p>
119 <a href="<?php echo esc_url( admin_url( 'admin.php?page=suretriggers' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Automating', 'suretriggers' ); ?> </a>
120 </div>
121 <?php
122 }
123
124 /**
125 * Load Plugin Text Domain.
126 * This will load the translation textdomain depending on the file priorities.
127 * 1. Global Languages /wp-content/languages/suretriggers/ folder
128 * 2. Local directory /wp-content/plugins/suretriggers/languages/ folder
129 *
130 * @return void
131 */
132 public function load_textdomain() {
133 // Default languages directory.
134 $lang_dir = SURE_TRIGGERS_DIR . 'languages/';
135
136 /**
137 * Filters the languages directory path to use for plugin.
138 *
139 * @param string $lang_dir The languages directory path.
140 */
141 $lang_dir = apply_filters( 'suretriggers_languages_directory', $lang_dir );
142
143 // Traditional WordPress plugin locale filter.
144 global $wp_version;
145
146 $get_locale = get_locale();
147
148 if ( $wp_version >= 4.7 ) {
149 $get_locale = get_user_locale();
150 }
151
152 /**
153 * Language Locale for plugin
154 *
155 * Uses get_user_locale()` in WordPress 4.7 or greater,
156 * otherwise uses `get_locale()`.
157 */
158 $locale = apply_filters( 'plugin_locale', $get_locale, 'suretriggers' );//phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- wordpress hook
159 $mofile = sprintf( '%1$s-%2$s.mo', 'suretriggers', $locale );
160
161 // Setup paths to current locale file.
162 $mofile_global = WP_LANG_DIR . '/plugins/' . $mofile;
163 $mofile_local = $lang_dir . $mofile;
164
165 $mofile_global = wp_normalize_path( $mofile_global );
166 $mofile_local = wp_normalize_path( $mofile_local );
167
168 if ( file_exists( $mofile_global ) && wp_is_file_mod_allowed( 'load_textdomain_mofile' ) ) {
169 // Look in global /wp-content/languages/suretriggers/ folder.
170 load_textdomain( 'suretriggers', $mofile_global );
171 } elseif ( file_exists( $mofile_local ) && wp_is_file_mod_allowed( 'load_textdomain_mofile' ) && $this->st_valid_file_path( $mofile_local ) ) {
172 // Look in local /wp-content/plugins/suretriggers/languages/ folder.
173 load_textdomain( 'suretriggers', $mofile_local );
174 } else {
175 load_plugin_textdomain( 'suretriggers', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
176 }
177 }
178
179 /**
180 * Check if file is valid.
181 *
182 * @param string $file_path file_path.
183 * @return bool
184 */
185 private function st_valid_file_path( $file_path ) {
186 $allowed_dir = realpath( SURE_TRIGGERS_DIR . 'languages/' );
187 $real_file_path = realpath( $file_path );
188 return false !== $real_file_path && $allowed_dir && 0 === strpos( $real_file_path, $allowed_dir );
189 }
190
191 /**
192 * Display notice.
193 *
194 * @return void
195 */
196 public function display_notice() {
197 global $pagenow;
198 if ( isset( OptionController::$options['secret_key'] ) ) {
199 return;
200 }
201 if ( 'index.php' != $pagenow ) {
202 return;
203 }
204 ?>
205 <div class="notice notice-success" style="padding-bottom: 15px;">
206 <p>
207 <strong>
208 <?php esc_html_e( 'Automate Your WordPress Site. Save Hours. Earn More.', 'suretriggers' ); ?>
209 <span style="transform: rotate(-90deg); font-size: 15px;" class="dashicons dashicons-admin-plugins"></span>
210 </strong>
211 </p>
212 <p> <?php esc_html_e( 'OttoKit connects your plugins and favorite apps so your business runs on autopilot — while you focus on what matters most.', 'suretriggers' ); ?> </p>
213
214 <a href="<?php echo esc_url( admin_url( 'admin.php?page=suretriggers' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Automating', 'suretriggers' ); ?> </a>
215 <a href="https://ottokit.com/?utm_source=wpplugin&utm_medium=dashboard&utm_campaign=top+bar" class="button button-secondary"> <?php esc_html_e( 'See How It Works', 'suretriggers' ); ?> </a>
216 </div>
217 <?php
218 }
219
220 /**
221 * Show Connection Error Admin Notice.
222 *
223 * @return void
224 */
225 public function suretriggers_show_api_connection_error() {
226 global $pagenow;
227 $is_authorized = true;
228 if ( ! current_user_can( 'manage_options' ) ) {
229 $is_authorized = self::suretriggers_user_permission_check();
230 }
231 if ( 'index.php' != $pagenow || ! isset( OptionController::$options['secret_key'] ) || ! $is_authorized ) {
232 return;
233 }
234 $notice = get_option( 'suretriggers_verify_connection' );
235 // If empty option value for connection status, then verify the connection.
236 if ( empty( $notice ) || 'suretriggers_connection_successful' != $notice ) {
237 $connection_status = RestController::suretriggers_verify_wp_connection();
238 $connection_status_code = wp_remote_retrieve_response_code( $connection_status );
239 if ( is_wp_error( $connection_status ) ) {
240 update_option( 'suretriggers_verify_connection', 'suretriggers_connection_wp_error' );
241 } else {
242 if ( 200 !== $connection_status_code ) {
243 update_option( 'suretriggers_verify_connection', 'suretriggers_connection_error' );
244 } else {
245 update_option( 'suretriggers_verify_connection', 'suretriggers_connection_successful' );
246 }
247 }
248 }
249 $notice = get_option( 'suretriggers_verify_connection' );
250 if ( 'suretriggers_connection_successful' != $notice ) {
251 // If connection status is not successful, then show the notice.
252 ?>
253 <div class="notice notice-error is-dismissible">
254 <p>
255 <strong>
256 <?php esc_html_e( 'OttoKit Connection Issue', 'suretriggers' ); ?>
257 <span style="transform: rotate(-180deg); font-size: 20px;" class="dashicons dashicons-warning"></span>
258 </strong>
259 </p>
260 <p>
261 <?php esc_html_e( 'There is an issue with the established connection between WordPress and OttoKit. Please visit the OttoKit dashboard to verify and re-establish the connection if necessary.', 'suretriggers' ); ?>
262 </p>
263 <p>
264 <a href="<?php echo esc_url( admin_url( 'admin.php?page=suretriggers' ) ); ?>" class="button button-secondary"> <?php esc_html_e( 'Go To OttoKit', 'suretriggers' ); ?> </a>
265 </p>
266 </div>
267 <?php
268 }
269 }
270
271 /**
272 * Redirect user after plugin activation.
273 *
274 * @return void
275 */
276 public function redirect_after_activation() {
277 $is_redirect = get_transient( 'st-redirect-after-activation' );
278 if ( $is_redirect ) {
279 delete_transient( 'st-redirect-after-activation' );
280 $url = get_admin_url() . 'admin.php?page=suretriggers';
281 wp_safe_redirect( $url );
282 die;
283 }
284 }
285
286 /**
287 * Adding setting link.
288 *
289 * @param array $links links.
290 * @return array
291 */
292 public function add_settings_link( array $links ) {
293 $url = get_admin_url() . 'admin.php?page=suretriggers';
294 $setting_option = get_option( 'suretrigger_options' );
295 if ( isset( $setting_option ) && ! empty( $setting_option ) ) {
296 $settings_link = '<a href="' . $url . '">' . __( 'Dashboard', 'suretriggers' ) . '</a>';
297 } else {
298 $settings_link = '<a href="' . $url . '">' . __( 'Connect', 'suretriggers' ) . '</a>';
299 }
300 $links[] = $settings_link;
301
302 // Add Get OttoKit Pro link for free and pro users.
303 if ( $this->should_show_upgrade_button() ) {
304 $upgrade_link = '<a href="https://ottokit.com/pricing/?utm_source=wpplugin&utm_medium=plugin+list&utm_campaign=plugin+list" target="_blank" style="color: #28a745; font-weight: bold;">' . __( 'Get OttoKit Pro', 'suretriggers' ) . '</a>';
305 $links[] = $upgrade_link;
306 }
307
308 return $links;
309 }
310
311 /**
312 * Define constants
313 *
314 * @return void
315 * @since 1.0.0
316 */
317 public function define_constants() {
318 $sass_url = 'https://app.ottokit.com';
319 $api_url = 'https://api.ottokit.com';
320 $webhook_url = 'https://webhook.ottokit.com';
321
322 define( 'SURE_TRIGGERS_BASE', plugin_basename( SURE_TRIGGERS_FILE ) );
323 define( 'SURE_TRIGGERS_DIR', plugin_dir_path( SURE_TRIGGERS_FILE ) );
324 define( 'SURE_TRIGGERS_URL', plugins_url( '/', SURE_TRIGGERS_FILE ) );
325 define( 'SURE_TRIGGERS_VER', '1.1.16' );
326 define( 'SURE_TRIGGERS_DB_VER', '1.1.16' );
327 define( 'SURE_TRIGGERS_REST_NAMESPACE', 'sure-triggers/v1' );
328 define( 'SURE_TRIGGERS_SASS_URL', $sass_url . '/wp-json/wp-plugs/v1/' );
329 define( 'SURE_TRIGGERS_SITE_URL', $sass_url );
330 define( 'SURE_TRIGGERS_API_SERVER_URL', $api_url );
331 define( 'SURE_TRIGGERS_WEBHOOK_SERVER_URL', $webhook_url );
332
333 define( 'SURE_TRIGGERS_PAGE', 'OttoKit' );
334 define( 'SURE_TRIGGERS_AS_GROUP', 'OttoKit' );
335
336 define( 'SURE_TRIGGERS_ACTION_ERROR_MESSAGE', 'An unexpected error occurred. Something went wrong with the action.' );
337 }
338
339 /**
340 * Flush permalink rules while plugin activation.
341 *
342 * @return void
343 */
344 public function st_activate() {
345 flush_rewrite_rules(); //phpcs:ignore
346
347 set_transient( 'st-redirect-after-activation', true, 120 );
348 }
349
350 /**
351 * SureTriggers Access for Users and User Roles.
352 *
353 * @return bool
354 */
355 private function suretriggers_user_permission_check() {
356 $current_user = wp_get_current_user();
357 $current_user_id = $current_user->ID;
358 $current_user_roles = $current_user->roles;
359
360 // Get enabled users and roles with proper default values.
361 $enabled_users = get_option( 'suretriggers_enabled_users', [] );
362 $enabled_user_roles = get_option( 'suretriggers_enabled_user_roles', [] );
363
364 $enabled_users = is_array( $enabled_users ) ? $enabled_users : [];
365 $enabled_user_roles = is_array( $enabled_user_roles ) ? $enabled_user_roles : [];
366
367 $is_authorized = in_array( $current_user_id, (array) $enabled_users ) || array_intersect( $current_user_roles, (array) $enabled_user_roles );
368
369 return $is_authorized;
370 }
371
372 /**
373 * Add main menu
374 *
375 * @since x.x.x
376 *
377 * @return void
378 */
379 public function admin_menu() {
380 $page_title = apply_filters( 'st_menu_page_title', esc_html__( 'OttoKit', 'suretriggers' ) );
381 $logo = file_get_contents( plugin_dir_path( SURE_TRIGGERS_FILE ) . 'assets/images/OttoKitLogo.svg' );
382
383 $is_authorized = true;
384 if ( ! current_user_can( 'manage_options' ) ) {
385 $is_authorized = self::suretriggers_user_permission_check();
386 }
387
388 if ( $is_authorized ) {
389 add_menu_page(
390 $page_title,
391 $page_title,
392 'read',
393 'suretriggers',
394 [ $this, 'menu_callback' ],
395 $logo ? 'data:image/svg+xml;base64,' . base64_encode( $logo ) : '',
396 30.6002
397 );
398
399 add_submenu_page(
400 'suretriggers',
401 __( 'OttoKit Status', 'suretriggers' ),
402 __( 'Status', 'suretriggers' ),
403 'read',
404 'suretriggers-status',
405 [ $this, 'suretriggers_status_menu_callback' ]
406 );
407
408 // Add Get OttoKit Pro menu for free and pro users.
409 if ( $this->should_show_upgrade_button() ) {
410 add_submenu_page(
411 'suretriggers',
412 __( 'Get OttoKit Pro', 'suretriggers' ),
413 '<span class="ottokit-upgrade-btn">' . __( 'Get OttoKit Pro', 'suretriggers' ) . '</span>',
414 'read',
415 'suretriggers-upgrade-plan',
416 [ $this, 'suretriggers_upgrade_plan_callback' ]
417 );
418 }
419 }
420
421 if ( isset( OptionController::$options['secret_key'] ) ) {
422 add_options_page(
423 __( 'OttoKit Settings', 'suretriggers' ),
424 __( 'OttoKit Settings', 'suretriggers' ),
425 'manage_options',
426 'ottokit-settings',
427 [ $this, 'suretriggers_render_interface_callback' ]
428 );
429 }
430 }
431
432 /**
433 * Enqueue the admin scripts
434 *
435 * @param string $hook hook.
436 * @since x.x.x
437 *
438 * @return void
439 */
440 public function enqueue_scripts( $hook = '' ) {
441 // Always enqueue admin CSS for upgrade button styling.
442 wp_enqueue_style( 'st-trigger-style', SURE_TRIGGERS_URL . 'assets/admin-css/st-admin-css.css', [], SURE_TRIGGERS_VER );
443
444 if ( ! in_array( $hook, [ 'toplevel_page_suretriggers', 'ottokit_page_suretriggers-status', 'settings_page_ottokit-settings' ], true ) ) {
445 return;
446 }
447
448 remove_all_actions( 'admin_notices' );
449
450 $file = SURE_TRIGGERS_DIR . 'app/build/main.asset.php';
451 if ( ! file_exists( $file ) ) {
452 return;
453 }
454
455 $asset = require_once $file;
456
457 if ( ! isset( $asset ) ) {
458 return;
459 }
460
461 wp_register_script(
462 'sure-trigger-admin',
463 SURE_TRIGGERS_URL . 'app/build/main.js',
464 array_merge( $asset['dependencies'], [ 'regenerator-runtime' ], [ 'wp-i18n' ] ),
465 $asset['version'],
466 true
467 );
468
469 wp_localize_script(
470 'sure-trigger-admin',
471 'sureTriggerData',
472 $this->get_localized_array()
473 );
474 wp_enqueue_script( 'sure-trigger-admin' );
475 // Set the script translations.
476 wp_set_script_translations( 'sure-trigger-admin', 'suretriggers', SURE_TRIGGERS_DIR . 'languages' );
477 wp_enqueue_style( 'sure-trigger-components', SURE_TRIGGERS_URL . 'app/build/style-main.css', [], SURE_TRIGGERS_VER );
478 wp_enqueue_style( 'sure-trigger-css', SURE_TRIGGERS_URL . 'app/build/main.css', [], SURE_TRIGGERS_VER );
479 }
480
481 /**
482 * Get localized array for sure triggers.
483 *
484 * @return array
485 */
486 private function get_localized_array() {
487 $settings_nonce = wp_create_nonce( 'suretriggers_settings_nonce_action' );
488 $current_user = wp_get_current_user();
489 global $wp_roles;
490 $is_authorized = true;
491 if ( ! current_user_can( 'manage_options' ) ) {
492 $is_authorized = self::suretriggers_user_permission_check();
493 }
494
495 $source_type = get_option( 'suretriggers_source' );
496
497 // Get enabled users and roles with proper default values.
498 $enabled_users = get_option( 'suretriggers_enabled_users', [] );
499 $enabled_user_roles = get_option( 'suretriggers_enabled_user_roles', [] );
500
501 $enabled_users = is_array( $enabled_users ) ? $enabled_users : [];
502 $enabled_user_roles = is_array( $enabled_user_roles ) ? $enabled_user_roles : [];
503
504 $data = [
505 'siteContent' => [
506 'siteUrl' => str_replace( '/wp-json/', '', get_rest_url() ),
507 'redirectUrl' => get_site_url() . '/wp-admin/themes.php?page=suretriggers',
508 'connectNonce' => wp_create_nonce( 'sure-trigger-connect' ),
509 'connectUrl' => SURE_TRIGGERS_SITE_URL . '/connect-st/connect',
510 'siteTitle' => get_bloginfo( 'name' ),
511 'resetUrl' => base64_encode( wp_nonce_url( admin_url( 'admin.php?st-reset=true' ), 'st-reset-action' ) ),
512 'sourceType' => $source_type,
513 'adminLanguage' => get_user_locale(),
514 ],
515 'user' => [
516 'name' => $current_user->display_name,
517 'email' => $current_user->user_email,
518 ],
519 'stSaasURL' => trailingslashit( SURE_TRIGGERS_SITE_URL ),
520 'stPluginURL' => plugin_dir_url( SURE_TRIGGERS_FILE ),
521 'integrations' => IntegrationsController::get_activated_integrations(),
522 'enabledIntegrations' => OptionController::get_option( 'enabled_integrations' ),
523 'verification_status' => false,
524 'projects' => [],
525 'apiSlug' => SURE_TRIGGERS_REST_NAMESPACE,
526 'reConnectSorryMsg' => (bool) OptionController::get_option( 'st_connect_notice_deprecated' ),
527 'usersRoles' => array_diff_key( $wp_roles->get_names(), [ 'administrator' => '' ] ),
528 'usersList' => get_users(
529 [
530 'fields' => [
531 'ID',
532 'display_name',
533 ],
534 'role__not_in' => [
535 'administrator',
536 ],
537 ]
538 ),
539 'enabledUsers' => $enabled_users,
540 'enabledUserRoles' => $enabled_user_roles,
541 ];
542
543 if ( $is_authorized ) {
544 $data['siteContent']['accessKey'] = SaasApiToken::get();
545 $data['siteContent']['connected_email'] = OptionController::get_option( 'connected_email_key' );
546 }
547
548 $data['settingsNonce'] = esc_js( $settings_nonce );
549 $data['ajaxurl'] = esc_url( admin_url( 'admin-ajax.php' ) );
550
551 return apply_filters( 'sure_trigger_control_localize_vars', $data );
552 }
553
554 /**
555 * Render OttoKit Interface callback.
556 *
557 * @return void
558 */
559 public function suretriggers_render_interface_callback() {
560 ?>
561 <div id="ottokit-settings-page" class="ottokit-settings"></div>
562 <?php
563 }
564
565 /**
566 * Menu callback.
567 *
568 * @since x.x.x
569 *
570 * @return void
571 */
572 public function menu_callback() {
573 // Check permalink structure first.
574 $permalink_structure = get_option( 'permalink_structure' );
575 $is_plain_permalink = empty( $permalink_structure );
576
577 // If permalink structure is "Plain" and we're trying to connect or already connected, show a prominent warning.
578 if ( $is_plain_permalink ) {
579 ?>
580 <div class="st-permalink-warning-wrapper">
581 <div class="st-permalink-warning-card">
582 <div class="st-permalink-warning-icon">
583 <span class="st-permalink-warning-icon-text">!</span>
584 </div>
585 <div class="st-permalink-warning-content">
586 <p class="st-permalink-warning-title">
587 <?php esc_html_e( '“Plain” Permalink Structure Detected', 'suretriggers' ); ?>
588 </p>
589 <p class="st-permalink-warning-message">
590 <?php esc_html_e( 'Your site is currently using the “Plain” permalink structure, which is not supported by OttoKit. Please visit', 'suretriggers' ); ?>
591 <a href="<?php echo esc_url( admin_url( 'options-permalink.php' ) ); ?>" target="_blank" class="st-permalink-warning-link">
592 <?php esc_html_e( 'Permalinks Settings', 'suretriggers' ); ?>
593 </a>
594 <?php esc_html_e( 'on your WordPress Dashboard and choose any structure other than “Plain”.', 'suretriggers' ); ?>
595 </p>
596 </div>
597 </div>
598 </div>
599 <?php
600 }
601
602 // Verify Token.
603 $response = RestController::verify_user_token();
604 $response_body = wp_remote_retrieve_body( $response );
605 $response_code = wp_remote_retrieve_response_code( $response );
606 if ( ! empty( $response_body ) ) {
607 $response_body = json_decode( $response_body, true );
608 }
609 if ( 200 === $response_code || 401 === $response_code ) {
610 if ( is_array( $response_body ) && isset( $response_body['is_iframe_enabled'] ) && 'NO' === $response_body['is_iframe_enabled'] ) {
611 ?>
612 <div class="suretriggers-nobase">
613 <div>
614 <div>
615 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-check inline-block h-8 w-8 text-green-400 mb-6" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m9 12 2 2 4-4"></path></svg>
616 <h2 class="suretriggers-info-title">
617 <?php esc_html_e( 'OttoKit is connected.', 'suretriggers' ); ?>
618 </h2>
619 <p class="suretriggers-info-content">
620 <?php esc_html_e( 'Your WordPress site is successfully connected to the OttoKit SaaS platform. However, the OttoKit interface display is currently disabled. Click below to enable it.', 'suretriggers' ); ?>
621 </p>
622 <a class="suretriggers-info-link" href="<?php echo esc_url( SURE_TRIGGERS_SITE_URL . '/apps/WordPress' ); ?>" target="_blank">
623 <?php esc_html_e( 'Access Connection Page', 'suretriggers' ); ?>
624 </a>
625 </div>
626 </div>
627 </div>
628 <?php
629 } else {
630 ?>
631 <div id="sure-triggger-entry" class="st-base"></div>
632 <?php
633 }
634 } elseif ( isset( $response ) && is_wp_error( $response ) || 200 !== $response_code ) {
635 ?>
636 <div class="suretriggers-nobase">
637 <div>
638 <div>
639 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="30" height="24" viewBox="0 0 122.88 122.879" enable-background="new 0 0 122.88 122.879" xml:space="preserve" class="lucide lucide-circle-check inline-block h-8 w-8 text-green-400 mb-6"><g><path fill="#FF4141" d="M61.44,0c16.96,0,32.328,6.882,43.453,17.986c11.104,11.125,17.986,26.494,17.986,43.453 c0,16.961-6.883,32.328-17.986,43.453C93.769,115.998,78.4,122.879,61.44,122.879c-16.96,0-32.329-6.881-43.454-17.986 C6.882,93.768,0,78.4,0,61.439C0,44.48,6.882,29.111,17.986,17.986C29.112,6.882,44.48,0,61.44,0L61.44,0z M73.452,39.152 c2.75-2.792,7.221-2.805,9.986-0.026c2.764,2.776,2.775,7.292,0.027,10.083L71.4,61.445l12.077,12.25 c2.728,2.77,2.689,7.256-0.081,10.021c-2.772,2.766-7.229,2.758-9.954-0.012L61.445,71.541L49.428,83.729 c-2.75,2.793-7.22,2.805-9.985,0.025c-2.763-2.775-2.776-7.291-0.026-10.082L51.48,61.435l-12.078-12.25 c-2.726-2.769-2.689-7.256,0.082-10.022c2.772-2.765,7.229-2.758,9.954,0.013L61.435,51.34L73.452,39.152L73.452,39.152z M96.899,25.98C87.826,16.907,75.29,11.296,61.44,11.296c-13.851,0-26.387,5.611-35.46,14.685 c-9.073,9.073-14.684,21.609-14.684,35.459s5.611,26.387,14.684,35.459c9.073,9.074,21.609,14.686,35.46,14.686 c13.85,0,26.386-5.611,35.459-14.686c9.073-9.072,14.684-21.609,14.684-35.459S105.973,35.054,96.899,25.98L96.899,25.98z"></path></g></svg>
640 <h2 class="suretriggers-info-title">
641 <?php esc_html_e( 'OttoKit Not Connected.', 'suretriggers' ); ?>
642 </h2>
643 <p class="suretriggers-info-content">
644 <?php esc_html_e( 'It looks like your WordPress site’s connection with OttoKit has been affected because the URL used for communication has changed. The current link for your site is different from the one OttoKit was originally connected to.', 'suretriggers' ); ?>
645 </p>
646 <a class="suretriggers-info-link" href="<?php echo esc_url( SURE_TRIGGERS_SITE_URL ); ?>" target="_blank">
647 <?php esc_html_e( 'Access Dashboard', 'suretriggers' ); ?>
648 </a>
649 <a class="suretriggers-info-link" href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin.php?st-reset=true' ), 'st-reset-action' ) ); ?>">
650 <?php esc_html_e( 'Disconnect OttoKit', 'suretriggers' ); ?>
651 </a>
652 </div>
653 </div>
654 </div>
655 <?php
656 }
657 }
658
659 /**
660 * Status Menu callback.
661 *
662 * @since x.x.x
663 *
664 * @return void
665 */
666 public function suretriggers_status_menu_callback() {
667 if ( ! isset( OptionController::$options['secret_key'] ) ) {
668 ?>
669 <div class="suretriggers-nobase">
670 <div>
671 <div>
672 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="30" height="24" viewBox="0 0 122.88 122.879" enable-background="new 0 0 122.88 122.879" xml:space="preserve" class="lucide lucide-circle-check inline-block h-8 w-8 text-green-400 mb-6"><g><path fill="#FF4141" d="M61.44,0c16.96,0,32.328,6.882,43.453,17.986c11.104,11.125,17.986,26.494,17.986,43.453 c0,16.961-6.883,32.328-17.986,43.453C93.769,115.998,78.4,122.879,61.44,122.879c-16.96,0-32.329-6.881-43.454-17.986 C6.882,93.768,0,78.4,0,61.439C0,44.48,6.882,29.111,17.986,17.986C29.112,6.882,44.48,0,61.44,0L61.44,0z M73.452,39.152 c2.75-2.792,7.221-2.805,9.986-0.026c2.764,2.776,2.775,7.292,0.027,10.083L71.4,61.445l12.077,12.25 c2.728,2.77,2.689,7.256-0.081,10.021c-2.772,2.766-7.229,2.758-9.954-0.012L61.445,71.541L49.428,83.729 c-2.75,2.793-7.22,2.805-9.985,0.025c-2.763-2.775-2.776-7.291-0.026-10.082L51.48,61.435l-12.078-12.25 c-2.726-2.769-2.689-7.256,0.082-10.022c2.772-2.765,7.229-2.758,9.954,0.013L61.435,51.34L73.452,39.152L73.452,39.152z M96.899,25.98C87.826,16.907,75.29,11.296,61.44,11.296c-13.851,0-26.387,5.611-35.46,14.685 c-9.073,9.073-14.684,21.609-14.684,35.459s5.611,26.387,14.684,35.459c9.073,9.074,21.609,14.686,35.46,14.686 c13.85,0,26.386-5.611,35.459-14.686c9.073-9.072,14.684-21.609,14.684-35.459S105.973,35.054,96.899,25.98L96.899,25.98z"></path></g></svg>
673 <h2 class="suretriggers-info-title">
674 <?php esc_html_e( 'OttoKit Not Connected.', 'suretriggers' ); ?>
675 </h2>
676 <p class="suretriggers-info-content">
677 <?php esc_html_e( 'Please connect your OttoKit account to access registered events and outgoing requests.', 'suretriggers' ); ?>
678 </p>
679 <a href="<?php echo esc_url( admin_url( 'admin.php?page=suretriggers' ) ); ?>" class="suretriggers-info-link"> <?php esc_html_e( 'Connect With OttoKit', 'suretriggers' ); ?> </a>
680 </div>
681 </div>
682 </div>
683 <?php
684 return;
685 }
686 ?>
687 <div class="wrap">
688 <?php
689 $tabs = [
690 'st_system_page' => __( 'Status', 'suretriggers' ),
691 'st_outgoing_requests' => __( 'Outgoing Requests', 'suretriggers' ),
692 'st_troubleshooting' => __( 'Troubleshooting', 'suretriggers' ),
693 ];
694 $current_tab = 'st_system_page';
695 if ( isset( $_REQUEST['tab'], $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'suretriggers_tab_nonce' ) ) {
696 if ( array_key_exists( sanitize_key( $_REQUEST['tab'] ), $tabs ) ) {
697 $current_tab = sanitize_key( $_REQUEST['tab'] );
698 }
699 }
700 ?>
701 <nav class="suretriggers-nav-tab nav-tab-wrapper">
702 <?php
703 foreach ( $tabs as $name => $label ) {
704 $tab_url = add_query_arg(
705 [
706 'tab' => $name,
707 '_wpnonce' => wp_create_nonce( 'suretriggers_tab_nonce' ),
708 ],
709 admin_url( 'admin.php?page=suretriggers-status' )
710 );
711 echo '<a href="' . esc_url( $tab_url ) . '" class="nav-tab ';
712 if ( $current_tab == $name ) {
713 echo 'nav-tab-active';
714 }
715 echo '">' . esc_html( $label ) . '</a>';
716 }
717 ?>
718 </nav>
719 <?php
720 switch ( $current_tab ) {
721 case 'st_system_page':
722 include_once __DIR__ . '/Admin/Views/st-admin-system-page.php';
723 break;
724 case 'st_outgoing_requests':
725 include_once __DIR__ . '/Admin/Views/st-admin-outgoing-req-page.php';
726 break;
727 case 'st_troubleshooting':
728 include_once __DIR__ . '/Admin/Views/st-admin-troubleshooting-page.php';
729 break;
730 }
731 ?>
732 </div>
733 <?php
734 }
735
736 /**
737 * Get OttoKit Pro Menu callback.
738 *
739 * @since x.x.x
740 *
741 * @return void
742 */
743 public function suretriggers_upgrade_plan_callback() {
744 ?>
745 <script type="text/javascript">
746 window.location.href = 'https://ottokit.com/pricing/?utm_source=wpplugin&utm_medium=menu&utm_campaign=left';
747 </script>
748 <?php
749 exit;
750 }
751
752 /**
753 * Add admin menu styles.
754 *
755 * @since x.x.x
756 *
757 * @return void
758 */
759 public function add_admin_menu_styles() {
760 ?>
761 <script>
762 jQuery(document).ready(function($) {
763 // Direct redirect for admin menu upgrade button
764 $('a[href*="suretriggers-lifetime-access"]').on('click', function(e) {
765 e.preventDefault();
766 window.open('https://ottokit.com/pricing/?utm_source=wpplugin&utm_medium=menu&utm_campaign=left', '_blank');
767 return false;
768 });
769 });
770 </script>
771 <?php
772 }
773
774 /**
775 * Include all files from the folder.
776 *
777 * @param string $folder folder path.
778 * @return void
779 */
780 public function include_all_files( $folder ) {
781 $dir = new DirectoryIterator( $folder );
782 foreach ( $dir as $file ) {
783 if ( ! $file->isDot() ) {
784 if ( $file->isDir() ) {
785 $this->include_all_files( $file->getPathname() );
786 } else {
787 require_once $file->getPathname();
788 }
789 }
790 }
791 }
792
793 /**
794 * Initialize core trigger and actions.
795 *
796 * @return void
797 */
798 public function initialize_core() {
799
800 IntegrationsController::load_event_files();
801
802 EventController::get_instance();
803 IntegrationsController::get_instance();
804 GlobalSearchController::get_instance();
805 RestController::get_instance();
806 OptionController::get_instance();
807 AutomationController::get_instance();
808 AuthController::get_instance();
809 RoutesController::get_instance();
810 WebhookRequestsController::get_instance();
811 SettingsController::get_instance();
812
813 // SureTriggers Custom Filter data.
814 add_filter( 'suretriggers_get_iframe_url', [ $this, 'suretriggers_iframe_data' ] );
815 add_filter( 'suretriggers_is_user_connected', [ $this, 'suretriggers_saas_connected_data' ] );
816
817 // Create Webhook Request Log table.
818 WebhookRequestsController::suretriggers_webhook_request_log_table();
819 // Schedule the cron jon to retry failed triggers.
820 WebhookRequestsController::suretriggers_setup_custom_cron();
821
822 $this->include_all_files( SURE_TRIGGERS_DIR . 'src/Integrations/' );
823 }
824
825 /**
826 * Added option to reset plugin in case of testing.
827 *
828 * @return void
829 */
830 public function reset_plugin() {
831 $nonce = sanitize_text_field( wp_unslash( isset( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : false ) );
832
833 if ( $nonce && wp_verify_nonce( $nonce, 'st-reset-action' ) ) {
834 $is_reset = sanitize_text_field( wp_unslash( isset( $_GET['st-reset'] ) ? $_GET['st-reset'] : false ) );
835 if ( $is_reset && current_user_can( 'manage_options' ) ) {
836 delete_option( 'suretrigger_options' );
837 self::clear_verification_cache();
838 wp_safe_redirect( admin_url( 'admin.php?page=suretriggers' ) );
839 exit();
840 }
841 }
842 }
843
844 /**
845 * Custom Filter data.
846 *
847 * @param string $site_url Optional. Site URL to include in the iframe data.
848 * @return string
849 */
850 public function suretriggers_iframe_data( $site_url = '' ) {
851 $site_url = esc_url_raw( $site_url );
852 if ( ! current_user_can( 'manage_options' ) ) {
853 return $site_url;
854 }
855 $site_content_data = [
856 'stSaasURL' => $site_url . 'wp-login',
857 'stCode' => SaasApiToken::get(),
858 'baseUrl' => str_replace( '/wp-json/', '', get_rest_url() ),
859 'resetUrl' => rtrim( base64_encode( wp_nonce_url( admin_url( 'admin.php?st-reset=true' ), 'st-reset-action' ) ), '=' ), // phpcs:ignore
860 ];
861 $params = [
862 'st-code' => $site_content_data['stCode'],
863 'base_url' => $site_content_data['baseUrl'],
864 'reset_url' => $site_content_data['resetUrl'],
865 'redirect_url' => $site_url . 'embed-login',
866 'is_embedded' => true,
867 ];
868
869 if ( filter_var( $site_url, FILTER_VALIDATE_URL ) ) {
870 $iframe_url = add_query_arg( $params, $site_content_data['stSaasURL'] );
871 } else {
872 $default_url = trailingslashit( SURE_TRIGGERS_SITE_URL ) . '?path=dashboard';
873 $iframe_url = add_query_arg( $params, $default_url );
874 }
875 return esc_url_raw( $iframe_url );
876 }
877
878
879 /**
880 * Custom Filter data to check if user is logged in iframe.
881 *
882 * @return bool
883 */
884 public function suretriggers_saas_connected_data() {
885 if ( ! current_user_can( 'manage_options' ) ) {
886 return false;
887 }
888 $token = SaasApiToken::get();
889
890 if ( '' === $token || null === $token || false === $token || 'connection-denied' === $token ) {
891 $logged_in = false;
892 } else {
893 $logged_in = true;
894 }
895 return $logged_in;
896 }
897
898 /**
899 * Check if user has lifetime plan
900 *
901 * @return bool
902 */
903 public function is_lifetime_plan() {
904 // Check if verification data is already stored in database.
905 $verification_data = get_option( 'suretriggers_lifetime_user_plan_data' );
906 // Return lifetime plan status from cached data.
907 if ( is_array( $verification_data ) && isset( $verification_data['is_lifetime_plan'] ) ) {
908 return (bool) $verification_data['is_lifetime_plan'];
909 }
910
911 return false;
912 }
913
914 /**
915 * Check if user should see upgrade button (free or pro plan)
916 *
917 * @return bool
918 */
919 public function should_show_upgrade_button() {
920 $verification_data = get_option( 'suretriggers_lifetime_user_plan_data' );
921
922 if ( is_array( $verification_data ) && isset( $verification_data['plan_id'] ) ) {
923 $plan_id = $verification_data['plan_id'];
924 return in_array( $plan_id, [ 'free', 'pro' ], true );
925 }
926
927 return false;
928 }
929
930 /**
931 * Clear cached user verification data when token changes
932 *
933 * @return void
934 */
935 public static function clear_verification_cache() {
936 delete_option( 'suretriggers_lifetime_user_plan_data' );
937 }
938 }
939