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 / ajax / onboarding.php

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

825 lines 24.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * CartFlows Onboarding ajax actions.
4 *
5 * @package CartFlows
6 */
7
8 namespace CartflowsAdmin\AdminCore\Ajax;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 use CartflowsAdmin\AdminCore\Ajax\AjaxBase;
16 use CartflowsAdmin\AdminCore\Ajax\Importer;
17 use CartflowsAdmin\AdminCore\Inc\AdminHelper;
18 use CartflowsAdmin\AdminCore\Inc\OnboardingCore;
19
20 /**
21 * Class Onboarding.
22 */
23 class Onboarding extends AjaxBase {
24
25 /**
26 * Instance
27 *
28 * @access private
29 * @var object Class object.
30 * @since 1.0.0
31 */
32 private static $instance;
33
34 /**
35 * Initiator
36 *
37 * @since 1.0.0
38 * @return object initialized object of class.
39 */
40 public static function get_instance() {
41 if ( ! isset( self::$instance ) ) {
42 self::$instance = new self();
43 }
44 return self::$instance;
45 }
46
47 /**
48 * Register ajax events.
49 *
50 * @since 1.0.0
51 * @return void
52 */
53 public function register_ajax_events() {
54
55 $ajax_events = array(
56 'page_builder_save_option',
57 'user_onboarding',
58 'wizard_activate_plugin',
59 'get_global_flow_list',
60 'get_single_store_checkout_flow',
61 'import_store_checkout',
62 'onboarding_completed',
63 'onboarding_exit',
64 );
65
66 $this->init_ajax_events( $ajax_events );
67 }
68
69 /**
70 * Localize nonce for ajax call — routes nonces to the onboarding JS var.
71 *
72 * @param string $action Action name.
73 * @return void
74 */
75 public function localize_ajax_action_nonce( $action ) {
76
77 if ( current_user_can( 'manage_options' ) ) {
78
79 add_filter(
80 'cartflows_onboarding_localized_vars',
81 function( $localize ) use ( $action ) {
82
83 $localize[ $action . '_nonce' ] = wp_create_nonce( 'cartflows_' . $action );
84 return $localize;
85 }
86 );
87
88 }
89 }
90
91 /**
92 * Update option — exit onboarding.
93 *
94 * @since 1.0.0
95 * @return void
96 */
97 public function onboarding_exit() {
98
99 /**
100 * Nonce verification
101 */
102 if ( ! check_ajax_referer( 'cartflows_onboarding_exit', 'security', false ) ) {
103 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
104 }
105
106 if ( ! current_user_can( 'manage_options' ) ) {
107 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
108 }
109
110 $step = isset( $_POST['current_step'] ) ? sanitize_text_field( wp_unslash( $_POST['current_step'] ) ) : '';
111
112 update_option( 'wcf_setup_skipped', true );
113 update_option( 'wcf_exit_setup_step', $step );
114
115 wp_send_json_success();
116 }
117
118 /**
119 * Update option — onboarding completed.
120 *
121 * @since 1.0.0
122 * @return void
123 */
124 public function onboarding_completed() {
125
126 /**
127 * Nonce verification
128 */
129 if ( ! check_ajax_referer( 'cartflows_onboarding_completed', 'security', false ) ) {
130 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
131 }
132
133 if ( ! current_user_can( 'manage_options' ) ) {
134 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
135 }
136
137 update_option( 'wcf_setup_complete', true );
138 delete_option( 'wcf_exit_setup_step' );
139 delete_option( 'wcf_setup_skipped' );
140
141 wp_send_json_success();
142 }
143
144 /**
145 * Save page builder.
146 *
147 * @since 1.0.0
148 * @return void
149 */
150 public function page_builder_save_option() {
151
152 /**
153 * Nonce verification
154 */
155 if ( ! check_ajax_referer( 'cartflows_page_builder_save_option', 'security', false ) ) {
156 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
157 }
158
159 if ( ! current_user_can( 'manage_options' ) ) {
160 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
161 }
162
163 $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : '';
164
165 $wcf_settings = get_option( '_cartflows_common', array() );
166
167 if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
168 $page_builder = 'beaver-builder';
169 }
170
171 if ( false !== strpos( $page_builder, 'gutenberg' ) ) {
172 $page_builder = 'gutenberg';
173 }
174
175 if ( false !== strpos( $page_builder, 'bricks' ) ) {
176 $page_builder = 'bricks-builder';
177 }
178
179 $wcf_settings['default_page_builder'] = $page_builder;
180
181 update_option( '_cartflows_common', $wcf_settings );
182
183 wp_send_json_success(
184 array( 'plugin' => $page_builder )
185 );
186 }
187
188 /**
189 * Optin step.
190 *
191 * @since 1.0.0
192 * @return void
193 */
194 public function user_onboarding() {
195
196 /**
197 * Nonce verification
198 */
199 if ( ! check_ajax_referer( 'cartflows_user_onboarding', 'security', false ) ) {
200 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
201 }
202
203 if ( ! current_user_can( 'manage_options' ) ) {
204 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
205 }
206
207 $target_url = CARTFLOWS_TEMPLATES_URL . 'wp-json/cartflows-server/v1/add-subscriber';
208 $response_body = array();
209
210 $email = isset( $_POST['user_email'] ) ? sanitize_email( wp_unslash( $_POST['user_email'] ) ) : '';
211 $user_name = isset( $_POST['user_fname'] ) ? sanitize_text_field( wp_unslash( $_POST['user_fname'] ) ) : '';
212 $usage_tracking = isset( $_POST['usage_tracking'] ) ? sanitize_text_field( wp_unslash( $_POST['usage_tracking'] ) ) : 'no';
213
214 if ( empty( $email ) ) {
215 wp_send_json_error(
216 array(
217 'success' => false,
218 'message' => __( 'Please enter your email ID.', 'cartflows' ),
219 )
220 );
221 }
222
223 // Enable the usage tracking for BSF Analytics.
224 AdminHelper::update_admin_settings_option( 'cf_usage_optin', $usage_tracking, true );
225
226 $api_args = array(
227 'timeout' => 30, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
228 'body' => array(
229 'user_email' => $email,
230 'user_fname' => $user_name,
231 'source' => 'cartflows',
232 'add-subscriber' => true,
233 ),
234
235 );
236
237 $response = wp_remote_post( $target_url, $api_args );
238
239 $has_errors = $this->is_api_error( $response );
240
241 if ( $has_errors['error'] ) {
242 wp_send_json_error(
243 array(
244 'success' => false,
245 'message' => $has_errors['error_message'],
246 )
247 );
248 }
249
250 $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
251
252 if ( ! is_array( $response_body ) || ! isset( $response_body['success'] ) ) {
253 wp_send_json_error( array( 'message' => __( 'Unexpected response from the subscription server.', 'cartflows' ) ) );
254 return;
255 }
256
257 // Store in option to send the weekly emails.
258 update_site_option( 'cartflows_stats_report_email_ids', $email );
259
260 wp_send_json_success(
261 array(
262 'success' => $response_body['success'],
263 'message' => isset( $response_body['message'] ) && $response_body['message'] ? $response_body['message'] : '',
264 )
265 );
266 }
267
268 /**
269 * Check is error in the received response.
270 *
271 * @param object $response Received API Response.
272 * @return array $result Error result.
273 */
274 public function is_api_error( $response ) {
275
276 $result = array(
277 'error' => false,
278 'error_message' => __( 'Oops! Something went wrong. Please refresh the page and try again.', 'cartflows' ),
279 'error_code' => 0,
280 );
281
282 if ( is_wp_error( $response ) ) {
283 $result['error'] = true;
284 $result['error_message'] = $response->get_error_message();
285 $result['error_code'] = $response->get_error_code();
286 } elseif ( ! empty( wp_remote_retrieve_response_code( $response ) ) && ! in_array( wp_remote_retrieve_response_code( $response ), array( 200, 201, 204 ), true ) ) {
287 $result['error'] = true;
288 $result['error_message'] = wp_remote_retrieve_response_message( $response );
289 $result['error_code'] = wp_remote_retrieve_response_code( $response );
290 }
291
292 return $result;
293 }
294
295 /**
296 * Activate plugin.
297 *
298 * @since 1.0.0
299 * @return void
300 */
301 public function wizard_activate_plugin() {
302
303 /**
304 * Nonce verification
305 */
306 if ( ! check_ajax_referer( 'cartflows_wizard_activate_plugin', 'security', false ) ) {
307 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
308 }
309
310 if ( ! current_user_can( 'manage_options' ) ) {
311 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
312 }
313
314 $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
315 $plugin_slug = isset( $_POST['plugin_slug'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_slug'] ) ) : '';
316
317 $do_silently = true;
318
319 $exclude_do_silently = array(
320 'woo-cart-abandonment-recovery',
321 );
322
323 if ( in_array( $plugin_slug, $exclude_do_silently, true ) ) {
324 $do_silently = false;
325 }
326
327 if ( false !== strpos( $plugin_slug, 'beaver-builder' ) ) {
328 $plugin_init = $plugin_slug . '/fl-builder.php';
329 }
330
331 $installed_plugins = get_plugins();
332 if ( ! array_key_exists( $plugin_init, $installed_plugins ) ) {
333 wp_send_json_error( array( 'message' => __( 'Invalid plugin path.', 'cartflows' ) ) );
334 return;
335 }
336
337 $activate = activate_plugin( $plugin_init, '', false, $do_silently );
338
339 if ( is_wp_error( $activate ) ) {
340 wp_send_json_error(
341 array(
342 'success' => false,
343 'message' => $activate->get_error_message(),
344 )
345 );
346 }
347
348 wp_send_json_success(
349 array(
350 'success' => true,
351 'message' => $plugin_slug,
352 )
353 );
354 }
355
356 /**
357 * Fetch all the available flows for global checkout.
358 *
359 * @since 1.10.0
360 */
361 public function get_global_flow_list() {
362
363 /**
364 * Nonce verification
365 */
366 if ( ! check_ajax_referer( 'cartflows_get_global_flow_list', 'security', false ) ) {
367 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
368 }
369
370 if ( ! current_user_can( 'manage_options' ) ) {
371 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
372 }
373
374 $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : '';
375
376 $page = 1;
377 $flows_list = array();
378
379 if ( empty( $page_builder ) ) {
380 $response_data = array( 'message' => __( 'Please select any of the page builder to display the ready templates.', 'cartflows' ) );
381 wp_send_json_error( $response_data );
382 }
383
384 // Check is the template library updated or not.
385 if ( 'no' === \CartFlows_Batch_Process::get_instance()->get_last_export_checksums( 'store-checkout' ) ) {
386 // Get the cached flows as no changes are made in the template library.
387 $cached_flows = get_site_option( 'cartflows-store-checkout-' . $page_builder . '-flows-and-steps-' . $page );
388
389 $flows_list = ! empty( $cached_flows ) ? $cached_flows : array();
390 }
391
392 // If the cached flow list is empty then make a new request and fetch the templates.
393 if ( empty( $flows_list ) ) {
394 // Fetch new list of templates.
395 $flows_list = $this->import_templates( $page_builder, $page );
396
397 // Update the cheksum after importing the latest templates.
398 \CartFlows_Batch_Process::get_instance()->update_latest_checksums( 'store-checkout' );
399 }
400
401 /**
402 * Redirect to the new step edit screen
403 */
404 $response_data = array(
405 'message' => __( 'Successful!', 'cartflows' ),
406 'flows' => $flows_list,
407 );
408
409 wp_send_json_success( $response_data );
410 }
411
412 /**
413 * Import
414 *
415 * @since 1.0.14
416 * @since 1.6.15 Added page no.
417 * @param string $page_builder page builder slug.
418 * @param integer $page Page number.
419 * @return array
420 */
421 public function import_templates( $page_builder, $page = 1 ) {
422
423 $api_args = array(
424 'timeout' => 30, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
425 );
426
427 $sites_and_pages = array();
428 $site_url = wcf()->get_site_url();
429
430 $query_args = array(
431 'per_page' => 100,
432 'page' => $page,
433 'flow_category' => array(
434 'include_terms' => array( 'store-checkout' ),
435 ),
436 );
437
438 $api_url = add_query_arg( $query_args, $site_url . 'wp-json/cartflows-server/v1/flows-and-steps/' );
439
440 $response = wp_remote_get( $api_url, $api_args );
441
442 if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
443
444 $sites_and_pages = json_decode( wp_remote_retrieve_body( $response ), true );
445
446 if ( isset( $sites_and_pages['code'] ) ) {
447 $message = isset( $sites_and_pages['message'] ) ? $sites_and_pages['message'] : '';
448 if ( ! empty( $message ) ) {
449 wcf()->logger->sync_log( 'HTTP Request Error: ' . $message );
450 } else {
451 wcf()->logger->sync_log( 'HTTP Request Error!' );
452 }
453 } elseif ( is_array( $sites_and_pages ) && isset( $sites_and_pages['flows'] ) && ! empty( $sites_and_pages['flows'] ) ) {
454 $option_name = 'cartflows-store-checkout-' . sanitize_key( $page_builder ) . '-flows-and-steps-' . $page;
455 update_site_option( $option_name, $sites_and_pages['flows'] );
456 } else {
457 $sites_and_pages['flows'] = array();
458 }
459 } elseif ( is_wp_error( $response ) ) {
460 wcf()->logger->sync_log( 'API Error: ' . $response->get_error_message() );
461 } else {
462 wcf()->logger->sync_log( 'API Error: HTTP ' . wp_remote_retrieve_response_code( $response ) );
463 }
464
465 return isset( $sites_and_pages['flows'] ) ? $sites_and_pages['flows'] : array();
466 }
467
468 /**
469 * Get store flow.
470 */
471 public function get_single_store_checkout_flow() {
472
473 /**
474 * Nonce verification
475 */
476 if ( ! check_ajax_referer( 'cartflows_get_single_store_checkout_flow', 'security', false ) ) {
477 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
478 }
479
480 if ( ! current_user_can( 'manage_options' ) ) {
481 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
482 }
483
484 $flow_id = isset( $_POST['flow_id'] ) ? absint( $_POST['flow_id'] ) : 0;
485
486 // Get single step Rest API response.
487 $response = \CartFlows_API::get_instance()->get_flow( $flow_id );
488
489 wp_send_json_success( $response['data'] );
490 }
491
492 /**
493 * Import the flow template for the store checkout.
494 * Once the import is done, then set it's checkout page as a Global Checkout.
495 *
496 * @since 1.10.0
497 * @return void
498 */
499 public function import_store_checkout() {
500
501 /**
502 * Nonce verification
503 */
504 if ( ! check_ajax_referer( 'cartflows_import_store_checkout', 'security', false ) ) {
505 wp_send_json_error( array( 'message' => $this->get_error_msg( 'nonce' ) ) );
506 }
507
508 if ( ! current_user_can( 'manage_options' ) ) {
509 wp_send_json_error( array( 'message' => $this->get_error_msg( 'permission' ) ) );
510 }
511
512 // $_POST['flow'] is the JSON, There is nothing to sanitize JSON as it is data format not data type.
513 $flow = isset( $_POST['flow'] ) ? json_decode( stripslashes( $_POST['flow'] ), true ) : array(); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
514
515 if ( empty( $flow ) ) {
516 $response_data = array( 'message' => __( 'No flow ID found. Please select atleast one flow to import.', 'cartflows' ) );
517 wp_send_json_error( $response_data );
518 }
519
520 // Import the Instant Checkout as a Store Checkour oR just a normal Store Checkout.
521 if ( ! empty( $flow['is_instant_checkout'] ) && (bool) $flow['is_instant_checkout'] ) {
522 $response_data = $this->create_instant_checkout_funnel( $flow );
523 } else {
524 // Get single step Rest API response.
525 $response = \CartFlows_API::get_instance()->get_flow( absint( $flow['ID'] ) );
526
527 if ( is_wp_error( $response['data'] ) ) {
528
529 /* translators: %1$s: html tag, %2$s: link html start %3$s: link html end */
530 $btn = sprintf( __( 'Request timeout error. Please check if the firewall or any security plugin is blocking the outgoing HTTP/HTTPS requests to templates.cartflows.com or not. %1$sTo resolve this issue, please check this %2$sarticle%3$s.', 'cartflows' ), '<br><br>', '<a target="_blank" href="' . esc_url( \Cartflows_Helper::get_kb_doc_link( 'https://cartflows.com/docs/request-timeout-error-while-importing-the-flow-step-templates/' ) ) . '">', '</a>' );
531
532 wp_send_json_error(
533 array(
534 'message' => $response['data']->get_error_message(),
535 'call_to_action' => $btn,
536 'data' => $response,
537 )
538 );
539 }
540
541 // Do license validation if showing Pro flows.
542 $license_status = isset( $response['data']['licence_status'] ) ? $response['data']['licence_status'] : '';
543
544 // If license is invalid then.
545 if ( 'valid' !== $license_status ) {
546
547 $cf_pro_status = OnboardingCore::get_instance()->get_plugin_status( 'cartflows-pro/cartflows-pro.php' );
548
549 $title = '';
550 $msg = '';
551 if ( 'not-installed' === $cf_pro_status ) {
552 /* translators: %1$s: link html start, %2$s: link html end*/
553 $msg = sprintf( __( 'To import this template, CartFlows Pro Required! %1$sUpgrade to CartFlows Pro%2$s', 'cartflows' ), '<a target="_blank" href="' . esc_url( \Cartflows_Helper::get_upgrade_to_pro_link( '', 'https://cartflows.com/' ) ) . '">', '</a>' );
554 $title = __( 'CartFlows Pro Required', 'cartflows' );
555 } elseif ( 'inactive' === $cf_pro_status ) {
556 $title = __( 'CartFlows Pro Required', 'cartflows' );
557 /* translators: %1$s: link html start, %2$s: link html end*/
558 $msg = sprintf( __( 'Activate the CartFlows Pro to import the flow! %1$sActivate CartFlows Pro%2$s', 'cartflows' ), '<a target="_blank" href="' . admin_url( 'plugins.php?plugin_status=search&paged=1&s=CartFlows+Pro' ) . '">', '</a>' );
559 } elseif ( 'active' === $cf_pro_status ) {
560 $title = __( 'Invalid License Key', 'cartflows' );
561 /* translators: %1$s: link html start, %2$s: link html end*/
562 $msg = sprintf( __( 'No valid license key found! %1$sActivate license%2$s', 'cartflows' ), '<a target="_blank" href="' . admin_url( 'plugins.php?cartflows-license-popup' ) . '">', '</a>' );
563 }
564
565 wp_send_json_error(
566 array(
567 'message' => $title,
568 'call_to_action' => $msg,
569 'data' => $response,
570 )
571 );
572 }
573 // Do license validation if showing pro flows.
574
575 /**
576 * Create Flow
577 */
578 $new_flow_post = array(
579 'post_title' => isset( $flow['title'] ) ? sanitize_text_field( wp_unslash( $flow['title'] ) ) : '',
580 'post_content' => '',
581 'post_status' => 'publish',
582 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
583 );
584
585 // Insert the post into the database.
586 $new_flow_id = wp_insert_post( $new_flow_post );
587
588 if ( is_wp_error( $new_flow_id ) ) {
589 wp_send_json_error( $new_flow_id->get_error_message() );
590 }
591
592 wcf()->logger->import_log( '✓ Flow Created! Flow ID: ' . $new_flow_id . ' - Remote Flow ID - ' . absint( $flow['ID'] ) );
593
594 /**
595 * Update Store Checkout flow meta
596 */
597
598 // Set newly created flow as store checkout.
599 update_option( '_cartflows_store_checkout', $new_flow_id );
600
601 // Remove old checkout key if available.
602 delete_option( '_cartflows_old_global_checkout' );
603
604 // reset global checkout on store checkout creation.
605 $common_settings = \Cartflows_Helper::get_common_settings();
606 $common_settings['global_checkout'] = '';
607 $common_settings['override_global_checkout'] = 'disable';
608 update_option( '_cartflows_common', $common_settings );
609
610 /**
611 * Import All Steps
612 */
613 $steps = isset( $flow['steps'] ) ? $flow['steps'] : array();
614
615 $is_checkout_available = false;
616 $flow_steps = array();
617
618 // Get importer function instance to call the import steps function.
619 $importer = new Importer();
620
621 foreach ( $steps as $key => $step ) {
622 // Separate out the Checkout step to set it as Global Checkout.
623 if ( 'checkout' === $step['type'] ) {
624 $is_checkout_available = true;
625 }
626
627 if ( in_array( $step['type'], array( 'upsell', 'downsell' ), true ) && ( ! _is_cartflows_pro() || is_wcf_starter_plan() ) ) {
628 continue;
629 }
630
631 $importer->import_single_step(
632 array(
633 'step' => array(
634 'id' => absint( $step['ID'] ),
635 'title' => $step['title'],
636 'type' => $step['type'],
637 ),
638 'flow' => array(
639 'id' => $new_flow_id,
640 ),
641 ),
642 'cartflows_import_store_checkout'
643 );
644 }
645
646 /**
647 * This option will be used to display the NPS survey notice.
648 */
649 update_option( '_cartflows_wizard_store_checkout_set', 'yes' );
650
651 /**
652 * Redirect to the new flow edit screen
653 */
654 $response_data = array(
655 'success' => true,
656 'message' => __( 'Successfully imported the Flow!', 'cartflows' ),
657 'items' => $flow,
658 'redirect_url' => admin_url( 'post.php?action=edit&post=' . $new_flow_id ),
659 'new_flow_id' => $new_flow_id,
660 );
661
662 wcf()->logger->import_log( 'COMPLETE! Importing Flow' );
663 }
664
665 wp_send_json_success( $response_data );
666 }
667
668 /**
669 * This function creates the Instant Checkout Funnel.
670 *
671 * @since 2.1.5
672 * @param array $flow The flow which is going to be imported.
673 * @return array Response of the function.
674 */
675 public function create_instant_checkout_funnel( $flow ) {
676
677 wcf()->logger->import_log( 'Importing the Instant Checkout Funnel from onboarding wizard' );
678
679 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
680
681 if ( ! current_user_can( 'manage_options' ) ) {
682 wcf()->logger->import_log( 'User don\'t have the permission to do this operation.' );
683 wp_send_json_error( $response_data );
684 }
685
686 /**
687 * Nonce verification
688 */
689 if ( ! check_ajax_referer( 'cartflows_import_store_checkout', 'security', false ) ) {
690 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
691 wcf()->logger->import_log( 'Nonce verificaton is failed.' );
692 wp_send_json_error( $response_data );
693 }
694
695 // Create post object.
696 $new_flow_post = array(
697 'post_title' => isset( $flow['title'] ) ? sanitize_text_field( wp_unslash( $flow['title'] ) ) : '',
698 'post_content' => '',
699 'post_status' => 'publish',
700 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
701 );
702
703 // Insert the post into the database.
704 $flow_id = wp_insert_post( $new_flow_post );
705
706 if ( is_wp_error( $flow_id ) ) {
707 wp_send_json_error( $flow_id->get_error_message() );
708 }
709
710 wcf()->logger->import_log( 'Blank funnel is created with title as: ' . $new_flow_post['post_title'] . ' and ID: ' . $flow_id );
711
712 // If is store checkout update store_checkout options.
713 update_option( '_cartflows_store_checkout', $flow_id );
714
715 // reset global checkout on store checkout creation.
716 $common_settings = \Cartflows_Helper::get_common_settings();
717 $common_settings['global_checkout'] = '';
718 $common_settings['override_global_checkout'] = 'disable';
719
720 update_option( '_cartflows_common', $common_settings );
721
722 wcf()->logger->import_log( 'Funnel is set as Store Checkout' );
723
724 $flow_steps = array();
725
726 wcf()->logger->import_log( 'Is WooCommerce Installed and Activated: ' . wcf()->is_woo_active );
727
728 if ( wcf()->is_woo_active ) {
729 $steps_data = array(
730 'order-form' => array(
731 'title' => __( 'Checkout', 'cartflows' ),
732 'type' => 'checkout',
733 ),
734 'order-confirmation' => array(
735 'title' => __( 'Thank You', 'cartflows' ),
736 'type' => 'thankyou',
737 ),
738 );
739 } else {
740 $steps_data = array(
741 'landing' => array(
742 'title' => __( 'Landing', 'cartflows' ),
743 'type' => 'landing',
744 ),
745 'thankyou' => array(
746 'title' => __( 'Thank You', 'cartflows' ),
747 'type' => 'landing',
748 ),
749 );
750 }
751
752 wcf()->logger->import_log( '====== Creating Steps for the selected funnel: ' . $flow_id . ' ======' );
753
754 foreach ( $steps_data as $slug => $data ) {
755
756 $post_content = '';
757 $step_type = trim( $data['type'] );
758
759 // Create new step.
760 $step_id = wp_insert_post(
761 array(
762 'post_type' => CARTFLOWS_STEP_POST_TYPE,
763 'post_title' => $data['title'],
764 'post_content' => $post_content,
765 'post_status' => 'publish',
766 )
767 );
768
769 // Return the error.
770 if ( is_wp_error( $step_id ) ) {
771 wp_send_json_error( $step_id->get_error_message() );
772 }
773
774 wcf()->logger->import_log( 'New step created: ' . $step_id . ' Step Type: ' . $step_type );
775
776 if ( $step_id ) {
777
778 $flow_steps[] = array(
779 'id' => $step_id,
780 'title' => $data['title'],
781 'type' => $step_type,
782 );
783
784 // Insert post meta.
785 update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
786 update_post_meta( $step_id, 'wcf-step-type', $step_type );
787
788 // Set taxonomies.
789 wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
790 wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
791
792 update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
793
794 wcf()->logger->import_log( 'Required step data set for newly created step: ' . $step_id );
795 }
796 }
797
798 wcf()->logger->import_log( '====== Steps created for the selected funnel: ' . $flow_id . ' ======' );
799
800 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
801
802 wcf()->logger->import_log( 'Steps in the funnel: ' . $flow_id . ' are set.' );
803
804 // Set the current funnel as instant checkout.
805 update_post_meta( $flow_id, 'instant-layout-style', 'yes' );
806
807 wcf()->logger->import_log( 'The funnel: ' . $flow_id . ' is enabled for instant checkout.' );
808
809 /**
810 * This option will be used to display the NPS survey notice.
811 */
812 update_option( '_cartflows_wizard_store_checkout_set', 'yes' );
813
814 /**
815 * Redirect to the new flow edit screen
816 */
817 return array(
818 'success' => true,
819 'message' => __( 'Successfully created the Funnel!', 'cartflows' ),
820 'redirect_url' => admin_url( 'post.php?action=edit&post=' . $flow_id ),
821 'new_flow_id' => $flow_id,
822 );
823 }
824 }
825