PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 6.0.2
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v6.0.2
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 5.6.2 All 33 releases
automatorwp / integrations / wordpress / actions / update-posts.php

update-posts.php in AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI 6.0.2, at integrations/wordpress/actions/update-posts.php

668 lines 28.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Update Posts
4 *
5 * @package AutomatorWP\Integrations\WordPress\Actions\Update_Posts
6 * @author AutomatorWP <contact@automatorwp.com>, Ruben Garcia <rubengcdev@gmail.com>
7 * @since 1.0.0
8 */
9 // Exit if accessed directly
10 if( !defined( 'ABSPATH' ) ) exit;
11
12 class AutomatorWP_WordPress_Update_Posts extends AutomatorWP_Integration_Action {
13
14 /**
15 * Initialize the trigger
16 *
17 * @since 1.0.0
18 */
19 public function __construct( $integration ) {
20
21 $this->integration = $integration;
22 $this->action = $integration . '_update_posts';
23
24 parent::__construct();
25
26 }
27
28 /**
29 * The post field conditions
30 *
31 * @since 1.0.0
32 *
33 * @var array $field_conditions
34 */
35 public $field_conditions = array();
36
37 /**
38 * The post meta conditions
39 *
40 * @since 1.0.0
41 *
42 * @var array $meta_conditions
43 */
44 public $meta_conditions = array();
45
46 /**
47 * The post meta
48 *
49 * @since 1.0.0
50 *
51 * @var array $post_meta
52 */
53 public $post_meta = array();
54
55 /**
56 * Store the action result
57 *
58 * @since 1.0.0
59 *
60 * @var string $result
61 */
62 public $result = '';
63
64 /**
65 * Register the trigger
66 *
67 * @since 1.0.0
68 */
69 public function register() {
70
71 $post_type_options = array();
72
73 foreach( get_post_types( array(), 'objects' ) as $post_type ) {
74 /* translators: %1$s: Post type key (post, page). %2$s: Post type name (Post, Page). */
75 $post_type_options[] = sprintf( __( '<code>%1$s</code> for %2$s', 'automatorwp' ), $post_type->name, $post_type->labels->name );
76 }
77
78 $post_status_options = array();
79
80 foreach( get_post_statuses() as $post_status => $post_status_label ) {
81 /* translators: %1$s: Post status key (draft, pending). %2$s: Post status label (Draft, Pending Review). */
82 $post_status_options[] = sprintf( __( '<code>%1$s</code> for %2$s', 'automatorwp' ), $post_status, $post_status_label );
83 }
84
85 automatorwp_register_action( $this->action, array(
86 'integration' => $this->integration,
87 'label' => __( 'Update all posts', 'automatorwp' ),
88 'select_option' => __( 'Update <strong>all posts</strong>', 'automatorwp' ),
89 /* translators: %1$s: Post. */
90 'edit_label' => sprintf( __( 'Update %1$s with %2$s', 'automatorwp' ), '{conditions}', '{post}' ),
91 /* translators: %1$s: Post. */
92 'log_label' => sprintf( __( 'Update %1$s with %2$s', 'automatorwp' ), '{conditions}', '{post}' ),
93 'options' => array(
94 'conditions' => array(
95 'default' => __( 'all posts', 'automatorwp' ),
96 'fields' => array(
97 'post_field_conditions' => array(
98 'name' => __( 'Field Conditions:', 'automatorwp' ),
99 'desc' => __( 'Set conditions to filter posts to update by post fields.', 'automatorwp' ),
100 'type' => 'group',
101 'classes' => 'automatorwp-fields-table',
102 'options' => array(
103 'add_button' => __( 'Add condition', 'automatorwp' ),
104 'remove_button' => '<span class="dashicons dashicons-no-alt"></span>',
105 ),
106 'fields' => array(
107 'field' => array(
108 'name' => __( 'Field:', 'automatorwp' ),
109 'type' => 'select',
110 'options' => array(
111 '' => __( 'Choose a field', 'automatorwp' ),
112 'ID' => __( 'ID', 'automatorwp' ),
113 'post_title' => __( 'Title', 'automatorwp' ),
114 'post_name' => __( 'Slug', 'automatorwp' ),
115 'post_type' => __( 'Type', 'automatorwp' ),
116 'post_status' => __( 'Status', 'automatorwp' ),
117 'post_date' => __( 'Date', 'automatorwp' ),
118 'post_date_modified' => __( 'Date Modified', 'automatorwp' ),
119 'post_author' => __( 'Author', 'automatorwp' ),
120 'post_content' => __( 'Content', 'automatorwp' ),
121 'post_excerpt' => __( 'Excerpt', 'automatorwp' ),
122 'post_parent' => __( 'Parent', 'automatorwp' ),
123 'menu_order' => __( 'Order', 'automatorwp' ),
124 'post_password' => __( 'Password', 'automatorwp' ),
125 ),
126 'default' => ''
127 ),
128 'condition' => automatorwp_utilities_condition_field(),
129 'value' => array(
130 'name' => __( 'Value:', 'automatorwp' ),
131 'type' => 'text',
132 'default' => ''
133 ),
134 ),
135 ),
136 'post_meta_conditions' => array(
137 'name' => __( 'Meta Conditions:', 'automatorwp' ),
138 'desc' => __( 'Set conditions to filter posts to update by post metas.', 'automatorwp' ),
139 'type' => 'group',
140 'classes' => 'automatorwp-fields-table',
141 'options' => array(
142 'add_button' => __( 'Add condition', 'automatorwp' ),
143 'remove_button' => '<span class="dashicons dashicons-no-alt"></span>',
144 ),
145 'fields' => array(
146 'meta_key' => array(
147 'name' => __( 'Meta Key:', 'automatorwp' ),
148 'type' => 'text',
149 'default' => ''
150 ),
151 'condition' => automatorwp_utilities_condition_field(),
152 'meta_value' => array(
153 'name' => __( 'Meta Value:', 'automatorwp' ),
154 'type' => 'text',
155 'default' => ''
156 ),
157 ),
158 ),
159 )
160 ),
161 'post' => array(
162 'default' => __( 'data', 'automatorwp' ),
163 'fields' => array(
164 'post_title' => array(
165 'name' => __( 'Title:', 'automatorwp' ),
166 'desc' => __( 'The post title.', 'automatorwp' )
167 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
168 'type' => 'text',
169 'default' => ''
170 ),
171 'post_name' => array(
172 'name' => __( 'URL slug:', 'automatorwp' ),
173 'desc' => __( 'The last part of the URL.', 'automatorwp' )
174 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' )
175 . ' ' . sprintf( __( '<a href="" target="_blank">Read about permalinks</a>', 'automatorwp' ), 'https://wordpress.org/support/article/writing-posts/#post-field-descriptions' ),
176 'type' => 'text',
177 'default' => ''
178 ),
179 'post_type' => array(
180 'name' => __( 'Type:', 'automatorwp' ),
181 'desc' => __( 'The post type.', 'automatorwp' )
182 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' )
183 . ' ' . automatorwp_toggleable_options_list( $post_type_options ),
184 'type' => 'text',
185 'default' => ''
186 ),
187 'post_status' => array(
188 'name' => __( 'Status:', 'automatorwp' ),
189 'desc' => __( 'The post status.', 'automatorwp' )
190 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' )
191 . ' ' . automatorwp_toggleable_options_list( $post_status_options ),
192 'type' => 'text',
193 'default' => ''
194 ),
195 'post_date' => array(
196 'name' => __( 'Date:', 'automatorwp' ),
197 'desc' => __( 'The date of the post. Supports "YYYY-MM-DD HH:MM:SS" and "YYYY-MM-DD" formats.', 'automatorwp' )
198 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
199 'type' => 'text',
200 'default' => ''
201 ),
202 'post_author' => array(
203 'name' => __( 'Author:', 'automatorwp' ),
204 'desc' => __( 'The ID of the user who added this post.', 'automatorwp' )
205 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
206 'type' => 'text',
207 'default' => ''
208 ),
209 'taxonomy' => automatorwp_utilities_ajax_selector_field( array(
210 'field' => 'taxonomy',
211 'option_default' => __( 'taxonomy', 'automatorwp' ),
212 'placeholder' => __( 'Select a taxonomy', 'automatorwp' ),
213 'name' => __( 'Taxonomy:', 'automatorwp' ),
214 'desc' => __( 'The post taxonomy.', 'automatorwp' ),
215 'action_cb' => 'automatorwp_wordpress_get_taxonomies',
216 'options_cb' => 'automatorwp_wordpress_options_cb_taxonomy',
217 'default' => ''
218 ) ),
219 'post_terms' => automatorwp_utilities_ajax_selector_field( array(
220 'field' => 'post_terms',
221 'option_default' => __( 'terms', 'automatorwp' ),
222 'placeholder' => __( 'Select a term', 'automatorwp' ),
223 'name' => __( 'Term:', 'automatorwp' ),
224 'desc' => __( 'The post term from taxonomy.', 'automatorwp' ),
225 'action_cb' => 'automatorwp_wordpress_get_terms',
226 'options_cb' => 'automatorwp_wordpress_options_cb_term',
227 'default' => ''
228 ) ),
229 'post_content' => array(
230 'name' => __( 'Content:', 'automatorwp' ),
231 'desc' => __( 'The post content.', 'automatorwp' )
232 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
233 'type' => 'wysiwyg',
234 'default' => ''
235 ),
236 'post_excerpt' => array(
237 'name' => __( 'Excerpt:', 'automatorwp' ),
238 'desc' => __( 'The post excerpt.', 'automatorwp' )
239 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
240 'type' => 'textarea',
241 'default' => ''
242 ),
243 'post_parent' => array(
244 'name' => __( 'Parent:', 'automatorwp' ),
245 'desc' => __( 'The post parent.', 'automatorwp' )
246 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
247 'type' => 'text',
248 'default' => ''
249 ),
250 'menu_order' => array(
251 'name' => __( 'Menu order:', 'automatorwp' ),
252 'desc' => __( 'The post menu order.', 'automatorwp' )
253 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
254 'type' => 'text',
255 'default' => ''
256 ),
257 'post_password' => array(
258 'name' => __( 'Password:', 'automatorwp' ),
259 'desc' => __( 'The password to access this post.', 'automatorwp' )
260 . ' ' . __( 'Leave empty to no update this field.', 'automatorwp' ),
261 'type' => 'text',
262 'default' => ''
263 ),
264 'post_meta' => array(
265 'name' => __( 'Post Meta:', 'automatorwp' ),
266 'desc' => __( 'The post meta values keyed by their post meta key.', 'automatorwp' ),
267 'type' => 'group',
268 'classes' => 'automatorwp-fields-table',
269 'options' => array(
270 'add_button' => __( 'Add meta', 'automatorwp' ),
271 'remove_button' => '<span class="dashicons dashicons-no-alt"></span>',
272 ),
273 'fields' => array(
274 'meta_key' => array(
275 'name' => __( 'Meta Key:', 'automatorwp' ),
276 'type' => 'text',
277 'default' => ''
278 ),
279 'meta_value' => array(
280 'name' => __( 'Meta Value:', 'automatorwp' ),
281 'type' => 'text',
282 'default' => ''
283 ),
284 ),
285 ),
286 )
287 )
288 ),
289 ) );
290
291 }
292
293 /**
294 * Action execution function
295 *
296 * @since 1.0.0
297 *
298 * @param stdClass $action The action object
299 * @param int $user_id The user ID
300 * @param array $action_options The action's stored options (with tags already passed)
301 * @param stdClass $automation The action's automation object
302 */
303 public function execute( $action, $user_id, $action_options, $automation ) {
304
305 $this->result = '';
306 $this->field_conditions = array();
307 $this->meta_conditions = array();
308 $this->post_meta = array();
309
310 global $wpdb;
311
312 // Filter the posts
313 $field_conditions = $action_options['post_field_conditions'];
314 $meta_conditions = $action_options['post_meta_conditions'];
315
316 $joins = array();
317 $where = array();
318
319 // Setup the post field conditions
320 foreach( $field_conditions as $condition ) {
321
322 // Parse automation tags replacements to both, key and value
323 $field = automatorwp_parse_automation_tags( $automation->id, $user_id, $condition['field'] );
324 $value = automatorwp_parse_automation_tags( $automation->id, $user_id, $condition['value'] );
325
326 // Sanitize
327 $field = sanitize_text_field( $field );
328 $value = sanitize_text_field( $value );
329
330 if( ! empty( $field ) ) {
331 $where[] = automatorwp_utilities_parse_condition_to_sql( 'p.' . $field, $condition['condition'], $value );
332
333 $this->field_conditions[] = array(
334 'field' => $field,
335 'condition' => $condition['condition'],
336 'value' => $value,
337 );
338 }
339 }
340
341 // Setup the post meta conditions
342 foreach( $meta_conditions as $condition ) {
343
344 // Parse automation tags replacements to both, key and value
345 $meta_key = automatorwp_parse_automation_tags( $automation->id, $user_id, $condition['meta_key'] );
346 $meta_value = automatorwp_parse_automation_tags( $automation->id, $user_id, $condition['meta_value'] );
347
348 // Sanitize
349 $meta_key = sanitize_text_field( $meta_key );
350 $meta_value = sanitize_text_field( $meta_value );
351
352 if( ! empty( $meta_key ) ) {
353 $index = count( $joins );
354
355 $joins[] = "INNER JOIN {$wpdb->postmeta} AS pm{$index} ON ( pm{$index}.post_id = p.ID AND pm{$index}.meta_key = '{$meta_key}' )";
356
357 $where[] = automatorwp_utilities_parse_condition_to_sql( "pm{$index}.meta_value", $condition['condition'], $meta_value, false );
358
359 $this->meta_conditions[] = array(
360 'meta_key' => $meta_key,
361 'condition' => $condition['condition'],
362 'meta_value' => $meta_value,
363 );
364 }
365 }
366
367 // Turn arrays into strings
368 $joins = implode( ' ', $joins );
369 $where = ( ! empty( $where ) ? 'WHERE ( ' . implode( ' ) AND ( ', $where ) . ' ) ' : '' );
370
371 $sql = "SELECT p.ID
372 FROM {$wpdb->posts} AS p
373 {$joins}
374 {$where}";
375
376 $post_ids = $wpdb->get_col( $sql );
377
378 // Bail if not posts found
379 if( count( $post_ids ) === 0 ) {
380 $this->result = __( 'No posts found to be updated.', 'automatorwp' );
381 return;
382 }
383
384 // Parse the metas to update
385 if( is_array( $action_options['post_meta'] ) ) {
386
387 foreach( $action_options['post_meta'] as $i => $meta ) {
388
389 // Parse automation tags replacements to both, key and value
390 $meta_key = automatorwp_parse_automation_tags( $automation->id, $user_id, $meta['meta_key'] );
391 $meta_value = automatorwp_parse_automation_tags( $automation->id, $user_id, $meta['meta_value'] );
392
393 // Sanitize
394 $meta_key = sanitize_text_field( $meta_key );
395 $meta_value = sanitize_text_field( $meta_value );
396
397 $this->post_meta[$meta_key] = $meta_value;
398
399 // Update action options to be passed on upcoming hooks
400 $action_options['post_meta'][$i] = array(
401 'meta_key' => $meta_key,
402 'meta_value' => $meta_value,
403 );
404
405 }
406
407 }
408
409 // Update the posts
410 foreach( $post_ids as $post_id ) {
411
412 // Setup post data
413 $post_data = array();
414
415 $post_fields = array(
416 'post_title',
417 'post_name',
418 'post_type',
419 'post_status',
420 'post_date',
421 'post_author',
422 'post_content',
423 'post_excerpt',
424 'post_parent',
425 'menu_order',
426 'post_password',
427 );
428
429 $post_taxonomy = $action_options['taxonomy'];
430 $post_term = $action_options['post_terms'];
431
432 foreach( $post_fields as $post_field ) {
433 if( ! empty( $action_options[$post_field] ) ) {
434 $post_data[$post_field] = $action_options[$post_field];
435 }
436 }
437
438 $post_data['ID'] = $post_id;
439
440 // Update the post
441 wp_update_post( $post_data );
442
443 // Add to term if is selected
444 if ( $post_taxonomy !== 'any' || $post_term !== 'any' ){
445 $term_data = get_term( $post_term );
446 wp_set_object_terms( $this->post_id, absint( $term_data->term_id ), $term_data->taxonomy, false );
447 }
448
449 // Update the post metas
450 foreach( $this->post_meta as $meta_key => $meta_value ) {
451 update_post_meta( $post_id, $meta_key, $meta_value );
452 }
453 }
454
455 $this->result = sprintf( __( '%d posts updated.', 'automatorwp' ), count( $post_ids ) );
456
457 }
458
459 /**
460 * Register required hooks
461 *
462 * @since 1.0.0
463 */
464 public function hooks() {
465
466 // Log meta data
467 add_filter( 'automatorwp_user_completed_action_log_meta', array( $this, 'log_meta' ), 10, 5 );
468
469 // Log fields
470 add_filter( 'automatorwp_log_fields', array( $this, 'log_fields' ), 10, 5 );
471
472 parent::hooks();
473 }
474
475 /**
476 * Action custom log meta
477 *
478 * @since 1.0.0
479 *
480 * @param array $log_meta Log meta data
481 * @param stdClass $action The action object
482 * @param int $user_id The user ID
483 * @param array $action_options The action's stored options (with tags already passed)
484 * @param stdClass $automation The action's automation object
485 *
486 * @return array
487 */
488 public function log_meta( $log_meta, $action, $user_id, $action_options, $automation ) {
489
490 // Bail if action type don't match this action
491 if( $action->type !== $this->action ) {
492 return $log_meta;
493 }
494
495 // Store the filters applied
496 $log_meta['field_conditions'] = $this->field_conditions;
497 $log_meta['field_conditions_parsed'] = '';
498
499 foreach( $this->field_conditions as $condition ) {
500 $log_meta['field_conditions_parsed'] .= sprintf( '%s %s %s',
501 $condition['field'],
502 automatorwp_utilities_get_condition_label( $condition['condition'] ),
503 $condition['value'],
504 ) . "<br>";
505 }
506
507 $log_meta['meta_conditions'] = $this->meta_conditions;
508 $log_meta['meta_conditions_parsed'] = '';
509
510 foreach( $this->meta_conditions as $condition ) {
511 $log_meta['meta_conditions_parsed'] .= sprintf( '%s %s %s',
512 $condition['meta_key'],
513 automatorwp_utilities_get_condition_label( $condition['condition'] ),
514 $condition['meta_value'],
515 ) . "<br>";
516 }
517
518 // Store result
519 $log_meta['result'] = $this->result;
520
521 // Store post fields
522 $post_fields = array(
523 'post_title',
524 'post_name',
525 'post_type',
526 'post_status',
527 'post_date',
528 'post_author',
529 'post_content',
530 'post_excerpt',
531 'post_parent',
532 'menu_order',
533 'post_password',
534 );
535
536 foreach( $post_fields as $post_field ) {
537 $log_meta[$post_field] = $action_options[$post_field];
538 }
539
540 // Store post meta
541 $log_meta['post_meta'] = $this->post_meta;
542
543 return $log_meta;
544 }
545
546 /**
547 * Action custom log fields
548 *
549 * @since 1.0.0
550 *
551 * @param array $log_fields The log fields
552 * @param stdClass $log The log object
553 * @param stdClass $object The trigger/action/automation object attached to the log
554 *
555 * @return array
556 */
557 public function log_fields( $log_fields, $log, $object ) {
558
559 // Bail if log is not assigned to an action
560 if( $log->type !== 'action' || $object->type !== $this->action )
561 return $log_fields;
562
563 $log_fields['posts_found_info'] = array(
564 'name' => __( 'Posts Filtered', 'automatorwp' ),
565 'desc' => __( 'Information about the filters applied and the posts found.', 'automatorwp' ),
566 'type' => 'title',
567 );
568
569 $log_fields['field_conditions_parsed'] = array(
570 'name' => __( 'Field conditions:', 'automatorwp' ),
571 'type' => 'text',
572 );
573
574 $log_fields['meta_conditions_parsed'] = array(
575 'name' => __( 'Meta conditions:', 'automatorwp' ),
576 'type' => 'text',
577 );
578
579 $log_fields['result'] = array(
580 'name' => __( 'Result:', 'automatorwp' ),
581 'type' => 'text',
582 );
583
584 $log_fields['post_info'] = array(
585 'name' => __( 'Data Updated', 'automatorwp' ),
586 'desc' => __( 'Information about the data updated to all posts found.', 'automatorwp' ),
587 'type' => 'title',
588 );
589
590 $log_fields['post_title'] = array(
591 'name' => __( 'Title:', 'automatorwp' ),
592 'desc' => __( 'The post title.', 'automatorwp' ),
593 'type' => 'text',
594 );
595
596 $log_fields['post_name'] = array(
597 'name' => __( 'URL slug:', 'automatorwp' ),
598 'desc' => __( 'The post URL slug.', 'automatorwp' ),
599 'type' => 'text',
600 );
601
602 $log_fields['post_type'] = array(
603 'name' => __( 'Type:', 'automatorwp' ),
604 'desc' => __( 'The post type.', 'automatorwp' ),
605 'type' => 'text',
606 );
607
608 $log_fields['post_status'] = array(
609 'name' => __( 'Status:', 'automatorwp' ),
610 'desc' => __( 'The post status.', 'automatorwp' ),
611 'type' => 'text',
612 );
613
614 $log_fields['post_date'] = array(
615 'name' => __( 'Date:', 'automatorwp' ),
616 'desc' => __( 'The date of the post.', 'automatorwp' ),
617 'type' => 'text',
618 );
619
620 $log_fields['post_author'] = array(
621 'name' => __( 'Author:', 'automatorwp' ),
622 'desc' => __( 'The ID of the user who added this post.', 'automatorwp' ),
623 'type' => 'text',
624 );
625
626 $log_fields['post_content'] = array(
627 'name' => __( 'Content:', 'automatorwp' ),
628 'desc' => __( 'The post content.', 'automatorwp' ),
629 'type' => 'text',
630 );
631
632 $log_fields['post_excerpt'] = array(
633 'name' => __( 'Excerpt:', 'automatorwp' ),
634 'desc' => __( 'The post excerpt.', 'automatorwp' ),
635 'type' => 'text',
636 );
637
638 $log_fields['post_parent'] = array(
639 'name' => __( 'Parent:', 'automatorwp' ),
640 'desc' => __( 'The post parent.', 'automatorwp' ),
641 'type' => 'text',
642 );
643
644 $log_fields['menu_order'] = array(
645 'name' => __( 'Menu order:', 'automatorwp' ),
646 'desc' => __( 'The post menu order.', 'automatorwp' ),
647 'type' => 'text',
648 );
649
650 $log_fields['post_password'] = array(
651 'name' => __( 'Password:', 'automatorwp' ),
652 'desc' => __( 'The password to access this post.', 'automatorwp' ),
653 'type' => 'text',
654 );
655
656 $log_fields['post_meta'] = array(
657 'name' => __( 'Post Meta:', 'automatorwp' ),
658 'desc' => __( 'The post meta values keyed by their post meta key.', 'automatorwp' ),
659 'type' => 'text',
660 );
661
662 return $log_fields;
663 }
664
665 }
666
667 new AutomatorWP_WordPress_Update_Posts( 'wordpress' );
668 new AutomatorWP_WordPress_Update_Posts( 'posts' );