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

wizard.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.2.1, at wizard/ajax/wizard.php

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