PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.2.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.2.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 / admin-legacy-core / ajax / flows.php

flows.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.2.0, at admin-legacy-core/ajax/flows.php

1,232 lines 32.9 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\AdminLegacyCore\Ajax;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 use CartflowsAdmin\AdminLegacyCore\Ajax\AjaxBase;
16 use CartflowsAdmin\AdminLegacyCore\Inc\AdminHelper;
17 use CartflowsAdmin\AdminLegacyCore\Inc\MetaOps;
18
19 /**
20 * Class Flows.
21 */
22 class Flows 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 'update_flow_title',
56 'clone_flow',
57 'delete_flow',
58 'trash_flow',
59 'restore_flow',
60 'reorder_flow_steps',
61 'trash_flows_in_bulk',
62 'update_flow_post_status',
63 'delete_flows_permanently',
64 'save_flow_meta_settings',
65 'export_flows_in_bulk',
66 'update_status',
67 'update_store_checkout_status',
68 'hide_instant_checkout_notice',
69 'get_published_flows',
70 );
71
72 $this->init_ajax_events( $ajax_events );
73 }
74
75 /**
76 * Export the flows and it's data.
77 */
78 public function export_flows_in_bulk() {
79
80 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
81
82 /**
83 * Check permission
84 */
85 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
86 wp_send_json_error( $response_data );
87 }
88
89 /**
90 * Nonce verification
91 */
92 if ( ! check_ajax_referer( 'cartflows_export_flows_in_bulk', 'security', false ) ) {
93 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
94 wp_send_json_error( $response_data );
95 }
96
97 if ( ! isset( $_POST['flow_ids'] ) ) {
98 $response_data = array( 'message' => __( 'No Funnel IDs has been supplied to export!', 'cartflows' ) );
99 wp_send_json_error( $response_data );
100 }
101
102 $flow_ids = array_map( 'intval', explode( ',', sanitize_text_field( $_POST['flow_ids'] ) ) );
103
104 $flows = array();
105 $export = \CartFlows_Importer::get_instance();
106 foreach ( $flow_ids as $key => $flow_id ) {
107 $flows[] = $export->get_flow_export_data( $flow_id );
108 }
109
110 $response_data = array(
111 'message' => __( 'Funnel exported successfully', 'cartflows' ),
112 'flows' => wp_json_encode( $flows ),
113 );
114
115 wp_send_json_success( $response_data );
116 }
117
118 /**
119 * Save flow meta data.
120 */
121 public function save_flow_meta_settings() {
122
123 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
124
125 /**
126 * Check permission
127 */
128 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
129 wp_send_json_error( $response_data );
130 }
131
132 /**
133 * Nonce verification
134 */
135 if ( ! check_ajax_referer( 'cartflows_save_flow_meta_settings', 'security', false ) ) {
136 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
137 wp_send_json_error( $response_data );
138 }
139
140 $response_data = array(
141 'status' => false,
142 'text' => __( 'Can\'t update the flow data', 'cartflows' ),
143 );
144
145 if ( isset( $_POST['flow_id'] ) ) {
146 $flow_id = intval( $_POST['flow_id'] );
147
148 if ( empty( $flow_id ) ) {
149 wp_send_json_error( $response_data );
150 }
151
152 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
153 wp_send_json_error( $response_data );
154 }
155
156 $new_flow_title = isset( $_POST['post_title'] ) ? sanitize_text_field( wp_unslash( $_POST['post_title'] ) ) : get_the_title( $flow_id );
157
158 if ( '' === $new_flow_title ) {
159 $new_flow_title = __( '(no title)', 'cartflows' );
160 }
161
162 $new_flow_slug = isset( $_POST['post_name'] ) ? sanitize_text_field( wp_unslash( $_POST['post_name'] ) ) : '';
163
164 $post_meta = wcf()->options->get_flow_fields( $flow_id );
165 MetaOps::save_meta_fields( $flow_id, $post_meta, 'cartflows_save_flow_meta_settings' );
166
167 $instant_layout_style = isset( $_POST['instant-layout-style'] ) ? sanitize_text_field( wp_unslash( $_POST['instant-layout-style'] ) ) : null;
168
169 if ( 'yes' === $instant_layout_style ) {
170 update_post_meta( $flow_id, 'wcf-instant-checkout-notice-skipped', 'yes' );
171 update_option( 'wcf-instant-checkout-notice-skipped', 'yes' );
172 }
173
174 $new_flow_data = array(
175 'ID' => $flow_id,
176 'post_title' => $new_flow_title,
177 'post_name' => $new_flow_slug,
178 );
179
180 wp_update_post( $new_flow_data );
181 }
182
183 $response_data = array(
184 'message' => __( 'Successfully saved the flow data!', 'cartflows' ),
185 );
186 wp_send_json_success( $response_data );
187 }
188
189 /**
190 * Delete the flow and it's data.
191 */
192 public function delete_flows_permanently() {
193
194 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
195
196 /**
197 * Check permission
198 */
199 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
200 wp_send_json_error( $response_data );
201 }
202
203 /**
204 * Nonce verification
205 */
206 if ( ! check_ajax_referer( 'cartflows_delete_flows_permanently', 'security', false ) ) {
207 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
208 wp_send_json_error( $response_data );
209 }
210
211 $flow_ids = isset( $_POST['flow_ids'] ) ? array_map( 'intval', explode( ',', sanitize_text_field( $_POST['flow_ids'] ) ) ) : array();
212
213 foreach ( $flow_ids as $key => $flow_id ) {
214
215 /* Check if CartFlows Post type */
216 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
217 continue;
218 }
219
220 /* Get Steps */
221 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
222
223 /* delte All steps */
224 if ( $steps && is_array( $steps ) ) {
225 foreach ( $steps as $step ) {
226
227 /* Need to delete ab test data as well */
228 wp_delete_post( $step['id'], true );
229 }
230 }
231 /* Trash term */
232 $term_data = term_exists( 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
233
234 if ( is_array( $term_data ) ) {
235 wp_trash_post( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
236 }
237
238 /* Finally trash flow post and it's data */
239 wp_delete_post( $flow_id, true );
240 }
241
242 /**
243 * Redirect to the new flow edit screen
244 */
245 $response_data = array(
246 'message' => __( 'Successfully deleted the Funnels!', 'cartflows' ),
247 );
248 wp_send_json_success( $response_data );
249 }
250
251 /**
252 * Update flow status.
253 */
254 public function update_flow_post_status() {
255
256 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
257
258 /**
259 * Check permission
260 */
261 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
262 wp_send_json_error( $response_data );
263 }
264
265 /**
266 * Nonce verification
267 */
268 if ( ! check_ajax_referer( 'cartflows_update_flow_post_status', 'security', false ) ) {
269 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
270 wp_send_json_error( $response_data );
271 }
272
273 if ( ! isset( $_POST['flow_ids'] ) ) {
274 $response_data = array( 'message' => __( 'No Funnel IDs has been supplied to delete!', 'cartflows' ) );
275 wp_send_json_error( $response_data );
276 }
277
278 $flow_ids = isset( $_POST['flow_ids'] ) ? array_map( 'intval', explode( ',', sanitize_text_field( $_POST['flow_ids'] ) ) ) : array();
279
280 $new_status = isset( $_POST['new_status'] ) ? sanitize_text_field( wp_unslash( $_POST['new_status'] ) ) : '';
281 $allowed_statuses = array( 'publish', 'draft', 'trash', 'pending' );
282 if ( ! in_array( $new_status, $allowed_statuses, true ) ) {
283 wp_send_json_error( array( 'message' => __( 'Invalid post status.', 'cartflows' ) ) );
284 }
285
286 foreach ( $flow_ids as $key => $flow_id ) {
287
288 /* Check if CartFlows Post type */
289 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
290 continue;
291 }
292
293 /* Get Steps */
294 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
295
296 /* Trash All steps */
297 if ( $steps && is_array( $steps ) ) {
298 foreach ( $steps as $step ) {
299
300 $my_post = array();
301 $my_post['ID'] = $step['id'];
302 $my_post['post_status'] = $new_status;
303 wp_update_post( wp_slash( $my_post ) );
304
305 }
306 }
307
308 /*
309 Trash term
310 // $term_data = term_exists( 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
311 // if ( is_array( $term_data ) ) {
312 // wp_trash_post( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
313 // }
314 */
315
316 /* Finally trash flow post and it's data */
317 $flow_post = array();
318 $flow_post['ID'] = $flow_id;
319 $flow_post['post_status'] = $new_status;
320 wp_update_post( $flow_post );
321 }
322
323 /**
324 * Redirect to the new flow edit screen
325 */
326 $response_data = array(
327 'message' => __( 'Successfully trashed the Funnels!', 'cartflows' ),
328 );
329 wp_send_json_success( $response_data );
330 }
331
332
333 /**
334 * Trash the flows and it's data.
335 */
336 public function trash_flows_in_bulk() {
337
338 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
339
340 /**
341 * Check permission
342 */
343 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
344 wp_send_json_error( $response_data );
345 }
346
347 /**
348 * Nonce verification
349 */
350 if ( ! check_ajax_referer( 'cartflows_trash_flows_in_bulk', 'security', false ) ) {
351 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
352 wp_send_json_error( $response_data );
353 }
354
355 if ( ! isset( $_POST['flow_ids'] ) ) {
356 $response_data = array( 'message' => __( 'No Funnel IDs has been supplied to delete!', 'cartflows' ) );
357 wp_send_json_error( $response_data );
358 }
359
360 $flow_ids = isset( $_POST['flow_ids'] ) ? array_map( 'intval', explode( ',', sanitize_text_field( $_POST['flow_ids'] ) ) ) : array();
361
362 foreach ( $flow_ids as $key => $flow_id ) {
363
364 /* Check if CartFlows Post type */
365 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
366 continue;
367 }
368 /* Get Steps */
369 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
370
371 /* Trash All steps */
372 if ( $steps && is_array( $steps ) ) {
373 foreach ( $steps as $step ) {
374
375 /* Need to delete ab test data as well */
376 wp_trash_post( $step['id'], true );
377 }
378 }
379
380 /* Trash term */
381 $term_data = term_exists( 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
382
383 if ( is_array( $term_data ) ) {
384 wp_trash_post( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
385 }
386
387 /* Finally trash flow post and it's data */
388 wp_trash_post( $flow_id, true );
389 }
390
391 /**
392 * Redirect to the new flow edit screen
393 */
394 $response_data = array(
395 'message' => __( 'Successfully trashed the Funnels!', 'cartflows' ),
396 );
397 wp_send_json_success( $response_data );
398 }
399 /**
400 * Update flow title.
401 */
402 public function update_flow_title() {
403
404 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
405
406 /**
407 * Check permission
408 */
409 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
410 wp_send_json_error( $response_data );
411 }
412
413 /**
414 * Nonce verification
415 */
416 if ( ! check_ajax_referer( 'cartflows_update_flow_title', 'security', false ) ) {
417 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
418 wp_send_json_error( $response_data );
419 }
420
421 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : 0;
422 $new_flow_title = isset( $_POST['new_flow_title'] ) ? sanitize_text_field( $_POST['new_flow_title'] ) : '';
423
424 /* Check if CartFlows Post type */
425 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
426 wp_send_json_error( array( 'message' => __( 'Invalid Funnel ID has been supplied to update title.', 'cartflows' ) ) );
427 }
428
429 $result = array(
430 'status' => false,
431 'text' => __( 'Can\'t update the flow title', 'cartflows' ),
432 );
433
434 if ( empty( $flow_id ) || empty( $new_flow_title ) ) {
435 wp_send_json( $result );
436 }
437
438 $new_flow_data = array(
439 'ID' => $flow_id,
440 'post_title' => $new_flow_title,
441 );
442 wp_update_post( $new_flow_data );
443
444 $result = array(
445 'status' => true,
446 /* translators: %s flow id */
447 'text' => sprintf( __( 'Funnel title updated - %s', 'cartflows' ), $flow_id ),
448 );
449
450 wp_send_json( $result );
451 }
452
453 /**
454 * Clone the Flow.
455 */
456 public function clone_flow() {
457
458 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
459
460 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
461 wp_send_json_error( $response_data );
462 }
463
464 /**
465 * Nonce verification
466 */
467 if ( ! check_ajax_referer( 'cartflows_clone_flow', 'security', false ) ) {
468 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
469 wp_send_json_error( $response_data );
470 }
471
472 $response_data = array( 'message' => __( 'Invalid Funnel ID has been supplied to clone!', 'cartflows' ) );
473
474 /**
475 * Check flow id
476 */
477 if ( empty( $_POST['id'] ) ) {
478 wp_send_json_error( $response_data );
479 }
480
481 /**
482 * Get the original post id
483 */
484 $post_id = absint( $_POST['id'] );
485
486 /* Check if CartFlows Post type */
487 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $post_id ) ) {
488 wp_send_json_error( $response_data );
489 }
490
491 /**
492 * And all the original post data then
493 */
494 $post = get_post( $post_id );
495
496 /**
497 * Assign current user to be the new post author
498 */
499 $current_user = wp_get_current_user();
500 $new_post_author = $current_user->ID;
501
502 /**
503 * If post data not exists, throw error
504 */
505 if ( ! isset( $post ) || null === $post ) {
506 $response_data = array( 'message' => __( 'Invalid Funnel ID has been supplied to duplicate!', 'cartflows' ) );
507 wp_send_json_error( $response_data );
508 }
509
510 global $wpdb;
511
512 /**
513 * Let's start cloning
514 */
515
516 /**
517 * New post data array
518 */
519 $args = array(
520 'comment_status' => $post->comment_status,
521 'ping_status' => $post->ping_status,
522 'post_author' => $new_post_author,
523 'post_content' => $post->post_content,
524 'post_excerpt' => $post->post_excerpt,
525 'post_name' => $post->post_name,
526 'post_parent' => $post->post_parent,
527 'post_password' => $post->post_password,
528 'post_status' => $post->post_status,
529 'post_title' => $post->post_title . ' Clone',
530 'post_type' => $post->post_type,
531 'to_ping' => $post->to_ping,
532 'menu_order' => $post->menu_order,
533 );
534
535 /**
536 * Insert the post
537 */
538 $new_flow_id = wp_insert_post( $args );
539
540 /**
541 * Get all current post terms ad set them to the new post
542 *
543 * Returns array of taxonomy names for post type, ex array("category", "post_tag");.
544 */
545 $taxonomies = get_object_taxonomies( $post->post_type );
546
547 foreach ( $taxonomies as $taxonomy ) {
548
549 $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
550
551 wp_set_object_terms( $new_flow_id, $post_terms, $taxonomy, false );
552 }
553
554 /**
555 * Duplicate all post meta just in two SQL queries
556 */
557 // Using custom query to clone flow & step meta data as it is better than WP functions in case in large data.
558 $post_meta_infos = $wpdb->get_results( //phpcs:ignore WordPress.DB.DirectDatabaseQuery
559 $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=%d", $post_id )
560 );
561
562 if ( ! empty( $post_meta_infos ) ) {
563
564 $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
565
566 $sql_query_sel = array();
567
568 foreach ( $post_meta_infos as $meta_info ) {
569
570 $meta_key = $meta_info->meta_key;
571
572 if ( '_wp_old_slug' === $meta_key ) {
573 continue;
574 }
575
576 $sql_query_sel[] = $wpdb->prepare( '( %d, %s, %s )', $new_flow_id, $meta_key, $meta_info->meta_value );
577
578 }
579
580 $sql_query .= implode( ',', $sql_query_sel );
581
582 $wpdb->query( $sql_query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
583 }
584
585 /* Steps Cloning */
586 $flow_steps = get_post_meta( $post_id, 'wcf-steps', true );
587 $new_flow_steps = array();
588
589 /* Set Steps Empty */
590 update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
591
592 if ( is_array( $flow_steps ) && ! empty( $flow_steps ) ) {
593
594 foreach ( $flow_steps as $index => $step_data ) {
595
596 $step_id = $step_data['id'];
597 $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
598
599 $step_object = get_post( $step_id );
600
601 /**
602 * New step post data array
603 */
604 $step_args = array(
605 'comment_status' => $step_object->comment_status,
606 'ping_status' => $step_object->ping_status,
607 'post_author' => $new_post_author,
608 'post_content' => $step_object->post_content,
609 'post_excerpt' => $step_object->post_excerpt,
610 'post_name' => $step_object->post_name,
611 'post_parent' => $step_object->post_parent,
612 'post_password' => $step_object->post_password,
613 'post_status' => $step_object->post_status,
614 'post_title' => $step_object->post_title,
615 'post_type' => $step_object->post_type,
616 'to_ping' => $step_object->to_ping,
617 'menu_order' => $step_object->menu_order,
618 );
619
620 /**
621 * Insert the post
622 */
623 $new_step_id = wp_insert_post( $step_args );
624
625 /**
626 * Duplicate all step meta
627 */
628 $post_meta_infos = $wpdb->get_results( //phpcs:ignore WordPress.DB.DirectDatabaseQuery
629 $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=%d", $step_id )
630 );
631
632 if ( ! empty( $post_meta_infos ) ) {
633
634 $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
635
636 $sql_query_sel = array();
637
638 foreach ( $post_meta_infos as $meta_info ) {
639
640 $meta_key = $meta_info->meta_key;
641
642 $meta_value = $meta_info->meta_value;
643
644 $sql_query_sel[] = $wpdb->prepare( '( %d, %s, %s )', $new_step_id, $meta_key, $meta_value );
645 }
646
647 $sql_query .= implode( ',', $sql_query_sel );
648
649 $wpdb->query( $sql_query ); //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
650 }
651
652 // insert post meta.
653 update_post_meta( $new_step_id, 'wcf-flow-id', $new_flow_id );
654 update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
655
656 /**
657 * @ to_do later
658 * delete split test connecctivity
659 */
660
661 wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
662 wp_set_object_terms( $new_step_id, 'flow-' . $new_flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
663
664 /* Add New Flow Steps */
665 $new_flow_steps[] = array(
666 'id' => $new_step_id,
667 'title' => $step_object->post_title,
668 'type' => $step_type,
669 );
670 }
671 }
672
673 /* Update New Flow Step Post Meta */
674 update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
675
676 /* Clear Page Builder Cache */
677 AdminHelper::clear_cache();
678
679 /**
680 * Redirect to the new flow edit screen
681 */
682 $response_data = array(
683 'message' => __( 'Successfully cloned the Funnel!', 'cartflows' ),
684 'redirect_url' => admin_url( 'post.php?action=edit&post=' . $new_flow_id ),
685 );
686 wp_send_json_success( $response_data );
687 }
688
689 /**
690 * Restore the flow and it's data.
691 */
692 public function restore_flow() {
693
694 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
695
696 /**
697 * Check permission
698 */
699 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
700 wp_send_json_error( $response_data );
701 }
702
703 /**
704 * Nonce verification
705 */
706 if ( ! check_ajax_referer( 'cartflows_restore_flow', 'security', false ) ) {
707 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
708 wp_send_json_error( $response_data );
709 }
710
711 $response_data = array( 'message' => __( 'Invalid Funnel ID has been supplied to restore!', 'cartflows' ) );
712
713
714 if ( ! isset( $_POST['flow_id'] ) ) {
715 wp_send_json_error( $response_data );
716 }
717
718 $flow_id = intval( $_POST['flow_id'] );
719
720 /* Check if CartFlows Post type */
721 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
722 wp_send_json_error( $response_data );
723 }
724
725 /* Get Steps */
726 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
727
728 /* Untrash All steps */
729 if ( $steps && is_array( $steps ) ) {
730 foreach ( $steps as $step ) {
731
732 /* Need to delete ab test data as well */
733 wp_untrash_post( $step['id'] );
734 }
735 }
736
737 /* Untrash term */
738 $term_data = term_exists( 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
739
740 if ( is_array( $term_data ) ) {
741 wp_untrash_post( $term_data['term_id'] );
742 }
743
744 /* Finally untrash flow post and it's data */
745 wp_untrash_post( $flow_id );
746
747 /**
748 * Redirect to the new flow edit screen
749 */
750 $response_data = array(
751 'message' => __( 'Successfully restored the Funnel!', 'cartflows' ),
752 );
753 wp_send_json_success( $response_data );
754 }
755
756 /**
757 * Trash the flow and it's data.
758 */
759 public function trash_flow() {
760
761 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
762
763 /**
764 * Check permission
765 */
766 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
767 wp_send_json_error( $response_data );
768 }
769
770 /**
771 * Nonce verification
772 */
773 if ( ! check_ajax_referer( 'cartflows_trash_flow', 'security', false ) ) {
774 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
775 wp_send_json_error( $response_data );
776 }
777
778 $response_data = array( 'message' => __( 'Invalid Funnel ID has been supplied to trash!', 'cartflows' ) );
779
780 if ( ! isset( $_POST['flow_id'] ) ) {
781 wp_send_json_error( $response_data );
782 }
783
784 $flow_id = intval( $_POST['flow_id'] );
785
786 /* Check if CartFlows Post type */
787 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
788 wp_send_json_error( $response_data );
789 }
790
791 /* Get Steps */
792 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
793
794 /* Trash All steps */
795 if ( $steps && is_array( $steps ) ) {
796 foreach ( $steps as $step ) {
797
798 /* Need to delete ab test data as well */
799 wp_trash_post( $step['id'], true );
800 }
801 }
802
803 /* Trash term */
804 $term_data = term_exists( 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
805
806 if ( is_array( $term_data ) ) {
807 wp_trash_post( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
808 }
809
810 /* Finally trash flow post and it's data */
811 wp_trash_post( $flow_id, true );
812
813 /**
814 * Redirect to the new flow edit screen
815 */
816 $response_data = array(
817 'message' => __( 'Successfully trashed the Funnel!', 'cartflows' ),
818 );
819 wp_send_json_success( $response_data );
820 }
821
822 /**
823 * Delete the flow and it's data.
824 */
825 public function delete_flow() {
826
827 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
828
829 /**
830 * Check permission
831 */
832 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
833 wp_send_json_error( $response_data );
834 }
835
836 /**
837 * Nonce verification
838 */
839 if ( ! check_ajax_referer( 'cartflows_delete_flow', 'security', false ) ) {
840 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
841 wp_send_json_error( $response_data );
842 }
843
844 $response_data = array( 'message' => __( 'Invalid Funnel ID has been supplied to delete!', 'cartflows' ) );
845
846 if ( ! isset( $_POST['flow_id'] ) ) {
847 wp_send_json_error( $response_data );
848 }
849
850 $flow_id = intval( $_POST['flow_id'] );
851
852 /* Check if CartFlows Post type */
853 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
854 wp_send_json_error( $response_data );
855 }
856
857 /* Get Steps */
858 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
859
860 /* Delete All steps */
861 if ( $steps && is_array( $steps ) ) {
862 foreach ( $steps as $step ) {
863
864 /* Need to delete ab test data as well */
865 wp_delete_post( $step['id'], true );
866 }
867 }
868
869 /* Delete term */
870 $term_data = term_exists( 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
871
872 if ( is_array( $term_data ) ) {
873 wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
874 }
875
876 /* Finally delete flow post and it's data */
877 wp_delete_post( $flow_id, true );
878
879 do_action( 'cartflows_admin_after_delete_flow', $flow_id );
880
881 /**
882 * Redirect to the new flow edit screen
883 */
884 $response_data = array(
885 'message' => __( 'Successfully deleted the Funnel!', 'cartflows' ),
886 );
887 wp_send_json_success( $response_data );
888 }
889
890 /**
891 * Update status.
892 */
893 public function update_status() {
894
895 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
896
897 /**
898 * Check permission
899 */
900 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
901 wp_send_json_error( $response_data );
902 }
903
904 /**
905 * Nonce verification
906 */
907 if ( ! check_ajax_referer( 'cartflows_update_status', 'security', false ) ) {
908 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
909 wp_send_json_error( $response_data );
910 }
911
912 $response_data = array( 'message' => __( 'Invalid Funnel IDs has been supplied to update status!', 'cartflows' ) );
913
914 if ( ! isset( $_POST['flow_id'] ) ) {
915 wp_send_json_error( $response_data );
916 }
917
918 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : 0;
919
920 /* Check if CartFlows Post type */
921 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
922 wp_send_json_error( $response_data );
923 }
924
925 $new_status = isset( $_POST['new_status'] ) ? sanitize_text_field( wp_unslash( $_POST['new_status'] ) ) : '';
926 $allowed_statuses = array( 'publish', 'draft', 'trash', 'pending' );
927 if ( ! in_array( $new_status, $allowed_statuses, true ) ) {
928 wp_send_json_error( array( 'message' => __( 'Invalid post status.', 'cartflows' ) ) );
929 }
930
931 /* Get Steps */
932 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
933
934 /* Trash All steps */
935 if ( $steps && is_array( $steps ) ) {
936 foreach ( $steps as $step ) {
937
938 $my_post = array();
939 $my_post['ID'] = $step['id'];
940 $my_post['post_status'] = $new_status;
941 wp_update_post( wp_slash( $my_post ) );
942
943 }
944 }
945
946 /*
947 Trash term
948 // $term_data = term_exists( 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
949
950 // if ( is_array( $term_data ) ) {
951 // wp_trash_post( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
952 // }
953 */
954
955 /* Finally trash flow post and it's data */
956 $flow_post = array();
957 $flow_post['ID'] = $flow_id;
958 $flow_post['post_status'] = $new_status;
959 wp_update_post( $flow_post );
960
961 /**
962 * Redirect to the new flow edit screen
963 */
964 $response_data = array(
965 'message' => __( 'Successfully updated the Funnel status!', 'cartflows' ),
966 );
967 wp_send_json_success( $response_data );
968 }
969
970 /**
971 * Enables / Disables Store Checkout on toggle click
972 *
973 * @return void
974 * @since X.X.X
975 */
976 public function update_store_checkout_status() {
977 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
978
979 /**
980 * Check permission
981 */
982 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
983 wp_send_json_error( $response_data );
984 }
985
986 /**
987 * Nonce verification
988 */
989 if ( ! check_ajax_referer( 'cartflows_update_store_checkout_status', 'security', false ) ) {
990 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
991 wp_send_json_error( $response_data );
992 }
993
994 if ( ! isset( $_POST['enable_store_checkout'] ) ) {
995 $response_data = array( 'message' => __( 'No Funnel IDs has been supplied to delete!', 'cartflows' ) );
996 wp_send_json_error( $response_data );
997 }
998
999 $enable_store_checkout = isset( $_POST['enable_store_checkout'] ) ? sanitize_text_field( wp_unslash( $_POST['enable_store_checkout'] ) ) : '';
1000 $checkout_id = isset( $_POST['checkout_id'] ) ? absint( wp_unslash( $_POST['checkout_id'] ) ) : '';
1001
1002 $old_global_checkout = get_option( '_cartflows_old_global_checkout ', false );
1003 $checkout_id = $old_global_checkout ? absint( $old_global_checkout ) : $checkout_id;
1004
1005 $common_settings = \Cartflows_Helper::get_common_settings();
1006
1007 $override_status = 'enable';
1008 if ( 'false' === $enable_store_checkout ) {
1009 $checkout_id = '';
1010 $override_status = 'disable';
1011 }
1012
1013 $common_settings['global_checkout'] = $checkout_id;
1014 $common_settings['override_global_checkout'] = $override_status;
1015
1016 AdminHelper::update_admin_settings_option( '_cartflows_common', $common_settings, false );
1017
1018 do_action( 'cartflows_after_save_store_checkout' );
1019
1020 /**
1021 * Redirect to the new flow edit screen
1022 */
1023 $response_data = array(
1024 'message' => __( 'Successfully updated the Funnel status!', 'cartflows' ),
1025 'checkout_id' => $checkout_id,
1026 );
1027 wp_send_json_success( $response_data );
1028 }
1029
1030
1031 /**
1032 * Prepare where items for query.
1033 */
1034 public function reorder_flow_steps() {
1035
1036 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
1037
1038 /**
1039 * Check permission
1040 */
1041 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
1042 wp_send_json_error( $response_data );
1043 }
1044
1045 /**
1046 * Nonce verification
1047 */
1048 if ( ! check_ajax_referer( 'cartflows_reorder_flow_steps', 'security', false ) ) {
1049 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
1050 wp_send_json_error( $response_data );
1051 }
1052
1053 $flow_id = false;
1054 $step_ids = array();
1055
1056 if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
1057 $flow_id = intval( $_POST['post_id'] );
1058 $step_ids = explode( ',', sanitize_text_field( $_POST['step_ids'] ) );
1059 $step_ids = array_map( 'intval', $step_ids );
1060 }
1061
1062 $response_data = array(
1063 'status' => false,
1064 'text' => __( 'Invalid flow ID has been provided.', 'cartflows' ),
1065 );
1066
1067 if ( ! $flow_id ) {
1068 wp_send_json( $response_data );
1069 }
1070
1071 if ( CARTFLOWS_FLOW_POST_TYPE !== get_post_type( $flow_id ) ) {
1072 wp_send_json( $response_data );
1073 }
1074
1075 if ( empty( $step_ids ) ) {
1076 wp_send_json(
1077 array(
1078 'status' => false,
1079 /* translators: %s flow id */
1080 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
1081 )
1082 );
1083 }
1084
1085 $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1086 $flow_steps_map = array();
1087
1088 if ( is_array( $flow_steps ) ) {
1089 foreach ( $flow_steps as $key => $value ) {
1090 $flow_steps_map[ $value['id'] ] = $value;
1091 }
1092 }
1093
1094 $new_flow_steps = array();
1095
1096 foreach ( $step_ids as $index => $step_id ) {
1097
1098 $new_flow_step_data = array();
1099
1100 if ( isset( $flow_steps_map[ $step_id ] ) ) {
1101 $new_flow_step_data = $flow_steps_map[ $step_id ];
1102 }
1103
1104 $new_flow_step_data['id'] = intval( $step_id );
1105 $new_flow_step_data['title'] = get_the_title( $step_id );
1106 $new_flow_step_data['type'] = get_post_meta( $step_id, 'wcf-step-type', true );
1107
1108 $new_flow_steps[] = $new_flow_step_data;
1109 }
1110
1111 update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
1112
1113 /* Setup steps data */
1114 $meta_options = AdminHelper::get_flow_meta_options( $flow_id );
1115 $steps = AdminHelper::prepare_step_data( $flow_id, $meta_options );
1116
1117 $result = array(
1118 'status' => true,
1119 /* translators: %s flow id */
1120 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
1121 'steps' => $steps,
1122 );
1123
1124 wp_send_json( $result );
1125 }
1126
1127 /**
1128 * Hide the instant Checkout Notice.
1129 *
1130 * @since X.X.X
1131 * @return void
1132 */
1133 public function hide_instant_checkout_notice() {
1134
1135 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
1136
1137 /**
1138 * Check permission
1139 */
1140 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
1141 wp_send_json_error( $response_data );
1142 }
1143
1144 /**
1145 * Nonce verification
1146 */
1147 if ( ! check_ajax_referer( 'cartflows_hide_instant_checkout_notice', 'security', false ) ) {
1148 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
1149 wp_send_json_error( $response_data );
1150 }
1151
1152 if ( ! isset( $_POST['flow_id'] ) ) {
1153 $response_data = array( 'message' => __( 'No Funnel ID is been supplied', 'cartflows' ) );
1154 wp_send_json_error( $response_data );
1155 }
1156
1157 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : 0;
1158
1159 // Set dismiss notice option for all flows.
1160 update_post_meta( $flow_id, 'wcf-instant-checkout-notice-skipped', 'yes' );
1161 update_option( 'wcf-instant-checkout-notice-skipped', 'yes' );
1162
1163 $result = array(
1164 'status' => true,
1165 /* translators: %s flow id */
1166 'text' => __( 'Notice Dismissed', 'cartflows' ),
1167 'instant_notice_status' => 'yes',
1168 );
1169
1170 wp_send_json( $result );
1171 }
1172
1173 /**
1174 * Get published flows for analytics dropdown.
1175 *
1176 * Returns only ID and title for better performance.
1177 *
1178 * @since 2.1.19
1179 * @return void
1180 */
1181 public function get_published_flows() {
1182 $response_data = array( 'message' => $this->get_error_msg( 'permission' ) );
1183
1184 /**
1185 * Check permission
1186 */
1187 if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) {
1188 wp_send_json_error( $response_data );
1189 }
1190
1191 /**
1192 * Nonce verification
1193 */
1194 if ( ! check_ajax_referer( 'cartflows_get_published_flows', 'security', false ) ) {
1195 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
1196 wp_send_json_error( $response_data );
1197 }
1198
1199 // Query only IDs for better performance.
1200 $flow_ids = get_posts(
1201 array(
1202 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1203 'post_status' => 'publish',
1204 'posts_per_page' => -1,
1205 'fields' => 'ids',
1206 'orderby' => 'title',
1207 'order' => 'ASC',
1208 'no_found_rows' => true, // Skip pagination calculations.
1209 'update_post_meta_cache' => false, // Skip meta cache.
1210 'update_post_term_cache' => false, // Skip term cache.
1211 )
1212 );
1213
1214 $flows = array();
1215
1216 if ( ! empty( $flow_ids ) && is_array( $flow_ids ) ) {
1217 foreach ( $flow_ids as $flow_id ) {
1218 $flow_title = get_the_title( $flow_id );
1219
1220 if ( ! empty( $flow_title ) ) {
1221 $flows[] = array(
1222 'flow_id' => $flow_id,
1223 'flow_title' => $flow_title,
1224 );
1225 }
1226 }
1227 }
1228
1229 wp_send_json_success( array( 'flows' => $flows ) );
1230 }
1231 }
1232