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

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

824 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 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 // sanitize_key() here as well as sanitize_text_field(): import_templates() writes the
359 // cache under the sanitized slug, so reading with the raw one missed it permanently.
360 $page_builder = isset( $_POST['page_builder'] ) ? sanitize_key( wp_unslash( $_POST['page_builder'] ) ) : '';
361
362 $page = 1;
363 $flows_list = array();
364
365 if ( empty( $page_builder ) ) {
366 $response_data = array( 'message' => __( 'Please select any of the page builder to display the ready templates.', 'cartflows' ) );
367 wp_send_json_error( $response_data );
368 }
369
370 // Check is the template library updated or not.
371 if ( 'no' === \CartFlows_Batch_Process::get_instance()->get_last_export_checksums( 'store-checkout' ) ) {
372 // Get the cached flows as no changes are made in the template library.
373 $cached_flows = get_site_option( 'cartflows-store-checkout-' . $page_builder . '-flows-and-steps-' . $page );
374
375 $flows_list = ! empty( $cached_flows ) ? $cached_flows : array();
376 }
377
378 // If the cached flow list is empty then make a new request and fetch the templates.
379 if ( empty( $flows_list ) ) {
380 // Fetch new list of templates.
381 $flows_list = $this->import_templates( $page_builder, $page );
382
383 // Update the cheksum after importing the latest templates.
384 \CartFlows_Batch_Process::get_instance()->update_latest_checksums( 'store-checkout' );
385 }
386
387 /**
388 * Redirect to the new step edit screen
389 */
390 $response_data = array(
391 'message' => __( 'Successful!', 'cartflows' ),
392 'flows' => $flows_list,
393 );
394
395 wp_send_json_success( $response_data );
396 }
397
398 /**
399 * Import
400 *
401 * @since 1.0.14
402 * @since 1.6.15 Added page no.
403 * @param string $page_builder page builder slug.
404 * @param integer $page Page number.
405 * @return array
406 */
407 public function import_templates( $page_builder, $page = 1 ) {
408
409 $api_args = array(
410 'timeout' => 30, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
411 );
412
413 // Always shaped like a successful response so the error paths below cannot return
414 // null for 'flows' — the client reads .flows.length off it.
415 $sites_and_pages = array( 'flows' => array() );
416 $site_url = wcf()->get_site_url();
417
418 $query_args = array(
419 'per_page' => 100,
420 'page' => $page,
421 'flow_category' => array(
422 'include_terms' => array( 'store-checkout' ),
423 ),
424 );
425
426 $api_url = add_query_arg( $query_args, $site_url . 'wp-json/cartflows-server/v1/flows-and-steps/' );
427
428 $response = wp_remote_get( $api_url, $api_args );
429
430 if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
431
432 // Decode into its own variable — assigning over $sites_and_pages let the error
433 // branches below return a response with no 'flows' key at all.
434 $decoded = json_decode( wp_remote_retrieve_body( $response ), true );
435
436 if ( is_array( $decoded ) && isset( $decoded['code'] ) ) {
437 $message = isset( $decoded['message'] ) ? $decoded['message'] : '';
438 if ( ! empty( $message ) ) {
439 wcf()->logger->sync_log( 'HTTP Request Error: ' . $message );
440 } else {
441 wcf()->logger->sync_log( 'HTTP Request Error!' );
442 }
443 } elseif ( is_array( $decoded ) && ! empty( $decoded['flows'] ) ) {
444 $sites_and_pages['flows'] = $decoded['flows'];
445
446 $option_name = 'cartflows-store-checkout-' . $page_builder . '-flows-and-steps-' . $page;
447 update_site_option( $option_name, $decoded['flows'] );
448 }
449 } else {
450 // A non-200 response is not necessarily a WP_Error, and get_error_message()
451 // only exists on one — the previous `||` sent those into the branch above.
452 $error_message = is_wp_error( $response )
453 ? $response->get_error_message()
454 : sprintf( 'HTTP %s', wp_remote_retrieve_response_code( $response ) );
455
456 wcf()->logger->sync_log( 'API Error: ' . $error_message );
457 }
458
459 return $sites_and_pages['flows'];
460 }
461
462 /**
463 * Get store flow.
464 */
465 public function get_single_store_checkout_flow() {
466
467 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
468
469 if ( ! current_user_can( 'manage_options' ) ) {
470 wp_send_json_error( $response_data );
471 }
472
473 /**
474 * Nonce verification
475 */
476 if ( ! check_ajax_referer( 'cartflows_get_single_store_checkout_flow', 'security', false ) ) {
477 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
478 wp_send_json_error( $response_data );
479 }
480
481 $flow_id = isset( $_POST['flow_id'] ) ? absint( $_POST['flow_id'] ) : 0;
482
483 // Get single step Rest API response.
484 $response = \CartFlows_API::get_instance()->get_flow( $flow_id );
485
486 wp_send_json_success( $response['data'] );
487 }
488
489 /**
490 * Import the flow template for the store checkout.
491 * Once the import is done, then set it's checkout page as a Global Checkout.
492 *
493 * @since 1.10.0
494 * @return void
495 */
496 public function import_store_checkout() {
497 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
498
499 if ( ! current_user_can( 'manage_options' ) ) {
500 wp_send_json_error( $response_data );
501 }
502
503 /**
504 * Nonce verification
505 */
506 if ( ! check_ajax_referer( 'cartflows_import_store_checkout', 'security', false ) ) {
507 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
508 wp_send_json_error( $response_data );
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( $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="' . esc_url( \Cartflows_Helper::get_kb_doc_link( 'https://cartflows.com/docs/request-timeout-error-while-importing-the-flow-step-templates/' ) ) . '">', '</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 = WizardCore::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="' . esc_url( \Cartflows_Helper::get_upgrade_to_pro_link( '', 'https://cartflows.com/' ) ) . '">', '</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 - ' . $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' => $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