PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.0.1
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.0.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.0.1, at admin-core/ajax/onboarding.php

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