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

402 lines 10.2 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 ];
211 }
212
213 wp_send_json_success( $filtered_products );
214 }
215
216 /**
217 * Filter step data before saving.
218 *
219 * @since 1.1.0
220 * @param string $post_id Post id.
221 */
222 public function after_create_step_callback( $post_id ) {
223 $steps = get_post_meta( $post_id, 'sellkit_steps', true );
224 $last_step = end( $steps );
225
226 array_pop( $steps );
227
228 $new_step_id = wp_insert_post( [
229 'post_type' => self::SELLKIT_STEP_POST_TYPE,
230 'post_title' => $last_step['title'],
231 'post_name' => sanitize_title( $last_step['title'] ),
232 'post_status' => 'publish',
233 ] );
234
235 $last_step['page_id'] = $new_step_id;
236 $last_step['slug'] = get_post_field( 'post_name', $new_step_id );
237
238 $step_data = $last_step;
239 $step_data['funnel_id'] = $post_id;
240 $step_data['number'] = count( $steps );
241
242 update_post_meta( $new_step_id, 'step_data', $step_data );
243
244 $new_steps = array_merge( $steps, [ $last_step ] );
245
246 update_post_meta( $post_id, 'sellkit_steps', $new_steps );
247 }
248
249 /**
250 * Loading page templates.
251 *
252 * @since 1.1.0
253 * @param string $template Template name.
254 */
255 public function load_page_template( $template ) {
256
257 global $post;
258
259 if ( 'string' !== gettype( $template ) || ! is_object( $post ) || self::SELLKIT_STEP_POST_TYPE !== $post->post_type ) {
260 return $template;
261 }
262
263 remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head' );
264 add_filter( 'next_post_rel_link', '__return_empty_string' );
265 add_filter( 'previous_post_rel_link', '__return_empty_string' );
266
267 $file = sellkit()->plugin_dir() . 'includes/templates/canvas.php';
268
269 if ( ! file_exists( $template ) ) {
270 return $template;
271 }
272
273 return $file;
274 }
275
276 /**
277 * Register step post type.
278 *
279 * @since 1.1.0
280 */
281 public function register_step_post_type() {
282 $labels = array(
283 'name' => esc_html_x( 'Steps', 'flow step general name', 'sellkit' ),
284 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'sellkit' ),
285 'search_items' => esc_html__( 'Search Steps', 'sellkit' ),
286 'all_items' => esc_html__( 'All Steps', 'sellkit' ),
287 'edit_item' => esc_html__( 'Edit Step', 'sellkit' ),
288 'view_item' => esc_html__( 'View Step', 'sellkit' ),
289 'add_new' => esc_html__( 'Add New', 'sellkit' ),
290 'update_item' => esc_html__( 'Update Step', 'sellkit' ),
291 'add_new_item' => esc_html__( 'Add New', 'sellkit' ),
292 'new_item_name' => esc_html__( 'New Step Name', 'sellkit' ),
293 );
294
295 $args = array(
296 'labels' => $labels,
297 'public' => true,
298 'query_var' => true,
299 'can_export' => true,
300 'exclude_from_search' => true,
301 'show_ui' => true,
302 'show_in_menu' => false,
303 'show_in_admin_bar' => true,
304 'show_in_rest' => true,
305 'publicly_queryable' => true,
306 'supports' => [ 'title', 'editor', 'elementor', 'revisions' ],
307 'capability_type' => 'post',
308 'capabilities' => [
309 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
310 ],
311 'map_meta_cap' => true,
312 );
313
314 register_post_type( self::SELLKIT_STEP_POST_TYPE, $args );
315 }
316
317 /**
318 * Edit step name or slug.
319 *
320 * @since 1.1.0
321 * @param string $funnel_id Funnel Id.
322 */
323 public function edit_step_name_and_slug( $funnel_id ) {
324 $sub_action_data = sellkit_post( 'sub_action_data' );
325 $title = ! empty( $sub_action_data['title'] ) ? $sub_action_data['title'] : '';
326 $slug = ! empty( $sub_action_data['slug'] ) ? $sub_action_data['slug'] : sanitize_title( $title );
327 $page_id = ! empty( $sub_action_data['page_id'] ) ? $sub_action_data['page_id'] : '';
328 $selected_step = $sub_action_data['selected_step'];
329
330 if ( empty( $page_id ) ) {
331 return;
332 }
333
334 wp_update_post( [
335 'ID' => $page_id,
336 'post_title' => $title,
337 'post_name' => $slug,
338 ] );
339
340 if ( get_post_field( 'post_name', $page_id ) === $slug ) {
341 return;
342 }
343
344 $post_data = get_post_meta( $funnel_id, 'sellkit_steps', true );
345 $post_data[ $selected_step ]['slug'] = get_post_field( 'post_name', $page_id );
346
347 update_post_meta( $funnel_id, 'sellkit_steps', $post_data );
348 }
349
350 /**
351 * Delete step page id.
352 *
353 * @since 1.1.0
354 */
355 public function delete_related_page() {
356 $sub_action_data = sellkit_post( 'sub_action_data' );
357
358 if ( empty( $sub_action_data['page_id'] ) ) {
359 return;
360 }
361
362 wp_delete_post( $sub_action_data['page_id'], true );
363 }
364
365 /**
366 * Flash rules.
367 *
368 * @since 1.1.0
369 */
370 public function sellkit_steps_flush_rules() {
371 $rules = get_option( 'rewrite_rules' );
372
373 if ( ! isset( $rules['sellkit_step/[^/]+/([^/]+)/?$'] ) ) {
374 flush_rewrite_rules();
375 }
376 }
377
378 /**
379 * Make publish steps page.
380 *
381 * @since 1.1.0
382 * @param string $funnel_id Funnel Id.
383 * @param string $new_status Status.
384 */
385 public function update_steps_post_status( $funnel_id, $new_status ) {
386 $steps = get_post_meta( $funnel_id, 'sellkit_steps', true );
387
388 foreach ( $steps as $step ) {
389 if ( $step['page_id'] === $funnel_id ) {
390 continue;
391 }
392
393 wp_update_post(array(
394 'ID' => $step['page_id'],
395 'post_status' => $new_status,
396 ) );
397 }
398 }
399 }
400
401 Sellkit_Admin_Steps::get_instance();
402