Skip to content

Commit 84dbdc4

Browse files
authored
Merge branch 'master' into add/ServerActivities
2 parents 62714a5 + edad4d8 commit 84dbdc4

19 files changed

+265
-34
lines changed

.github/workflows/phpunit.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ jobs:
1515
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=10s --health-retries=10
1616
strategy:
1717
matrix:
18-
php-versions: ['5.6', '7.0', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
18+
php-versions: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
1919
include:
2020
- wp-version: latest
21-
- wp-version: '6.2'
22-
php-versions: '5.6'
2321
steps:
2422
- name: Checkout
2523
uses: actions/checkout@v2

CHANGELOG.md

+22
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.5.0] - 2024-07-01
9+
10+
### Added
11+
12+
* WebFinger cors header
13+
* WebFinger Content-Type
14+
* The Fediverse creator of a post to OpenGraph
15+
16+
### Changed
17+
18+
* Try to lookup local users first for Enable Mastodon Apps
19+
* Send also Announces for deletes
20+
* Load time by adding `count_total=false` to `WP_User_Query`
21+
22+
### Fixed
23+
24+
* Several WebFinger issues
25+
* Redirect issue for Application user
26+
* Accessibilty issues with missing screen-reader-text on User overview page
27+
28+
829
## [2.4.0] - 2024-06-05
930

1031
### Added
@@ -778,6 +799,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
778799

779800
* initial
780801

802+
[2.5.0]: https://github.com/Automattic/wordpress-activitypub/compare/2.4.0...2.5.0
781803
[2.4.0]: https://github.com/Automattic/wordpress-activitypub/compare/2.3.1...2.4.0
782804
[2.3.1]: https://github.com/Automattic/wordpress-activitypub/compare/2.3.0...2.3.1
783805
[2.3.0]: https://github.com/Automattic/wordpress-activitypub/compare/2.2.0...2.3.0

README.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
**Tags:** OStatus, fediverse, activitypub, activitystream
44
**Requires at least:** 5.5
55
**Tested up to:** 6.5
6-
**Stable tag:** 2.4.0
7-
**Requires PHP:** 5.6
6+
**Stable tag:** 2.5.0
7+
**Requires PHP:** 7.0
88
**License:** MIT
99
**License URI:** http://opensource.org/licenses/MIT
1010

@@ -101,9 +101,9 @@ Add the following to the site.conf in sites-available:
101101

102102
Where 'blog' is the path to the subdirectory at which your blog resides.
103103

104-
### What if you are running your blog in a subdirectory, but have a different [wp_siteurl](https://wordpress.org/documentation/article/giving-wordpress-its-own-directory/)? ###
104+
### What if you are running your blog in a subdirectory? ###
105105

106-
In that case you don't need the redirect, because the index.php will take care of that.
106+
If you are running your blog in a subdirectory, but have a different [wp_siteurl](https://wordpress.org/documentation/article/giving-wordpress-its-own-directory/), you don't need the redirect, because the index.php will take care of that.
107107

108108
### Constants ###
109109

@@ -133,6 +133,18 @@ For reasons of data protection, it is not possible to see the followers of other
133133

134134
## Changelog ##
135135

136+
### 2.5.0 ###
137+
138+
* Added: WebFinger cors header
139+
* Added: WebFinger Content-Type
140+
* Added: The Fediverse creator of a post to OpenGraph
141+
* Improved: Try to lookup local users first for Enable Mastodon Apps
142+
* Improved: Send also Announces for deletes
143+
* Improved: Load time by adding `count_total=false` to `WP_User_Query`
144+
* Fixed: Several WebFinger issues
145+
* Fixed: Redirect issue for Application user
146+
* Fixed: Accessibilty issues with missing screen-reader-text on User overview page
147+
136148
### 2.4.0 ###
137149

138150
* Added: A core/embed block filter to transform iframes to links

activitypub.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
* Plugin Name: ActivityPub
44
* Plugin URI: https://github.com/pfefferle/wordpress-activitypub/
55
* Description: The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format.
6-
* Version: 2.4.0
6+
* Version: 2.5.0
77
* Author: Matthias Pfefferle & Automattic
88
* Author URI: https://automattic.com/
99
* License: MIT
1010
* License URI: http://opensource.org/licenses/MIT
11-
* Requires PHP: 5.6
11+
* Requires PHP: 7.0
1212
* Text Domain: activitypub
1313
* Domain Path: /languages
1414
*/
@@ -23,7 +23,7 @@
2323
require_once __DIR__ . '/includes/compat.php';
2424
require_once __DIR__ . '/includes/functions.php';
2525

26-
\define( 'ACTIVITYPUB_PLUGIN_VERSION', '2.4.0' );
26+
\define( 'ACTIVITYPUB_PLUGIN_VERSION', '2.5.0' );
2727

2828
/**
2929
* Initialize the plugin constants.
@@ -104,6 +104,9 @@ function plugin_init() {
104104
require_once __DIR__ . '/integration/class-enable-mastodon-apps.php';
105105
Integration\Enable_Mastodon_Apps::init();
106106

107+
require_once __DIR__ . '/integration/class-opengraph.php';
108+
Integration\Opengraph::init();
109+
107110
if ( \defined( 'JETPACK__VERSION' ) && ! \defined( 'IS_WPCOM' ) ) {
108111
require_once __DIR__ . '/integration/class-jetpack.php';
109112
Integration\Jetpack::init();

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format.",
44
"type": "wordpress-plugin",
55
"require": {
6-
"php": ">=5.6.0",
6+
"php": ">=7.0",
77
"composer/installers": "^1.0 || ^2.0"
88
},
99
"require-dev": {
+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Extended Objects
2+
13
This folder contains more complex ActivityPub objects.
24

3-
Although they could be created using the Base_Object, they provide an easier structure for creating objects with maximum compatibility.
5+
Although they could be created using the `Base_Object`, they provide an easier structure for creating objects with maximum compatibility.

includes/class-admin.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,9 @@ public static function manage_users_custom_column( $output, $column_name, $user_
423423
}
424424

425425
if ( \user_can( $user_id, 'activitypub' ) ) {
426-
return '✓';
426+
return '<span aria-hidden="true">&#x2713;</span><span class="screen-reader-text">' . esc_html__( 'ActivityPub enabled for this author', 'activitypub' ) . '</span>';
427427
} else {
428-
return '&#x2717;';
428+
return '<span aria-hidden="true">&#x2717;</span><span class="screen-reader-text">' . esc_html__( 'ActivityPub disabled for this author', 'activitypub' ) . '</span>';
429429
}
430430
}
431431

includes/class-comment.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public static function should_be_federated( $comment ) {
241241
*
242242
* @param string $id ActivityPub object ID (usually a URL) to check.
243243
*
244-
* @return int|boolean Comment ID, or false on failure.
244+
* @return \WP_Comment|false Comment object, or false on failure.
245245
*/
246246
public static function object_id_to_comment( $id ) {
247247
$comment_query = new WP_Comment_Query(

includes/class-scheduler.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,16 @@ public static function schedule_post_activity( $new_status, $old_status, $post )
133133

134134
$type = false;
135135

136-
if ( 'publish' === $new_status && 'publish' !== $old_status ) {
136+
if (
137+
'publish' === $new_status &&
138+
'publish' !== $old_status
139+
) {
137140
$type = 'Create';
138-
} elseif ( 'publish' === $new_status ) {
141+
} elseif (
142+
'publish' === $new_status ||
143+
( 'draft' === $new_status &&
144+
'draft' !== $old_status )
145+
) {
139146
$type = 'Update';
140147
} elseif ( 'trash' === $new_status ) {
141148
$type = 'Delete';

includes/class-webfinger.php

+32-7
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ public static function resolve( $uri ) {
4646
return new WP_Error(
4747
'webfinger_missing_links',
4848
__( 'No valid Link elements found.', 'activitypub' ),
49-
$data
49+
array(
50+
'status' => 400,
51+
'data' => $data,
52+
)
5053
);
5154
}
5255

@@ -65,7 +68,10 @@ public static function resolve( $uri ) {
6568
return new WP_Error(
6669
'webfinger_url_no_activitypub',
6770
__( 'The Site supports WebFinger but not ActivityPub', 'activitypub' ),
68-
$data
71+
array(
72+
'status' => 400,
73+
'data' => $data,
74+
)
6975
);
7076
}
7177

@@ -103,7 +109,10 @@ public static function uri_to_acct( $uri ) {
103109
return new WP_Error(
104110
'webfinger_url_no_acct',
105111
__( 'No acct URI found.', 'activitypub' ),
106-
$data
112+
array(
113+
'status' => 400,
114+
'data' => $data,
115+
)
107116
);
108117
}
109118

@@ -144,7 +153,14 @@ public static function get_identifier_and_host( $url ) {
144153
}
145154

146155
if ( empty( $host ) ) {
147-
return new WP_Error( 'webfinger_invalid_identifier', __( 'Invalid Identifier', 'activitypub' ) );
156+
return new WP_Error(
157+
'webfinger_invalid_identifier',
158+
__( 'Invalid Identifier', 'activitypub' ),
159+
array(
160+
'status' => 400,
161+
'data' => $url,
162+
)
163+
);
148164
}
149165

150166
return array( $identifier, $host );
@@ -187,7 +203,10 @@ public static function get_data( $uri ) {
187203
return new WP_Error(
188204
'webfinger_url_not_accessible',
189205
__( 'The WebFinger Resource is not accessible.', 'activitypub' ),
190-
$webfinger_url
206+
array(
207+
'status' => 400,
208+
'data' => $webfinger_url,
209+
)
191210
);
192211
}
193212

@@ -215,7 +234,10 @@ public static function get_remote_follow_endpoint( $uri ) {
215234
return new WP_Error(
216235
'webfinger_missing_links',
217236
__( 'No valid Link elements found.', 'activitypub' ),
218-
$data
237+
array(
238+
'status' => 400,
239+
'data' => $data,
240+
)
219241
);
220242
}
221243

@@ -228,7 +250,10 @@ public static function get_remote_follow_endpoint( $uri ) {
228250
return new WP_Error(
229251
'webfinger_missing_remote_follow_endpoint',
230252
__( 'No valid Remote-Follow endpoint found.', 'activitypub' ),
231-
$data
253+
array(
254+
'status' => 400,
255+
'data' => $data,
256+
)
232257
);
233258
}
234259

includes/collection/class-interactions.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ public static function add_comment( $activity ) {
5454
return false;
5555
}
5656

57+
$url = object_to_uri( $meta['url'] );
58+
5759
$commentdata = array(
5860
'comment_post_ID' => $comment_post_id,
5961
'comment_author' => isset( $meta['name'] ) ? \esc_attr( $meta['name'] ) : \esc_attr( $meta['preferredUsername'] ),
60-
'comment_author_url' => \esc_url_raw( $meta['url'] ),
62+
'comment_author_url' => \esc_url_raw( $url ),
6163
'comment_content' => \addslashes( $activity['object']['content'] ),
6264
'comment_type' => 'comment',
6365
'comment_author_email' => '',
@@ -73,7 +75,7 @@ public static function add_comment( $activity ) {
7375
}
7476

7577
if ( isset( $activity['object']['url'] ) ) {
76-
$commentdata['comment_meta']['source_url'] = \esc_url_raw( $activity['object']['url'] );
78+
$commentdata['comment_meta']['source_url'] = \esc_url_raw( object_to_uri( $activity['object']['url'] ) );
7779
}
7880

7981
// disable flood control
@@ -198,7 +200,7 @@ public static function get_interactions_by_actor( $actor ) {
198200

199201
// get URL, because $actor seems to be the ID
200202
if ( $meta && ! is_wp_error( $meta ) && isset( $meta['url'] ) ) {
201-
$actor = $meta['url'];
203+
$actor = object_to_uri( $meta['url'] );
202204
}
203205

204206
$args = array(

includes/functions.php

+20
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ function is_local_comment( $comment ) {
794794
* Mark a WordPress object as federated.
795795
*
796796
* @param WP_Comment|WP_Post|mixed $wp_object
797+
*
797798
* @return void
798799
*/
799800
function set_wp_object_state( $wp_object, $state ) {
@@ -808,6 +809,25 @@ function set_wp_object_state( $wp_object, $state ) {
808809
}
809810
}
810811

812+
/**
813+
* Get the federation state of a WordPress object.
814+
*
815+
* @param WP_Comment|WP_Post|mixed $wp_object
816+
*
817+
* @return string|false The state of the object or false if not found.
818+
*/
819+
function get_wp_object_state( $wp_object ) {
820+
$meta_key = 'activitypub_status';
821+
822+
if ( $wp_object instanceof \WP_Post ) {
823+
return \get_post_meta( $wp_object->ID, $meta_key, true );
824+
} elseif ( $wp_object instanceof \WP_Comment ) {
825+
return \get_comment_meta( $wp_object->comment_ID, $meta_key, true );
826+
} else {
827+
return \apply_filters( 'activitypub_get_wp_object_state', false, $wp_object );
828+
}
829+
}
830+
811831
/**
812832
* Get the description of a post type.
813833
*

includes/handler/class-create.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public static function handle_create( $array, $user_id, $object = null ) {
6161
$state = Interactions::add_comment( $array );
6262
$reaction = null;
6363

64-
if ( $state && ! \is_wp_error( $reaction ) ) {
64+
if ( $state && ! \is_wp_error( $state ) ) {
6565
$reaction = \get_comment( $state );
6666
}
6767

includes/rest/class-comment.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static function init() {
2929
public static function register_routes() {
3030
\register_rest_route(
3131
ACTIVITYPUB_REST_NAMESPACE,
32-
'/(users|actors)/(?P<comment_id>\d+)/remote-reply',
32+
'/comments/(?P<comment_id>\d+)/remote-reply',
3333
array(
3434
array(
3535
'methods' => WP_REST_Server::READABLE,

includes/transformer/class-post.php

+18
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ public function get_url() {
101101

102102
if ( 'trash' === get_post_status( $post ) ) {
103103
$permalink = \get_post_meta( $post->ID, 'activitypub_canonical_url', true );
104+
} elseif ( 'draft' === get_post_status( $post ) && get_sample_permalink( $post->ID ) ) {
105+
$sample = get_sample_permalink( $post->ID );
106+
$permalink = str_replace( array( '%pagename%', '%postname%' ), $sample[1], $sample[0] );
104107
} else {
105108
$permalink = \get_permalink( $post );
106109
}
@@ -137,6 +140,11 @@ protected function get_attributed_to() {
137140
* @return array The Attachments.
138141
*/
139142
protected function get_attachment() {
143+
// Remove attachments from drafts.
144+
if ( 'draft' === \get_post_status( $this->wp_object ) ) {
145+
return array();
146+
}
147+
140148
// Once upon a time we only supported images, but we now support audio/video as well.
141149
// We maintain the image-centric naming for backwards compatibility.
142150
$max_media = \intval(
@@ -692,6 +700,11 @@ protected function get_summary() {
692700
return null;
693701
}
694702

703+
// Remove Teaser from drafts.
704+
if ( 'draft' === \get_post_status( $this->wp_object ) ) {
705+
return \__( '(This post is being modified)', 'activitypub' );
706+
}
707+
695708
$content = \get_post_field( 'post_content', $this->wp_object->ID );
696709
$content = \html_entity_decode( $content );
697710
$content = \wp_strip_all_tags( $content );
@@ -746,6 +759,11 @@ protected function get_name() {
746759
* @return string The content.
747760
*/
748761
protected function get_content() {
762+
// Remove Content from drafts.
763+
if ( 'draft' === \get_post_status( $this->wp_object ) ) {
764+
return \__( '(This post is being modified)', 'activitypub' );
765+
}
766+
749767
global $post;
750768

751769
/**

0 commit comments

Comments
 (0)