PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.2.1
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.2.1
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 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 All 162 releases
cartflows / admin-core / inc / onboarding-core.php

onboarding-core.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.2.1, at admin-core/inc/onboarding-core.php

494 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * CartFlows Onboarding Core.
4 *
5 * @package CartFlows
6 */
7
8 namespace CartflowsAdmin\AdminCore\Inc;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class OnboardingCore.
17 */
18 class OnboardingCore {
19
20 /**
21 * Instance
22 *
23 * @access private
24 * @var object Class object.
25 * @since 1.0.0
26 */
27 private static $instance;
28
29 /**
30 * Initiator
31 *
32 * @since 1.0.0
33 * @return object initialized object of class.
34 */
35 public static function get_instance() {
36 if ( ! isset( self::$instance ) ) {
37 self::$instance = new self();
38 }
39 return self::$instance;
40 }
41
42 /**
43 * Constructor.
44 */
45 public function __construct() {
46
47 if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
48
49 add_action( 'admin_menu', array( $this, 'admin_menus' ) );
50 add_action( 'admin_init', array( $this, 'setup_wizard' ) );
51 add_action( 'admin_init', array( $this, 'hide_notices' ) );
52 add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
53 add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
54 // We are hiding admin bar intentionally, only on the setup wizard page.
55 if ( isset( $_GET['page'] ) && 'cartflows-onboarding' === $_GET['page'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
56 add_filter( 'show_admin_bar', '__return_false', 1 ); //phpcs:ignore WordPressVIPMinimum.UserExperience.AdminBarRemoval.RemovalDetected, WordPressVIPMinimum.UserExperience.AdminBarRemoval.HidingDetected
57 }
58
59 add_action( 'init', array( $this, 'load_scripts' ) );
60 add_action( 'admin_print_styles', array( $this, 'load_admin_media_styles' ) );
61
62 add_action( 'admin_init', array( $this, 'redirect_to_onboarding' ) );
63 add_filter( 'before_cp_load_popup', array( $this, 'hide_convert_pro_popups' ), 10, 1 ); // Disable the render of Convert Pro popups in onboarding wizard.
64 add_filter( 'astra_get_option_scroll-to-top-enable', '__return_false' ); // Remove Astra's Scroll to top arrow.
65 }
66 }
67
68 /**
69 * Redirect to onboarding if required.
70 *
71 * @return void
72 * @since 2.0.0
73 */
74 public function redirect_to_onboarding() {
75
76 if ( ! get_option( 'wcf_start_onboarding', false ) ) {
77 return;
78 }
79
80 if ( '1' === get_option( 'wcf_setup_complete', false ) || '1' === get_option( 'wcf_setup_skipped', false ) ) {
81 return;
82 }
83
84 delete_option( 'wcf_start_onboarding' );
85 wp_safe_redirect( esc_url_raw( admin_url( 'index.php?page=cartflows-onboarding' ) ) );
86 exit();
87 }
88
89
90 /**
91 * Load styles.
92 */
93 public function load_admin_media_styles() {
94
95 $ary_libs = array(
96 'common',
97 'forms',
98 );
99 $admin_media_styles_url = add_query_arg(
100 array(
101 'c' => 0,
102 'dir' => ! is_rtl() ? 'ltr' : 'rtl',
103 'load[]' => implode( ',', $ary_libs ),
104 'ver' => 'you_wp_version',
105 ),
106 admin_url() . 'load-styles.php'
107 );
108 echo "<link rel='stylesheet' id='admin_styles_for_media-css' href='" . esc_url( $admin_media_styles_url ) . "' type='text/css' media='all' />";
109 }
110
111 /**
112 * Load media.
113 */
114 public function load_scripts() {
115
116 add_action( 'wp_enqueue_scripts', array( $this, 'load_media_script' ) );
117 }
118
119 /**
120 * Load WP media script on init.
121 */
122 public function load_media_script() {
123 wp_enqueue_media();
124 }
125
126 /**
127 * Hide a notice if the GET variable is set.
128 */
129 public function hide_notices() {
130
131 if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
132 return;
133 }
134
135 $wcf_hide_notice = isset( $_GET['wcf-hide-notice'] ) ? sanitize_text_field( wp_unslash( $_GET['wcf-hide-notice'] ) ) : '';
136 $_wcf_notice_nonce = isset( $_GET['_wcf_notice_nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wcf_notice_nonce'] ) ) : '';
137
138 if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
139 update_option( 'wcf_setup_skipped', true );
140 }
141 }
142
143 /**
144 * Disable the woo redirect for new setup.
145 */
146 public function disable_woo_setup_redirect() {
147
148 delete_transient( '_wc_activation_redirect' );
149 }
150
151 /**
152 * Show action links on the plugin screen.
153 *
154 * @since 1.0.0
155 * @return void
156 */
157 public function show_setup_wizard() {
158
159 $screen = get_current_screen();
160 $screen_id = $screen ? $screen->id : '';
161 $allowed_screens = array(
162 'cartflows_page_cartflows_settings',
163 'edit-cartflows_flow',
164 'dashboard',
165 'plugins',
166 );
167
168 if ( ! in_array( $screen_id, $allowed_screens, true ) ) {
169 return;
170 }
171
172 $status = get_option( 'wcf_setup_complete', false );
173 $skip_setup = get_option( 'wcf_setup_skipped', false );
174
175 if ( false === $status && ! $skip_setup ) { ?>
176 <div class="notice notice-info wcf-notice">
177 <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
178 <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
179 <p>
180 <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflows-onboarding' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Setup', 'cartflows' ); ?></a>
181 <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
182 </p>
183 </div>
184 <?php
185 }
186 }
187
188 /**
189 * Add admin menus/screens.
190 */
191 public function admin_menus() {
192
193 // Ignoring phpcs nonce rule as we are calling this function on admin action.
194 if ( empty( $_GET['page'] ) || 'cartflows-onboarding' !== $_GET['page'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
195 return;
196 }
197
198 add_dashboard_page( '', '', 'manage_options', 'cartflows-onboarding', '' );
199 }
200
201 /**
202 * Show the setup wizard.
203 */
204 public function setup_wizard() {
205
206 // Ignoring phpcs nonce rule as we are calling this function on admin action.
207 if ( empty( $_GET['page'] ) || 'cartflows-onboarding' !== $_GET['page'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
208 return;
209 }
210 $this->load_required_scripts();
211 $this->localize_vars();
212 $this->unhook_deprecated_wp_callbacks();
213
214 // Disable loading of Query Monitor in footer.
215 add_filter( 'qm/dispatch/html', '__return_false' );
216
217 ob_start();
218 include_once CARTFLOWS_DIR . 'admin-core/views/onboarding-base.php';
219 }
220
221 /**
222 * Detach WP core callbacks deprecated in 6.4 from the actions the
223 * standalone onboarding view fires manually (admin_print_styles, admin_head).
224 *
225 * Without this, every onboarding load on WP 6.4+ emits PHP deprecation
226 * notices for print_emoji_styles, wp_admin_bar_header, and
227 * the_block_template_skip_link via _deprecated_function().
228 *
229 * Centralised here (rather than inline in the view) so the deprecated-
230 * callback list lives in one place and the view stays presentation-only.
231 *
232 * Scoped strictly to the CartFlows onboarding screen — the guard ensures
233 * it cannot affect any other admin page even if called from elsewhere.
234 *
235 * @since x.x.x
236 * @return void
237 */
238 private function unhook_deprecated_wp_callbacks() {
239
240 // Hard guard — only run on the CartFlows onboarding screen.
241 if ( empty( $_GET['page'] ) || 'cartflows-onboarding' !== $_GET['page'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
242 return;
243 }
244
245 $deprecated_callbacks = array(
246 'admin_print_styles' => array( 'print_emoji_styles' ),
247 'admin_head' => array( 'wp_admin_bar_header', 'the_block_template_skip_link' ),
248 );
249
250 foreach ( $deprecated_callbacks as $action => $callbacks ) {
251 foreach ( $callbacks as $callback ) {
252 remove_action( $action, $callback );
253 }
254 }
255 }
256
257 /**
258 * Load scripts.
259 */
260 public function load_required_scripts() {
261 $handle = 'wcf-onboarding-app';
262 $build_path = CARTFLOWS_DIR . 'admin-core/assets/build/';
263 $build_url = CARTFLOWS_URL . 'admin-core/assets/build/';
264 $script_asset_path = $build_path . 'onboarding-app.asset.php';
265 $script_info = file_exists( $script_asset_path )
266 ? include $script_asset_path
267 : array(
268 'dependencies' => array(),
269 'version' => CARTFLOWS_VER,
270 );
271
272 $script_dep = array_merge( $script_info['dependencies'], array( 'updates' ) );
273
274 wp_register_script(
275 $handle,
276 $build_url . 'onboarding-app.js',
277 $script_dep,
278 $script_info['version'],
279 true
280 );
281
282 wp_register_style(
283 $handle,
284 $build_url . 'onboarding-app.css',
285 array(),
286 CARTFLOWS_VER
287 );
288
289 wp_enqueue_script( $handle );
290 wp_enqueue_style( $handle );
291 wp_style_add_data( $handle, 'rtl', 'replace' );
292
293 wp_register_script(
294 'wcf-onboarding-helper',
295 CARTFLOWS_URL . 'admin-core/assets/js/onboarding-helper.js',
296 array( 'jquery', 'wp-util', 'updates', 'media-upload' ),
297 CARTFLOWS_VER,
298 true
299 );
300 wp_enqueue_script( 'wcf-onboarding-helper' );
301 wp_enqueue_media();
302 wp_enqueue_script( 'jquery-ui' );
303 }
304
305 /**
306 * Localize variables in admin.
307 */
308 public function localize_vars() {
309
310 $vars = array();
311
312 $plugins = array(
313 array(
314 'name' => 'WooCommerce',
315 'slug' => 'woocommerce',
316 'status' => $this->get_plugin_status( 'woocommerce/woocommerce.php' ),
317 ),
318 array(
319 'name' => 'Cart Abandonment',
320 'slug' => 'woo-cart-abandonment-recovery',
321 'status' => $this->get_plugin_status( 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' ),
322 ),
323 array(
324 'name' => 'Modern cart',
325 'slug' => 'modern-cart',
326 'status' => $this->get_plugin_status( 'modern-cart/modern-cart.php' ),
327 ),
328 array(
329 'name' => 'Power Coupons',
330 'slug' => 'power-coupons',
331 'status' => $this->get_plugin_status( 'power-coupons/power-coupons.php' ),
332 ),
333 array(
334 'name' => 'WooCommerce Payments',
335 'slug' => 'woocommerce-payments',
336 'status' => $this->get_plugin_status( 'woocommerce-payments/woocommerce-payments.php' ),
337 ),
338 array(
339 'name' => 'Spectra',
340 'slug' => 'ultimate-addons-for-gutenberg',
341 'status' => $this->get_plugin_status( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ),
342 ),
343 );
344
345 $installed_plugins = get_plugins();
346
347 $page_builders = array(
348 'elementor' => array(
349 'slug' => 'elementor',
350 'init' => 'elementor/elementor.php',
351 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
352 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
353 ),
354 'beaver-builder' => array(
355 'slug' => 'beaver-builder-lite-version',
356 'init' => 'beaver-builder-lite-version/fl-builder.php',
357 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
358 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
359 ),
360 'divi' => array(
361 'slug' => 'divi',
362 'init' => 'divi',
363 'active' => 'yes',
364 'install' => 'NA', // Removed the Support of DIVI theme that is why it is set as NA.
365 ),
366 'gutenberg' => array(
367 'slug' => 'ultimate-addons-for-gutenberg',
368 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
369 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
370 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
371 ),
372 'bricks-builder' => array(
373 'slug' => 'bricks',
374 'init' => 'bricks',
375 'active' => 'yes',
376 'install' => 'NA', // Bricks is an paid theme that is why, the install option is set to NA. As this will be enabled on the user's website before the CartFlows Install.
377 ),
378 // Intentionally installing the GB plugin when the other option is selected.
379 'other' => array(
380 'slug' => 'ultimate-addons-for-gutenberg',
381 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
382 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
383 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
384 ),
385 );
386
387 $current_user = wp_get_current_user();
388
389 $vars = array(
390 'current_user_name' => ! empty( $current_user->user_firstname ) ? $current_user->user_firstname : $current_user->display_name,
391 'current_user_email' => ! empty( $current_user->user_email ) ? $current_user->user_email : '',
392 'plugins' => $plugins,
393 'page_builders' => $page_builders,
394 'active_page_builder' => OnboardingHelper::get_active_supported_builder( $page_builders ),
395 'ajax_url' => admin_url( 'admin-ajax.php' ),
396 'admin_url' => admin_url( 'admin.php' ),
397 'admin_base_url' => admin_url(),
398 'admin_index_url' => admin_url( 'index.php' ),
399 'default_page_builder' => \Cartflows_Helper::get_common_settings()['default_page_builder'],
400 'site_logo' => $this->get_site_logo_url(),
401 'template_import_errors' => array(
402 'api_errors' => array(
403 'title' => __( 'Oops!! Unexpected error occoured', 'cartflows' ),
404 'msg' => __( 'Import template API call failed. Please reload the page and try again!', 'cartflows' ),
405 ),
406 ),
407 'is_pro' => _is_cartflows_pro(),
408 'cf_pro_type' => defined( 'CARTFLOWS_PRO_PLUGIN_TYPE' ) ? CARTFLOWS_PRO_PLUGIN_TYPE : 'free',
409 'woocommerce_status' => $this->get_plugin_status( 'woocommerce/woocommerce.php' ),
410 );
411
412 $vars = apply_filters( 'cartflows_onboarding_localized_vars', $vars );
413
414 wp_localize_script( 'wcf-onboarding-app', 'cartflows_onboarding', $vars );
415
416 // Satisfies the @Styles/common contract — UTM helpers read from cartflows_admin.
417 wp_localize_script(
418 'wcf-onboarding-app',
419 'cartflows_admin',
420 array(
421 'utm_defaults' => \Cartflows_Helper::get_utm_defaults(),
422 'cf_domain_url' => CARTFLOWS_DOMAIN_URL,
423 'cf_upgrade_to_pro_url' => \Cartflows_Helper::get_upgrade_to_pro_link(),
424 )
425 );
426 }
427
428 /**
429 * Get customizer/site logo URL.
430 *
431 * @since 1.10.0
432 *
433 * @return $image_url Site logo URL
434 */
435 public function get_site_logo_url() {
436
437 $logo = get_theme_mod( 'custom_logo' );
438 $site_logo = '';
439
440 if ( ! empty( $logo ) ) {
441
442 $image = wp_get_attachment_image_src( $logo, 'full' );
443
444 $site_logo = array(
445 'id' => $logo,
446 'url' => $image[0] ? $image[0] : '',
447 'width' => $image[1] ? $image[1] : '',
448 'height' => $image[2] ? $image[2] : '',
449 );
450 }
451
452 return $site_logo;
453 }
454
455 /**
456 * Get plugin status
457 *
458 * @since 1.1.4
459 *
460 * @param string $plugin_init_file Plguin init file.
461 * @return mixed
462 */
463 public function get_plugin_status( $plugin_init_file ) {
464
465 $installed_plugins = get_plugins();
466
467 if ( ! isset( $installed_plugins[ $plugin_init_file ] ) ) {
468 return 'not-installed';
469 } elseif ( is_plugin_active( $plugin_init_file ) ) {
470 return 'active';
471 } else {
472 return 'inactive';
473 }
474 }
475
476 /**
477 * Function to hide Convert Pro popups during the onboarding wizard process.
478 *
479 * This function checks if the current page is the CartFlows onboarding page and if so, it sets the load parameter to false, effectively hiding the Convert Pro popups.
480 *
481 * @param bool $load The initial load state of the Convert Pro popups.
482 * @return bool The modified load state of the Convert Pro popups.
483 */
484 public function hide_convert_pro_popups( $load ) {
485
486 if ( ! empty( $_GET['page'] ) && 'cartflows-onboarding' === $_GET['page'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
487 $load = false;
488 }
489
490 return $load;
491 }
492 }
493
494