PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.2.9
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.2.9
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 / admin / class-steps.php

class-steps.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 1.2.9, at includes/admin/class-steps.php

403 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 defined( 'ABSPATH' ) || die();
4
5 /**
6 * Steps class.
7 *
8 * @since 1.1.0
9 */
10 class Sellkit_Admin_Steps {
11
12 /**
13 * Class instance.
14 *
15 * @since 1.1.0
16 * @var Sellkit_Admin_Steps
17 */
18 private static $instance = null;
19
20 /**
21 * Class instance.
22 *
23 * @since 1.1.0
24 * @var string
25 */
26 const SELLKIT_STEP_POST_TYPE = 'sellkit_step';
27
28 /**
29 * Get a class instance.
30 *
31 * @since 1.1.0
32 *
33 * @return Sellkit_Admin_Steps Class instance.
34 */
35 public static function get_instance() {
36 if ( null === self::$instance ) {
37 self::$instance = new self();
38 }
39
40 return self::$instance;
41 }
42
43 /**
44 * Class constructor.
45 *
46 * @since 1.1.0
47 */
48 public function __construct() {
49 $this->register_step_post_type();
50
51 add_action( 'wp_ajax_sellkit_steps_get_products', [ $this, 'get_products' ] );
52 add_action( 'wp_ajax_sellkit_steps_get_products_data', [ $this, 'get_products_data' ] );
53 add_action( 'sellkit_funnels_after_create_new_step', [ $this, 'after_create_step_callback' ], 10 );
54 add_action( 'sellkit_funnels_after_edit_step_name_slug', [ $this, 'edit_step_name_and_slug' ], 10 );
55 add_action( 'sellkit_funnels_after_delete_step_post', [ $this, 'delete_related_page' ], 10 );
56 add_action( 'sellkit_funnels_update_steps', [ $this, 'save_steps_data' ], 10, 2 );
57 add_filter( 'template_include', [ $this, 'load_page_template' ], 10 );
58 add_action( 'wp_ajax_sellkit_steps_get_coupons', [ $this, 'get_coupons' ] );
59 add_action( 'wp_loaded', [ $this, 'sellkit_steps_flush_rules' ] );
60 add_action( 'sellkit_after_toggle_status_sellkit-funnels', [ $this, 'update_steps_post_status' ], 10, 2 );
61 }
62
63 /**
64 * Get default funnels.
65 *
66 * @since 1.1.0
67 */
68 public static function get_default_funnel_steps() {
69 return [
70 'sales-page' => esc_html__( 'Sales Page', 'sellkit' ),
71 'checkout' => esc_html__( 'Checkout', 'sellkit' ),
72 'thankyou' => esc_html__( 'Thank You', 'sellkit' ),
73 'upsell' => esc_html__( 'Upsell', 'sellkit' ),
74 ];
75 }
76
77 /**
78 * Save_steps_data.
79 *
80 * @since 1.1.0
81 * @param array $steps Steps.
82 * @param int $funnel_id Funnel Id.
83 */
84 public static function save_steps_data( $steps, $funnel_id ) {
85 foreach ( $steps as $step_number => $step ) {
86 $step['funnel_id'] = $funnel_id;
87 $step['number'] = $step_number;
88
89 update_post_meta( $step['page_id'], 'step_data', $step );
90 }
91 }
92
93 /**
94 * Get all coupons.
95 *
96 * @since 1.1.0
97 */
98 public static function get_coupons() {
99 check_ajax_referer( 'sellkit', 'nonce' );
100
101 $input_value = sellkit_htmlspecialchars( INPUT_GET, 'input_value' );
102
103 $filtered_products = [];
104 $args = [
105 'post_type' => 'shop_coupon',
106 'post_status' => 'any',
107 's' => $input_value,
108 ];
109
110 $query = new WP_Query( $args );
111
112 if ( $query->have_posts() ) {
113 while ( $query->have_posts() ) {
114 $query->the_post();
115 $filtered_products[] = [
116 'label' => htmlspecialchars_decode( get_the_title() ),
117 'value' => get_the_ID(),
118 ];
119 }
120 }
121
122 wp_send_json_success( $filtered_products );
123 }
124
125 /**
126 * Get products.
127 *
128 * @since 1.1.0
129 */
130 public static function get_products() {
131 check_ajax_referer( 'sellkit', 'nonce' );
132
133 $input_value = sellkit_htmlspecialchars( INPUT_GET, 'input_value' );
134
135 $filtered_products = [];
136
137 $args = [
138 'status' => 'any',
139 'orderby' => 'name',
140 'order' => 'ASC',
141 's' => $input_value,
142 'posts_per_page' => -1,
143 ];
144
145 $all_products = wc_get_products( $args );
146
147 foreach ( $all_products as $product ) {
148 if ( $product->get_type() !== 'variable' ) {
149 $filtered_products[] = [
150 'label' => $product->get_title(),
151 'value' => $product->get_id(),
152 ];
153 }
154
155 if ( $product->get_type() === 'variable' ) {
156 foreach ( $product->get_available_variations() as $available_variation ) {
157 $attributes = $available_variation['attributes'];
158 $attributes = implode( ', ', array_values( $attributes ) );
159
160 $filtered_products[] = [
161 'label' => "{$product->get_title()} - {$attributes} (#{$available_variation['variation_id']})",
162 'value' => $available_variation['variation_id'],
163 ];
164 }
165 }
166 }
167
168 wp_send_json_success( $filtered_products );
169 }
170
171 /**
172 * Get products.
173 *
174 * @since 1.1.0
175 */
176 public static function get_products_data() {
177 check_ajax_referer( 'sellkit', 'nonce' );
178
179 $filtered_products = [];
180 $products_id = filter_input( INPUT_GET, 'products_id', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
181
182 if ( empty( $products_id ) ) {
183 wp_send_json_error( __( 'Please send some product ids' ) );
184 }
185
186 $products_id = is_array( $products_id ) ? $products_id : [ $products_id ];
187
188 foreach ( $products_id as $product_id ) {
189 $product = wc_get_product( $product_id );
190
191 if ( empty( $product ) ) {
192 wp_send_json_error( __( 'Product does not exist', 'sellkit' ) );
193 continue;
194 }
195
196 $attributes = $product->get_attributes();
197 $label = $product->get_title();
198
199 if ( $product->get_type() === 'variation' ) {
200 $attributes = implode( ', ', array_values( $attributes ) );
201 $label = "{$product->get_title()} - $attributes (#{$product->get_id()})";
202 }
203
204 $filtered_products[] = [
205 'label' => $label,
206 'id' => $product->get_id(),
207 'title' => $label,
208 'thumbnail' => $product->get_image(),
209 'regular_price' => $product->get_regular_price( 'edit' ),
210 'sale_price' => ( $product->is_on_sale() ) ? $product->get_sale_price() : false,
211 ];
212 }
213
214 wp_send_json_success( $filtered_products );
215 }
216
217 /**
218 * Filter step data before saving.
219 *
220 * @since 1.1.0
221 * @param string $post_id Post id.
222 */
223 public function after_create_step_callback( $post_id ) {
224 $steps = get_post_meta( $post_id, 'sellkit_steps', true );
225 $last_step = end( $steps );
226
227 array_pop( $steps );
228
229 $new_step_id = wp_insert_post( [
230 'post_type' => self::SELLKIT_STEP_POST_TYPE,
231 'post_title' => $last_step['title'],
232 'post_name' => sanitize_title( $last_step['title'] ),
233 'post_status' => 'publish',
234 ] );
235
236 $last_step['page_id'] = $new_step_id;
237 $last_step['slug'] = get_post_field( 'post_name', $new_step_id );
238
239 $step_data = $last_step;
240 $step_data['funnel_id'] = $post_id;
241 $step_data['number'] = count( $steps );
242
243 update_post_meta( $new_step_id, 'step_data', $step_data );
244
245 $new_steps = array_merge( $steps, [ $last_step ] );
246
247 update_post_meta( $post_id, 'sellkit_steps', $new_steps );
248 }
249
250 /**
251 * Loading page templates.
252 *
253 * @since 1.1.0
254 * @param string $template Template name.
255 */
256 public function load_page_template( $template ) {
257
258 global $post;
259
260 if ( 'string' !== gettype( $template ) || ! is_object( $post ) || self::SELLKIT_STEP_POST_TYPE !== $post->post_type ) {
261 return $template;
262 }
263
264 remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head' );
265 add_filter( 'next_post_rel_link', '__return_empty_string' );
266 add_filter( 'previous_post_rel_link', '__return_empty_string' );
267
268 $file = sellkit()->plugin_dir() . 'includes/templates/canvas.php';
269
270 if ( ! file_exists( $template ) ) {
271 return $template;
272 }
273
274 return $file;
275 }
276
277 /**
278 * Register step post type.
279 *
280 * @since 1.1.0
281 */
282 public function register_step_post_type() {
283 $labels = array(
284 'name' => esc_html_x( 'Steps', 'flow step general name', 'sellkit' ),
285 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'sellkit' ),
286 'search_items' => esc_html__( 'Search Steps', 'sellkit' ),
287 'all_items' => esc_html__( 'All Steps', 'sellkit' ),
288 'edit_item' => esc_html__( 'Edit Step', 'sellkit' ),
289 'view_item' => esc_html__( 'View Step', 'sellkit' ),
290 'add_new' => esc_html__( 'Add New', 'sellkit' ),
291 'update_item' => esc_html__( 'Update Step', 'sellkit' ),
292 'add_new_item' => esc_html__( 'Add New', 'sellkit' ),
293 'new_item_name' => esc_html__( 'New Step Name', 'sellkit' ),
294 );
295
296 $args = array(
297 'labels' => $labels,
298 'public' => true,
299 'query_var' => true,
300 'can_export' => true,
301 'exclude_from_search' => true,
302 'show_ui' => true,
303 'show_in_menu' => false,
304 'show_in_admin_bar' => true,
305 'show_in_rest' => true,
306 'publicly_queryable' => true,
307 'supports' => [ 'title', 'editor', 'elementor', 'revisions' ],
308 'capability_type' => 'post',
309 'capabilities' => [
310 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
311 ],
312 'map_meta_cap' => true,
313 );
314
315 register_post_type( self::SELLKIT_STEP_POST_TYPE, $args );
316 }
317
318 /**
319 * Edit step name or slug.
320 *
321 * @since 1.1.0
322 * @param string $funnel_id Funnel Id.
323 */
324 public function edit_step_name_and_slug( $funnel_id ) {
325 $sub_action_data = sellkit_post( 'sub_action_data' );
326 $title = ! empty( $sub_action_data['title'] ) ? $sub_action_data['title'] : '';
327 $slug = ! empty( $sub_action_data['slug'] ) ? $sub_action_data['slug'] : sanitize_title( $title );
328 $page_id = ! empty( $sub_action_data['page_id'] ) ? $sub_action_data['page_id'] : '';
329 $selected_step = $sub_action_data['selected_step'];
330
331 if ( empty( $page_id ) ) {
332 return;
333 }
334
335 wp_update_post( [
336 'ID' => $page_id,
337 'post_title' => $title,
338 'post_name' => $slug,
339 ] );
340
341 if ( get_post_field( 'post_name', $page_id ) === $slug ) {
342 return;
343 }
344
345 $post_data = get_post_meta( $funnel_id, 'sellkit_steps', true );
346 $post_data[ $selected_step ]['slug'] = get_post_field( 'post_name', $page_id );
347
348 update_post_meta( $funnel_id, 'sellkit_steps', $post_data );
349 }
350
351 /**
352 * Delete step page id.
353 *
354 * @since 1.1.0
355 */
356 public function delete_related_page() {
357 $sub_action_data = sellkit_post( 'sub_action_data' );
358
359 if ( empty( $sub_action_data['page_id'] ) ) {
360 return;
361 }
362
363 wp_delete_post( $sub_action_data['page_id'], true );
364 }
365
366 /**
367 * Flash rules.
368 *
369 * @since 1.1.0
370 */
371 public function sellkit_steps_flush_rules() {
372 $rules = get_option( 'rewrite_rules' );
373
374 if ( ! isset( $rules['sellkit_step/[^/]+/([^/]+)/?$'] ) ) {
375 flush_rewrite_rules();
376 }
377 }
378
379 /**
380 * Make publish steps page.
381 *
382 * @since 1.1.0
383 * @param string $funnel_id Funnel Id.
384 * @param string $new_status Status.
385 */
386 public function update_steps_post_status( $funnel_id, $new_status ) {
387 $steps = get_post_meta( $funnel_id, 'sellkit_steps', true );
388
389 foreach ( $steps as $step ) {
390 if ( $step['page_id'] === $funnel_id ) {
391 continue;
392 }
393
394 wp_update_post(array(
395 'ID' => $step['page_id'],
396 'post_status' => $new_status,
397 ) );
398 }
399 }
400 }
401
402 Sellkit_Admin_Steps::get_instance();
403