PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.3.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.3.0
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
← All changes | classes/class-cartflows-loader.php +413 -62 1.0.4 → 3.3.0 View file →
@@ -4,8 +4,12 @@
4 4 *
5 5 * @package CartFlows
6 6 */
7 7
8 +// Exit if accessed directly.
9 +if ( ! defined( 'ABSPATH' ) ) {
10 + exit;
11 +}
8 12 if ( ! class_exists( 'Cartflows_Loader' ) ) {
9 13
10 14 /**
11 15 * Class Cartflows_Loader.
@@ -35,26 +39,25 @@
35 39
36 40 /**
37 41 * Member Variable
38 42 *
39 - * @var session
43 + * @var options
40 44 */
41 - public $session = null;
45 + public $options = null;
42 46
43 -
44 47 /**
45 48 * Member Variable
46 49 *
47 - * @var options
50 + * @var meta
48 51 */
49 - public $options = null;
52 + public $meta = null;
50 53
51 54 /**
52 55 * Member Variable
53 56 *
54 - * @var meta
57 + * @var Tracking_Data
55 58 */
56 - public $meta = null;
59 + public $alldata;
57 60
58 61 /**
59 62 * Member Variable
60 63 *
@@ -62,15 +65,37 @@
62 65 */
63 66 public $flow = null;
64 67
65 68 /**
69 + * Member Variable
70 + *
71 + * @var wcf_step_objs
72 + */
73 +
74 + public $wcf_step_objs = array();
75 +
76 + /**
77 + * Member Variable
78 + *
79 + * @var assets_vars
80 + */
81 + public $assets_vars = null;
82 +
83 + /**
84 + * Member Variable
85 + *
86 + * @var assets_vars
87 + */
88 +
89 + public $is_woo_active = true;
90 +
91 + /**
66 92 * Initiator
67 93 */
68 94 public static function get_instance() {
69 -
70 95 if ( is_null( self::$instance ) ) {
71 96
72 - self::$instance = new self;
97 + self::$instance = new self();
73 98
74 99 /**
75 100 * CartFlows loaded.
76 101 *
@@ -87,9 +112,8 @@
87 112 /**
88 113 * Constructor
89 114 */
90 115 public function __construct() {
91 -
92 116 $this->define_constants();
93 117
94 118 // Activation hook.
95 119 register_activation_hook( CARTFLOWS_FILE, array( $this, 'activation_reset' ) );
@@ -96,14 +120,17 @@
96 120
97 121 // deActivation hook.
98 122 register_deactivation_hook( CARTFLOWS_FILE, array( $this, 'deactivation_reset' ) );
99 123
124 + // Need to add library before the plugin loaded. https://actionscheduler.org/usage/.
125 + require_once CARTFLOWS_DIR . '/libraries/action-scheduler/action-scheduler.php';
126 +
100 127 add_action( 'plugins_loaded', array( $this, 'load_plugin' ), 99 );
128 + add_action( 'init', array( $this, 'load_cf_textdomain' ) );
101 129
102 - add_action( 'plugins_loaded', array( $this, 'load_cf_textdomain' ) );
103 -
104 - // Update compatibility.
105 - require_once CARTFLOWS_DIR . 'classes/class-cartflows-update.php';
130 + // Priority 5 mirrors Astra's init_bsf_analytics() pattern: set_entity() must
131 + // run before BSF_Analytics_Loader::load_analytics() fires at priority 10.
132 + add_action( 'init', array( $this, 'deactivation_survey_data_handler' ), 5 );
106 133 }
107 134
108 135 /**
109 136 * Defines all constants
@@ -114,20 +141,40 @@
114 141
115 142 define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
116 143 define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
117 144 define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
118 - define( 'CARTFLOWS_VER', '1.0.4' );
145 +
146 + define( 'CARTFLOWS_VER', '3.3.0' );
119 147 define( 'CARTFLOWS_SLUG', 'cartflows' );
120 148 define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
149 + define( 'CARTFLOWS_NAME', 'CartFlows' );
121 150
151 + define( 'CARTFLOWS_REQ_CF_PRO_VER', '3.2.0' );
152 +
153 + // Resolves to true for users upgrading from <3.0.0 (set by Cartflows_Update on first 3.0+ admin_init)
154 + // and stays true until the user opts out via the Advanced-tab toggle or the legacy in-app switch.
155 + // Fresh installs never see this option set, so they default to the new UI. The toggle saves
156 + // 'enable'/'disable' strings; older code paths may have stored a boolean true — accept both.
157 + $cartflows_legacy_admin_saved = get_option( 'cartflows-legacy-admin', false );
158 + define( 'CARTFLOWS_LEGACY_ADMIN', in_array( $cartflows_legacy_admin_saved, array( true, 1, '1', 'enable', 'yes' ), true ) );
159 +
160 + define( 'CARTFLOWS_ASSETS_VERSION', get_option( 'cartflows-assets-version', time() ) );
161 +
122 162 define( 'CARTFLOWS_FLOW_POST_TYPE', 'cartflows_flow' );
123 163 define( 'CARTFLOWS_STEP_POST_TYPE', 'cartflows_step' );
124 164
165 + define( 'CARTFLOWS_FLOW_PERMALINK_SLUG', 'flow' );
166 + define( 'CARTFLOWS_STEP_PERMALINK_SLUG', 'step' );
167 +
125 168 if ( ! defined( 'CARTFLOWS_SERVER_URL' ) ) {
126 169 define( 'CARTFLOWS_SERVER_URL', 'https://my.cartflows.com/' );
127 170 }
128 - define( 'CARTFLOWS_DOMAIN_URL', 'https://cartflows.com/' );
129 - define( 'CARTFLOWS_TEMPLATES_URL', 'https://templates.cartflows.com/' );
171 + if ( ! defined( 'CARTFLOWS_DOMAIN_URL' ) ) {
172 + define( 'CARTFLOWS_DOMAIN_URL', 'https://cartflows.com/' );
173 + }
174 + if ( ! defined( 'CARTFLOWS_TEMPLATES_URL' ) ) {
175 + define( 'CARTFLOWS_TEMPLATES_URL', 'https://templates.cartflows.com/' );
176 + }
130 177 define( 'CARTFLOWS_TAXONOMY_STEP_TYPE', 'cartflows_step_type' );
131 178 define( 'CARTFLOWS_TAXONOMY_STEP_FLOW', 'cartflows_step_flow' );
132 179
133 180 if ( ! defined( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER' ) ) {
@@ -132,14 +179,70 @@
132 179
133 180 if ( ! defined( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER' ) ) {
134 181 define( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER', 'cartflows_step_page_builder' );
135 182 }
183 + if ( ! defined( 'CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER' ) ) {
184 + define( 'CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER', 'cartflows_flow_page_builder' );
185 + }
136 186 if ( ! defined( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY' ) ) {
137 187 define( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY', 'cartflows_flow_category' );
138 188 }
189 +
190 + if ( ! defined( 'CARTFLOWS_LOG_DIR' ) ) {
191 +
192 + $upload_dir = wp_upload_dir( null, false );
193 +
194 + define( 'CARTFLOWS_LOG_DIR', $upload_dir['basedir'] . '/cartflows-logs/' );
195 + }
196 +
197 + $cookie_prefix = '';
198 +
199 + if ( defined( 'CARTFLOWS_COOKIE_PREFIX' ) ) {
200 + $cookie_prefix = CARTFLOWS_COOKIE_PREFIX;
201 + }
202 +
203 + define( 'CARTFLOWS_ACTIVE_CHECKOUT', $cookie_prefix . 'wcf_active_checkout' );
204 +
205 + define( 'CARTFLOWS_PINTEREST_CONSENT', $cookie_prefix . 'cartflows_pinterest_consent' );
206 +
207 + if ( ! defined( 'CARTFLOWS_HTTPS' ) ) {
208 + define( 'CARTFLOWS_HTTPS', is_ssl() ? true : false );
209 + }
210 +
211 + define( 'CARTFLOWS_NPS_WEBHOOK_URL', 'https://webhook.ottokit.com/ottokit/af2151cc-6fe3-40a4-a9d3-12859be4d602' );
212 +
213 + $GLOBALS['wcf_step'] = null;
139 214 }
140 215
141 216 /**
217 + * Get site slug
218 + *
219 + * @since 1.6.15
220 + * @return string
221 + */
222 + public function get_site_slug() {
223 + return Cartflows_Helper::get_common_setting( 'default_page_builder' );
224 + }
225 +
226 + /**
227 + * Get site URL
228 + *
229 + * @since 1.6.15
230 + * @param string $page_builder_slug Page builder slug.
231 + * @return string
232 + */
233 + public function get_site_url( $page_builder_slug = '' ) {
234 +
235 + $page_builder_slug = ( ! empty( $page_builder_slug ) ) ? $page_builder_slug : wcf()->get_site_slug();
236 +
237 + if ( ! empty( $page_builder_slug ) ) {
238 + return trailingslashit( CARTFLOWS_TEMPLATES_URL ) . $page_builder_slug . '/';
239 + }
240 +
241 + return CARTFLOWS_TEMPLATES_URL;
242 + }
243 +
244 + /**
142 245 * Loads plugin files.
143 246 *
144 247 * @since 1.0.0
145 248 *
@@ -144,19 +247,20 @@
144 247 * @since 1.0.0
145 248 *
146 249 * @return void
147 250 */
148 - function load_plugin() {
251 + public function load_plugin() {
252 + $this->load_helper_files_components();
253 + $this->load_core_files();
254 + $this->load_core_components();
149 255
150 - if ( ! function_exists( 'WC' ) ) {
256 + add_action( 'wp_loaded', array( $this, 'initialize' ) );
257 + add_action( 'cartflows_pro_init', array( $this, 'after_cartflows_pro_init' ) );
258 +
259 + if ( ! $this->is_woo_active ) {
151 260 add_action( 'admin_notices', array( $this, 'fails_to_load' ) );
152 - return;
153 261 }
154 262
155 - $this->load_helper_files_components();
156 - $this->load_core_files();
157 - $this->load_core_components();
158 -
159 263 /**
160 264 * CartFlows Init.
161 265 *
162 266 * Fires when Cartflows is instantiated.
@@ -166,8 +270,62 @@
166 270 do_action( 'cartflows_init' );
167 271 }
168 272
169 273 /**
274 + * After CartFlows Pro init.
275 + *
276 + * @since 1.1.19
277 + *
278 + * @return void
279 + */
280 + public function after_cartflows_pro_init() {
281 + if ( ! is_admin() ) {
282 + return;
283 + }
284 +
285 + if ( version_compare( CARTFLOWS_PRO_VER, CARTFLOWS_REQ_CF_PRO_VER, '<' ) ) {
286 + add_action( 'admin_notices', array( $this, 'required_cartflows_pro_notice' ) );
287 + }
288 +
289 + if ( version_compare( CARTFLOWS_PRO_VER, '1.11.14', '=' ) && 'starter' === CARTFLOWS_PRO_PLUGIN_TYPE ) {
290 + add_action( 'admin_notices', array( $this, 'show_upgrade_starter_plan_notice' ) );
291 + }
292 + }
293 +
294 + /**
295 + * Show CartFlows Pro: Starter plan update Notice.
296 + *
297 + * @since 1.11.14
298 + *
299 + * @return void
300 + */
301 + public function show_upgrade_starter_plan_notice() {
302 +
303 + $class = 'notice notice-warning wcf-notice';
304 + /* translators: %s: html tags */
305 + $message = sprintf( __( 'The new version of %1$s%3$s%2$s is released. Please download the latest zip to install the new updates. Click here to %4$sdownload%5$s.', 'cartflows' ), '<strong>', '</strong>', CARTFLOWS_PRO_DISPLAY_TITLE, '<a href="https://my.cartflows.com/" target="_blank">', '</a>' );
306 +
307 + printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), wp_kses_post( $message ) );
308 + }
309 +
310 + /**
311 + * Required CartFlows Pro Notice.
312 + *
313 + * @since 1.1.19
314 + *
315 + * @return void
316 + */
317 + public function required_cartflows_pro_notice() {
318 + $required_pro_version = CARTFLOWS_REQ_CF_PRO_VER;
319 +
320 + $class = 'notice notice-warning wcf-notice';
321 + /* translators: %s: html tags */
322 + $message = sprintf( __( 'You are using an older version of %1$s%3$s%2$s. Please update %1$s%3$s%2$s plugin to version %1$s%4$s%2$s or higher.', 'cartflows' ), '<strong>', '</strong>', CARTFLOWS_PRO_DISPLAY_TITLE, $required_pro_version );
323 +
324 + printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), wp_kses_post( $message ) );
325 + }
326 +
327 + /**
170 328 * Load Helper Files and Components.
171 329 *
172 330 * @since 1.0.0
173 331 *
@@ -172,32 +330,110 @@
172 330 * @since 1.0.0
173 331 *
174 332 * @return void
175 333 */
176 - function load_helper_files_components() {
334 + public function load_helper_files_components() {
335 + $this->is_woo_active = function_exists( 'WC' );
177 336
178 337 /* Public Utils */
179 338 include_once CARTFLOWS_DIR . 'classes/class-cartflows-utils.php';
180 339
181 - /* Public Session */
182 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-session.php';
183 -
184 - /* Public Global namespace functions */
340 + /* Public Global Name space Functions */
185 341 include_once CARTFLOWS_DIR . 'classes/class-cartflows-functions.php';
186 342
187 343 /* Admin Helper */
188 344 include_once CARTFLOWS_DIR . 'classes/class-cartflows-helper.php';
189 345
346 + /* Title and SKU scoped search behind the admin product pickers */
347 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-product-search.php';
348 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-coupon-search.php';
349 +
350 + /* Factory objects */
351 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-step-factory.php';
352 +
190 353 /* Meta Default Values */
191 354 include_once CARTFLOWS_DIR . 'classes/class-cartflows-default-meta.php';
192 355
356 + require_once CARTFLOWS_DIR . 'classes/class-cartflows-tracking.php';
357 + require_once CARTFLOWS_DIR . 'classes/class-cartflows-rollback.php';
358 +
359 + if ( is_admin() ) {
360 + require_once CARTFLOWS_DIR . 'libraries/astra-notices/class-bsf-admin-notices.php';
361 + }
362 +
363 + if ( ! class_exists( 'BSF_Analytics_Loader' ) ) {
364 + require_once CARTFLOWS_DIR . 'libraries/bsf-analytics/class-bsf-analytics-loader.php';
365 + }
366 +
193 367 $this->utils = Cartflows_Utils::get_instance();
194 - $this->session = Cartflows_Session::get_instance();
195 368 $this->options = Cartflows_Default_Meta::get_instance();
196 369
370 + // Plugin major update notice.
371 + if ( ! class_exists( 'Cartflows_Plugin_Update_Notifications' ) ) {
372 + require_once CARTFLOWS_DIR . 'libraries/cartflows-plugin-update-notifications/class-cartflows-plugin-update-notifications.php';
373 + }
374 +
375 + // Load the NPS Survey library.
376 + if ( ! class_exists( 'Cartflows_Nps_Survey' ) ) {
377 + require_once CARTFLOWS_DIR . 'libraries/class-cartflows-nps-survey.php';
378 + }
379 +
380 + // Load the CartFlows Pointer library.
381 + if ( ! class_exists( 'Cartflows_Pointer' ) ) {
382 + require_once CARTFLOWS_DIR . 'libraries/cartflows-pointer/class-cartflows-pointer.php';
383 + }
197 384 }
198 385
199 386 /**
387 + * Deactivation Survey Data Handler
388 + *
389 + * @since 2.1.17
390 + *
391 + * @return void
392 + */
393 + public function deactivation_survey_data_handler() {
394 + $bsf_analytics = BSF_Analytics_Loader::get_instance();
395 +
396 + $bsf_analytics->set_entity(
397 + array(
398 + 'cf' => array(
399 + 'hide_optin_checkbox' => true,
400 + 'product_name' => 'CartFlows',
401 + 'usage_doc_link' => 'https://my.cartflows.com/usage-tracking/',
402 + 'path' => CARTFLOWS_DIR . 'libraries/bsf-analytics',
403 + 'author' => 'CartFlows Inc',
404 + 'deactivation_survey' => apply_filters(
405 + 'cartflows_bsf_analytics_deactivation_survey_data',
406 + array(
407 + array(
408 + 'id' => 'deactivation-survey-cartflows',
409 + 'popup_logo' => CARTFLOWS_URL . 'admin-core/assets/images/cartflows-icon.svg',
410 + 'plugin_slug' => 'cartflows',
411 + 'plugin_version' => CARTFLOWS_VER,
412 + 'popup_title' => __( 'Quick Feedback', 'cartflows' ),
413 + 'support_url' => 'https://cartflows.com/contact/',
414 + 'popup_description' => __( 'If you have a moment, please share why you are deactivating CartFlows:', 'cartflows' ),
415 + 'show_on_screens' => array( 'plugins' ),
416 + ),
417 + )
418 + ),
419 + ),
420 + )
421 + );
422 + }
423 +
424 + /**
425 + * Init hooked function.
426 + *
427 + * @since 1.0.0
428 + *
429 + * @return void
430 + */
431 + public function initialize() {
432 + $this->assets_vars = $this->utils->get_assets_path();
433 + }
434 +
435 + /**
200 436 * Load Core Files.
201 437 *
202 438 * @since 1.0.0
203 439 *
@@ -202,24 +438,67 @@
202 438 * @since 1.0.0
203 439 *
204 440 * @return void
205 441 */
206 - function load_core_files() {
442 + public function load_core_files() {
443 + /* Update compatibility. */
444 + require_once CARTFLOWS_DIR . 'classes/class-cartflows-update.php';
207 445
208 446 /* Page builder compatibilty class */
209 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-compatibility.php';
447 + include_once CARTFLOWS_DIR . 'compatibilities/class-cartflows-compatibility.php';
210 448
449 + /* Theme support */
450 + if ( $this->is_woo_active ) {
451 + /* Woo hooks */
452 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-woo-hooks.php';
453 + }
454 +
455 + /* Importer */
456 + include_once CARTFLOWS_DIR . 'classes/importer/class-cartflows-importer-loader.php';
457 +
211 458 /* Admin Meta Fields*/
212 459 include_once CARTFLOWS_DIR . 'classes/fields/typography/class-cartflows-font-families.php';
213 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta-fields.php';
214 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta.php';
215 460
216 - /* Cloning */
217 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-cloning.php';
461 + // Learn progress — shared by the Learn REST route and the analytics payload.
462 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-learn-progress.php';
218 463
219 - /* Admin Settings */
220 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin.php';
464 + // Analytics — BSF Analytics Events integration. Loaded on every request so the
465 + // bsf_core_stats filter is registered for both frontend and admin transmissions.
466 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-analytics.php';
221 467
468 + if ( is_admin() ) {
469 +
470 + /* Admin helper */
471 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin.php';
472 +
473 + /* Dashboard widget — funnel performance summary on wp-admin/index.php. */
474 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-dashboard-widget.php';
475 + }
476 +
477 + /* Admin loader — fork between legacy (admin-legacy-core/) and current (admin-core/) UI. */
478 + if ( defined( 'CARTFLOWS_LEGACY_ADMIN' ) && CARTFLOWS_LEGACY_ADMIN ) {
479 + include_once CARTFLOWS_DIR . 'admin-legacy-loader.php';
480 + } else {
481 + include_once CARTFLOWS_DIR . 'admin-loader.php';
482 + }
483 +
484 + if ( class_exists( 'WP_CLI' ) ) {
485 + /* WP-CLI registration follows the active UI tree. */
486 + if ( defined( 'CARTFLOWS_LEGACY_ADMIN' ) && CARTFLOWS_LEGACY_ADMIN ) {
487 + require_once CARTFLOWS_DIR . 'admin-legacy-core/inc/wp-cli.php';
488 + } else {
489 + require_once CARTFLOWS_DIR . 'admin-core/inc/wp-cli.php';
490 + }
491 + }
492 +
493 + /* Logger */
494 + include_once CARTFLOWS_DIR . 'classes/logger/class-cartflows-log-handler-interface.php';
495 + include_once CARTFLOWS_DIR . 'classes/logger/class-cartflows-log-handler.php';
496 + include_once CARTFLOWS_DIR . 'classes/logger/class-cartflows-log-handler-file.php';
497 + include_once CARTFLOWS_DIR . 'classes/logger/class-cartflows-log-levels.php';
498 + include_once CARTFLOWS_DIR . 'classes/logger/class-cartflows-logger-interface.php';
499 + include_once CARTFLOWS_DIR . 'classes/logger/class-cartflows-wc-logger.php';
500 +
222 501 /* Core Modules */
223 502 include_once CARTFLOWS_DIR . 'classes/class-cartflows-logger.php';
224 503
225 504 /* Frontend Global */
@@ -228,16 +507,39 @@
228 507
229 508 /* Modules */
230 509 include_once CARTFLOWS_DIR . 'modules/flow/class-cartflows-flow.php';
231 510 include_once CARTFLOWS_DIR . 'modules/landing/class-cartflows-landing.php';
232 - include_once CARTFLOWS_DIR . 'modules/checkout/class-cartflows-checkout.php';
233 - include_once CARTFLOWS_DIR . 'modules/thankyou/class-cartflows-thankyou.php';
234 511
235 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-api.php';
236 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-importer-core.php';
512 + if ( $this->is_woo_active ) {
513 + include_once CARTFLOWS_DIR . 'modules/checkout/class-cartflows-checkout.php';
514 + include_once CARTFLOWS_DIR . 'modules/thankyou/class-cartflows-thankyou.php';
515 + include_once CARTFLOWS_DIR . 'modules/optin/class-cartflows-optin.php';
516 + include_once CARTFLOWS_DIR . 'modules/woo-dynamic-flow/class-cartflows-woo-dynamic-flow.php';
517 + include_once CARTFLOWS_DIR . 'modules/email-report/class-cartflows-admin-report-emails.php';
518 + include_once CARTFLOWS_DIR . 'modules/frequently-bought-together/class-cartflows-fbt.php';
519 + }
237 520
238 - include_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-batch-process.php';
239 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-importer.php';
521 + if ( class_exists( '\Elementor\Plugin' ) ) {
522 + // Load the widgets.
523 + include_once CARTFLOWS_DIR . 'modules/elementor/class-cartflows-el-widgets-loader.php';
524 + }
525 +
526 + if ( class_exists( 'FLBuilder' ) ) {
527 +
528 + include_once CARTFLOWS_DIR . 'modules/beaver-builder/class-cartflows-bb-modules-loader.php';
529 + }
530 +
531 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-notices.php';
532 +
533 + include_once CARTFLOWS_DIR . 'classes/deprecated/deprecated-hooks.php';
534 +
535 + include_once CARTFLOWS_DIR . 'modules/gutenberg/classes/class-cartflows-block-loader.php';
536 +
537 + // Abilities API (WordPress 6.9+).
538 + require_once CARTFLOWS_DIR . 'abilities/class-cartflows-abilities-loader.php';
539 + include_once CARTFLOWS_DIR . 'modules/webhook/class-cartflows-webhook-loader.php';
540 +
541 + include_once CARTFLOWS_DIR . 'modules/content-generation/class-cartflows-ai-init.php';
240 542 }
241 543
242 544 /**
243 545 * Load Core Components.
@@ -245,16 +547,45 @@
245 547 * @since 1.0.0
246 548 *
247 549 * @return void
248 550 */
249 - function load_core_components() {
250 -
251 - $this->meta = Cartflows_Meta_Fields::get_instance();
551 + public function load_core_components() {
252 552 $this->logger = Cartflows_Logger::get_instance();
253 553 $this->flow = Cartflows_Flow_Frontend::get_instance();
254 554 }
255 555
256 556 /**
557 + * Create files/directories.
558 + */
559 + public function create_files() {
560 + // Install files and folders for uploading files and prevent hotlinking.
561 + $upload_dir = wp_upload_dir();
562 +
563 + $files = array(
564 + array(
565 + 'base' => CARTFLOWS_LOG_DIR,
566 + 'file' => '.htaccess',
567 + 'content' => 'deny from all',
568 + ),
569 + array(
570 + 'base' => CARTFLOWS_LOG_DIR,
571 + 'file' => 'index.html',
572 + 'content' => '',
573 + ),
574 + );
575 +
576 + foreach ( $files as $file ) {
577 + if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
578 + $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen
579 + if ( $file_handle ) {
580 + fwrite( $file_handle, $file['content'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite, WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite
581 + fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
582 + }
583 + }
584 + }
585 + }
586 +
587 + /**
257 588 * Load CartFlows Pro Text Domain.
258 589 * This will load the translation textdomain depending on the file priorities.
259 590 * 1. Global Languages /wp-content/languages/cartflows/ folder
260 591 * 2. Local dorectory /wp-content/plugins/cartflows/languages/ folder
@@ -262,9 +593,8 @@
262 593 * @since 1.0.3
263 594 * @return void
264 595 */
265 596 public function load_cf_textdomain() {
266 -
267 597 // Default languages directory for CartFlows Pro.
268 598 $lang_dir = CARTFLOWS_DIR . 'languages/';
269 599
270 600 /**
@@ -316,18 +646,25 @@
316 646 *
317 647 * @return void
318 648 */
319 649 public function fails_to_load() {
650 + $screen = get_current_screen();
320 651
321 - $screen = get_current_screen();
652 + if ( ! wcf()->utils->is_step_post_type() ) {
653 + return;
654 + }
322 655
323 - if ( isset( $screen->parent_file ) && 'plugins.php' === $screen->parent_file && 'update' === $screen->id ) {
656 + if ( ! wcf()->utils->check_is_woo_required_page() ) {
324 657 return;
325 658 }
326 659
327 - $class = 'notice notice-error';
660 + $skip_notice = false;
661 +
662 + wp_localize_script( 'wcf-global-admin', 'cartflows_woo', array( 'show_update_post' => $skip_notice ) );
663 +
664 + $class = 'notice notice-warning';
328 665 /* translators: %s: html tags */
329 - $message = sprintf( __( 'The %1$sCartFlows%2$s plugin requires %1$sWooCommerce%2$s plugin installed & activated.', 'cartflows' ), '<strong>', '</strong>' );
666 + $message = sprintf( __( 'This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & activated.', 'cartflows' ), '<strong>', '</strong>' );
330 667
331 668 $plugin = 'woocommerce/woocommerce.php';
332 669
333 670 if ( _is_woo_installed() ) {
@@ -336,9 +673,8 @@
336 673 }
337 674
338 675 $action_url = wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $plugin . '&amp;plugin_status=all&amp;paged=1&amp;s', 'activate-plugin_' . $plugin );
339 676 $button_label = __( 'Activate WooCommerce', 'cartflows' );
340 -
341 677 } else {
342 678 if ( ! current_user_can( 'install_plugins' ) ) {
343 679 return;
344 680 }
@@ -348,38 +684,54 @@
348 684 }
349 685
350 686 $button = '<p><a href="' . $action_url . '" class="button-primary">' . $button_label . '</a></p><p></p>';
351 687
352 - printf( '<div class="%1$s"><p>%2$s</p>%3$s</div>', esc_attr( $class ), $message, $button );
688 + printf( '<div class="%1$s"><p>%2$s</p>%3$s</div>', esc_attr( $class ), wp_kses_post( $message ), wp_kses_post( $button ) );
353 689 }
354 690
355 691 /**
356 692 * Activation Reset
357 693 */
358 - function activation_reset() {
694 + public function activation_reset() {
695 + if ( ! defined( 'CARTFLOWS_LOG_DIR' ) ) {
359 696
697 + $upload_dir = wp_upload_dir( null, false );
698 +
699 + define( 'CARTFLOWS_LOG_DIR', $upload_dir['basedir'] . '/cartflows-logs/' );
700 + }
701 +
702 + $this->create_files();
703 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-helper.php';
704 + include_once CARTFLOWS_DIR . 'classes/class-cartflows-functions.php';
360 705 include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-flow-post-type.php';
361 706 include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-step-post-type.php';
362 707
363 708 Cartflows_Flow_Post_Type::get_instance()->flow_post_type();
364 709 Cartflows_Step_Post_Type::get_instance()->step_post_type();
365 - flush_rewrite_rules();
710 + // Required to flush rules while registering custom post type.
711 + flush_rewrite_rules(); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.flush_rewrite_rules_flush_rewrite_rules
712 +
713 + // Update the cartflows asset version when plugin activated.
714 + update_option( 'cartflows-assets-version', time() );
715 +
716 + update_option( 'wcf_start_onboarding', true );
717 +
718 + // Record install time for time-to-value analytics (only on fresh install).
719 + Cartflows_Helper::set_analytics_flag( 'usage_installed_time', time() );
366 720 }
367 721
368 722 /**
369 723 * Deactivation Reset
370 724 */
371 - function deactivation_reset() {
725 + public function deactivation_reset() {
372 726 }
373 727
374 728 /**
375 729 * Logger Class Instance
376 730 */
377 - function logger() {
731 + public function logger() {
378 732 return Cartflows_Logger::get_instance();
379 733 }
380 -
381 -
382 734 }
383 735
384 736 /**
385 737 * Prepare if class 'Cartflows_Loader' exist.
@@ -392,9 +744,9 @@
392 744 * Get global class.
393 745 *
394 746 * @return object
395 747 */
396 -function wcf() {
748 +function wcf() { //phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed
397 749 return Cartflows_Loader::get_instance();
398 750 }
399 751
400 752 if ( ! function_exists( '_is_woo_installed' ) ) {
@@ -406,9 +758,8 @@
406 758 *
407 759 * @access public
408 760 */
409 761 function _is_woo_installed() {
410 -
411 762 $path = 'woocommerce/woocommerce.php';
412 763 $plugins = get_plugins();
413 764
414 765 return isset( $plugins[ $path ] );