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
← All changes | classes/class-cartflows-flow-frontend.php +360 -199 1.1.13 → 3.3.0 View file →
@@ -1,199 +1,360 @@
1 -<?php
2 -/**
3 - * Frontend & Markup
4 - *
5 - * @package CartFlows
6 - */
7 -
8 -/**
9 - * Flow Markup
10 - *
11 - * @since 1.0.0
12 - */
13 -class Cartflows_Flow_Frontend {
14 -
15 -
16 - /**
17 - * Member Variable
18 - *
19 - * @var object instance
20 - */
21 - private static $instance;
22 -
23 - /**
24 - * Initiator
25 - */
26 - public static function get_instance() {
27 - if ( ! isset( self::$instance ) ) {
28 - self::$instance = new self;
29 - }
30 - return self::$instance;
31 - }
32 -
33 - /**
34 - * Constructor
35 - */
36 - public function __construct() {
37 -
38 - /* Analytics */
39 - add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40 - }
41 -
42 - /**
43 - * Footer markup
44 - */
45 - function footer_markup() {
46 -
47 - if ( wcf()->utils->is_step_post_type() ) {
48 - // @codingStandardsIgnoreStart
49 - ?>
50 - <?php if( $this->is_flow_testmode() ) { ?>
51 - <div class="wcf-preview-mode">
52 - <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
53 - </div>
54 - <?php } ?>
55 - <?php
56 - // @codingStandardsIgnoreEnd
57 - }
58 - }
59 -
60 - /**
61 - * Check if flow test mode is enable.
62 - *
63 - * @since 1.0.0
64 - * @param int $flow_id flow ID.
65 - *
66 - * @return boolean
67 - */
68 - function is_flow_testmode( $flow_id = '' ) {
69 -
70 - if ( ! $flow_id ) {
71 - $flow_id = wcf()->utils->get_flow_id();
72 - }
73 -
74 - $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
75 -
76 - if ( 'no' === $test_mode ) {
77 - return false;
78 - }
79 -
80 - return true;
81 - }
82 -
83 - /**
84 - * Get steps data.
85 - *
86 - * @since 1.0.0
87 - * @param int $flow_id flow ID.
88 - *
89 - * @return array
90 - */
91 - function get_steps( $flow_id ) {
92 -
93 - $steps = get_post_meta( $flow_id, 'wcf-steps', true );
94 -
95 - if ( ! is_array( $steps ) ) {
96 -
97 - $steps = array();
98 - }
99 -
100 - return $steps;
101 - }
102 -
103 - /**
104 - * Check thank you page exists.
105 - *
106 - * @since 1.0.0
107 - * @param array $order order data.
108 - *
109 - * @return bool
110 - */
111 - function is_thankyou_page_exists( $order ) {
112 -
113 - $thankyou_step_exist = false;
114 -
115 - $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
116 -
117 - if ( $flow_id ) {
118 -
119 - $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
120 - $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
121 -
122 - if ( is_array( $flow_steps ) ) {
123 -
124 - $current_step_found = false;
125 -
126 - foreach ( $flow_steps as $index => $data ) {
127 -
128 - if ( $current_step_found ) {
129 -
130 - if ( 'thankyou' === $data['type'] ) {
131 -
132 - $thankyou_step_exist = true;
133 - break;
134 - }
135 - } else {
136 -
137 - if ( intval( $data['id'] ) === $step_id ) {
138 -
139 - $current_step_found = true;
140 - }
141 - }
142 - }
143 - }
144 - }
145 -
146 - return $thankyou_step_exist;
147 - }
148 -
149 - /**
150 - * Check thank you page exists.
151 - *
152 - * @since 1.0.0
153 - * @param array $order order data.
154 - *
155 - * @return bool
156 - */
157 - function get_thankyou_page_id( $order ) {
158 -
159 - $thankyou_step_id = false;
160 -
161 - $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
162 -
163 - if ( $flow_id ) {
164 -
165 - $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
166 - $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
167 -
168 - if ( is_array( $flow_steps ) ) {
169 -
170 - $current_step_found = false;
171 -
172 - foreach ( $flow_steps as $index => $data ) {
173 -
174 - if ( $current_step_found ) {
175 -
176 - if ( 'thankyou' === $data['type'] ) {
177 -
178 - $thankyou_step_id = intval( $data['id'] );
179 - break;
180 - }
181 - } else {
182 -
183 - if ( intval( $data['id'] ) === $step_id ) {
184 -
185 - $current_step_found = true;
186 - }
187 - }
188 - }
189 - }
190 - }
191 -
192 - return $thankyou_step_id;
193 - }
194 -}
195 -
196 -/**
197 - * Kicking this off by calling 'get_instance()' method
198 - */
199 -Cartflows_Flow_Frontend::get_instance();
1 +<?php
2 +/**
3 + * Frontend & Markup
4 + *
5 + * @package CartFlows
6 + */
7 +
8 +// Exit if accessed directly.
9 +if ( ! defined( 'ABSPATH' ) ) {
10 + exit;
11 +}
12 +/**
13 + * Flow Markup
14 + *
15 + * @since 1.0.0
16 + */
17 +class Cartflows_Flow_Frontend {
18 +
19 +
20 + /**
21 + * Member Variable
22 + *
23 + * @var object instance
24 + */
25 + private static $instance;
26 +
27 + /**
28 + * Initiator
29 + */
30 + public static function get_instance() {
31 + if ( ! isset( self::$instance ) ) {
32 + self::$instance = new self();
33 + }
34 + return self::$instance;
35 + }
36 +
37 + /**
38 + * Constructor
39 + */
40 + public function __construct() {
41 +
42 + /* Analytics */
43 + add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
44 + add_action( 'admin_bar_menu', array( $this, 'add_edit_flow_menu' ), 999 );
45 + add_action( 'admin_bar_menu', array( $this, 'update_edit_step_menu_link' ), 999 );
46 + add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_gcp_color_vars' ), 23 );
47 + }
48 +
49 +
50 +
51 + /**
52 + * Add a new admin bar menu to navigate to edit the flow.
53 + *
54 + * @param object $admin_bar The object of admin bar.
55 + * @return void
56 + */
57 + public function add_edit_flow_menu( $admin_bar ) {
58 +
59 + if ( wcf()->utils->is_step_post_type() ) {
60 + $flow_id = wcf()->utils->get_flow_id();
61 +
62 + if ( ! empty( $flow_id ) ) {
63 +
64 + $path = Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' ) === $flow_id ? 'store-checkout' : 'flows';
65 +
66 + $admin_bar->add_node(
67 + array(
68 + 'id' => 'edit-flow',
69 + 'title' => '<span class="ab-icon dashicons dashicons-edit"></span>' . esc_html__( 'Edit Funnel', 'cartflows' ),
70 + 'href' => admin_url( 'admin.php?page=cartflows&path=' . $path . '&action=wcf-edit-flow&flow_id=' . $flow_id ),
71 + 'meta' => array(
72 + 'class' => 'wcf-admin_bar-edit_flow--menu',
73 + ),
74 + )
75 + );
76 + }
77 + }
78 + }
79 +
80 + /**
81 + * Footer markup
82 + */
83 + public function footer_markup() {
84 +
85 + // Keep onboarding template previews aspirational — no admin notices inside the iframe.
86 + if ( isset( $_GET['wcf-load-onboarding-iframe'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
87 + return;
88 + }
89 +
90 + if ( wcf()->utils->is_step_post_type() ) {
91 + $flow_id = wcf()->utils->get_flow_id();
92 +
93 + $default_strings = array(
94 + 'message' => __( 'Test mode is currently enabled to help you preview your funnel. You can turn it off anytime from the funnel\'s settings in the admin dashboard.', 'cartflows' ),
95 + 'link_text' => __( 'Click here to disable it.', 'cartflows' ),
96 + );
97 +
98 + $test_mode_strings = array_merge(
99 + $default_strings,
100 + // Make sure that if empty strings are sent, then assign the default strings.
101 + array_filter(
102 + apply_filters( 'cartflows_test_mode_strings', $default_strings )
103 + )
104 + );
105 +
106 + ?>
107 + <?php if ( $this->is_flow_testmode( $flow_id ) ) { ?>
108 + <div class="wcf-preview-mode">
109 + <span><?php echo esc_html( $test_mode_strings['message'] ); ?></span>
110 + <?php if ( current_user_can( 'cartflows_manage_flows_steps' ) ) { ?>
111 + <?php
112 + $path = Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' ) === $flow_id ? 'store-checkout' : 'flows';
113 + $flow_edit_link = admin_url( 'admin.php?page=cartflows&path=' . $path . '&action=wcf-edit-flow&flow_id=' . $flow_id );
114 + ?>
115 + <a href="<?php echo esc_url( $flow_edit_link ); ?>"><?php echo esc_html( $test_mode_strings['link_text'] ); ?></a>
116 + <?php } ?>
117 + </div>
118 + <?php } ?>
119 + <?php
120 + }
121 + }
122 +
123 + /**
124 + * Check if flow test mode is enable.
125 + *
126 + * @since 1.0.0
127 + * @param int $flow_id flow ID.
128 + *
129 + * @return boolean
130 + */
131 + public function is_flow_testmode( $flow_id = '' ) {
132 +
133 + if ( ! $flow_id ) {
134 + $flow_id = wcf()->utils->get_flow_id();
135 + }
136 +
137 + $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
138 +
139 + if ( 'yes' === $test_mode ) {
140 + return true;
141 + }
142 +
143 + return false;
144 + }
145 +
146 + /**
147 + * Get steps data.
148 + *
149 + * @since 1.0.0
150 + * @param int $flow_id flow ID.
151 + *
152 + * @return array
153 + */
154 + public function get_steps( $flow_id ) {
155 +
156 + $steps = get_post_meta( $flow_id, 'wcf-steps', true );
157 +
158 + if ( ! is_array( $steps ) ) {
159 +
160 + $steps = array();
161 + }
162 +
163 + return $steps;
164 + }
165 +
166 + /**
167 + * Check thank you page exists.
168 + *
169 + * @since 1.0.0
170 + * @param array $order order data.
171 + *
172 + * @return bool
173 + */
174 + public function is_thankyou_page_exists( $order ) {
175 +
176 + $thankyou_step_exist = false;
177 +
178 + $flow_id = wcf()->utils->get_flow_id_from_order( $order );
179 +
180 + if ( $flow_id ) {
181 +
182 + $step_id = wcf()->utils->get_checkout_id_from_order( $order );
183 +
184 + // Get control step and flow steps.
185 + $wcf_step_obj = wcf_get_step( $step_id );
186 + $flow_steps = $wcf_step_obj->get_flow_steps();
187 + $control_step = $wcf_step_obj->get_control_step();
188 +
189 + if ( is_array( $flow_steps ) ) {
190 +
191 + $current_step_found = false;
192 +
193 + foreach ( $flow_steps as $index => $data ) {
194 +
195 + if ( $current_step_found ) {
196 +
197 + if ( 'thankyou' === $data['type'] ) {
198 +
199 + $thankyou_step_exist = true;
200 + break;
201 + }
202 + } elseif ( intval( $data['id'] ) === $control_step ) {
203 +
204 +
205 + $current_step_found = true;
206 + }
207 + }
208 + }
209 + }
210 +
211 + return $thankyou_step_exist;
212 + }
213 +
214 + /**
215 + * Check thank you page exists.
216 + *
217 + * @since 1.0.0
218 + * @param array $order order data.
219 + *
220 + * @return bool
221 + */
222 + public function get_thankyou_page_id( $order ) {
223 +
224 + $thankyou_step_id = false;
225 +
226 + $flow_id = wcf()->utils->get_flow_id_from_order( $order );
227 +
228 + if ( $flow_id ) {
229 +
230 + $step_id = wcf()->utils->get_checkout_id_from_order( $order );
231 +
232 + // Get control step and flow steps.
233 + $wcf_step_obj = wcf_get_step( $step_id );
234 + $flow_steps = $wcf_step_obj->get_flow_steps();
235 + $control_step = $wcf_step_obj->get_control_step();
236 +
237 + if ( is_array( $flow_steps ) ) {
238 +
239 + $current_step_found = false;
240 +
241 + foreach ( $flow_steps as $index => $data ) {
242 +
243 + if ( $current_step_found ) {
244 +
245 + if ( 'thankyou' === $data['type'] ) {
246 +
247 + $thankyou_step_id = intval( $data['id'] );
248 + break;
249 + }
250 + } elseif ( intval( $data['id'] ) === $control_step ) {
251 +
252 +
253 + $current_step_found = true;
254 + }
255 + }
256 + }
257 + }
258 +
259 + return $thankyou_step_id;
260 + }
261 +
262 + /**
263 + * Update the CartFlows steps link as per the latest UI.
264 + *
265 + * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar object.
266 + * @since 2.0.0
267 + */
268 + public function update_edit_step_menu_link( $wp_admin_bar ) {
269 +
270 + if ( wcf()->utils->is_step_post_type() ) {
271 +
272 + global $post;
273 +
274 + if ( ! empty( $post ) ) {
275 +
276 + $edit_node = $wp_admin_bar->get_node( 'edit' );
277 +
278 + if ( $edit_node ) {
279 + $post_id = $post->ID;
280 + $flow_id = wcf()->utils->get_flow_id_from_step_id( $post_id );
281 +
282 + // Show the edit node only if the page builder option is set to other and gutenberg, else remove/hide the node.
283 + if ( in_array( Cartflows_Helper::get_common_setting( 'default_page_builder' ), array( 'other', 'gutenberg' ) ) || Cartflows_Helper::is_instant_layout_enabled( intval( $flow_id ) ) ) {
284 + $edit_node->title = esc_html__( 'Edit Design', 'cartflows' );
285 + $edit_node->href = $this->get_prepared_edit_step_url( $post->ID );
286 + $wp_admin_bar->add_node( $edit_node );
287 + } else {
288 + $wp_admin_bar->remove_node( 'edit' );
289 + }
290 + }
291 + }
292 + }
293 + }
294 +
295 + /**
296 + * Enqueue the Global Color Pallet CSS vars to the page to use in the page builder settings.
297 + *
298 + * Note: Currently the GCP support is added for Elementor and Block Builder.
299 + *
300 + * @param string $css_dependency the CSS file handle as a dependency to add the inline css.
301 + * @since 2.0.0
302 + * @return void
303 + */
304 + public function enqueue_gcp_color_vars( $css_dependency = '' ) {
305 +
306 + if ( wcf()->utils->is_step_post_type() ) {
307 +
308 + $flow_id = wcf()->utils->get_flow_id();
309 +
310 + // Return if no flow ID is found.
311 + if ( empty( $flow_id ) ) {
312 + return;
313 + }
314 +
315 + if ( ! Cartflows_Helper::is_gcp_styling_enabled( (int) $flow_id ) ) {
316 + return;
317 + }
318 +
319 + $gcp_vars = Cartflows_Helper::generate_gcp_css_style( (int) $flow_id );
320 + $css_dependency = ! empty( $css_dependency ) ? $css_dependency : 'wcf-frontend-global';
321 +
322 + // Don't print the inline CSS style if no style is generated.
323 + if ( ! empty( $gcp_vars ) ) {
324 + $output = ':root { ' . $gcp_vars . ' }';
325 + wp_add_inline_style( $css_dependency, $output );
326 + }
327 + }
328 + }
329 +
330 + /**
331 + * Generates the edit URL for a step based on the page builder and Instant Checkout features.
332 + *
333 + * @since 2.1.0
334 + * @param int $step_id The ID of the step to generate the edit URL for.
335 + * @return string $edit_url The edit URL for the specified step.
336 + */
337 + public function get_prepared_edit_step_url( $step_id ) {
338 + // Default Edit Step URL.
339 + $edit_url = Cartflows_Helper::get_page_builder_edit_link( $step_id );
340 +
341 + // Get the current flow ID from the step.
342 + $flow_id = (int) wcf()->utils->get_flow_id_from_step_id( $step_id );
343 +
344 + // Update the edit URL if instant Checkout is enabled.
345 + if ( Cartflows_Helper::is_instant_layout_enabled( (int) $flow_id ) ) {
346 + $store_checkout = Cartflows_Helper::get_global_setting( '_cartflows_store_checkout' );
347 + $store_checkout_path = intval( $store_checkout ) === intval( $flow_id ) ? 'store-checkout' : 'flows';
348 +
349 + $edit_url = admin_url( 'admin.php?page=' . CARTFLOWS_SLUG . '&path=' . $store_checkout_path . '&action=wcf-edit-flow&flow_id=' . $flow_id . '&step_id=' . $step_id . '&tab=design' );
350 + }
351 +
352 + // Return the updated edit URL.
353 + return $edit_url;
354 + }
355 +}
356 +
357 +/**
358 + * Kicking this off by calling 'get_instance()' method
359 + */
360 +Cartflows_Flow_Frontend::get_instance();