PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.7.9
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.7.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 / components / class-list-table.php

class-list-table.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 1.7.9, at includes/admin/components/class-list-table.php

463 lines 11.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 use Elementor\Plugin;
6 use Sellkit\Admin\Funnel\Importer\Ajax_Handler;
7 use Sellkit\Global_Checkout\Checkout;
8
9 /**
10 * List Table component class.
11 *
12 * @since 1.1.0
13 * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
14 */
15 class Sellkit_Admin_List_Table {
16
17 /**
18 * Class instance.
19 *
20 * @since 1.1.0
21 * @var Sellkit_Admin_List_Table
22 */
23 private static $instance = null;
24
25 /**
26 * Get a class instance.
27 *
28 * @since 1.1.0
29 *
30 * @return Sellkit_Admin_List_Table Class instance.
31 */
32 public static function get_instance() {
33 if ( null === self::$instance ) {
34 self::$instance = new self();
35 }
36
37 return self::$instance;
38 }
39
40 /**
41 * Class constructor.
42 *
43 * @since 1.1.0
44 */
45 public function __construct() {
46 add_action( 'wp_ajax_sellkit_list_table_posts', [ $this, 'get_posts' ] );
47 add_action( 'wp_ajax_sellkit_list_table_post', [ $this, 'handle_post' ] );
48 }
49
50 /**
51 * Get posts.
52 *
53 * @since 1.1.0
54 */
55 public function get_posts() {
56 check_ajax_referer( 'sellkit', 'nonce' );
57
58 // Sanitize.
59 $post_type = sellkit_htmlspecialchars( INPUT_POST, 'post_type' );
60 $paged = filter_input( INPUT_POST, 'paged', FILTER_SANITIZE_NUMBER_INT );
61 $posts_per_page = filter_input( INPUT_POST, 'posts_per_page', FILTER_SANITIZE_NUMBER_INT );
62 $search_args = filter_input( INPUT_POST, 'args', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
63 $page = filter_input( INPUT_POST, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
64
65 /**
66 * Filter List Table query arguments.
67 *
68 * @since 1.1.0
69 *
70 * @param array $args The query arguments.
71 */
72 $args = apply_filters( "sellkit_list_table_{$post_type}_args", [
73 'post_type' => $post_type,
74 'paged' => $paged,
75 'posts_per_page' => ! empty( $posts_per_page ) ? $posts_per_page : 20,
76 'orderby' => 'ID',
77 'order' => 'DESC',
78 ] );
79
80 if ( is_array( $search_args ) && ! empty( $search_args ) ) {
81 foreach ( $search_args as $search_arg ) {
82 $args[ $search_arg['param'] ] = $search_arg['value'];
83 }
84 }
85
86 if ( 'checkout' !== $page ) {
87 $global_checkout_id = get_option( Checkout::SELLKIT_GLOBAL_CHECKOUT_OPTION, 0 );
88 $args['post__not_in'] = [ $global_checkout_id ];
89 }
90
91 // Query.
92 $query = new \WP_Query( $args );
93
94 /**
95 * Filter List Table query posts.
96 *
97 * @since 1.1.0
98 *
99 * @param array $args The taxonomy arguments.
100 */
101 $posts = apply_filters( "sellkit_list_table_{$post_type}_posts", $query->posts );
102
103 /**
104 * Filter List Table columns.
105 *
106 * @since 1.1.0
107 *
108 * @param array $args The columns headings and values.
109 */
110 $columns = apply_filters( "sellkit_list_table_{$post_type}_columns", [
111 'labels' => [],
112 'values' => [],
113 ], $posts );
114
115 // Send response.
116 wp_send_json_success( [
117 'posts' => $posts,
118 'max_num_pages' => $query->max_num_pages,
119 'columns' => $columns,
120 ] );
121 }
122
123 /**
124 * Handle post actions.
125 *
126 * @since 1.1.0
127 */
128 public function handle_post() {
129 check_ajax_referer( 'sellkit', 'nonce' );
130
131 // Sanitize.
132 $post = filter_input( INPUT_POST, 'post', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
133 $sub_action = sellkit_htmlspecialchars( INPUT_POST, 'sub_action' );
134
135 if ( count( $post ) < 3 ) {
136 $post = (array) get_post( $post['ID'] );
137 }
138
139 call_user_func( [ $this, "handle_post_{$sub_action}" ], $post );
140 }
141
142 /**
143 * Handle post toggle status.
144 *
145 * @since 1.1.0
146 * @param array $post Post Array.
147 */
148 private function handle_post_toggle_status( $post ) {
149 // Format proper post status.
150 $post_status = ( 'publish' === $post['post_status'] ) ? 'draft' : 'publish';
151
152 // Update post status.
153 $result = wp_update_post( [
154 'ID' => $post['ID'],
155 'post_status' => $post_status,
156 ], true );
157
158 do_action( "sellkit_after_toggle_status_{$post['post_type']}", $post['ID'], $post_status );
159
160 // Handle error.
161 if ( is_wp_error( $result ) ) {
162 wp_send_json_error( $result );
163 }
164
165 // Send success response.
166 wp_send_json_success( $result );
167 }
168
169 /**
170 * Duplicate post.
171 *
172 * @since 1.1.0
173 * @param array $post Post Array.
174 */
175 private function handle_post_duplicate_post( $post ) {
176 $main_post_id = $post['ID'];
177
178 unset( $post['ID'] );
179
180 $post['post_title'] = sprintf( '%1s - %2s', esc_html( $post['post_title'] ), esc_html__( 'Clone', 'sellkit' ) );
181 $post['post_status'] = 'draft';
182
183 $post_id = wp_insert_post( $post );
184
185 $main_post_meta = get_post_custom( $main_post_id );
186
187 foreach ( $main_post_meta as $key => $value ) {
188 update_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
189 }
190
191 // Handle error.
192 if ( is_wp_error( $post_id ) ) {
193 wp_send_json_error( $post_id );
194 }
195
196 // Send success response.
197 wp_send_json_success( $post_id );
198 }
199
200 /**
201 * Handle post remove.
202 *
203 * @since 1.1.0
204 * @param array $post Post array.
205 */
206 private function handle_post_remove( $post ) {
207 do_action( 'sellkit_funnels_after_delete_posts_' . $post['post_type'], $post );
208 // Delete post.
209 $result = wp_delete_post( $post['ID'] );
210
211 // Handle error.
212 if ( ! is_object( $result ) ) {
213 wp_send_json_error( $result );
214 }
215
216 // Send success response.
217 wp_send_json_success( $result );
218 }
219
220 /**
221 * Duplicate funnel item.
222 *
223 * @since 1.5.0
224 * @param array $post Post Array.
225 */
226 private function handle_post_duplicate_single_funnel( $post ) {
227 $post_id = $post['ID'];
228 $parent_title = sprintf( '%1s - %2s', esc_html( $post['post_title'] ), esc_html__( 'Clone', 'sellkit' ) );
229 $funnel_data = get_post_meta( $post_id, 'nodes', true );
230 $nodes = true;
231
232 if ( empty( $funnel_data ) ) {
233 $funnel_data = get_post_meta( $post_id, 'sellkit_steps', true );
234 $nodes = false;
235 }
236
237 $funnel_slug = get_post_meta( $post_id, 'sellkit_post_slug', true );
238
239 // Let's create parent funnel post first.
240 $new_funnel_id = wp_insert_post( [
241 'post_title' => $parent_title,
242 'post_status' => 'draft',
243 'post_type' => 'sellkit-funnels',
244 'meta_input' => [
245 'sellkit_post_slug' => $funnel_slug,
246 ],
247 ] );
248
249 // Loop through old parent data and create steps posts of new funnel.
250 foreach ( $funnel_data as $key => $funnel_item ) {
251 $old_id = $funnel_item['page_id'];
252
253 // Create steps.
254 $title = $funnel_item['title'];
255 $args = [
256 'post_type' => 'sellkit_step',
257 'post_title' => esc_html( $title ),
258 'post_status' => get_post_status( $old_id ),
259 ];
260
261 $args = $this->handle_post_content( $args, $old_id );
262
263 $new_id = wp_insert_post( $args );
264
265 // Update new parent funnel data with new steps id.
266 $funnel_data[ $key ]['page_id'] = $new_id;
267 $funnel_data[ $key ]['funnel_id'] = $new_funnel_id;
268
269 // Add old steps meta data to new steps.
270 $old_data = get_post_meta( $old_id );
271
272 foreach ( $old_data as $key => $data ) {
273 if ( 'step_data' === $key ) {
274 $data[0] = str_replace( $post_id, $new_funnel_id, $data[0] );
275 }
276
277 if ( '_elementor_data' === $key && '[' === substr( $data[0], 0, 1 ) ) {
278 update_post_meta( $new_id, $key, maybe_unserialize( wp_slash( $data[0] ) ) );
279
280 continue;
281 }
282
283 update_post_meta( $new_id, $key, maybe_unserialize( $data[0] ) );
284 }
285
286 if ( class_exists( 'Elementor\Plugin' ) ) {
287 // Also save post in elementor way. after all it's elementor post.
288 $document = Plugin::$instance->documents->get( $new_id );
289 $document->save( [] );
290 }
291 }
292
293 // At the end update parent main meta.
294 if ( false === $nodes ) {
295 update_post_meta( $new_funnel_id, 'sellkit_steps', $funnel_data );
296 } else {
297 update_post_meta( $new_funnel_id, 'nodes', $funnel_data );
298 }
299
300 wp_send_json_success();
301 }
302
303 /**
304 * Handle post content for templates without elementor.
305 *
306 * @param array $args funnel nodes arguments.
307 * @param integer $old_id node id.
308 * @since 1.5.0
309 * @return array
310 */
311 private function handle_post_content( $args, $old_id ) {
312 if ( empty( $old_id ) ) {
313 return $args;
314 }
315
316 $is_elementor = get_post_meta( $old_id, '_elementor_data', true );
317
318 if ( ! empty( $is_elementor ) ) {
319 return $args;
320 }
321
322 $post_content = get_post( $old_id );
323 $content = $post_content->post_content;
324
325 return array_merge( $args, [ 'post_content' => $content ] );
326 }
327
328 /**
329 * Export single funnel.
330 *
331 * @since 1.5.0
332 * @param array $post Post Array.
333 */
334 private function export_single_funnel( $post ) {
335 $post_id = $post['ID'];
336 $data['funnel']['id'] = $post_id;
337 $data['funnel']['name'] = $post['post_name'];
338 $data['funnel']['title'] = $post['post_title'];
339 $data['funnel']['post_type'] = $post['post_type'];
340 $data['funnel']['post_status'] = $post['post_status'];
341 $data['funnel']['sellkit_steps'] = get_post_meta( $post_id, 'nodes', true );
342
343 // Integration with flowchart.
344 if ( empty( $data['funnel']['sellkit_steps'] ) ) {
345 $data['funnel']['sellkit_steps'] = get_post_meta( $post_id, 'sellkit_steps', true );
346 }
347
348 // Check for steps.
349 if ( ! is_array( $data['funnel']['sellkit_steps'] ) ) {
350 return $data;
351 }
352
353 foreach ( $data['funnel']['sellkit_steps'] as $step ) {
354 if ( ! array_key_exists( 'page_id', $step ) ) {
355 continue;
356 }
357
358 $id = $step['page_id'];
359 $post = get_post( $id );
360 $export_data = get_post_meta( $id );
361
362 $data['step'][ $id ]['ID'] = $post->ID;
363 $data['step'][ $id ]['name'] = $post->post_name;
364 $data['step'][ $id ]['title'] = $post->post_title;
365 $data['step'][ $id ]['post_type'] = $post->post_type;
366 $data['step'][ $id ]['post_status'] = $post->post_status;
367 $data['step'][ $id ]['post_content'] = $post->post_content;
368 $data['step'][ $id ]['page_id'] = $id;
369
370 foreach ( $export_data as $key => $meta ) {
371 if ( '_elementor_data' === $key && defined( 'ELEMENTOR_VERSION' ) ) {
372 $document = Plugin::$instance->documents->get( $id );
373 $template_data = $document->get_export_data();
374
375 $data['step'][ $id ]['meta'][ $key ] = wp_json_encode( $template_data['content'] );
376 continue;
377 }
378
379 $data['step'][ $id ]['meta'][ $key ] = $meta[0];
380 }
381 }
382
383 return $data;
384 }
385
386 /**
387 * Handle exporting single funnel by ajax.
388 *
389 * @since 1.5.0
390 * @param array $post Post Array.
391 */
392 private function handle_post_export_single_funnel( $post ) {
393 $data = [];
394 $data['type'] = 'single';
395 $data['data'] = $this->export_single_funnel( $post );
396
397 wp_send_json_success( $data );
398 }
399
400 /**
401 * Handle exporting single funnel by ajax.
402 *
403 * @since 1.5.0
404 */
405 private function handle_post_export_all_funnel() {
406 $data = [];
407 $data['type'] = 'multi';
408
409 $args = [
410 'post_type' => 'sellkit-funnels',
411 'posts_per_page' => -1,
412 ];
413
414 $posts = new \WP_Query( $args );
415 $posts = $posts->posts;
416
417 if ( empty( $posts ) ) {
418 wp_send_json_error();
419 }
420
421 foreach ( $posts as $post ) {
422 $post = (array) $post;
423
424 $data['data'][] = $this->export_single_funnel( $post );
425 }
426
427 wp_send_json_success( $data );
428 }
429
430 /**
431 * Handle import funnel.
432 *
433 * @since 1.5.0
434 */
435 private function handle_post_import_funnel() {
436 $json = filter_input( INPUT_POST, 'funnel', FILTER_DEFAULT );
437 $page = filter_input( INPUT_POST, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
438 $data = json_decode( $json );
439
440 $ajax_handler = new Ajax_Handler();
441
442 if ( 'single' === $data->type ) {
443 $funnel_data = $data->data->funnel;
444 $steps_data = $data->data->step;
445 $funnel_id = $ajax_handler->import_funnel_by_data( $funnel_data, $steps_data );
446 }
447
448 if ( 'multi' === $data->type ) {
449 foreach ( $data->data as $item ) {
450 $funnel_data = $item->funnel;
451 $steps_data = $item->step;
452 $funnel_id = $ajax_handler->import_funnel_by_data( $funnel_data, $steps_data );
453 }
454 }
455
456 if ( 'checkout' === $page && (int) $funnel_id > 0 ) {
457 update_option( Checkout::SELLKIT_GLOBAL_CHECKOUT_OPTION, $funnel_id );
458 }
459 }
460 }
461
462 Sellkit_Admin_List_Table::get_instance();
463