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-multiple-posts.php

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

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