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 +392 -62 1.1.15 → 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,8 +65,16 @@
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 + /**
66 77 * Member Variable
67 78 *
68 79 * @var assets_vars
69 80 */
@@ -69,15 +80,22 @@
69 80 */
70 81 public $assets_vars = null;
71 82
72 83 /**
84 + * Member Variable
85 + *
86 + * @var assets_vars
87 + */
88 +
89 + public $is_woo_active = true;
90 +
91 + /**
73 92 * Initiator
74 93 */
75 94 public static function get_instance() {
76 -
77 95 if ( is_null( self::$instance ) ) {
78 96
79 - self::$instance = new self;
97 + self::$instance = new self();
80 98
81 99 /**
82 100 * CartFlows loaded.
83 101 *
@@ -94,9 +112,8 @@
94 112 /**
95 113 * Constructor
96 114 */
97 115 public function __construct() {
98 -
99 116 $this->define_constants();
100 117
101 118 // Activation hook.
102 119 register_activation_hook( CARTFLOWS_FILE, array( $this, 'activation_reset' ) );
@@ -103,13 +120,17 @@
103 120
104 121 // deActivation hook.
105 122 register_deactivation_hook( CARTFLOWS_FILE, array( $this, 'deactivation_reset' ) );
106 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 +
107 127 add_action( 'plugins_loaded', array( $this, 'load_plugin' ), 99 );
108 - add_action( 'plugins_loaded', array( $this, 'load_cf_textdomain' ) );
128 + add_action( 'init', array( $this, 'load_cf_textdomain' ) );
109 129
110 - // Update compatibility.
111 - 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 );
112 133 }
113 134
114 135 /**
115 136 * Defines all constants
@@ -120,20 +141,40 @@
120 141
121 142 define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
122 143 define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
123 144 define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
124 - define( 'CARTFLOWS_VER', '1.1.15' );
145 +
146 + define( 'CARTFLOWS_VER', '3.3.0' );
125 147 define( 'CARTFLOWS_SLUG', 'cartflows' );
126 148 define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
149 + define( 'CARTFLOWS_NAME', 'CartFlows' );
127 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 +
128 162 define( 'CARTFLOWS_FLOW_POST_TYPE', 'cartflows_flow' );
129 163 define( 'CARTFLOWS_STEP_POST_TYPE', 'cartflows_step' );
130 164
165 + define( 'CARTFLOWS_FLOW_PERMALINK_SLUG', 'flow' );
166 + define( 'CARTFLOWS_STEP_PERMALINK_SLUG', 'step' );
167 +
131 168 if ( ! defined( 'CARTFLOWS_SERVER_URL' ) ) {
132 169 define( 'CARTFLOWS_SERVER_URL', 'https://my.cartflows.com/' );
133 170 }
134 - define( 'CARTFLOWS_DOMAIN_URL', 'https://cartflows.com/' );
135 - 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 + }
136 177 define( 'CARTFLOWS_TAXONOMY_STEP_TYPE', 'cartflows_step_type' );
137 178 define( 'CARTFLOWS_TAXONOMY_STEP_FLOW', 'cartflows_step_flow' );
138 179
139 180 if ( ! defined( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER' ) ) {
@@ -144,11 +185,64 @@
144 185 }
145 186 if ( ! defined( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY' ) ) {
146 187 define( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY', 'cartflows_flow_category' );
147 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;
148 214 }
149 215
150 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 + /**
151 245 * Loads plugin files.
152 246 *
153 247 * @since 1.0.0
154 248 *
@@ -153,21 +247,20 @@
153 247 * @since 1.0.0
154 248 *
155 249 * @return void
156 250 */
157 - function load_plugin() {
158 -
159 - if ( ! function_exists( 'WC' ) ) {
160 - add_action( 'admin_notices', array( $this, 'fails_to_load' ) );
161 - return;
162 - }
163 -
251 + public function load_plugin() {
164 252 $this->load_helper_files_components();
165 253 $this->load_core_files();
166 254 $this->load_core_components();
167 255
168 256 add_action( 'wp_loaded', array( $this, 'initialize' ) );
257 + add_action( 'cartflows_pro_init', array( $this, 'after_cartflows_pro_init' ) );
169 258
259 + if ( ! $this->is_woo_active ) {
260 + add_action( 'admin_notices', array( $this, 'fails_to_load' ) );
261 + }
262 +
170 263 /**
171 264 * CartFlows Init.
172 265 *
173 266 * Fires when Cartflows is instantiated.
@@ -177,8 +270,62 @@
177 270 do_action( 'cartflows_init' );
178 271 }
179 272
180 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 + /**
181 328 * Load Helper Files and Components.
182 329 *
183 330 * @since 1.0.0
184 331 *
@@ -183,31 +330,99 @@
183 330 * @since 1.0.0
184 331 *
185 332 * @return void
186 333 */
187 - function load_helper_files_components() {
334 + public function load_helper_files_components() {
335 + $this->is_woo_active = function_exists( 'WC' );
188 336
189 337 /* Public Utils */
190 338 include_once CARTFLOWS_DIR . 'classes/class-cartflows-utils.php';
191 339
192 - /* Public Session */
193 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-session.php';
194 -
195 - /* Public Global namespace functions */
340 + /* Public Global Name space Functions */
196 341 include_once CARTFLOWS_DIR . 'classes/class-cartflows-functions.php';
197 342
198 343 /* Admin Helper */
199 344 include_once CARTFLOWS_DIR . 'classes/class-cartflows-helper.php';
200 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 +
201 353 /* Meta Default Values */
202 354 include_once CARTFLOWS_DIR . 'classes/class-cartflows-default-meta.php';
203 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 +
204 367 $this->utils = Cartflows_Utils::get_instance();
205 - $this->session = Cartflows_Session::get_instance();
206 368 $this->options = Cartflows_Default_Meta::get_instance();
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 + }
207 384 }
208 385
209 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 + /**
210 425 * Init hooked function.
211 426 *
212 427 * @since 1.0.0
213 428 *
@@ -212,9 +427,9 @@
212 427 * @since 1.0.0
213 428 *
214 429 * @return void
215 430 */
216 - function initialize() {
431 + public function initialize() {
217 432 $this->assets_vars = $this->utils->get_assets_path();
218 433 }
219 434
220 435 /**
@@ -223,24 +438,67 @@
223 438 * @since 1.0.0
224 439 *
225 440 * @return void
226 441 */
227 - function load_core_files() {
442 + public function load_core_files() {
443 + /* Update compatibility. */
444 + require_once CARTFLOWS_DIR . 'classes/class-cartflows-update.php';
228 445
229 446 /* Page builder compatibilty class */
230 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-compatibility.php';
447 + include_once CARTFLOWS_DIR . 'compatibilities/class-cartflows-compatibility.php';
231 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 +
232 458 /* Admin Meta Fields*/
233 459 include_once CARTFLOWS_DIR . 'classes/fields/typography/class-cartflows-font-families.php';
234 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta-fields.php';
235 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta.php';
236 460
237 - /* Cloning */
238 - 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';
239 463
240 - /* Admin Settings */
241 - 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';
242 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 +
243 501 /* Core Modules */
244 502 include_once CARTFLOWS_DIR . 'classes/class-cartflows-logger.php';
245 503
246 504 /* Frontend Global */
@@ -249,16 +507,39 @@
249 507
250 508 /* Modules */
251 509 include_once CARTFLOWS_DIR . 'modules/flow/class-cartflows-flow.php';
252 510 include_once CARTFLOWS_DIR . 'modules/landing/class-cartflows-landing.php';
253 - include_once CARTFLOWS_DIR . 'modules/checkout/class-cartflows-checkout.php';
254 - include_once CARTFLOWS_DIR . 'modules/thankyou/class-cartflows-thankyou.php';
255 511
256 - include_once CARTFLOWS_DIR . 'classes/class-cartflows-api.php';
257 - 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 + }
258 520
259 - include_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-batch-process.php';
260 - 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';
261 542 }
262 543
263 544 /**
264 545 * Load Core Components.
@@ -266,16 +547,45 @@
266 547 * @since 1.0.0
267 548 *
268 549 * @return void
269 550 */
270 - function load_core_components() {
271 -
272 - $this->meta = Cartflows_Meta_Fields::get_instance();
551 + public function load_core_components() {
273 552 $this->logger = Cartflows_Logger::get_instance();
274 553 $this->flow = Cartflows_Flow_Frontend::get_instance();
275 554 }
276 555
277 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 + /**
278 588 * Load CartFlows Pro Text Domain.
279 589 * This will load the translation textdomain depending on the file priorities.
280 590 * 1. Global Languages /wp-content/languages/cartflows/ folder
281 591 * 2. Local dorectory /wp-content/plugins/cartflows/languages/ folder
@@ -283,9 +593,8 @@
283 593 * @since 1.0.3
284 594 * @return void
285 595 */
286 596 public function load_cf_textdomain() {
287 -
288 597 // Default languages directory for CartFlows Pro.
289 598 $lang_dir = CARTFLOWS_DIR . 'languages/';
290 599
291 600 /**
@@ -337,18 +646,25 @@
337 646 *
338 647 * @return void
339 648 */
340 649 public function fails_to_load() {
650 + $screen = get_current_screen();
341 651
342 - $screen = get_current_screen();
652 + if ( ! wcf()->utils->is_step_post_type() ) {
653 + return;
654 + }
343 655
344 - if ( isset( $screen->parent_file ) && 'plugins.php' === $screen->parent_file && 'update' === $screen->id ) {
656 + if ( ! wcf()->utils->check_is_woo_required_page() ) {
345 657 return;
346 658 }
347 659
348 - $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';
349 665 /* translators: %s: html tags */
350 - $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>' );
351 667
352 668 $plugin = 'woocommerce/woocommerce.php';
353 669
354 670 if ( _is_woo_installed() ) {
@@ -357,9 +673,8 @@
357 673 }
358 674
359 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 );
360 676 $button_label = __( 'Activate WooCommerce', 'cartflows' );
361 -
362 677 } else {
363 678 if ( ! current_user_can( 'install_plugins' ) ) {
364 679 return;
365 680 }
@@ -369,38 +684,54 @@
369 684 }
370 685
371 686 $button = '<p><a href="' . $action_url . '" class="button-primary">' . $button_label . '</a></p><p></p>';
372 687
373 - 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 ) );
374 689 }
375 690
376 691 /**
377 692 * Activation Reset
378 693 */
379 - function activation_reset() {
694 + public function activation_reset() {
695 + if ( ! defined( 'CARTFLOWS_LOG_DIR' ) ) {
380 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';
381 705 include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-flow-post-type.php';
382 706 include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-step-post-type.php';
383 707
384 708 Cartflows_Flow_Post_Type::get_instance()->flow_post_type();
385 709 Cartflows_Step_Post_Type::get_instance()->step_post_type();
386 - 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() );
387 720 }
388 721
389 722 /**
390 723 * Deactivation Reset
391 724 */
392 - function deactivation_reset() {
725 + public function deactivation_reset() {
393 726 }
394 727
395 728 /**
396 729 * Logger Class Instance
397 730 */
398 - function logger() {
731 + public function logger() {
399 732 return Cartflows_Logger::get_instance();
400 733 }
401 -
402 -
403 734 }
404 735
405 736 /**
406 737 * Prepare if class 'Cartflows_Loader' exist.
@@ -413,9 +744,9 @@
413 744 * Get global class.
414 745 *
415 746 * @return object
416 747 */
417 -function wcf() {
748 +function wcf() { //phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed
418 749 return Cartflows_Loader::get_instance();
419 750 }
420 751
421 752 if ( ! function_exists( '_is_woo_installed' ) ) {
@@ -427,9 +758,8 @@
427 758 *
428 759 * @access public
429 760 */
430 761 function _is_woo_installed() {
431 -
432 762 $path = 'woocommerce/woocommerce.php';
433 763 $plugins = get_plugins();
434 764
435 765 return isset( $plugins[ $path ] );