Merge commit 'a3ea9955d98c93999f3a5572ce293b9ee35addaf' into dev/extendable-transformers
Some checks failed
PHP_CodeSniffer / phpcs (push) Has been cancelled
Unit Testing / phpunit (5.6, 6.2) (push) Has been cancelled
Unit Testing / phpunit (7.0) (push) Has been cancelled
Unit Testing / phpunit (7.2) (push) Has been cancelled
Unit Testing / phpunit (7.3) (push) Has been cancelled
Unit Testing / phpunit (7.4) (push) Has been cancelled
Unit Testing / phpunit (8.0) (push) Has been cancelled
Unit Testing / phpunit (8.1) (push) Has been cancelled
Unit Testing / phpunit (8.2) (push) Has been cancelled
Unit Testing / phpunit (latest) (push) Has been cancelled

This commit is contained in:
André Menrath 2023-12-22 09:30:23 +01:00
commit eabfbc9179
14 changed files with 103 additions and 28 deletions

View file

@ -14,6 +14,7 @@ The WordPress plugin largely follows ActivityPub's server-to-server specificatio
- [FEP-f1d5: NodeInfo in Fediverse Software](https://codeberg.org/fediverse/fep/src/branch/main/fep/f1d5/fep-f1d5.md) - [FEP-f1d5: NodeInfo in Fediverse Software](https://codeberg.org/fediverse/fep/src/branch/main/fep/f1d5/fep-f1d5.md)
- [FEP-67ff: FEDERATION.md](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md) - [FEP-67ff: FEDERATION.md](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md)
- [FEP-5feb: Search indexing consent for actors](https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md) - [FEP-5feb: Search indexing consent for actors](https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md)
- [FEP-2677: Identifying the Application Actor](https://codeberg.org/fediverse/fep/src/branch/main/fep/2677/fep-2677.md)
Partially supported FEPs Partially supported FEPs

View file

@ -68,10 +68,10 @@ Implemented:
* share posts * share posts
* receive comments/reactions * receive comments/reactions
* signature verification * signature verification
* threaded comments support
To implement: To implement:
* threaded comments support
* replace shortcodes with blocks for layout * replace shortcodes with blocks for layout
### What is "ActivityPub for WordPress" ### ### What is "ActivityPub for WordPress" ###
@ -111,7 +111,9 @@ Project maintained on GitHub at [automattic/wordpress-activitypub](https://githu
* Fixed: Normalize attributes that can have mixed value types * Fixed: Normalize attributes that can have mixed value types
* Added: URL support for WebFinger * Added: URL support for WebFinger
* Added: Make Post-Template filterable * Added: Make Post-Template filterable
* Addes: CSS class for ActivityPub comments to allow custom designs * Added: CSS class for ActivityPub comments to allow custom designs
* Added: FEP-2677: Identifying the Application Actor
* Improved: WebFinger endpoints
### 1.3.0 ### ### 1.3.0 ###

View file

@ -196,7 +196,7 @@ class Activity extends Base_Object {
public function set_object( $object ) { public function set_object( $object ) {
// convert array to object // convert array to object
if ( is_array( $object ) ) { if ( is_array( $object ) ) {
$object = Base_Object::init_from_array( $object ); $object = self::init_from_array( $object );
} }
// set object // set object

View file

@ -39,11 +39,6 @@ class Health_Check {
'test' => array( self::class, 'test_webfinger' ), 'test' => array( self::class, 'test_webfinger' ),
); );
$tests['direct']['activitypub_test_system_cron'] = array(
'label' => __( 'System Cron Test', 'activitypub' ),
'test' => array( self::class, 'test_system_cron' ),
);
return $tests; return $tests;
} }

View file

@ -127,8 +127,7 @@ class Shortcodes {
// Strip out any remaining tags. // Strip out any remaining tags.
$excerpt = \wp_strip_all_tags( $excerpt ); $excerpt = \wp_strip_all_tags( $excerpt );
/** This filter is documented in wp-includes/formatting.php */ $excerpt_more = \apply_filters( 'activitypub_excerpt_more', ' […]' );
$excerpt_more = \apply_filters( 'excerpt_more', ' [...]' );
$excerpt_more_len = strlen( $excerpt_more ); $excerpt_more_len = strlen( $excerpt_more );
// We now have a excerpt, but we need to check it's length, it may be longer than we want for two reasons: // We now have a excerpt, but we need to check it's length, it may be longer than we want for two reasons:

View file

@ -38,6 +38,15 @@ class Application_User extends Blog_User {
return get_rest_url_by_path( 'application' ); return get_rest_url_by_path( 'application' );
} }
/**
* Returns the User-URL with @-Prefix for the username.
*
* @return string The User-URL with @-Prefix for the username.
*/
public function get_alternate_url() {
return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
}
public function get_name() { public function get_name() {
return 'application'; return 'application';
} }
@ -69,4 +78,8 @@ class Application_User extends Blog_User {
public function get_indexable() { public function get_indexable() {
return false; return false;
} }
public function get_type() {
return $this->type;
}
} }

View file

@ -100,12 +100,12 @@ class Blog_User extends User {
} }
/** /**
* Returns the User-URL with @-Prefix for the username. * Get blog's homepage URL.
* *
* @return string The User-URL with @-Prefix for the username. * @return string The User-Url.
*/ */
public function get_at_url() { public function get_alternate_url() {
return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() ); return \esc_url( \trailingslashit( get_home_url() ) );
} }
/** /**

View file

@ -135,8 +135,8 @@ class User extends Actor {
* *
* @return string The User-URL with @-Prefix for the username. * @return string The User-URL with @-Prefix for the username.
*/ */
public function get_at_url() { public function get_alternate_url() {
return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_username() ); return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
} }
public function get_preferred_username() { public function get_preferred_username() {

View file

@ -108,6 +108,12 @@ class Nodeinfo {
'outbound' => array(), 'outbound' => array(),
); );
$nodeinfo['metadata'] = array(
'nodeName' => \get_bloginfo( 'name' ),
'nodeDescription' => \get_bloginfo( 'description' ),
'nodeIcon' => \get_site_icon_url(),
);
return new WP_REST_Response( $nodeinfo, 200 ); return new WP_REST_Response( $nodeinfo, 200 );
} }
@ -174,7 +180,7 @@ class Nodeinfo {
), ),
array( array(
'rel' => 'https://www.w3.org/ns/activitystreams#Application', 'rel' => 'https://www.w3.org/ns/activitystreams#Application',
'href' => Application_User::from_wp_user( Users::APPLICATION_USER_ID )->get_url(), 'href' => get_rest_url_by_path( 'application' ),
), ),
); );

View file

@ -94,10 +94,13 @@ class Webfinger {
$aliases = array( $aliases = array(
$user->get_url(), $user->get_url(),
$user->get_alternate_url(),
); );
$aliases = array_unique( $aliases );
$profile = array( $profile = array(
'subject' => $resource, 'subject' => sprintf( 'acct:%s', $user->get_resource() ),
'aliases' => array_values( array_unique( $aliases ) ), 'aliases' => array_values( array_unique( $aliases ) ),
'links' => array( 'links' => array(
array( array(
@ -113,9 +116,9 @@ class Webfinger {
), ),
); );
if ( 'Group' === $user->get_type() ) { if ( 'Person' !== $user->get_type() ) {
$profile['links'][0]['properties'] = array( $profile['links'][0]['properties'] = array(
'https://www.w3.org/ns/activitystreams#type' => 'Group', 'https://www.w3.org/ns/activitystreams#type' => $user->get_type(),
); );
} }

View file

@ -3,6 +3,7 @@ namespace Activitypub\Integration;
use function Activitypub\get_total_users; use function Activitypub\get_total_users;
use function Activitypub\get_active_users; use function Activitypub\get_active_users;
use function Activitypub\get_rest_url_by_path;
/** /**
* Compatibility with the NodeInfo plugin * Compatibility with the NodeInfo plugin
@ -14,8 +15,10 @@ class Nodeinfo {
* Initialize the class, registering WordPress hooks * Initialize the class, registering WordPress hooks
*/ */
public static function init() { public static function init() {
\add_filter( 'nodeinfo_data', array( self::class, 'add_nodeinfo_discovery' ), 10, 2 ); \add_filter( 'nodeinfo_data', array( self::class, 'add_nodeinfo_data' ), 10, 2 );
\add_filter( 'nodeinfo2_data', array( self::class, 'add_nodeinfo2_discovery' ), 10 ); \add_filter( 'nodeinfo2_data', array( self::class, 'add_nodeinfo2_data' ), 10 );
\add_filter( 'wellknown_nodeinfo_data', array( self::class, 'add_wellknown_nodeinfo_data' ), 10, 2 );
} }
/** /**
@ -26,7 +29,7 @@ class Nodeinfo {
* *
* @return array The extended array * @return array The extended array
*/ */
public static function add_nodeinfo_discovery( $nodeinfo, $version ) { public static function add_nodeinfo_data( $nodeinfo, $version ) {
if ( $version >= '2.0' ) { if ( $version >= '2.0' ) {
$nodeinfo['protocols'][] = 'activitypub'; $nodeinfo['protocols'][] = 'activitypub';
} else { } else {
@ -50,7 +53,7 @@ class Nodeinfo {
* *
* @return array The extended array * @return array The extended array
*/ */
public static function add_nodeinfo2_discovery( $nodeinfo ) { public static function add_nodeinfo2_data( $nodeinfo ) {
$nodeinfo['protocols'][] = 'activitypub'; $nodeinfo['protocols'][] = 'activitypub';
$nodeinfo['usage']['users'] = array( $nodeinfo['usage']['users'] = array(
@ -61,4 +64,20 @@ class Nodeinfo {
return $nodeinfo; return $nodeinfo;
} }
/**
* Extend the well-known nodeinfo data
*
* @param array $data The well-known nodeinfo data
*
* @return array The extended array
*/
public static function add_wellknown_nodeinfo_data( $data ) {
$data['links'][] = array(
'rel' => 'https://www.w3.org/ns/activitystreams#Application',
'href' => get_rest_url_by_path( 'application' ),
);
return $data;
}
} }

View file

@ -14,8 +14,8 @@ class Webfinger {
* Initialize the class, registering WordPress hooks * Initialize the class, registering WordPress hooks
*/ */
public static function init() { public static function init() {
\add_filter( 'webfinger_user_data', array( self::class, 'add_user_discovery' ), 10, 3 ); \add_filter( 'webfinger_user_data', array( self::class, 'add_user_discovery' ), 1, 3 );
\add_filter( 'webfinger_data', array( self::class, 'add_pseudo_user_discovery' ), 99, 2 ); \add_filter( 'webfinger_data', array( self::class, 'add_pseudo_user_discovery' ), 1, 2 );
} }
/** /**
@ -34,6 +34,11 @@ class Webfinger {
return $array; return $array;
} }
$array['subject'] = sprintf( 'acct:%s', $user->get_resource() );
$array['aliases'][] = $user->get_url();
$array['aliases'][] = $user->get_alternate_url();
$array['links'][] = array( $array['links'][] = array(
'rel' => 'self', 'rel' => 'self',
'type' => 'application/activity+json', 'type' => 'application/activity+json',

View file

@ -68,10 +68,10 @@ Implemented:
* share posts * share posts
* receive comments/reactions * receive comments/reactions
* signature verification * signature verification
* threaded comments support
To implement: To implement:
* threaded comments support
* replace shortcodes with blocks for layout * replace shortcodes with blocks for layout
= What is "ActivityPub for WordPress" = = What is "ActivityPub for WordPress" =
@ -111,7 +111,9 @@ Project maintained on GitHub at [automattic/wordpress-activitypub](https://githu
* Fixed: Normalize attributes that can have mixed value types * Fixed: Normalize attributes that can have mixed value types
* Added: URL support for WebFinger * Added: URL support for WebFinger
* Added: Make Post-Template filterable * Added: Make Post-Template filterable
* Addes: CSS class for ActivityPub comments to allow custom designs * Added: CSS class for ActivityPub comments to allow custom designs
* Added: FEP-2677: Identifying the Application Actor
* Improved: WebFinger endpoints
= 1.3.0 = = 1.3.0 =

View file

@ -62,4 +62,34 @@ class Test_Activitypub_Shortcodes extends WP_UnitTestCase {
$this->assertEquals( '', $content ); $this->assertEquals( '', $content );
Shortcodes::unregister(); Shortcodes::unregister();
} }
public function test_excerpt() {
Shortcodes::register();
global $post;
$post_id = -97; // negative ID, to avoid clash with a valid post
$post = new stdClass();
$post->ID = $post_id;
$post->post_author = 1;
$post->post_date = current_time( 'mysql' );
$post->post_date_gmt = current_time( 'mysql', 1 );
$post->post_title = 'Some title or other';
$post->post_content = '<script>test</script>Lorem ipsum dolor sit amet, consectetur.<script type="javascript">{"asdf": "qwerty"}</script><style></style>';
$post->post_status = 'publish';
$post->comment_status = 'closed';
$post->ping_status = 'closed';
$post->post_name = 'fake-page-' . rand( 1, 99999 ); // append random number to avoid clash
$post->post_type = 'page';
$post->filter = 'raw'; // important!
$content = '[ap_excerpt length="25"]';
// Fill in the shortcodes.
setup_postdata( $post );
$content = do_shortcode( $content );
wp_reset_postdata();
$this->assertEquals( "<p>Lorem ipsum [&hellip;]</p>\n", $content );
Shortcodes::unregister();
}
} }