PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.7.5
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.7.5
2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 1.8.1 All 42 releases
sellkit / includes / funnel / class.php

class.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 1.7.5, at includes/funnel/class.php

394 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Elementor\Utils as ElementorUtils;
4 use Sellkit\Global_Checkout\Checkout as Global_Checkout;
5
6 defined( 'ABSPATH' ) || die();
7
8 /**
9 * Class Sellkit_Funnel
10 *
11 * @since 1.1.0
12 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
13 * @SuppressWarnings(PHPMD.NPathComplexity)
14 */
15 class Sellkit_Funnel {
16
17 /**
18 * Funnel Id.
19 *
20 * @var integer Funnel Id.
21 * @since 1.1.0
22 */
23 public $funnel_id;
24
25 /**
26 * Next step data.
27 *
28 * @var array $next_step_data.
29 * @since 1.1.0
30 */
31 public $next_step_data;
32
33 /**
34 * Next no step data.
35 *
36 * @var array $next_no_step_data.
37 * @since 1.5.0
38 */
39 public $next_no_step_data;
40
41 /**
42 * Ending node step data.
43 *
44 * @var array $end_node_step_data.
45 * @since 1.5.0
46 */
47 public $end_node_step_data;
48
49 /**
50 * The current step data.
51 *
52 * @var array $current_step_data.
53 * @since 1.1.0
54 */
55 public $current_step_data;
56
57 /**
58 * The class instance.
59 *
60 * @var Object Class instance.
61 * @since 1.1.0
62 */
63 public static $instance = null;
64
65 /**
66 * Sellkit_Funnel constructor.
67 *
68 * @param string $page_id Page Id.
69 * @since 1.1.0
70 */
71 public function __construct( $page_id = null ) {
72 $this->order_customization();
73
74 if ( null === $page_id ) {
75 $page_id = self::get_page_id();
76 }
77
78 if ( empty( $page_id ) ) {
79 return;
80 }
81
82 $this->set_funnel_data( $page_id );
83
84 if ( empty( $this->funnel_id ) ) {
85 return;
86 }
87
88 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_funnel_frontend_script' ] );
89 }
90
91 /**
92 * Class Instance.
93 *
94 * @since 1.1.0
95 * @return Sellkit_Funnel|null
96 */
97 public static function get_instance() {
98 if ( null === self::$instance ) {
99 self::$instance = new self();
100 }
101
102 return self::$instance;
103 }
104
105 /**
106 * Gets funnel if the page is step otherwise do nothing.
107 *
108 * @since 1.1.0
109 * @return void
110 * @param string $page_id Page id.
111 */
112 public function set_funnel_data( $page_id ) {
113 $this->current_step_data = get_post_meta( $page_id, 'step_data', true );
114
115 if ( empty( $this->current_step_data['funnel_id'] ) ) {
116 return;
117 }
118
119 $is_nofollow = sellkit_get_option( 'disallow_funnels_from_search_engine' );
120
121 if ( true === (bool) $is_nofollow ) {
122 add_action( 'wp_head', function () {
123 echo '<meta name="robots" content="noindex" />';
124 } );
125 }
126
127 $funnel_data = (array) get_post_meta( $this->current_step_data['funnel_id'], 'nodes', true );
128 $is_flowchart = true;
129
130 if ( empty( $funnel_data ) ) {
131 $funnel_data = get_post_meta( $this->current_step_data['funnel_id'], 'sellkit_steps', true );
132 $is_flowchart = false;
133 }
134
135 $this->funnel_id = $this->current_step_data['funnel_id'];
136
137 if ( false === $is_flowchart ) {
138 $this->next_step_data = ! empty( $funnel_data[ $this->current_step_data['number'] + 1 ] ) ? $funnel_data[ $this->current_step_data['number'] + 1 ] : false;
139 }
140
141 if (
142 true === $is_flowchart &&
143 ! empty( $this->current_step_data['targets'] ) &&
144 ! empty( $funnel_data[ $this->current_step_data['targets'][0]['nodeId'] ] )
145 ) {
146 $this->next_step_data = 'none' !== $funnel_data[ $this->current_step_data['targets'][0]['nodeId'] ] ? $funnel_data[ $this->current_step_data['targets'][0]['nodeId'] ] : false;
147 }
148
149 if ( true === $is_flowchart && ! empty( $this->current_step_data['targets'][1]['nodeId'] ) ) {
150 $this->next_no_step_data = ! empty( $funnel_data[ $this->current_step_data['targets'][1]['nodeId'] ] ) ? $funnel_data[ $this->current_step_data['targets'][1]['nodeId'] ] : false;
151 }
152
153 $end_node_id = $this->get_end_node_id( $funnel_data );
154
155 if ( ! empty( $end_node_id ) ) {
156 $this->end_node_step_data = $funnel_data[ $end_node_id ];
157 }
158 }
159
160 /**
161 * Enqueue funnel frontend scripts.
162 *
163 * @since 1.1.0
164 * @return void
165 */
166 public function enqueue_funnel_frontend_script() {
167 $suffix = defined( 'WP_DEBUG' ) && WP_DEBUG ? '' : '.min';
168
169 wp_enqueue_script(
170 'funnel-frontend',
171 sellkit()->plugin_url() . 'assets/dist/js/funnel-frontend' . $suffix . '.js',
172 [ 'jquery', 'wp-util' ],
173 sellkit()->version(),
174 true
175 );
176
177 wp_localize_script( 'funnel-frontend', 'funnel', $this->get_localize_data() );
178
179 if ( empty( sellkit_get_option( 'google_analytics' ) ) && empty( sellkit_get_option( 'facebook_pixel' ) ) ) {
180 return;
181 }
182
183 wp_enqueue_script(
184 'funnel-settings-variables',
185 sellkit()->plugin_url() . 'assets/dist/js/funnel-settings-variables' . $suffix . '.js',
186 [ 'jquery', 'wp-util' ],
187 sellkit()->version(),
188 true
189 );
190 }
191
192 /**
193 * Get localize data.
194 *
195 * @return array
196 */
197 public function get_localize_data() {
198 if ( ! empty( $this->next_step_data['page_id'] ) ) {
199 $next_step_link = add_query_arg( [
200 'post_type' => Sellkit_Admin_Steps::SELLKIT_STEP_POST_TYPE,
201 'p' => $this->next_step_data['page_id'],
202 ], site_url() );
203 }
204
205 return [
206 'currentStep' => $this->current_step_data,
207 'nextStep' => $this->next_step_data,
208 'nextStepLink' => ! empty( $next_step_link ) ? $next_step_link : '',
209 'siteUrl' => site_url(),
210 ];
211 }
212
213 /**
214 * Gets page id.
215 *
216 * @since 1.1.0
217 * @return false|int
218 * @SuppressWarnings(PHPMD.NPathComplexity)
219 */
220 public static function get_page_id() {
221 $page_id = sellkit_htmlspecialchars( INPUT_POST, 'sellkit_current_page_id' );
222 $preview = sellkit_htmlspecialchars( INPUT_GET, 'preview' );
223 $structure = get_option( 'permalink_structure' );
224 $post_data = filter_input( INPUT_POST, 'post_data', FILTER_DEFAULT );
225
226 if ( ! empty( $post_data ) ) {
227 parse_str( $post_data, $post_data );
228
229 if ( ! empty( $post_data['sellkit_current_page_id'] ) ) {
230 return (int) $post_data['sellkit_current_page_id'];
231 }
232 }
233
234 if ( ! empty( $preview ) ) {
235 return false;
236 }
237
238 if ( is_numeric( $page_id ) ) {
239 return $page_id;
240 }
241
242 $current_url = esc_url_raw( remove_query_arg( 'order-key' ) );
243
244 if ( ! empty( $structure ) ) {
245 $current_url = self::get_base_url( $current_url );
246 }
247
248 if ( empty( strpos( $current_url, 'sellkit_step' ) ) ) {
249 return false;
250 }
251
252 if ( empty( $current_url ) ) {
253 return false;
254 }
255
256 $page_id = sellkit_htmlspecialchars( INPUT_GET, 'p' );
257 $page_slug = sellkit_htmlspecialchars( INPUT_GET, 'sellkit_step' );
258 $page = get_page_by_path( basename( untrailingslashit( $current_url ) ), null, 'sellkit_step' );
259
260 if ( empty( $page ) && ! empty( $page_slug ) ) {
261 $page = get_page_by_path( sanitize_text_field( $page_slug ), null, 'sellkit_step' );
262 }
263
264 if ( empty( $page ) && empty( $page_id ) ) {
265 return false;
266 }
267
268 if ( ! empty( $page_id ) && 'sellkit_step' === get_post_type( $page_id ) ) {
269 return $page_id;
270 }
271
272 if ( empty( $page->ID ) ) {
273 return false;
274 }
275
276 return $page->ID;
277 }
278
279 /**
280 * Gets main url.
281 *
282 * @since 1.5.4
283 * @param string $url Url.
284 * @return string
285 */
286 private static function get_base_url( $url ) {
287 $parsed = wp_parse_url( $url );
288
289 if ( empty( $parsed['query'] ) ) {
290 return $url;
291 }
292
293 return explode( '?', $url )[0];
294 }
295
296 /**
297 * Customization order pages in admin area.
298 *
299 * @since 1.1.0
300 */
301 public function order_customization() {
302 if ( ! is_admin() ) {
303 return;
304 }
305
306 // Orders filters.
307 add_filter( 'woocommerce_get_formatted_order_total', [ $this, 'add_order_type' ], 10, 2 );
308 add_action( 'woocommerce_admin_order_data_after_order_details', [ $this, 'show_linked_orders' ], 10, 1 );
309 }
310
311 /**
312 * Adding order type to order list table.
313 *
314 * @since 1.1.0
315 * @return string
316 * @param string $formatted_total formatted total price.
317 * @param object $order Order object.
318 */
319 public function add_order_type( $formatted_total, $order ) {
320 $screen = get_current_screen();
321 $is_upsell = $order->get_meta( 'sellkit_main_order_id' );
322
323 if ( ! $screen || 'edit' !== $screen->base || 'shop_order' !== $screen->post_type ) {
324 return $formatted_total;
325 }
326
327 if ( is_numeric( $is_upsell ) ) {
328 $formatted_total .= '<div><span>' . esc_html__( 'Sellkit Upsell', 'sellkit' ) . '</span></div>';
329 }
330
331 return $formatted_total;
332 }
333
334 /**
335 * Show the related between orders.
336 *
337 * @since 1.1.0
338 * @param object $order Order object.
339 */
340 public function show_linked_orders( $order ) {
341 $upsell_order_id = $order->get_meta( 'sellkit_upsell_order_id' );
342 $main_order_id = $order->get_meta( 'sellkit_main_order_id' );
343
344 if ( is_numeric( $main_order_id ) ) {
345 $parent_order = wc_get_order( $main_order_id );
346 $order_number = $parent_order->get_order_number();
347 $parent_order_html = sprintf( '<p class="form-field form-field-wide" style= "margin-top: 20px;"><strong>%s: </strong>', esc_html__( 'SellKit Parent Order', 'sellkit' ) );
348 $parent_order_html .= sprintf( '<span style= "display: block;"><a href="%1s"><strong>#%2s</strong></a></span>', get_edit_post_link( $main_order_id ), esc_attr( $order_number ) );
349 $parent_order_html .= '</p>';
350 echo $parent_order_html;
351 }
352
353 if ( is_numeric( $upsell_order_id ) ) {
354 $upsell_order = wc_get_order( $upsell_order_id );
355 $order_number = $upsell_order->get_order_number();
356 $upsell_order_html = sprintf( '<p class="form-field form-field-wide" style= "margin-top: 20px;"><strong>%s: </strong>', esc_html__( 'SellKit Upsell Order', 'sellkit' ) );
357 $upsell_order_html .= sprintf( '<span style= "display: block;"><a href="%1s"><strong>#%2s</strong></a></span>', get_edit_post_link( $upsell_order_id ), esc_attr( $order_number ) );
358 $upsell_order_html .= '</p>';
359 echo $upsell_order_html;
360 }
361 }
362
363 /**
364 * Gets end node.
365 *
366 * @since 1.5.0
367 * @param array $funnels Funnels array.
368 */
369 public function get_end_node_id( $funnels ) {
370 $funnels = (array) $funnels;
371
372 foreach ( $funnels as $key => $funnel ) {
373 if ( ! empty( $funnel['origin_node'] ) && 'last-node' === $funnel['origin_node'] ) {
374 return $key;
375 }
376 }
377
378 return false;
379 }
380 }
381
382 if ( ! function_exists( 'sellkit_funnel' ) ) {
383 /**
384 * Sellkit funnel wrapper.
385 *
386 * @since 1.1.0
387 * @return Object|Sellkit_Funnel|null
388 */
389 function sellkit_funnel() {
390 return Sellkit_Funnel::get_instance();
391 }
392 }
393
394