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

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

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