PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 6.0.0
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v6.0.0
6.0.3 6.0.2 6.0.1 6.0.0 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 5.7.9.2 5.7.9.1 5.7.8 5.7.9 5.7.6 5.7.7 5.7.5 5.7.4 5.7.3 5.7.2 5.7.1 trunk 5.6.0 5.6.1 All 34 releases
automatorwp / includes / ajax-functions.php

ajax-functions.php in AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI 6.0.0, at includes/ajax-functions.php

1,128 lines 34.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Ajax Functions
4 *
5 * @package AutomatorWP\Ajax_Functions
6 * @author AutomatorWP <[email protected]>, Ruben Garcia <[email protected]>
7 * @since 1.0.0
8 */
9 // Exit if accessed directly
10 if( !defined( 'ABSPATH' ) ) exit;
11
12 /**
13 * Add an automation trigger/action through ajax
14 *
15 * @since 1.0.0
16 */
17 function automatorwp_ajax_add_automation_item() {
18 // Security check, forces to die if not security passed
19 check_ajax_referer( 'automatorwp_admin', 'nonce' );
20
21 // Permissions check
22 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
23 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
24 }
25
26 // Sanitize parameters
27 $automation_id = absint( $_POST['automation_id'] );
28 $type = sanitize_text_field( $_POST['type'] ); // The trigger or action reference
29 $item_type = sanitize_text_field( $_POST['item_type'] ); // 'trigger' or 'action'
30 $position = absint( $_POST['position'] );
31
32 // Check parameters
33 if( $automation_id === 0 ) {
34 wp_send_json_error( __( 'Invalid automation.', 'automatorwp' ) );
35 }
36
37 $automation = automatorwp_get_automation_object( $automation_id );
38
39 if( ! $automation ) {
40 wp_send_json_error( __( 'Invalid automation.', 'automatorwp' ) );
41 }
42
43 if( ! in_array( $item_type, array( 'trigger', 'action' ) ) ) {
44 wp_send_json_error( __( 'Invalid item type.', 'automatorwp' ) );
45 }
46
47 ct_setup_table( "automatorwp_{$item_type}s" );
48
49 if( $item_type === 'trigger' ) {
50 $type_args = automatorwp_get_trigger( $type );
51 } else if( $item_type === 'action' ) {
52 $type_args = automatorwp_get_action( $type );
53 }
54
55 if( ! $type_args ) {
56 if( $item_type === 'trigger' ) {
57 wp_send_json_error( __( 'Invalid trigger.', 'automatorwp' ) );
58 } else if( $item_type === 'action' ) {
59 wp_send_json_error( __( 'Invalid action.', 'automatorwp' ) );
60 }
61 }
62
63 $object = array(
64 'automation_id' => $automation_id,
65 'title' => '',
66 'type' => $type,
67 'status' => 'active',
68 'position' => $position,
69 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
70 );
71
72 // Create the new trigger
73 $id = ct_insert_object( $object );
74
75 // Initialize trigger options
76 if( $id ) {
77
78 // Append the id to the trigger data
79 $object['id'] = $id;
80
81 // Loop all options looking for their fields
82 foreach( $type_args['options'] as $option => $args ) {
83
84 // Loop all option fields to initialize them
85 foreach( $args['fields'] as $field_id => $field_args ) {
86
87 if( isset( $field_args['default'] ) ) {
88 ct_update_object_meta( $id, $field_id, $field_args['default'] );
89 }
90
91 }
92
93 }
94
95 // Update the trigger title
96 ct_update_object( array(
97 'id' => $id,
98 'title' => automatorwp_parse_automation_item_edit_label( (object) $object, $item_type, 'view' )
99 ) );
100 }
101
102 ct_reset_setup_table();
103
104 // Flush cache to ensure that option replacement gets the newest value
105 wp_cache_flush();
106
107 if( $id ) {
108
109 // Append the trigger html
110 ob_start();
111 automatorwp_automation_item_edit_html( (object) $object, $item_type, $automation );
112 $edit_html = ob_get_clean();
113
114 $tags_html = '';
115
116 if( $item_type === 'trigger' )
117 delete_transient( 'automatorwp_triggers_in_use' );
118 else if( $item_type === 'action' )
119 delete_transient( 'automatorwp_actions_in_use' );
120
121 // Set up the trigger tags html
122 if( $item_type === 'trigger' ) {
123
124 // Get the trigger tags
125 $tags = automatorwp_get_trigger_tags( (object) $object );
126
127 if( ! empty( $tags ) && isset( $tags[$id] ) ) {
128 $tags_html = automatorwp_get_tags_selector_group_html( $id, $tags[$id] );
129 }
130
131 }
132
133 // Set up the action tags html
134 if( $item_type === 'action' ) {
135
136 // Get the action tags
137 $tags = automatorwp_get_action_tags( (object) $object );
138
139 if( ! empty( $tags ) && isset( $tags[$id] ) ) {
140 $tags_html = automatorwp_get_tags_selector_group_html( $id, $tags[$id] );
141 }
142 }
143
144 // Send back a successful response
145 wp_send_json_success( array(
146 $item_type => $object,
147 'edit_html' => $edit_html,
148 'tags_html' => $tags_html,
149 ) );
150 } else {
151 if( $item_type === 'trigger' )
152 wp_send_json_error( __( 'Trigger can\'t be created.', 'automatorwp' ) );
153 else if( $item_type === 'action' )
154 wp_send_json_error( __( 'Action can\'t be created.', 'automatorwp' ) );
155 }
156
157 }
158 add_action( 'wp_ajax_automatorwp_add_automation_item', 'automatorwp_ajax_add_automation_item' );
159
160 /**
161 * Delete an automation trigger/action through ajax
162 *
163 * @since 1.0.0
164 */
165 function automatorwp_ajax_delete_automation_item() {
166 // Security check, forces to die if not security passed
167 check_ajax_referer( 'automatorwp_admin', 'nonce' );
168
169 // Permissions check
170 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
171 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
172 }
173
174 // Sanitize parameters
175 $id = absint( $_POST['id'] );
176 $item_type = sanitize_text_field( $_POST['item_type'] ); // 'trigger' or 'action'
177
178 // Check parameters
179 if( $id === 0 ) {
180 wp_send_json_error( __( 'Invalid item.', 'automatorwp' ) );
181 }
182
183 if( ! in_array( $item_type, array( 'trigger', 'action' ) ) ) {
184 wp_send_json_error( __( 'Invalid item type.', 'automatorwp' ) );
185 }
186
187 ct_setup_table( "automatorwp_{$item_type}s" );
188
189 ct_delete_object( $id );
190
191 ct_reset_setup_table();
192
193 if( $item_type === 'trigger' )
194 delete_transient( 'automatorwp_triggers_in_use' );
195 else if( $item_type === 'action' )
196 delete_transient( 'automatorwp_actions_in_use' );
197
198 // Send back a successful response
199 wp_send_json_success( __( 'Item deleted.', 'automatorwp' ) );
200 }
201 add_action( 'wp_ajax_automatorwp_delete_automation_item', 'automatorwp_ajax_delete_automation_item' );
202
203 /**
204 * Update automation triggers/actions order through ajax
205 *
206 * @since 1.0.0
207 */
208 function automatorwp_ajax_update_automation_items_order() {
209
210 // Security check, forces to die if not security passed
211 check_ajax_referer( 'automatorwp_admin', 'nonce' );
212
213 // Permissions check
214 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
215 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
216 }
217
218 // Sanitize parameters
219 $items_order = $_POST['items_order']; // Sanitized before
220 $item_type = sanitize_text_field( $_POST['item_type'] ); // 'trigger' or 'action'
221
222 // Check parameters
223 if( ! is_array( $items_order ) ) {
224 wp_send_json_error( __( 'Invalid items.', 'automatorwp' ) );
225 }
226
227 if( empty( $items_order ) ) {
228 wp_send_json_error( __( 'Invalid items.', 'automatorwp' ) );
229 }
230
231 if( ! in_array( $item_type, array( 'trigger', 'action' ) ) ) {
232 wp_send_json_error( __( 'Invalid item type.', 'automatorwp' ) );
233 }
234
235 ct_setup_table( "automatorwp_{$item_type}s" );
236
237 foreach( $items_order as $id => $position ) {
238
239 // Sanitize id and position
240 $id = absint( $id );
241 $position = absint( $position );
242
243 // Skip if not ID provided
244 if( $id === 0 ) {
245 continue;
246 }
247
248 // Update item position
249 ct_update_object( array(
250 'id' => $id,
251 'position' => $position,
252 ) );
253 }
254
255 ct_reset_setup_table();
256
257 // Send back a successful response
258 wp_send_json_error( __( 'Items order updated.', 'automatorwp' ) );
259
260 }
261 add_action( 'wp_ajax_automatorwp_update_automation_items_order', 'automatorwp_ajax_update_automation_items_order' );
262
263 /**
264 * Update a trigger option through ajax
265 *
266 * @since 1.0.0
267 */
268 function automatorwp_ajax_update_item_option() {
269
270 // Security check, forces to die if not security passed
271 check_ajax_referer( 'automatorwp_admin', 'nonce' );
272
273 // Permissions check
274 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
275 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
276 }
277
278 // Sanitize parameters
279 $id = absint( $_POST['id'] );
280 $item_type = sanitize_text_field( $_POST['item_type'] );
281 $option = sanitize_text_field( $_POST['option_name'] );
282
283 // Check parameters
284 if( $id === 0 ) {
285 wp_send_json_error( __( 'Invalid trigger.', 'automatorwp' ) );
286 }
287
288 if( ! in_array( $item_type, array( 'trigger', 'action' ) ) ) {
289 wp_send_json_error( __( 'Invalid item type.', 'automatorwp' ) );
290 }
291
292 if( $item_type === 'trigger' ) {
293 $automation = automatorwp_get_trigger_automation( $id );
294 } else if( $item_type === 'action' ) {
295 $automation = automatorwp_get_action_automation( $id );
296 }
297
298 ct_setup_table( "automatorwp_{$item_type}s" );
299
300 // Check object
301 $object = ct_get_object( $id );
302
303 ct_reset_setup_table();
304
305 if( ! $object ) {
306 wp_send_json_error( __( 'Invalid item.', 'automatorwp' ) );
307 }
308
309 $type_args = automatorwp_automation_item_type_args( $object, $item_type );
310
311 // Check if trigger is registered
312 if( ! $type_args ) {
313 wp_send_json_error( __( 'Invalid item.', 'automatorwp' ) );
314 }
315
316 // Get the option form
317 $cmb2 = automatorwp_get_automation_item_option_form( $object, $item_type, $option, $automation );
318
319 if( ! $cmb2 ) {
320 wp_send_json_error( __( 'Invalid option.', 'automatorwp' ) );
321 }
322
323 // Get option sanitized values
324 $sanitized_values = $cmb2->get_sanitized_values( $_POST );
325
326 // Fields not in sanitized values need to recover its default value
327 foreach ( $type_args['options'][$option]['fields'] as $field_id => $field ) {
328
329 // Skip fields in sanitized values
330 if( isset( $sanitized_values[$field_id] ) ) {
331 continue;
332 }
333
334 // If field has a default value, add it to the array of sanitize values
335 if( isset( $field['default'] ) ) {
336 $sanitized_values[$field_id] = sanitize_text_field( $field['default'] );
337 }
338
339 }
340
341 // Field groups requires a custom way to handle their values saving
342 foreach ( $type_args['options'][$option]['fields'] as $field_id => $field ) {
343
344 // Skip fields that are not group
345 if( $field['type'] !== 'group' ) {
346 continue;
347 }
348
349 // Skip group fields that have not been received any value
350 if( ! isset( $_POST[$field_id] ) ) {
351 continue;
352 }
353
354 if( ! is_array( $_POST[$field_id] ) ) {
355 continue;
356 }
357
358 $sanitized_values[$field_id] = array();
359
360 // Group fields are correctly setup on $_POST and needs get sanitized
361 foreach( $_POST[$field_id] as $i => $field_values ) {
362
363 $values = array();
364
365 foreach( $field_values as $field_group_id => $value ) {
366
367 // Skip if this field is not registered
368 if( ! isset( $field['fields'][$field_group_id] ) ) {
369 continue;
370 }
371
372 if( ! empty( $value ) ) {
373 // Add the value from $_POST
374 $values[$field_group_id] = sanitize_text_field( $value );
375 } else if( isset( $field['fields'][$field_group_id]['default'] ) ) {
376 // If field has a default value, add it to the array of sanitize values
377 $values[$field_group_id] = sanitize_text_field( $field['fields'][$field_group_id]['default'] );
378 }
379 }
380
381 $sanitized_values[$field_id][] = $values;
382
383 }
384
385 }
386
387 // Setup the table here to ensure to store meta data on the correct table
388 ct_setup_table( "automatorwp_{$item_type}s" );
389
390 foreach( $sanitized_values as $field_id => $value ) {
391 ct_update_object_meta( $object->id, $field_id, $value );
392 }
393
394 // Flush cache to ensure that option replacement gets the newest value
395 wp_cache_flush();
396
397 // Update the trigger title
398 ct_update_object( array(
399 'id' => $id,
400 'title' => automatorwp_parse_automation_item_edit_label( $object, $item_type, 'view' )
401 ) );
402
403 ct_reset_setup_table();
404
405 $tags_html = '';
406
407 // Setup the tags html
408 if( $item_type === 'trigger' ) {
409 // Get the trigger tags
410 $tags = automatorwp_get_trigger_tags( (object) $object );
411
412 if( ! empty( $tags ) && isset( $tags[$id] ) ) {
413 $tags_html = automatorwp_get_tags_selector_group_html( $id, $tags[$id] );
414 }
415 }
416
417 $response = array(
418 'edit_html' => automatorwp_parse_automation_item_edit_label( (object) $object, $item_type ),
419 'tags_html' => $tags_html
420 );
421
422 // Setup the tags html
423 if( $item_type === 'action' ) {
424 // Get the action tags
425 $tags = automatorwp_get_action_tags( (object) $object );
426
427 if( ! empty( $tags ) && isset( $tags[$id] ) ) {
428 $tags_html = automatorwp_get_tags_selector_group_html( $id, $tags[$id] );
429 }
430 }
431
432 $response = array(
433 'edit_html' => automatorwp_parse_automation_item_edit_label( (object) $object, $item_type ),
434 'tags_html' => $tags_html
435 );
436
437 // Special condition for filters
438 if( $object->type === 'filter' ) {
439
440 ob_start();
441 automatorwp_automation_item_edit_html( $object, $item_type, $automation );
442 $edit_html = ob_get_clean();
443
444 $response['item_html'] = $edit_html;
445 }
446
447 wp_send_json_success( $response );
448
449 }
450 add_action( 'wp_ajax_automatorwp_update_item_option', 'automatorwp_ajax_update_item_option' );
451
452 /**
453 * Run automation through ajax
454 *
455 * @since 2.2.2
456 */
457 function automatorwp_ajax_run_automation() {
458
459 // Security check, forces to die if not security passed
460 check_ajax_referer( 'automatorwp_admin', 'nonce' );
461
462 // Permissions check
463 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
464 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
465 }
466
467 // Sanitize parameters
468 $automation_id = absint( $_POST['automation_id'] );
469
470 $automation = automatorwp_get_automation_object( $automation_id );
471
472 // Bail if automation not found
473 if( ! $automation ) {
474 wp_send_json_error( sprintf( __( 'Automation with ID %d not found.', 'automatorwp' ), $automation_id ) );
475 }
476
477 /**
478 * Hook when running automation through ajax
479 *
480 * @since 2.2.2
481 *
482 * @param stdClass $automation The automation object
483 */
484 do_action( 'automatorwp_ajax_run_automation', $automation );
485
486 // Run the automation
487 $result = automatorwp_run_automation( $automation_id );
488
489 if( $result ) {
490 wp_send_json_success( automatorwp_get_automation_run_details( $automation ) );
491 } else {
492 wp_send_json_error( array(
493 'message' => automatorwp_get_run_automation_error()
494 ) );
495 }
496
497
498 }
499 add_action( 'wp_ajax_automatorwp_run_automation', 'automatorwp_ajax_run_automation' );
500
501 /**
502 * Cancel automation run through ajax
503 *
504 * @since 2.2.2
505 */
506 function automatorwp_ajax_cancel_automation_run() {
507
508 // Security check, forces to die if not security passed
509 check_ajax_referer( 'automatorwp_admin', 'nonce' );
510
511 // Permissions check
512 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
513 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
514 }
515
516 // Sanitize parameters
517 $automation_id = absint( $_POST['automation_id'] );
518
519 $automation = automatorwp_get_automation_object( $automation_id );
520
521 // Bail if automation not found
522 if( ! $automation ) {
523 wp_send_json_error( sprintf( __( 'Automation with ID %d not found.', 'automatorwp' ), $automation_id ) );
524 }
525
526 // Cancel the automation run
527 $result = automatorwp_cancel_automation_run( $automation_id );
528
529 if( $result ) {
530 wp_send_json_success();
531 } else {
532 wp_send_json_error( array(
533 'message' => automatorwp_get_run_automation_error()
534 ) );
535 }
536
537 }
538 add_action( 'wp_ajax_automatorwp_cancel_automation_run', 'automatorwp_ajax_cancel_automation_run' );
539
540 /**
541 * AJAX Helper for selecting posts
542 *
543 * @since 1.0.0
544 */
545 function automatorwp_ajax_get_posts() {
546 // Security check, forces to die if not security passed
547 check_ajax_referer( 'automatorwp_admin', 'nonce' );
548
549 // Permissions check
550 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
551 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
552 }
553
554 global $wpdb;
555
556 // Pull back the search string
557 $search = isset( $_REQUEST['q'] ) ? $wpdb->esc_like( $_REQUEST['q'] ) : '';
558
559 // Setup where conditions (initialized with 1=1)
560 $where = '1=1';
561
562 // Post type conditional
563 $post_type = ( isset( $_REQUEST['post_type'] ) && ! empty( $_REQUEST['post_type'] ) ? $_REQUEST['post_type'] : array( 'post', 'page' ) );
564
565 // Add support to the post_type_cb parameter (used on post selector fields)
566 if( isset( $_REQUEST['post_type_cb'] ) && ! empty( $_REQUEST['post_type_cb'] ) ) {
567
568 $post_type_cb = sanitize_text_field( $_REQUEST['post_type_cb'] );
569
570 if( is_callable( $post_type_cb ) ) {
571 $post_type = call_user_func( $post_type_cb );
572 }
573
574 }
575
576 $post_type_any = false;
577
578 if ( is_array( $post_type ) ) {
579
580 // Support for any post type
581 if( ! in_array( 'any', $post_type ) ) {
582
583 // Sanitize all post types given
584 foreach( $post_type as $i => $value ) {
585 $post_type[$i] = sanitize_text_field( $value );
586 }
587
588 $where .= sprintf( ' AND p.post_type IN(\'%s\')', implode( "','", $post_type ) );
589
590 } else {
591 $post_type_any = true;
592 }
593
594 } else {
595
596 // Support for any post type
597 if( $post_type !== 'any' ) {
598
599 // Sanitize the post type
600 $post_type = sanitize_text_field( $post_type );
601
602 $where .= sprintf( ' AND p.post_type = \'%s\'', $post_type );
603 } else {
604 $post_type_any = true;
605 }
606 }
607
608 // Exclude some undesired post types if showing all posts types
609 if( $post_type_any ) {
610 $post_types_excluded = array(
611 'revision',
612 'nav_menu_item',
613 'custom_css',
614 'customize_changeset',
615 'user_request',
616 'oembed_cache',
617 'wp_block',
618 'wp_template',
619 );
620
621 $where .= sprintf( ' AND p.post_type NOT IN(\'%s\')', implode( "','", $post_types_excluded ) );
622 }
623
624 // Post title conditional
625 $where .= " AND p.post_title LIKE %s";
626
627 // Post status conditional
628 $where .= " AND p.post_status NOT IN ( 'pending', 'draft' )";
629
630 // Check for trigger type extra conditionals
631 if( isset( $_REQUEST['trigger_type'] ) ) {
632
633 $query_args = array();
634 $trigger_type = sanitize_text_field( $_REQUEST['trigger_type'] );
635
636 /**
637 * Specific activity triggers query args (used on requirements UI and on ajax get posts)
638 * Note: Use $_REQUEST for all given parameters
639 *
640 * @since 1.0.0
641 *
642 * @param array|string $query_args
643 * @param string $trigger_type
644 *
645 * @return array|string
646 */
647 $query_args = apply_filters( 'automatorwp_specific_trigger_type_query_args', $query_args, $trigger_type );
648
649 if( ! empty( $query_args ) ) {
650
651 if( is_array( $query_args ) ) {
652 // If is an array of conditionals, then build the new conditionals
653 foreach( $query_args as $field => $value ) {
654 $where .= " AND p.{$field} = '$value'";
655 }
656 } else {
657 // Leave an extra space if query args doesn't have one
658 $where .= ' ' . $query_args;
659 }
660
661 }
662
663 }
664
665 /**
666 * Ajax posts query args (used on almost every post selector)
667 * Note: Use $_REQUEST for all given parameters
668 *
669 * @since 1.0.0
670 *
671 * @param string $query_args
672 *
673 * @return array|string
674 */
675 $extra_query_args = apply_filters( 'automatorwp_ajax_get_posts_query_args', '' );
676
677 // Check for extra conditionals
678 if( ! empty( $extra_query_args ) ) {
679
680 if( is_array( $extra_query_args ) ) {
681 // If is an array of conditionals, then build the new conditionals
682 foreach( $extra_query_args as $field => $value ) {
683 $where .= " AND p.{$field} = '$value'";
684 }
685 } else {
686 // Leave an extra space if extra query args doesn't have one
687 $where .= ' ' . $extra_query_args;
688 }
689
690 }
691
692 // Setup from (from is filtered to allow joins)
693 $from = "{$wpdb->posts} AS p";
694
695 /**
696 * Ajax posts from (used on almost every post selector)
697 * Note: Use $_REQUEST for all given parameters
698 *
699 * @since 1.0.0
700 *
701 * @param string $from By default '{$wpdb->posts} AS p'
702 *
703 * @return string
704 */
705 $from = apply_filters( 'automatorwp_ajax_get_posts_from', $from );
706
707 /**
708 * Ajax posts where (used on almost every post selector)
709 * Note: Use $_REQUEST for all given parameters
710 *
711 * @since 1.0.0
712 *
713 * @param string $where Contains all wheres
714 *
715 * @return string
716 */
717 $where = apply_filters( 'automatorwp_ajax_get_posts_where', $where );
718
719 // Setup order by
720 $order_by = "p.post_type ASC, p.menu_order DESC";
721
722 /**
723 * Ajax posts order by (used on almost every post selector)
724 * Note: Use $_REQUEST for all given parameters
725 *
726 * @since 1.0.0
727 *
728 * @param string $order_by By default 'p.post_type ASC, p.menu_order DESC'
729 *
730 * @return string
731 */
732 $order_by = apply_filters( 'automatorwp_ajax_get_posts_order_by', $order_by );
733
734 // Pagination args
735 $page = isset( $_REQUEST['page'] ) ? absint( $_REQUEST['page'] ) : 1;
736 $limit = 20;
737 $offset = $limit * ( $page - 1 );
738
739 // On this query, keep $wpdb->posts to get current site posts
740 $results = $wpdb->get_results( $wpdb->prepare(
741 "SELECT p.ID, p.post_title, p.post_type
742 FROM {$from}
743 WHERE {$where}
744 ORDER BY {$order_by}
745 LIMIT {$offset}, {$limit}",
746 "%%{$search}%%"
747 ) );
748
749 $count = absint( $wpdb->get_var( $wpdb->prepare(
750 "SELECT COUNT(*) FROM {$from} WHERE {$where}",
751 "%%{$search}%%"
752 ) ) );
753
754 /**
755 * Ajax posts results (used on almost every post selector)
756 * Note: Use $_REQUEST for all given parameters
757 *
758 * @since 1.0.0
759 *
760 * @param array $results
761 *
762 * @return array
763 */
764 $results = apply_filters( 'automatorwp_ajax_get_posts_results', $results );
765
766 $response = array(
767 'results' => $results,
768 'more_results' => $count > $limit && $count > $offset,
769 );
770
771 // Return our results
772 wp_send_json_success( $response );
773
774 }
775 add_action( 'wp_ajax_automatorwp_get_posts', 'automatorwp_ajax_get_posts' );
776
777 /**
778 * Parse the posts results to prepend custom options
779 *
780 * @since 1.0.0
781 *
782 * @param array $results
783 *
784 * @return array
785 */
786 function automatorwp_ajax_parse_posts_results( $results ) {
787 return automatorwp_ajax_parse_extra_options( $results, 'ID', 'post_title' );
788 }
789 add_filter( 'automatorwp_ajax_get_posts_results', 'automatorwp_ajax_parse_posts_results' );
790
791 /**
792 * AJAX Helper for selecting terms
793 *
794 * @since 1.0.0
795 */
796 function automatorwp_ajax_get_terms() {
797 // Security check, forces to die if not security passed
798 check_ajax_referer( 'automatorwp_admin', 'nonce' );
799
800 // Permissions check
801 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
802 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
803 }
804
805 // Pull back the search string
806 $search = isset( $_REQUEST['q'] ) ? sanitize_text_field( $_REQUEST['q'] ) : '';
807
808 // Taxonomy conditional
809 $taxonomy = ( isset( $_REQUEST['taxonomy'] ) && ! empty( $_REQUEST['taxonomy'] ) ? sanitize_text_field( $_REQUEST['taxonomy'] ) : 'category' );
810
811 // Pagination args
812 $page = isset( $_REQUEST['page'] ) ? absint( $_REQUEST['page'] ) : 1;
813 $limit = 20;
814 $offset = $limit * ( $page - 1 );
815
816 $term_query = new WP_Term_Query( array(
817 'search' => $search,
818 'taxonomy' => $taxonomy,
819 'hide_empty' => false,
820 'number' => $limit,
821 'offset' => $offset,
822 ) );
823
824 $results = $term_query->get_terms();
825
826 $count_term_query = new WP_Term_Query( array(
827 'fields' => 'count',
828 'taxonomy' => $taxonomy,
829 'hide_empty' => false,
830 ) );
831
832 $count = $count_term_query->get_terms();
833
834 /**
835 * Ajax posts results (used on almost every post selector)
836 * Note: Use $_REQUEST for all given parameters
837 *
838 * @since 1.0.0
839 *
840 * @param array $results
841 *
842 * @return array
843 */
844 $results = apply_filters( 'automatorwp_ajax_get_terms_results', $results );
845
846 $response = array(
847 'results' => $results,
848 'more_results' => $count > $limit && $count > $offset,
849 );
850
851 // Return our results
852 wp_send_json_success( $response );
853
854 }
855 add_action( 'wp_ajax_automatorwp_get_terms', 'automatorwp_ajax_get_terms' );
856
857 /**
858 * Parse the terms results to prepend custom options
859 *
860 * @since 1.0.0
861 *
862 * @param array $results
863 *
864 * @return array
865 */
866 function automatorwp_ajax_parse_terms_results( $results ) {
867 return automatorwp_ajax_parse_extra_options( $results, 'term_id', 'name' );
868 }
869 add_filter( 'automatorwp_ajax_get_terms_results', 'automatorwp_ajax_parse_terms_results' );
870
871 /**
872 * AJAX Helper for selecting users
873 *
874 * @since 1.0.0
875 */
876 function automatorwp_ajax_get_users() {
877 // Security check, forces to die if not security passed
878 check_ajax_referer( 'automatorwp_admin', 'nonce' );
879
880 // Permissions check
881 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
882 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
883 }
884
885 // If no word query sent, initialize it
886 if ( ! isset( $_REQUEST['q'] ) ) {
887 $_REQUEST['q'] = '';
888 }
889
890 global $wpdb;
891
892 // Pull back the search string
893 $search = esc_sql( $wpdb->esc_like( $_REQUEST['q'] ) );
894 $where = '';
895
896 if ( ! empty( $search ) ) {
897 $where = " WHERE user_login LIKE '%{$search}%'";
898 $where .= " OR user_email LIKE '%{$search}%'";
899 $where .= " OR display_name LIKE '%{$search}%'";
900 }
901
902 // Pagination args
903 $page = isset( $_REQUEST['page'] ) ? absint( $_REQUEST['page'] ) : 1;
904 $limit = 20;
905 $offset = $limit * ( $page - 1 );
906
907 // Fetch our results (store as associative array)
908 $results = $wpdb->get_results(
909 "SELECT ID, user_login, user_email, display_name
910 FROM {$wpdb->users}
911 {$where}
912 LIMIT {$offset}, {$limit}",
913 'ARRAY_A'
914 );
915
916 $count = $wpdb->get_var(
917 "SELECT COUNT(*)
918 FROM {$wpdb->users}
919 {$where}"
920 );
921
922 $response = array(
923 'results' => $results,
924 'more_results' => absint( $count ) > $offset,
925 );
926
927 // Return our results
928 wp_send_json_success( $response );
929 }
930 add_action( 'wp_ajax_automatorwp_get_users', 'automatorwp_ajax_get_users' );
931
932 /**
933 * AJAX Helper for selecting objects
934 *
935 * @since 1.0.0
936 */
937 function automatorwp_ajax_get_objects() {
938 // Security check, forces to die if not security passed
939 check_ajax_referer( 'automatorwp_admin', 'nonce' );
940
941 // Permissions check
942 if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
943 wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
944 }
945
946 global $ct_registered_tables;
947
948 // Pull back the search string
949 $search = isset( $_REQUEST['q'] ) ? sanitize_text_field( $_REQUEST['q'] ) : '';
950
951 // Table conditional
952 $table = ( isset( $_REQUEST['table'] ) ? sanitize_text_field( $_REQUEST['table'] ) : '' );
953
954 if( ! isset( $ct_registered_tables[$table] ) ) {
955 wp_send_json_error( __( 'Table not found.', 'automatorwp' ) );
956 }
957
958 $ct_table = ct_setup_table( $table );
959
960 // Pagination args
961 $page = isset( $_REQUEST['page'] ) ? absint( $_REQUEST['page'] ) : 1;
962 $limit = 20;
963 $offset = $limit * ( $page - 1 );
964
965 $ct_query_args = array(
966 's' => $search,
967 'items_per_page' => $limit,
968 'page' => $page,
969 );
970
971 /**
972 * Ajax objects query parameters (used on almost every object selector)
973 * Note: Use $_REQUEST for all given parameters
974 *
975 * @since 1.0.0
976 *
977 * @param array $ct_query_args
978 * @param CT_Table $ct_table
979 *
980 * @return array
981 */
982 $ct_query_args = apply_filters( 'automatorwp_ajax_get_objects_query_args', $ct_query_args, $ct_table );
983
984 $ct_query = new CT_Query( $ct_query_args );
985
986 $results = $ct_query->get_results();
987 $count = $ct_query->found_results;
988
989 /**
990 * Ajax objects results (used on almost every object selector)
991 * Note: Use $_REQUEST for all given parameters
992 *
993 * @since 1.0.0
994 *
995 * @param array $results
996 * @param CT_Table $ct_table
997 *
998 * @return array Should return elements with an array of array( 'id' => 1, 'text' => '' )
999 */
1000 $results = apply_filters( 'automatorwp_ajax_get_objects_results', $results, $ct_table );
1001
1002 ct_reset_setup_table();
1003
1004 $response = array(
1005 'results' => $results,
1006 'more_results' => $count > $limit && $count > $offset,
1007 );
1008
1009 // Return our results
1010 wp_send_json_success( $response );
1011
1012 }
1013 add_action( 'wp_ajax_automatorwp_get_objects', 'automatorwp_ajax_get_objects' );
1014
1015 /**
1016 * Parse automations objects results
1017 *
1018 * @since 1.0.0
1019 *
1020 * @param array $results
1021 * @param CT_Table $ct_table
1022 *
1023 * @return array
1024 */
1025 function automatorwp_ajax_get_automations_results( $results, $ct_table ) {
1026
1027 if( $ct_table->name !== 'automatorwp_automations' ) {
1028 return $results;
1029 }
1030
1031 $new_results = array();
1032
1033 foreach( $results as $object ) {
1034
1035 $title = ( ! empty( $object->title ) ? $object->title : __( '(No title)', 'automatorwp' ) );
1036
1037 $new_results[] = array(
1038 'id' => $object->id,
1039 'text' => $title,
1040 );
1041 }
1042
1043 return $new_results;
1044 }
1045 add_filter( 'automatorwp_ajax_get_objects_results', 'automatorwp_ajax_get_automations_results', 10, 2 );
1046
1047 /**
1048 * Parse the objects results to prepend custom options
1049 *
1050 * @since 1.0.0
1051 *
1052 * @param array $results
1053 *
1054 * @return array
1055 */
1056 function automatorwp_ajax_parse_objects_results( $results ) {
1057 return automatorwp_ajax_parse_extra_options( $results );
1058 }
1059 add_filter( 'automatorwp_ajax_get_objects_results', 'automatorwp_ajax_parse_objects_results', 11 );
1060
1061 /**
1062 * Helper function to prepend the option none to the ajax results
1063 *
1064 * @since 1.0.0
1065 *
1066 * @deprecated use automatorwp_ajax_parse_extra_options() instead
1067 * Note: Keep for backward compatibility
1068 *
1069 * @param array $results
1070 *
1071 * @return array
1072 */
1073 function automatorwp_ajax_get_ajax_results_option_none( $results ) {
1074 return automatorwp_ajax_parse_extra_options( $results );
1075 }
1076
1077 /**
1078 * Helper function to prepend extra options to the ajax results
1079 *
1080 * @since 1.0.0
1081 *
1082 * @param array $results
1083 * @param string $id_key
1084 * @param string $text_key
1085 *
1086 * @return array
1087 */
1088 function automatorwp_ajax_parse_extra_options( $results, $id_key = 'id', $text_key = 'text' ) {
1089
1090 global $wpdb;
1091
1092 // Pull back the search string
1093 $search = isset( $_REQUEST['q'] ) ? $wpdb->esc_like( $_REQUEST['q'] ) : '';
1094 $page = isset( $_REQUEST['page'] ) ? absint( $_REQUEST['page'] ) : 1;
1095
1096 // Option none
1097 $option_none = isset( $_REQUEST['option_none'] ) ? absint( $_REQUEST['option_none'] ) : 0;
1098 $option_none_value = isset( $_REQUEST['option_none_value'] ) ? sanitize_text_field( $_REQUEST['option_none_value'] ) : '';
1099 $option_none_label = isset( $_REQUEST['option_none_label'] ) ? sanitize_text_field( $_REQUEST['option_none_label'] ) : '';
1100
1101 if( $option_none && ! empty( $option_none_value ) && ! empty( $option_none_label ) ) {
1102
1103 if( ( $page === 1 && empty( $search ) ) // Prepend option none if is first page
1104 || ( strpos( $option_none_label , $search ) ) // Prepend if search matches option none label
1105 ) {
1106 array_unshift( $results, array( $id_key => $option_none_value, $text_key => $option_none_label ) );
1107 }
1108
1109 }
1110
1111 // Option custom
1112 $option_custom = isset( $_REQUEST['option_custom'] ) ? absint( $_REQUEST['option_custom'] ) : 0;
1113 $option_custom_value = isset( $_REQUEST['option_custom_value'] ) ? sanitize_text_field( $_REQUEST['option_custom_value'] ) : '';
1114 $option_custom_label = isset( $_REQUEST['option_custom_label'] ) ? sanitize_text_field( $_REQUEST['option_custom_label'] ) : '';
1115
1116 if( $option_custom && ! empty( $option_custom_value ) && ! empty( $option_custom_label ) ) {
1117
1118 if( ( $page === 1 && empty( $search ) ) // Prepend option custom if is first page
1119 || ( strpos( $option_custom_label , $search ) ) // Prepend if search matches option custom label
1120 ) {
1121 array_unshift( $results, array( $id_key => $option_custom_value, $text_key => $option_custom_label ) );
1122 }
1123
1124 }
1125
1126 return $results;
1127
1128 }