PluginProbe
ActivityPub / 5.1.0
ActivityPub v5.1.0
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / scheduler / class-post.php

class-post.php in ActivityPub 5.1.0, at includes/scheduler/class-post.php

197 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Post scheduler class file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Scheduler;
9
10 use Activitypub\Activity\Activity;
11 use Activitypub\Scheduler;
12 use Activitypub\Collection\Outbox;
13 use Activitypub\Collection\Actors;
14 use Activitypub\Transformer\Factory;
15
16 use function Activitypub\add_to_outbox;
17 use function Activitypub\is_post_disabled;
18 use function Activitypub\get_wp_object_state;
19
20 /**
21 * Post scheduler class.
22 */
23 class Post {
24 /**
25 * Initialize the class, registering WordPress hooks.
26 */
27 public static function init() {
28 // Post transitions.
29 \add_action( 'transition_post_status', array( self::class, 'schedule_post_activity' ), 33, 3 );
30
31 // Attachment transitions.
32 \add_action( 'add_attachment', array( self::class, 'transition_attachment_status' ) );
33 \add_action( 'edit_attachment', array( self::class, 'transition_attachment_status' ) );
34 \add_action( 'delete_attachment', array( self::class, 'transition_attachment_status' ) );
35
36 \add_action( 'post_activitypub_add_to_outbox', array( self::class, 'schedule_announce_activity' ), 10, 4 );
37
38 // Get all post types that support ActivityPub.
39 $post_types = \get_post_types_by_support( 'activitypub' );
40
41 foreach ( $post_types as $post_type ) {
42 \add_filter( "rest_pre_insert_{$post_type}", array( self::class, 'rest_insert' ), 10, 2 );
43 }
44 }
45
46 /**
47 * Schedules Activities for attachment transitions.
48 *
49 * @param int $post_id Attachment ID.
50 */
51 public static function transition_attachment_status( $post_id ) {
52 if ( ! \post_type_supports( 'attachment', 'activitypub' ) ) {
53 return;
54 }
55
56 switch ( current_action() ) {
57 case 'add_attachment':
58 self::schedule_post_activity( 'publish', '', get_post( $post_id ) );
59 break;
60 case 'edit_attachment':
61 self::schedule_post_activity( 'publish', 'publish', get_post( $post_id ) );
62 break;
63 case 'delete_attachment':
64 self::schedule_post_activity( 'trash', '', get_post( $post_id ) );
65 break;
66 }
67 }
68
69 /**
70 * Schedule Activities.
71 *
72 * @param string $new_status New post status.
73 * @param string $old_status Old post status.
74 * @param \WP_Post $post Post object.
75 */
76 public static function schedule_post_activity( $new_status, $old_status, $post ) {
77 if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
78 return;
79 }
80
81 if ( is_post_disabled( $post ) ) {
82 return;
83 }
84
85 switch ( $new_status ) {
86 case 'publish':
87 $type = ( 'publish' === $old_status ) ? 'Update' : 'Create';
88 break;
89
90 case 'draft':
91 $type = ( 'publish' === $old_status ) ? 'Update' : false;
92 break;
93
94 case 'trash':
95 $type = 'Delete';
96 break;
97
98 default:
99 $type = false;
100 }
101
102 // Do not send Activities if `$type` is not set or unknown.
103 if ( empty( $type ) ) {
104 return;
105 }
106
107 // Add the post to the outbox.
108 add_to_outbox( $post, $type, $post->post_author );
109 }
110
111 /**
112 * Send announces.
113 *
114 * @param int $outbox_activity_id The outbox activity ID.
115 * @param Activity $activity_object The activity object.
116 * @param int $actor_id The actor ID.
117 * @param int $content_visibility The content visibility.
118 */
119 public static function schedule_announce_activity( $outbox_activity_id, $activity_object, $actor_id, $content_visibility ) {
120 // Only if we're in both Blog and User modes.
121 if ( ACTIVITYPUB_ACTOR_AND_BLOG_MODE !== \get_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_MODE ) ) {
122 return;
123 }
124
125 // Only if this isn't the Blog Actor.
126 if ( Actors::BLOG_USER_ID === $actor_id ) {
127 return;
128 }
129
130 // Only if the content is public or quiet public.
131 if ( ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC !== $content_visibility ) {
132 return;
133 }
134
135 $activity_type = \get_post_meta( $outbox_activity_id, '_activitypub_activity_type', true );
136
137 // Only if the activity is a Create, Update or Delete.
138 if ( ! in_array( $activity_type, array( 'Create', 'Update', 'Delete' ), true ) ) {
139 return;
140 }
141
142 // Check if the object is an article, image, audio, video, event or document and ignore profile updates and other activities.
143 if ( ! in_array( $activity_object->get_type(), array( 'Note', 'Article', 'Image', 'Audio', 'Video', 'Event', 'Document' ), true ) ) {
144 return;
145 }
146
147 $transformer = Factory::get_transformer( $activity_object );
148 if ( ! $transformer || \is_wp_error( $transformer ) ) {
149 return;
150 }
151
152 $outbox_activity_id = Outbox::add( $transformer->to_activity( $activity_type ), 'Announce', Actors::BLOG_USER_ID );
153
154 if ( ! $outbox_activity_id ) {
155 return;
156 }
157
158 // Schedule the outbox item for federation.
159 Scheduler::schedule_outbox_activity_for_federation( $outbox_activity_id );
160 }
161
162 /**
163 * Filter the post data before it is inserted via the REST API.
164 *
165 * Posts being inserted via the REST API have a different order of operations than in wp_insert_post().
166 * This filter updates post meta before the post is inserted into the database, so that the
167 * information is available by the time @see Outbox::add() runs.
168 *
169 * @param \stdClass $post An object representing a single post prepared for inserting or updating the database.
170 * @param \WP_REST_Request $request The request object.
171 *
172 * @return \stdClass The prepared post.
173 */
174 public static function rest_insert( $post, $request ) {
175 $metas = $request->get_param( 'meta' );
176
177 if ( ! $post->ID || ! $metas || ! is_array( $metas ) ) {
178 return $post;
179 }
180
181 foreach ( $metas as $meta_key => $meta_value ) {
182 if (
183 \str_starts_with( $meta_key, 'activitypub_' ) ||
184 \str_starts_with( $meta_key, '_activitypub_' )
185 ) {
186 if ( $meta_value ) {
187 \update_post_meta( $post->ID, $meta_key, $meta_value );
188 } else {
189 \delete_post_meta( $post->ID, $meta_key );
190 }
191 }
192 }
193
194 return $post;
195 }
196 }
197