PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 1.1.15
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v1.1.15
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 / modules / flow / classes / class-cartflows-flow-meta.php

class-cartflows-flow-meta.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 1.1.15, at modules/flow/classes/class-cartflows-flow-meta.php

744 lines 16.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Flow meta
4 *
5 * @package CartFlows
6 */
7
8 /**
9 * Meta Boxes setup
10 */
11 class Cartflows_Flow_Meta {
12
13
14 /**
15 * Instance
16 *
17 * @var $instance
18 */
19 private static $instance;
20
21 /**
22 * Meta Option
23 *
24 * @var $meta_option
25 */
26 private static $meta_option;
27
28 /**
29 * Initiator
30 */
31 public static function get_instance() {
32 if ( ! isset( self::$instance ) ) {
33 self::$instance = new self;
34 }
35
36 return self::$instance;
37 }
38
39 /**
40 * Constructor
41 */
42 public function __construct() {
43
44 add_action( 'admin_head', array( $this, 'menu_highlight' ) );
45
46 add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
47
48 /* Init Metabox */
49 add_action( 'load-post.php', array( $this, 'init_metabox' ) );
50 add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
51
52 /* Add Scripts */
53 add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
54
55 add_action( 'wp_ajax_cartflows_setup_default_steps', array( $this, 'cartflows_setup_default_steps' ) );
56 add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
57
58 add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
59
60 add_action( 'admin_notices', array( $this, 'admin_notices' ) );
61
62 add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
63 }
64
65 /**
66 * Display admin notices.
67 *
68 * @since 1.0.0
69 *
70 * @return void
71 */
72 function admin_notices() {
73
74 if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
75 return;
76 }
77
78 $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
79 if ( $flow_id ) { ?>
80 <div class="wcf-notice-back-edit-flow">
81 <p>
82 <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero" style="text-decoration: none;">
83 <i class="dashicons dashicons-arrow-left-alt"></i>
84 <?php _e( 'Back to edit Flow', 'cartflows' ); ?>
85 </a>
86 </p>
87 </div>
88 <?php
89 }
90 }
91
92 /**
93 * Initialize admin actions.
94 *
95 * @since 1.0.0
96 *
97 * @return void
98 */
99 function admin_init_actions() {
100 add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
101 add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
102 add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
103 }
104
105 /**
106 * Delete term data and steps data after deleting flow.
107 *
108 * @since 1.0.0
109 * @param int $pid post id.
110 *
111 * @return void
112 */
113 function step_post_sync( $pid ) {
114
115 global $post_type;
116
117 if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
118
119 $steps = get_post_meta( $pid, 'wcf-steps', true );
120
121 if ( $steps && is_array( $steps ) ) {
122 foreach ( $steps as $i => $step ) {
123 wp_delete_post( $step['id'], true );
124 }
125 }
126
127 $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
128
129 if ( is_array( $term_data ) ) {
130 wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
131 }
132 }
133 }
134
135 /**
136 * Trash steps data after trashing flow.
137 *
138 * @since 1.0.0
139 * @param int $pid post id.
140 *
141 * @return void
142 */
143 function step_post_trash_sync( $pid ) {
144
145 global $post_type;
146
147 if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
148
149 $steps = get_post_meta( $pid, 'wcf-steps', true );
150
151 if ( $steps && is_array( $steps ) ) {
152 foreach ( $steps as $i => $step ) {
153 wp_trash_post( $step['id'] );
154 }
155 }
156 }
157 }
158
159 /**
160 * Untrash steps data after restoring flow.
161 *
162 * @since 1.0.0
163 * @param int $pid post id.
164 *
165 * @return void
166 */
167 function step_post_untrash_sync( $pid ) {
168
169 global $post_type;
170
171 if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
172
173 $steps = get_post_meta( $pid, 'wcf-steps', true );
174
175 if ( $steps && is_array( $steps ) ) {
176 foreach ( $steps as $i => $step ) {
177 wp_untrash_post( $step['id'] );
178 }
179 }
180 }
181 }
182
183 /**
184 * Setup default steps for flow
185 *
186 * @since 1.0.0
187 *
188 * @return void
189 */
190 public function cartflows_setup_default_steps() {
191
192 check_ajax_referer( 'wcf-setup-default-steps', 'security' );
193
194 $flow_id = intval( $_POST['post_id'] );
195
196 $result = array(
197 'status' => false,
198 /* translators: %s flow id */
199 'text' => sprintf( __( 'Steps not created for flow - %s', 'cartflows' ), $flow_id ),
200 );
201
202 if ( ! $flow_id ) {
203 wp_send_json( $result );
204 }
205
206 $is_step_exists = get_post_meta( $flow_id, 'wcf-steps', true );
207
208 if ( $is_step_exists ) {
209
210 $result = array(
211 'status' => false,
212 /* translators: %s flow id */
213 'text' => sprintf( __( 'Steps already exists. Flow - %s', 'cartflows' ), $flow_id ),
214 );
215
216 wp_send_json( $result );
217 }
218
219 /* Start Creating */
220
221 $flow_steps = array();
222
223 $steps_data = array(
224 'landing' => __( 'Landing Page', 'cartflows' ),
225 'checkout' => __( 'Checkout Page', 'cartflows' ),
226 'thankyou' => __( 'Thank You Page', 'cartflows' ),
227 );
228
229 foreach ( $steps_data as $slug => $title ) {
230
231 $step_id = wp_insert_post(
232 array(
233 'post_type' => CARTFLOWS_STEP_POST_TYPE,
234 'post_title' => $title,
235 'post_content' => '[cartflows_navigation]',
236 'post_status' => 'publish',
237 )
238 );
239
240 if ( $step_id ) {
241
242 $flow_steps[] = array(
243 'id' => $step_id,
244 'title' => $title,
245 'type' => $slug,
246 );
247
248 // insert post meta.
249 update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
250 update_post_meta( $step_id, 'wcf-step-type', $slug );
251
252 wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
253 wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
254 }
255 }
256
257 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
258
259 $result = array(
260 'status' => true,
261 /* translators: %s flow id */
262 'text' => sprintf( __( 'Steps created for flow - %s', 'cartflows' ), $flow_id ),
263 'redirect' => get_edit_post_link( $flow_id ),
264 );
265
266 wp_send_json( $result );
267 }
268
269 /**
270 * Create step for given flow.
271 *
272 * @param int $flow_id flow ID.
273 * @param int $step_type step type.
274 * @param int $step_title step title.
275 * @since 1.0.0
276 *
277 * @return int
278 */
279 public function create_step( $flow_id, $step_type, $step_title ) {
280
281 $new_step_id = wp_insert_post(
282 array(
283 'post_type' => CARTFLOWS_STEP_POST_TYPE,
284 'post_title' => $step_title,
285 'post_status' => 'publish',
286 )
287 );
288
289 if ( $new_step_id ) {
290
291 $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
292
293 if ( ! is_array( $flow_steps ) ) {
294 $flow_steps = array();
295 }
296
297 $flow_steps[] = array(
298 'id' => $new_step_id,
299 'title' => $step_title,
300 'type' => $step_type,
301 );
302
303 // insert post meta.
304 update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
305 update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
306
307 wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
308 wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
309 }
310
311 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
312
313 return $new_step_id;
314 }
315
316 /**
317 * Delete step for flow
318 *
319 * @since 1.0.0
320 *
321 * @return void
322 */
323 public function cartflows_delete_flow_step() {
324
325 check_ajax_referer( 'wcf-delete-flow-step', 'security' );
326
327 $flow_id = intval( $_POST['post_id'] );
328 $step_id = intval( $_POST['step_id'] );
329
330 $result = array(
331 'status' => false,
332 /* translators: %s flow id */
333 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
334 );
335
336 if ( ! $flow_id || ! $step_id ) {
337 wp_send_json( $result );
338 }
339
340 wp_delete_post( $step_id, true );
341
342 $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
343
344 if ( ! is_array( $flow_steps ) ) {
345 wp_send_json( $result );
346 }
347
348 foreach ( $flow_steps as $index => $data ) {
349
350 if ( intval( $data['id'] ) === $step_id ) {
351 unset( $flow_steps[ $index ] );
352 break;
353 }
354 }
355
356 /* Set index order properly */
357 $flow_steps = array_merge( $flow_steps );
358
359 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
360
361 $result = array(
362 'status' => true,
363 /* translators: %s flow id */
364 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
365 );
366
367 wp_send_json( $result );
368 }
369
370 /**
371 * Reorder step flow
372 *
373 * @since 1.0.0
374 *
375 * @return void
376 */
377 public function cartflows_reorder_flow_steps() {
378
379 check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
380
381 $flow_id = intval( $_POST['post_id'] );
382 $step_ids = array_map( 'intval', $_POST['step_ids'] );
383
384 $result = array(
385 'status' => false,
386 /* translators: %s flow id */
387 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
388 );
389
390 if ( ! $flow_id || ! is_array( $step_ids ) ) {
391 wp_send_json( $result );
392 }
393
394 $new_flow_steps = array();
395
396 foreach ( $step_ids as $index => $step_id ) {
397
398 $new_flow_steps[] = array(
399 'id' => intval( $step_id ),
400 'title' => get_the_title( $step_id ),
401 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
402 );
403 }
404
405 update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
406
407 $result = array(
408 'status' => true,
409 /* translators: %s flow id */
410 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
411 );
412
413 wp_send_json( $result );
414 }
415
416
417 /**
418 * Load admin scripts
419 *
420 * @since 1.0.0
421 *
422 * @return void
423 */
424 public function admin_scripts() {
425
426 global $pagenow;
427 global $post;
428
429 $screen = get_current_screen();
430
431 if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
432
433 wp_enqueue_script(
434 'wcf-flow-meta',
435 CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
436 array( 'jquery', 'jquery-ui-sortable' ),
437 CARTFLOWS_VER,
438 true
439 );
440
441 wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
442 wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
443
444 $localize = array(
445 'ajax_url' => admin_url( 'admin-ajax.php' ),
446 );
447
448 wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
449 }
450 }
451
452 /**
453 * Initialize meta box
454 *
455 * @since 1.0.0
456 *
457 * @return void
458 */
459 public function init_metabox() {
460
461 /**
462 * Fires after the title field.
463 *
464 * @param WP_Post $post Post object.
465 */
466 add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
467 add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
468 add_action( 'save_post', array( $this, 'save_meta_box' ) );
469 }
470
471 /**
472 * Is first time import?
473 *
474 * @param integer $post_id post ID.
475 * @return bool
476 */
477 function is_flow_imported( $post_id = 0 ) {
478
479 if ( 0 === $post_id ) {
480 $post_id = get_the_ID();
481 }
482
483 $steps = get_post_meta( $post_id, 'wcf-steps', true );
484 $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
485
486 if ( empty( $steps ) && 'import' === $choice ) {
487 return true;
488 }
489
490 return false;
491 }
492
493 /**
494 * Setup meta box.
495 *
496 * @return void
497 */
498 function setup_meta_box() {
499 if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
500 return;
501 }
502
503 /**
504 * Adding Add new step button to the top*/
505 echo $this->add_add_new_step_button();
506
507 $this->markup_meta_box();
508 }
509
510 /**
511 * Settings meta box.
512 *
513 * @return void
514 */
515 function settings_meta_box() {
516
517 if ( CARTFLOWS_FLOW_POST_TYPE == get_post_type() ) {
518
519 add_meta_box(
520 'wcf-sandbox-settings', // Id.
521 __( 'Flow Settings', 'cartflows' ), // Title.
522 array( $this, 'sandbox_meta_box' ), // Callback.
523 CARTFLOWS_FLOW_POST_TYPE, // Post_type.
524 'side', // Context.
525 'high' // Priority.
526 );
527
528 do_action( 'cartflows_add_flow_metabox' );
529 }
530 }
531
532 /**
533 * Metabox Markup
534 *
535 * @return void
536 */
537 function markup_meta_box() {
538 global $post;
539
540 wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
541
542 // Get defaults.
543 $meta = self::get_current_post_meta( $post->ID );
544
545 /**
546 * Get options
547 */
548 $updated_data = array(
549 'steps' => $meta['wcf-steps']['default'],
550 );
551
552 do_action( 'wcf_flow_settings_markup_before', $meta );
553 $this->page_header_tab( $updated_data );
554 do_action( 'wcf_flow_settings_markup_after', $meta );
555 }
556
557 /**
558 * Metabox Markup
559 *
560 * @param object $post Post object.
561 * @return void
562 */
563 function sandbox_meta_box( $post ) {
564
565 // Get defaults.
566 $meta = self::get_current_post_meta( $post->ID );
567
568 /**
569 * Get options
570 */
571 foreach ( $meta as $key => $value ) {
572 $updated_data[ $key ] = $meta[ $key ]['default'];
573 }
574
575 do_action( 'wcf_flow_sandbox_markup_before', $meta );
576 $this->sandbox_markup( $updated_data );
577 do_action( 'wcf_flow_sandbox_markup_after', $meta );
578 }
579
580 /**
581 * Page Header Tabs
582 *
583 * @param array $options Post meta.
584 * @return void
585 */
586 function page_header_tab( $options ) {
587
588 include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
589 }
590
591 /**
592 * Sandbox Markup
593 *
594 * @param array $options Post meta.
595 * @return void
596 */
597 function sandbox_markup( $options ) {
598 ?>
599 <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
600 <div class="wcf-flow-sandbox-table-container">
601 <?php
602 echo wcf()->meta->get_checkbox_field(
603 array(
604 'name' => 'wcf-testing',
605 'value' => $options['wcf-testing'],
606 'after' => __( 'Enable Test Mode', 'cartflows' ),
607 )
608 );
609
610 echo wcf()->meta->get_description_field(
611 array(
612 'name' => 'wcf-testing-note',
613 'content' => __( 'Test mode adds random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
614 )
615 );
616
617 ?>
618 </div>
619 </div>
620 <?php
621 }
622
623 /**
624 * Keep the menu open when editing the flows.
625 * Highlights the wanted admin (sub-) menu items for the CPT.
626 *
627 * @since 1.0.0
628 */
629 public function menu_highlight() {
630 global $parent_file, $submenu_file, $post_type;
631 if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
632 $parent_file = CARTFLOWS_SLUG;
633 $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;
634 endif;
635 }
636
637 /**
638 * Get metabox options
639 *
640 * @param int $post_id post id.
641 * @return array
642 */
643 public static function get_meta_option( $post_id ) {
644
645 if ( null === self::$meta_option ) {
646 /**
647 * Set metabox options
648 */
649 self::$meta_option = wcf()->options->get_flow_fields( $post_id );
650 }
651
652 return self::$meta_option;
653 }
654
655 /**
656 * Get metabox options
657 *
658 * @param int $post_id post ID.
659 * @return array
660 */
661 public static function get_current_post_meta( $post_id ) {
662
663 $stored = get_post_meta( $post_id );
664
665 $default_meta = self::get_meta_option( $post_id );
666
667 // Set stored and override defaults.
668 foreach ( $stored as $key => $value ) {
669 if ( array_key_exists( $key, $default_meta ) ) {
670 self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
671 } else {
672 self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
673 }
674 }
675
676 return self::get_meta_option( $post_id );
677 }
678
679 /**
680 * Metabox Save
681 *
682 * @param number $post_id Post ID.
683 * @return void
684 */
685 function save_meta_box( $post_id ) {
686
687 // Checks save status.
688 $is_autosave = wp_is_post_autosave( $post_id );
689 $is_revision = wp_is_post_revision( $post_id );
690
691 $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( $_POST['nonce-flow-meta'], 'save-nonce-flow-meta' ) ) ? true : false;
692
693 // Exits script depending on save status.
694 if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
695 return;
696 }
697
698 wcf()->options->save_flow_fields( $post_id );
699 }
700
701 /**
702 * Localize variables in admin
703 *
704 * @param array $vars variables.
705 */
706 function localize_vars( $vars ) {
707
708 $ajax_actions = array(
709 'wcf_setup_default_steps',
710 'wcf_add_flow_step',
711 'wcf_delete_flow_step',
712 'wcf_reorder_flow_steps',
713 );
714
715 foreach ( $ajax_actions as $action ) {
716
717 $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
718 }
719
720 return $vars;
721 }
722
723 /**
724 * Add New Step Button
725 *
726 * @return string
727 */
728 function add_add_new_step_button() {
729 $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
730 $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
731 $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
732 $add_new_btn_markup .= esc_html( 'Add New Step', 'cartflows' );
733 $add_new_btn_markup .= '</button>';
734 $add_new_btn_markup .= '</div>';
735
736 return $add_new_btn_markup;
737 }
738 }
739
740 /**
741 * Kicking this off by calling 'get_instance()' method
742 */
743 Cartflows_Flow_Meta::get_instance();
744