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

411 lines 10.6 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 if ( ! sellkit()->has_valid_dependencies() ) {
136 wp_send_json_error( __( 'Please install and activate WooCommerce.', 'sellkit' ) );
137 }
138
139 $filtered_products = [];
140
141 $args = [
142 'status' => 'any',
143 'orderby' => 'name',
144 'order' => 'ASC',
145 's' => $input_value,
146 'posts_per_page' => -1,
147 ];
148
149 $all_products = wc_get_products( $args );
150
151 foreach ( $all_products as $product ) {
152 if ( $product->get_type() !== 'variable' && $product->get_type() !== 'external' ) {
153 $filtered_products[] = [
154 'label' => $product->get_title(),
155 'value' => $product->get_id(),
156 ];
157 }
158
159 if ( $product->get_type() === 'variable' ) {
160 foreach ( $product->get_available_variations() as $available_variation ) {
161 $attributes = $available_variation['attributes'];
162 $attributes = implode( ', ', array_values( $attributes ) );
163
164 $filtered_products[] = [
165 'label' => "{$product->get_title()} - {$attributes} (#{$available_variation['variation_id']})",
166 'value' => $available_variation['variation_id'],
167 ];
168 }
169 }
170 }
171
172 wp_send_json_success( $filtered_products );
173 }
174
175 /**
176 * Get products.
177 *
178 * @since 1.1.0
179 */
180 public static function get_products_data() {
181 check_ajax_referer( 'sellkit', 'nonce' );
182
183 $filtered_products = [];
184 $products_id = filter_input( INPUT_GET, 'products_id', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
185
186 if ( ! sellkit()->has_valid_dependencies() ) {
187 wp_send_json_error( __( 'Please install and activate WooCommerce.', 'sellkit' ) );
188 }
189
190 if ( empty( $products_id ) ) {
191 wp_send_json_error( __( 'Please send some product ids' ) );
192 }
193
194 $products_id = is_array( $products_id ) ? $products_id : [ $products_id ];
195
196 foreach ( $products_id as $product_id ) {
197 $product = wc_get_product( $product_id );
198
199 if ( empty( $product ) ) {
200 wp_send_json_error( __( 'Product does not exist', 'sellkit' ) );
201 continue;
202 }
203
204 $attributes = $product->get_attributes();
205 $label = $product->get_title();
206
207 if ( $product->get_type() === 'variation' ) {
208 $attributes = implode( ', ', array_values( $attributes ) );
209 $label = "{$product->get_title()} - $attributes (#{$product->get_id()})";
210 }
211
212 $filtered_products[] = [
213 'label' => $label,
214 'id' => $product->get_id(),
215 'title' => $label,
216 'thumbnail' => $product->get_image(),
217 'regular_price' => $product->get_regular_price( 'edit' ),
218 'sale_price' => ( $product->is_on_sale() ) ? $product->get_sale_price() : false,
219 ];
220 }
221
222 wp_send_json_success( $filtered_products );
223 }
224
225 /**
226 * Filter step data before saving.
227 *
228 * @since 1.1.0
229 * @param string $post_id Post id.
230 */
231 public function after_create_step_callback( $post_id ) {
232 $steps = get_post_meta( $post_id, 'sellkit_steps', true );
233 $last_step = end( $steps );
234
235 array_pop( $steps );
236
237 $new_step_id = wp_insert_post( [
238 'post_type' => self::SELLKIT_STEP_POST_TYPE,
239 'post_title' => $last_step['title'],
240 'post_name' => sanitize_title( $last_step['title'] ),
241 'post_status' => 'publish',
242 ] );
243
244 $last_step['page_id'] = $new_step_id;
245 $last_step['slug'] = get_post_field( 'post_name', $new_step_id );
246
247 $step_data = $last_step;
248 $step_data['funnel_id'] = $post_id;
249 $step_data['number'] = count( $steps );
250
251 update_post_meta( $new_step_id, 'step_data', $step_data );
252
253 $new_steps = array_merge( $steps, [ $last_step ] );
254
255 update_post_meta( $post_id, 'sellkit_steps', $new_steps );
256 }
257
258 /**
259 * Loading page templates.
260 *
261 * @since 1.1.0
262 * @param string $template Template name.
263 */
264 public function load_page_template( $template ) {
265
266 global $post;
267
268 if ( 'string' !== gettype( $template ) || ! is_object( $post ) || self::SELLKIT_STEP_POST_TYPE !== $post->post_type ) {
269 return $template;
270 }
271
272 remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head' );
273 add_filter( 'next_post_rel_link', '__return_empty_string' );
274 add_filter( 'previous_post_rel_link', '__return_empty_string' );
275
276 $file = sellkit()->plugin_dir() . 'includes/templates/canvas.php';
277
278 if ( ! file_exists( $template ) ) {
279 return $template;
280 }
281
282 return $file;
283 }
284
285 /**
286 * Register step post type.
287 *
288 * @since 1.1.0
289 */
290 public function register_step_post_type() {
291 $labels = array(
292 'name' => esc_html_x( 'Steps', 'flow step general name', 'sellkit' ),
293 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'sellkit' ),
294 'search_items' => esc_html__( 'Search Steps', 'sellkit' ),
295 'all_items' => esc_html__( 'All Steps', 'sellkit' ),
296 'edit_item' => esc_html__( 'Edit Step', 'sellkit' ),
297 'view_item' => esc_html__( 'View Step', 'sellkit' ),
298 'add_new' => esc_html__( 'Add New', 'sellkit' ),
299 'update_item' => esc_html__( 'Update Step', 'sellkit' ),
300 'add_new_item' => esc_html__( 'Add New', 'sellkit' ),
301 'new_item_name' => esc_html__( 'New Step Name', 'sellkit' ),
302 );
303
304 $args = array(
305 'labels' => $labels,
306 'public' => true,
307 'query_var' => true,
308 'can_export' => true,
309 'exclude_from_search' => true,
310 'show_ui' => true,
311 'show_in_menu' => false,
312 'show_in_admin_bar' => true,
313 'show_in_rest' => true,
314 'publicly_queryable' => true,
315 'supports' => [ 'title', 'editor', 'elementor', 'revisions' ],
316 'capability_type' => 'post',
317 'capabilities' => [
318 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
319 ],
320 'map_meta_cap' => true,
321 );
322
323 register_post_type( self::SELLKIT_STEP_POST_TYPE, $args );
324 }
325
326 /**
327 * Edit step name or slug.
328 *
329 * @since 1.1.0
330 * @param string $funnel_id Funnel Id.
331 */
332 public function edit_step_name_and_slug( $funnel_id ) {
333 $sub_action_data = sellkit_post( 'sub_action_data' );
334 $title = ! empty( $sub_action_data['title'] ) ? $sub_action_data['title'] : '';
335 $slug = ! empty( $sub_action_data['slug'] ) ? $sub_action_data['slug'] : sanitize_title( $title );
336 $page_id = ! empty( $sub_action_data['page_id'] ) ? $sub_action_data['page_id'] : '';
337 $selected_step = $sub_action_data['selected_step'];
338
339 if ( empty( $page_id ) ) {
340 return;
341 }
342
343 wp_update_post( [
344 'ID' => $page_id,
345 'post_title' => $title,
346 'post_name' => $slug,
347 ] );
348
349 if ( get_post_field( 'post_name', $page_id ) === $slug ) {
350 return;
351 }
352
353 $post_data = get_post_meta( $funnel_id, 'sellkit_steps', true );
354 $post_data[ $selected_step ]['slug'] = get_post_field( 'post_name', $page_id );
355
356 update_post_meta( $funnel_id, 'sellkit_steps', $post_data );
357 }
358
359 /**
360 * Delete step page id.
361 *
362 * @since 1.1.0
363 */
364 public function delete_related_page() {
365 $sub_action_data = sellkit_post( 'sub_action_data' );
366
367 if ( empty( $sub_action_data['page_id'] ) ) {
368 return;
369 }
370
371 wp_delete_post( $sub_action_data['page_id'], true );
372 }
373
374 /**
375 * Flash rules.
376 *
377 * @since 1.1.0
378 */
379 public function sellkit_steps_flush_rules() {
380 $rules = get_option( 'rewrite_rules' );
381
382 if ( ! isset( $rules['sellkit_step/[^/]+/([^/]+)/?$'] ) ) {
383 flush_rewrite_rules();
384 }
385 }
386
387 /**
388 * Make publish steps page.
389 *
390 * @since 1.1.0
391 * @param string $funnel_id Funnel Id.
392 * @param string $new_status Status.
393 */
394 public function update_steps_post_status( $funnel_id, $new_status ) {
395 $steps = get_post_meta( $funnel_id, 'sellkit_steps', true );
396
397 foreach ( $steps as $step ) {
398 if ( $step['page_id'] === $funnel_id ) {
399 continue;
400 }
401
402 wp_update_post(array(
403 'ID' => $step['page_id'],
404 'post_status' => $new_status,
405 ) );
406 }
407 }
408 }
409
410 Sellkit_Admin_Steps::get_instance();
411