-
Notifications
You must be signed in to change notification settings - Fork 85
Add support for ActivityPub Reader-Item post type #2311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
27ce87b
Add support for ActivityPub object post type
pfefferle fd3661e
Add ActivityPub content sanitizer and update usage
pfefferle 5707420
Add HTML to blocks conversion and refactor sanitization
pfefferle 630aec6
Remove get_node_attributes method and inline list attribute
pfefferle ca3305e
Rename html_to_blocks to convert_from_html in Blocks
pfefferle 5ab729b
Apply suggestion from @Copilot
pfefferle e302e93
Apply suggestion from @Copilot
pfefferle 955921c
Apply suggestion from @Copilot
pfefferle d0fa8e1
Add tests for content sanitization and block conversion
pfefferle 7d6004e
Add tests for Create handler object sanitization and edge cases
pfefferle 7466883
Add unit tests for Objects collection class
pfefferle b61302e
Add changelog
matticbot a400925
Refactor Update handler methods for clarity
pfefferle 859b33b
Update @covers annotation to handle_actor_update
pfefferle 9f43130
Update post type labels from 'Post' to 'Object'
pfefferle 67932d8
Add missing newline after use statements
pfefferle 7f07d36
Remove HTML to blocks conversion logic
pfefferle 02528e1
Rename Objects collection to Posts throughout codebase
pfefferle f59a8f4
Fix comments and return types
obenland 64d92ce
Rename create_object to create_post in Create handler
pfefferle 94a9cc7
Update @covers annotation in test for create_post
pfefferle 406d34e
Register post meta for remote actor ID
pfefferle 3b345a0
Add 'ap_object_type' taxonomy to post type
pfefferle 5dbbd42
Remove custom labels from taxonomy registration
pfefferle b5adfa3
Remove custom rewrite slugs from taxonomy registration
pfefferle f6dd350
Rename handle_actor_update to update_actor
pfefferle f784eb1
Rename test method and update covered function
pfefferle f9fc961
Refactor update handler result and docblock types
pfefferle a367a97
Improve error handling in Create and Update handlers
pfefferle c86fb3c
Refactor default error handling in handle_object_update
pfefferle ea44b16
Handle missing actor data in update handler
pfefferle df5afff
Refactor return values for create handler methods
pfefferle eb6c737
Merge branch 'trunk' into cpt-ap-post
pfefferle daa1ea4
Merge branch 'trunk' into cpt-ap-post
pfefferle f6a9aa6
Apply suggestion from @obenland
pfefferle 0a323e3
Refactor post type and update handler method names
pfefferle 77df3fc
Update post type registration method names in tests
pfefferle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: minor | ||
Type: added | ||
|
||
Added a new ap_object post type and taxonomies for storing and managing incoming ActivityPub objects, with updated handlers |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
<?php | ||
/** | ||
* Posts collection file. | ||
* | ||
* @package Activitypub | ||
*/ | ||
|
||
namespace Activitypub\Collection; | ||
|
||
use Activitypub\Sanitize; | ||
|
||
use function Activitypub\object_to_uri; | ||
|
||
/** | ||
* Posts collection. | ||
* | ||
* Provides methods to retrieve, create, update, and manage ActivityPub posts (articles, notes, media, etc.). | ||
*/ | ||
class Posts { | ||
/** | ||
* The post type for the posts. | ||
* | ||
* @var string | ||
*/ | ||
const POST_TYPE = 'ap_post'; | ||
|
||
/** | ||
* Add an object to the collection. | ||
* | ||
* @param array $activity The activity object data. | ||
* | ||
* @return \WP_Post|\WP_Error The object post or WP_Error on failure. | ||
*/ | ||
public static function add( $activity ) { | ||
$activity_object = $activity['object']; | ||
$actor = Remote_Actors::fetch_by_uri( object_to_uri( $activity_object['attributedTo'] ) ); | ||
|
||
if ( \is_wp_error( $actor ) ) { | ||
return $actor; | ||
} | ||
|
||
$post_array = self::activity_to_post( $activity_object ); | ||
$post_id = \wp_insert_post( $post_array, true ); | ||
|
||
if ( \is_wp_error( $post_id ) ) { | ||
return $post_id; | ||
} | ||
|
||
\add_post_meta( $post_id, '_activitypub_remote_actor_id', $actor->ID ); | ||
|
||
self::add_taxonomies( $post_id, $activity_object ); | ||
|
||
return \get_post( $post_id ); | ||
} | ||
|
||
/** | ||
* Get an object from the collection. | ||
* | ||
* @param int $id The object ID. | ||
* | ||
* @return \WP_Post|null The post object or null on failure. | ||
*/ | ||
public static function get( $id ) { | ||
return \get_post( $id ); | ||
} | ||
|
||
/** | ||
* Get an object by its GUID. | ||
* | ||
* @param string $guid The object GUID. | ||
* | ||
* @return \WP_Post|\WP_Error The object post or WP_Error on failure. | ||
*/ | ||
public static function get_by_guid( $guid ) { | ||
global $wpdb; | ||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | ||
$post_id = $wpdb->get_var( | ||
$wpdb->prepare( | ||
"SELECT ID FROM $wpdb->posts WHERE guid=%s AND post_type=%s", | ||
\esc_url( $guid ), | ||
self::POST_TYPE | ||
) | ||
); | ||
|
||
if ( ! $post_id ) { | ||
return new \WP_Error( | ||
'activitypub_object_not_found', | ||
\__( 'Object not found', 'activitypub' ), | ||
array( 'status' => 404 ) | ||
); | ||
} | ||
|
||
return \get_post( $post_id ); | ||
} | ||
|
||
/** | ||
* Update an object in the collection. | ||
* | ||
* @param array $activity The activity object data. | ||
* | ||
* @return \WP_Post|\WP_Error The updated object post or WP_Error on failure. | ||
*/ | ||
public static function update( $activity ) { | ||
$post = self::get_by_guid( $activity['object']['id'] ); | ||
if ( \is_wp_error( $post ) ) { | ||
return $post; | ||
} | ||
|
||
$post_array = self::activity_to_post( $activity['object'] ); | ||
$post_array['ID'] = $post->ID; | ||
$post_id = \wp_update_post( $post_array, true ); | ||
|
||
if ( \is_wp_error( $post_id ) ) { | ||
return $post_id; | ||
} | ||
|
||
self::add_taxonomies( $post_id, $activity['object'] ); | ||
|
||
return \get_post( $post_id ); | ||
} | ||
|
||
/** | ||
* Convert an activity to a post array. | ||
* | ||
* @param array $activity The activity array. | ||
* | ||
* @return array|\WP_Error The post array or WP_Error on failure. | ||
*/ | ||
private static function activity_to_post( $activity ) { | ||
if ( ! is_array( $activity ) ) { | ||
return new \WP_Error( 'invalid_activity', __( 'Invalid activity format', 'activitypub' ) ); | ||
} | ||
|
||
return array( | ||
'post_title' => isset( $activity['name'] ) ? \wp_strip_all_tags( $activity['name'] ) : '', | ||
'post_content' => isset( $activity['content'] ) ? Sanitize::content( $activity['content'] ) : '', | ||
'post_excerpt' => isset( $activity['summary'] ) ? \wp_strip_all_tags( $activity['summary'] ) : '', | ||
'post_status' => 'publish', | ||
'post_type' => self::POST_TYPE, | ||
'guid' => isset( $activity['id'] ) ? \esc_url_raw( $activity['id'] ) : '', | ||
); | ||
} | ||
|
||
/** | ||
* Add taxonomies to the object post. | ||
* | ||
* @param int $post_id The post ID. | ||
* @param array $activity_object The activity object data. | ||
*/ | ||
private static function add_taxonomies( $post_id, $activity_object ) { | ||
// Save Object Type as Taxonomy item. | ||
\wp_set_post_terms( $post_id, array( $activity_object['type'] ), 'ap_object_type' ); | ||
|
||
$tags = array(); | ||
|
||
// Save the Hashtags as Taxonomy items. | ||
if ( ! empty( $activity_object['tag'] ) && \is_array( $activity_object['tag'] ) ) { | ||
foreach ( $activity_object['tag'] as $tag ) { | ||
if ( isset( $tag['type'] ) && 'Hashtag' === $tag['type'] && isset( $tag['name'] ) ) { | ||
$tags[] = \wp_strip_all_tags( ltrim( $tag['name'], '#' ) ); | ||
} | ||
} | ||
} | ||
|
||
\wp_set_post_terms( $post_id, $tags, 'ap_tag' ); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.