prepare pseudo users like a blog wide user.
this allows also other constructs like tag oder category users fix #1
This commit is contained in:
parent
a7eeee904d
commit
09518ea66b
20 changed files with 744 additions and 237 deletions
|
@ -39,6 +39,7 @@ function init() {
|
|||
Collection\Followers::init();
|
||||
|
||||
// Configure the REST API route
|
||||
Rest\User::init();
|
||||
Rest\Outbox::init();
|
||||
Rest\Inbox::init();
|
||||
Rest\Followers::init();
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.settings_page_activitypub .wrap {
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.activitypub-settings-header {
|
||||
text-align: center;
|
||||
margin: 0 0 1rem;
|
||||
|
@ -28,7 +32,7 @@
|
|||
-ms-grid-columns: 1fr 1fr;
|
||||
vertical-align: top;
|
||||
display: inline-grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
.activitypub-settings-tab.active {
|
||||
|
|
|
@ -224,6 +224,11 @@ class Activitypub {
|
|||
'index.php?rest_route=/' . ACTIVITYPUB_REST_NAMESPACE . '/nodeinfo2',
|
||||
'top'
|
||||
);
|
||||
\add_rewrite_rule(
|
||||
'^@([\w]+)',
|
||||
'index.php?rest_route=/' . ACTIVITYPUB_REST_NAMESPACE . '/users/$matches[1]',
|
||||
'top'
|
||||
);
|
||||
}
|
||||
|
||||
\add_rewrite_endpoint( 'activitypub', EP_AUTHORS | EP_PERMALINK | EP_PAGES );
|
||||
|
|
|
@ -13,6 +13,10 @@ class Admin {
|
|||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
if ( ! current_user_can( 'publish_posts' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
\add_action( 'admin_menu', array( self::class, 'admin_menu' ) );
|
||||
\add_action( 'admin_init', array( self::class, 'register_settings' ) );
|
||||
\add_action( 'show_user_profile', array( self::class, 'add_profile' ) );
|
||||
|
@ -24,6 +28,11 @@ class Admin {
|
|||
* Add admin menu entry
|
||||
*/
|
||||
public static function admin_menu() {
|
||||
// user has to be able to publish posts
|
||||
if ( ! current_user_can( 'publish_posts' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$settings_page = \add_options_page(
|
||||
'Welcome',
|
||||
'ActivityPub',
|
||||
|
@ -55,6 +64,9 @@ class Admin {
|
|||
case 'settings':
|
||||
\load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/settings.php' );
|
||||
break;
|
||||
case 'followers':
|
||||
\load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/followers-list.php' );
|
||||
break;
|
||||
case 'welcome':
|
||||
default:
|
||||
wp_enqueue_script( 'plugin-install' );
|
||||
|
@ -70,6 +82,9 @@ class Admin {
|
|||
* Load user settings page
|
||||
*/
|
||||
public static function followers_list_page() {
|
||||
if ( ! current_user_can( 'publish_posts' ) ) {
|
||||
return;
|
||||
}
|
||||
\load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/followers-list.php' );
|
||||
}
|
||||
|
||||
|
|
157
includes/class-user-factory.php
Normal file
157
includes/class-user-factory.php
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
use WP_Error;
|
||||
use WP_User_Query;
|
||||
use Activitypub\Model\User;
|
||||
use Activitypub\Model\Blog_User;
|
||||
|
||||
class User_Factory {
|
||||
/**
|
||||
* The ID of the Blog User
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const BLOG_USER_ID = 0;
|
||||
|
||||
/**
|
||||
* The ID of the Application User
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const APPLICATION_USER_ID = -1;
|
||||
|
||||
/**
|
||||
* Get the User by ID
|
||||
*
|
||||
* @param int $user_id The User-ID.
|
||||
*
|
||||
* @return \Acitvitypub\Model\User The User.
|
||||
*/
|
||||
public static function get_by_id( $user_id ) {
|
||||
$user_id = (int) $user_id;
|
||||
|
||||
if ( self::BLOG_USER_ID === $user_id ) {
|
||||
return new Blog_User( $user_id );
|
||||
} elseif ( self::APPLICATION_USER_ID === $user_id ) {
|
||||
return new Application_User( $user_id );
|
||||
} else {
|
||||
$user = get_user_by( 'ID', $user_id );
|
||||
if ( ! $user || ! \user_can( $user, 'publish_posts' ) ) {
|
||||
return new WP_Error(
|
||||
'activitypub_user_not_found',
|
||||
\__( 'User not found', 'activitypub' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
return new User( $user->ID );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User by username.
|
||||
*
|
||||
* @param string $username The User-Name.
|
||||
*
|
||||
* @return \Acitvitypub\Model\User The User.
|
||||
*/
|
||||
public static function get_by_username( $username ) {
|
||||
// check for blog user.
|
||||
if ( get_option( 'activitypub_blog_identifier', null ) === $username ) {
|
||||
return self::get_by_id( self::BLOG_USER_ID );
|
||||
}
|
||||
|
||||
// check for 'activitypub_username' meta
|
||||
$user = new WP_User_Query(
|
||||
array(
|
||||
'number' => 1,
|
||||
'hide_empty' => true,
|
||||
'fields' => 'ID',
|
||||
'meta_query' => array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'activitypub_identifier',
|
||||
'value' => $username,
|
||||
'compare' => 'LIKE',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
if ( $user->results ) {
|
||||
return self::get_by_id( $user->results[0] );
|
||||
}
|
||||
|
||||
// check for login or nicename.
|
||||
$user = new WP_User_Query(
|
||||
array(
|
||||
'search' => $username,
|
||||
'search_columns' => array( 'user_login', 'user_nicename' ),
|
||||
'number' => 1,
|
||||
'hide_empty' => true,
|
||||
'fields' => 'ID',
|
||||
)
|
||||
);
|
||||
|
||||
if ( $user->results ) {
|
||||
return self::get_by_id( $user->results[0] );
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
'activitypub_user_not_found',
|
||||
\__( 'User not found', 'activitypub' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User by resource.
|
||||
*
|
||||
* @param string $resource The User-Resource.
|
||||
*
|
||||
* @return \Acitvitypub\Model\User The User.
|
||||
*/
|
||||
public static function get_by_resource( $resource ) {
|
||||
if ( \strpos( $resource, '@' ) === false ) {
|
||||
return new WP_Error(
|
||||
'activitypub_unsupported_resource',
|
||||
\__( 'Resource is invalid', 'activitypub' ),
|
||||
array( 'status' => 400 )
|
||||
);
|
||||
}
|
||||
|
||||
$resource = \str_replace( 'acct:', '', $resource );
|
||||
|
||||
$resource_identifier = \substr( $resource, 0, \strrpos( $resource, '@' ) );
|
||||
$resource_host = \str_replace( 'www.', '', \substr( \strrchr( $resource, '@' ), 1 ) );
|
||||
$blog_host = \str_replace( 'www.', '', \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) );
|
||||
|
||||
if ( $blog_host !== $resource_host ) {
|
||||
return new WP_Error(
|
||||
'activitypub_wrong_host',
|
||||
\__( 'Resource host does not match blog host', 'activitypub' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
return self::get_by_username( $resource_identifier );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User by resource.
|
||||
*
|
||||
* @param string $resource The User-Resource.
|
||||
*
|
||||
* @return \Acitvitypub\Model\User The User.
|
||||
*/
|
||||
public static function get_by_various( $id ) {
|
||||
if ( is_numeric( $id ) ) {
|
||||
return self::get_by_id( $id );
|
||||
} elseif ( filter_var( $id, FILTER_VALIDATE_URL ) ) {
|
||||
return self::get_by_resource( $id );
|
||||
} else {
|
||||
return self::get_by_username( $id );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,27 +7,7 @@ namespace Activitypub;
|
|||
* @return array the activitypub context
|
||||
*/
|
||||
function get_context() {
|
||||
$context = array(
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
array(
|
||||
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
||||
'PropertyValue' => 'schema:PropertyValue',
|
||||
'schema' => 'http://schema.org#',
|
||||
'pt' => 'https://joinpeertube.org/ns#',
|
||||
'toot' => 'http://joinmastodon.org/ns#',
|
||||
'value' => 'schema:value',
|
||||
'Hashtag' => 'as:Hashtag',
|
||||
'featured' => array(
|
||||
'@id' => 'toot:featured',
|
||||
'@type' => '@id',
|
||||
),
|
||||
'featuredTags' => array(
|
||||
'@id' => 'toot:featuredTags',
|
||||
'@type' => '@id',
|
||||
),
|
||||
),
|
||||
);
|
||||
$context = Model\Activity::CONTEXT;
|
||||
|
||||
return \apply_filters( 'activitypub_json_context', $context );
|
||||
}
|
||||
|
@ -187,21 +167,6 @@ function url_to_authorid( $url ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the custom Activity Pub description, if set, or default author description.
|
||||
*
|
||||
* @param int $user_id The user ID.
|
||||
*
|
||||
* @return string The author description.
|
||||
*/
|
||||
function get_author_description( $user_id ) {
|
||||
$description = get_user_meta( $user_id, 'activitypub_user_description', true );
|
||||
if ( empty( $description ) ) {
|
||||
$description = get_user_meta( $user_id, 'description', true );
|
||||
}
|
||||
return \wpautop( \wp_kses( $description, 'default' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for Tombstone Objects
|
||||
*
|
||||
|
|
|
@ -11,12 +11,8 @@ use function Activitypub\get_rest_url_by_path;
|
|||
* @see https://www.w3.org/TR/activitypub/
|
||||
*/
|
||||
class Activity {
|
||||
/**
|
||||
* The JSON-LD context.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $context = array(
|
||||
|
||||
const CONTEXT = array(
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
array(
|
||||
|
@ -38,6 +34,13 @@ class Activity {
|
|||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* The JSON-LD context.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $context = self::CONTEXT;
|
||||
|
||||
/**
|
||||
* The published date.
|
||||
*
|
||||
|
|
39
includes/model/class-application-user.php
Normal file
39
includes/model/class-application-user.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
namespace Activitypub\Model;
|
||||
|
||||
use WP_Query;
|
||||
use Activitypub\User_Factory;
|
||||
|
||||
class Application_User extends Blog_User {
|
||||
/**
|
||||
* The User-ID
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $user_id = User_Factory::APPLICATION_USER_ID;
|
||||
|
||||
/**
|
||||
* The User-Type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $type = 'Application';
|
||||
|
||||
/**
|
||||
* The User constructor.
|
||||
*
|
||||
* @param int $user_id The User-ID.
|
||||
*/
|
||||
public function __construct( $user_id ) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Url.
|
||||
*
|
||||
* @return string The User-Url.
|
||||
*/
|
||||
public function get_url() {
|
||||
return '';
|
||||
}
|
||||
}
|
91
includes/model/class-blog-user.php
Normal file
91
includes/model/class-blog-user.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
namespace Activitypub\Model;
|
||||
|
||||
use WP_Query;
|
||||
use Activitypub\User_Factory;
|
||||
|
||||
class Blog_User extends User {
|
||||
/**
|
||||
* The User-ID
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $user_id = User_Factory::BLOG_USER_ID;
|
||||
|
||||
/**
|
||||
* The User-Type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $type = 'Person';
|
||||
|
||||
/**
|
||||
* The User constructor.
|
||||
*
|
||||
* @param int $user_id The User-ID.
|
||||
*/
|
||||
public function __construct( $user_id ) {
|
||||
add_filter( 'activitypub_json_author_array', array( $this, 'add_api_endpoints' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Name.
|
||||
*
|
||||
* @return string The User-Name.
|
||||
*/
|
||||
public function get_name() {
|
||||
return \esc_html( \get_bloginfo( 'name' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Description.
|
||||
*
|
||||
* @return string The User-Description.
|
||||
*/
|
||||
public function get_summary() {
|
||||
return \wpautop( \wp_kses( \get_bloginfo( 'description' ), 'default' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Url.
|
||||
*
|
||||
* @return string The User-Url.
|
||||
*/
|
||||
public function get_url() {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function get_username() {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function get_avatar() {
|
||||
return \esc_url( \get_site_icon_url( 120 ) );
|
||||
}
|
||||
|
||||
public function get_header_image() {
|
||||
if ( \has_header_image() ) {
|
||||
return esc_url( \get_header_image() );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_published() {
|
||||
$first_post = new WP_Query(
|
||||
array(
|
||||
'orderby' => 'date',
|
||||
'order' => 'ASC',
|
||||
'number' => 1,
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! empty( $first_post->posts[0] ) ) {
|
||||
$time = \strtotime( $first_post->posts[0]->post_date_gmt );
|
||||
} else {
|
||||
$time = \time();
|
||||
}
|
||||
|
||||
return \gmdate( 'Y-m-d\TH:i:s\Z', $time );
|
||||
}
|
||||
}
|
|
@ -1,23 +1,242 @@
|
|||
<?php
|
||||
namespace Activitypub\Model;
|
||||
|
||||
/**
|
||||
* ActivityPub User Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
use WP_Query;
|
||||
use WP_Error;
|
||||
use Activitypub\Model\User;
|
||||
use Activitypub\User_Factory;
|
||||
|
||||
use function Activitypub\get_rest_url_by_path;
|
||||
|
||||
class User {
|
||||
/**
|
||||
* The ID of the Blog User
|
||||
* The User-ID
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const BLOG_USER_ID = 0;
|
||||
public $user_id;
|
||||
|
||||
/**
|
||||
* The ID of the Application User
|
||||
* The User-Type
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const APPLICATION_USER_ID = -1;
|
||||
private $type = 'Person';
|
||||
|
||||
/**
|
||||
* The User constructor.
|
||||
*
|
||||
* @param numeric $user_id The User-ID.
|
||||
*/
|
||||
public function __construct( $user_id ) {
|
||||
$this->user_id = $user_id;
|
||||
|
||||
add_filter( 'activitypub_json_author_array', array( $this, 'add_api_endpoints' ), 10, 2 );
|
||||
add_filter( 'activitypub_json_author_array', array( $this, 'add_attachments' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic function to implement getter and setter
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $params
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __call( $method, $params ) {
|
||||
$var = \strtolower( \substr( $method, 4 ) );
|
||||
|
||||
if ( \strncasecmp( $method, 'get', 3 ) === 0 ) {
|
||||
return $this->$var;
|
||||
}
|
||||
|
||||
if ( \strncasecmp( $method, 'has', 3 ) === 0 ) {
|
||||
return (bool) call_user_func( 'get_' . $var, $this );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-ID.
|
||||
*
|
||||
* @return string The User-ID.
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->get_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Name.
|
||||
*
|
||||
* @return string The User-Name.
|
||||
*/
|
||||
public function get_name() {
|
||||
return \esc_attr( \get_the_author_meta( 'display_name', $this->user_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Description.
|
||||
*
|
||||
* @return string The User-Description.
|
||||
*/
|
||||
public function get_summary() {
|
||||
$description = get_user_meta( $this->user_id, 'activitypub_user_description', true );
|
||||
if ( empty( $description ) ) {
|
||||
$description = get_user_meta( $this->user_id, 'description', true );
|
||||
}
|
||||
return \wpautop( \wp_kses( $description, 'default' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Url.
|
||||
*
|
||||
* @return string The User-Url.
|
||||
*/
|
||||
public function get_url() {
|
||||
return \esc_url( \get_author_posts_url( $this->user_id ) );
|
||||
}
|
||||
|
||||
public function get_username() {
|
||||
return \esc_attr( \get_the_author_meta( 'login', $this->user_id ) );
|
||||
}
|
||||
|
||||
public function get_avatar() {
|
||||
return \esc_url(
|
||||
\get_avatar_url(
|
||||
$this->user_id,
|
||||
array( 'size' => 120 )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function get_header_image() {
|
||||
if ( \has_header_image() ) {
|
||||
return \esc_url( \get_header_image() );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_published() {
|
||||
return \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( \get_the_author_meta( 'registered', $this->user_id ) ) );
|
||||
}
|
||||
|
||||
public function get_public_key() {
|
||||
//return Signature::get_public_key( $this->user_id );
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array representation of the User.
|
||||
*
|
||||
* @param bool $context Whether to include the @context.
|
||||
*
|
||||
* @return array The array representation of the User.
|
||||
*/
|
||||
public function to_array( $context = true ) {
|
||||
$output = array();
|
||||
|
||||
if ( $context ) {
|
||||
$output['@context'] = Activity::CONTEXT;
|
||||
}
|
||||
|
||||
$output['id'] = $this->get_url();
|
||||
$output['type'] = $this->get_type();
|
||||
$output['name'] = $this->get_name();
|
||||
$output['summary'] = \html_entity_decode(
|
||||
$this->get_summary(),
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
);
|
||||
$output['preferredUsername'] = $this->get_username(); // phpcs:ignore
|
||||
$output['url'] = $this->get_url();
|
||||
$output['icon'] = array(
|
||||
'type' => 'Image',
|
||||
'url' => $this->get_avatar(),
|
||||
);
|
||||
|
||||
if ( $this->has_header_image() ) {
|
||||
$output['image'] = array(
|
||||
'type' => 'Image',
|
||||
'url' => $this->get_header_image(),
|
||||
);
|
||||
}
|
||||
|
||||
$output['published'] = $this->get_published();
|
||||
|
||||
$output['publicKey'] = array(
|
||||
'id' => $this->get_url() . '#main-key',
|
||||
'owner' => $this->get_url(),
|
||||
'publicKeyPem' => \trim( $this->get_public_key() ),
|
||||
);
|
||||
|
||||
$output['manuallyApprovesFollowers'] = \apply_filters( 'activitypub_json_manually_approves_followers', \__return_false() ); // phpcs:ignore
|
||||
|
||||
// filter output
|
||||
$output = \apply_filters( 'activitypub_json_author_array', $output, $this->user_id, $this );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the User-Output with API-Endpoints.
|
||||
*
|
||||
* @param array $array The User-Output.
|
||||
* @param numeric $user_id The User-ID.
|
||||
*
|
||||
* @return array The extended User-Output.
|
||||
*/
|
||||
public function add_api_endpoints( $array, $user_id ) {
|
||||
$array['inbox'] = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user_id ) );
|
||||
$array['outbox'] = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user_id ) );
|
||||
$array['followers'] = get_rest_url_by_path( sprintf( 'users/%d/followers', $user_id ) );
|
||||
$array['following'] = get_rest_url_by_path( sprintf( 'users/%d/following', $user_id ) );
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the User-Output with Attachments.
|
||||
*
|
||||
* @param array $array The User-Output.
|
||||
* @param numeric $user_id The User-ID.
|
||||
*
|
||||
* @return array The extended User-Output.
|
||||
*/
|
||||
public function add_attachments( $array, $user_id ) {
|
||||
$array['attachment'] = array();
|
||||
|
||||
$array['attachment']['blog_url'] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \__( 'Blog', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \home_url( '/' ) ) . '" target="_blank" href="' . \home_url( '/' ) . '">' . \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) . '</a>',
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
$array['attachment']['profile_url'] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \__( 'Profile', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \get_author_posts_url( $user_id ) ) . '" target="_blank" href="' . \get_author_posts_url( $user_id ) . '">' . \wp_parse_url( \get_author_posts_url( $user_id ), \PHP_URL_HOST ) . '</a>',
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
if ( \get_the_author_meta( 'user_url', $user_id ) ) {
|
||||
$array['attachment']['user_url'] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \__( 'Website', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \get_the_author_meta( 'user_url', $user_id ) ) . '" target="_blank" href="' . \get_the_author_meta( 'user_url', $user_id ) . '">' . \wp_parse_url( \get_the_author_meta( 'user_url', $user_id ), \PHP_URL_HOST ) . '</a>',
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use WP_Error;
|
|||
use stdClass;
|
||||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\User_Factory;
|
||||
use Activitypub\Collection\Followers as FollowerCollection;
|
||||
|
||||
use function Activitypub\get_rest_url_by_path;
|
||||
|
@ -30,7 +31,7 @@ class Followers {
|
|||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>\d+)/followers',
|
||||
'/users/(?P<user_id>\w+)/followers',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
|
@ -51,19 +52,10 @@ class Followers {
|
|||
*/
|
||||
public static function get( $request ) {
|
||||
$user_id = $request->get_param( 'user_id' );
|
||||
$user = \get_user_by( 'ID', $user_id );
|
||||
$user = User_Factory::get_by_various( $user_id );
|
||||
|
||||
if ( ! $user ) {
|
||||
return new WP_Error(
|
||||
'rest_invalid_param',
|
||||
\__( 'User not found', 'activitypub' ),
|
||||
array(
|
||||
'status' => 404,
|
||||
'params' => array(
|
||||
'user_id' => \__( 'User not found', 'activitypub' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
if ( is_wp_error( $user ) ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -77,18 +69,18 @@ class Followers {
|
|||
|
||||
$json->id = \home_url( \add_query_arg( null, null ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . \get_bloginfo_rss( 'version' );
|
||||
$json->actor = \get_author_posts_url( $user_id );
|
||||
$json->actor = $user->get_id();
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/followers', $user_id ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/followers', $user->get_user_id() ) ); // phpcs:ignore
|
||||
$json->first = $json->partOf; // phpcs:ignore
|
||||
$json->totalItems = FollowerCollection::count_followers( $user_id ); // phpcs:ignore
|
||||
$json->totalItems = FollowerCollection::count_followers( $user->get_user_id() ); // phpcs:ignore
|
||||
// phpcs:ignore
|
||||
$json->orderedItems = array_map(
|
||||
function( $item ) {
|
||||
return $item->get_url();
|
||||
},
|
||||
FollowerCollection::get_followers( $user_id )
|
||||
FollowerCollection::get_followers( $user->get_user_id() )
|
||||
);
|
||||
|
||||
$response = new WP_REST_Response( $json, 200 );
|
||||
|
@ -111,10 +103,7 @@ class Followers {
|
|||
|
||||
$params['user_id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
'validate_callback' => function( $param, $request, $key ) {
|
||||
return user_can( $param, 'publish_posts' );
|
||||
},
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
return $params;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
use Activitypub\User_Factory;
|
||||
|
||||
use function Activitypub\get_rest_url_by_path;
|
||||
|
||||
/**
|
||||
|
@ -24,7 +26,7 @@ class Following {
|
|||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>\d+)/following',
|
||||
'/users/(?P<user_id>\w+)/following',
|
||||
array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
|
@ -45,19 +47,10 @@ class Following {
|
|||
*/
|
||||
public static function get( $request ) {
|
||||
$user_id = $request->get_param( 'user_id' );
|
||||
$user = \get_user_by( 'ID', $user_id );
|
||||
$user = User_Factory::get_by_various( $user_id );
|
||||
|
||||
if ( ! $user ) {
|
||||
return new \WP_Error(
|
||||
'rest_invalid_param',
|
||||
\__( 'User not found', 'activitypub' ),
|
||||
array(
|
||||
'status' => 404,
|
||||
'params' => array(
|
||||
'user_id' => \__( 'User not found', 'activitypub' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
if ( is_wp_error( $user ) ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -71,10 +64,10 @@ class Following {
|
|||
|
||||
$json->id = \home_url( \add_query_arg( null, null ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . \get_bloginfo_rss( 'version' );
|
||||
$json->actor = \get_author_posts_url( $user_id );
|
||||
$json->actor = $user->get_id();
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/following', $user_id ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/following', $user->get_user_id() ) ); // phpcs:ignore
|
||||
$json->totalItems = 0; // phpcs:ignore
|
||||
$json->orderedItems = apply_filters( 'activitypub_following', array(), $user ); // phpcs:ignore
|
||||
|
||||
|
@ -100,10 +93,7 @@ class Following {
|
|||
|
||||
$params['user_id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
'validate_callback' => function( $param, $request, $key ) {
|
||||
return user_can( $param, 'publish_posts' );
|
||||
},
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
return $params;
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Activitypub\Rest;
|
|||
use WP_Error;
|
||||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\Signature;
|
||||
use Activitypub\User_Factory;
|
||||
use Activitypub\Model\Activity;
|
||||
|
||||
use function Activitypub\get_context;
|
||||
|
@ -48,7 +48,7 @@ class Inbox {
|
|||
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>\d+)/inbox',
|
||||
'/users/(?P<user_id>\w+)/inbox',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
|
@ -74,6 +74,12 @@ class Inbox {
|
|||
*/
|
||||
public static function user_inbox_get( $request ) {
|
||||
$user_id = $request->get_param( 'user_id' );
|
||||
$user = User_Factory::get_by_various( $user_id );
|
||||
|
||||
if ( is_wp_error( $user ) ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$page = $request->get_param( 'page', 0 );
|
||||
|
||||
/*
|
||||
|
@ -87,7 +93,7 @@ class Inbox {
|
|||
$json->id = \home_url( \add_query_arg( null, null ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . \get_bloginfo_rss( 'version' );
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user_id ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user->get_user_id() ) ); // phpcs:ignore
|
||||
|
||||
$json->totalItems = 0; // phpcs:ignore
|
||||
|
||||
|
@ -120,13 +126,18 @@ class Inbox {
|
|||
public static function user_inbox_post( $request ) {
|
||||
|
||||
$user_id = $request->get_param( 'user_id' );
|
||||
$user = User_Factory::get_by_various( $user_id );
|
||||
|
||||
if ( is_wp_error( $user ) ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$data = $request->get_params();
|
||||
$type = $request->get_param( 'type' );
|
||||
$type = \strtolower( $type );
|
||||
|
||||
\do_action( 'activitypub_inbox', $data, $user_id, $type );
|
||||
\do_action( "activitypub_inbox_{$type}", $data, $user_id );
|
||||
\do_action( 'activitypub_inbox', $data, $user->get_user_id(), $type );
|
||||
\do_action( "activitypub_inbox_{$type}", $data, $user->get_user_id() );
|
||||
|
||||
return new WP_REST_Response( array(), 202 );
|
||||
}
|
||||
|
@ -185,10 +196,7 @@ class Inbox {
|
|||
|
||||
$params['user_id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
'validate_callback' => function( $param, $request, $key ) {
|
||||
return user_can( $param, 'publish_posts' );
|
||||
},
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
return $params;
|
||||
|
@ -208,10 +216,7 @@ class Inbox {
|
|||
|
||||
$params['user_id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
'validate_callback' => function( $param, $request, $key ) {
|
||||
return user_can( $param, 'publish_posts' );
|
||||
},
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
$params['id'] = array(
|
||||
|
|
|
@ -5,6 +5,7 @@ use stdClass;
|
|||
use WP_Error;
|
||||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\User_Factory;
|
||||
use Activitypub\Model\Post;
|
||||
use Activitypub\Model\Activity;
|
||||
|
||||
|
@ -32,7 +33,7 @@ class Outbox {
|
|||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>\d+)/outbox',
|
||||
'/users/(?P<user_id>\w+)/outbox',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
|
@ -52,22 +53,14 @@ class Outbox {
|
|||
*/
|
||||
public static function user_outbox_get( $request ) {
|
||||
$user_id = $request->get_param( 'user_id' );
|
||||
$author = \get_user_by( 'ID', $user_id );
|
||||
$post_types = \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) );
|
||||
$user = User_Factory::get_by_various( $user_id );
|
||||
|
||||
if ( ! $author ) {
|
||||
return new WP_Error(
|
||||
'rest_invalid_param',
|
||||
\__( 'User not found', 'activitypub' ),
|
||||
array(
|
||||
'status' => 404,
|
||||
'params' => array(
|
||||
'user_id' => \__( 'User not found', 'activitypub' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
if ( is_wp_error( $user ) ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$post_types = \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) );
|
||||
|
||||
$page = $request->get_param( 'page', 0 );
|
||||
|
||||
/*
|
||||
|
@ -80,9 +73,9 @@ class Outbox {
|
|||
$json->{'@context'} = get_context();
|
||||
$json->id = \home_url( \add_query_arg( null, null ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . \get_bloginfo_rss( 'version' );
|
||||
$json->actor = \get_author_posts_url( $user_id );
|
||||
$json->actor = $user->get_id();
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user_id ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user->get_user_id() ) ); // phpcs:ignore
|
||||
$json->totalItems = 0; // phpcs:ignore
|
||||
|
||||
// phpcs:ignore
|
||||
|
@ -104,7 +97,7 @@ class Outbox {
|
|||
$posts = \get_posts(
|
||||
array(
|
||||
'posts_per_page' => 10,
|
||||
'author' => $user_id,
|
||||
'author' => $user->get_user_id(),
|
||||
'offset' => ( $page - 1 ) * 10,
|
||||
'post_type' => $post_types,
|
||||
)
|
||||
|
@ -148,10 +141,7 @@ class Outbox {
|
|||
|
||||
$params['user_id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
'validate_callback' => function( $param, $request, $key ) {
|
||||
return user_can( $param, 'publish_posts' );
|
||||
},
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
return $params;
|
||||
|
|
89
includes/rest/class-user.php
Normal file
89
includes/rest/class-user.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
use WP_Error;
|
||||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\User_Factory;
|
||||
|
||||
/**
|
||||
* ActivityPub Followers REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/#followers
|
||||
*/
|
||||
class User {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'rest_api_init', array( self::class, 'register_routes' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>\w+)',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( self::class, 'get' ),
|
||||
'args' => self::request_parameters(),
|
||||
'permission_callback' => '__return_true',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle GET request
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function get( $request ) {
|
||||
$user_id = $request->get_param( 'user_id' );
|
||||
$user = User_Factory::get_by_various( $user_id );
|
||||
|
||||
if ( is_wp_error( $user ) ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the ActivityPub profile being created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_outbox_pre' );
|
||||
|
||||
$json = $user->to_array();
|
||||
|
||||
$response = new WP_REST_Response( $json, 200 );
|
||||
$response->header( 'Content-Type', 'application/activity+json' );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* The supported parameters
|
||||
*
|
||||
* @return array list of parameters
|
||||
*/
|
||||
public static function request_parameters() {
|
||||
$params = array();
|
||||
|
||||
$params['page'] = array(
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
$params['user_id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ namespace Activitypub\Rest;
|
|||
|
||||
use WP_Error;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\User_Factory;
|
||||
|
||||
/**
|
||||
* ActivityPub WebFinger REST-Class
|
||||
|
@ -47,41 +48,27 @@ class Webfinger {
|
|||
public static function webfinger( $request ) {
|
||||
$resource = $request->get_param( 'resource' );
|
||||
|
||||
if ( \strpos( $resource, '@' ) === false ) {
|
||||
return new WP_Error( 'activitypub_unsupported_resource', \__( 'Resource is invalid', 'activitypub' ), array( 'status' => 400 ) );
|
||||
}
|
||||
$user = User_Factory::get_by_resource( $resource );
|
||||
|
||||
$resource = \str_replace( 'acct:', '', $resource );
|
||||
|
||||
$resource_identifier = \substr( $resource, 0, \strrpos( $resource, '@' ) );
|
||||
$resource_host = \str_replace( 'www.', '', \substr( \strrchr( $resource, '@' ), 1 ) );
|
||||
$blog_host = \str_replace( 'www.', '', \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) );
|
||||
|
||||
if ( $blog_host !== $resource_host ) {
|
||||
return new WP_Error( 'activitypub_wrong_host', \__( 'Resource host does not match blog host', 'activitypub' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$user = \get_user_by( 'login', \esc_sql( $resource_identifier ) );
|
||||
|
||||
if ( ! $user || ! \user_can( $user, 'publish_posts' ) ) {
|
||||
return new WP_Error( 'activitypub_user_not_found', \__( 'User not found', 'activitypub' ), array( 'status' => 404 ) );
|
||||
if ( is_wp_error( $user ) ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$json = array(
|
||||
'subject' => $resource,
|
||||
'aliases' => array(
|
||||
\get_author_posts_url( $user->ID ),
|
||||
$user->get_url(),
|
||||
),
|
||||
'links' => array(
|
||||
array(
|
||||
'rel' => 'self',
|
||||
'type' => 'application/activity+json',
|
||||
'href' => \get_author_posts_url( $user->ID ),
|
||||
'href' => $user->get_url(),
|
||||
),
|
||||
array(
|
||||
'rel' => 'http://webfinger.net/rel/profile-page',
|
||||
'type' => 'text/html',
|
||||
'href' => \get_author_posts_url( $user->ID ),
|
||||
'href' => $user->get_url(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -9,6 +9,24 @@ if ( ! \class_exists( '\WP_List_Table' ) ) {
|
|||
}
|
||||
|
||||
class Followers extends WP_List_Table {
|
||||
private $user_id;
|
||||
|
||||
public function __construct() {
|
||||
if ( get_current_screen()->id === 'settings_page_activitypub' ) {
|
||||
$this->user_id = -1;
|
||||
} else {
|
||||
$this->user_id = \get_current_user_id();
|
||||
}
|
||||
|
||||
parent::__construct(
|
||||
array(
|
||||
'singular' => \__( 'Follower', 'activitypub' ),
|
||||
'plural' => \__( 'Followers', 'activitypub' ),
|
||||
'ajax' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'cb' => '<input type="checkbox" />',
|
||||
|
@ -36,8 +54,8 @@ class Followers extends WP_List_Table {
|
|||
$page_num = $this->get_pagenum();
|
||||
$per_page = 20;
|
||||
|
||||
$followers = FollowerCollection::get_followers( \get_current_user_id(), $per_page, ( $page_num - 1 ) * $per_page );
|
||||
$counter = FollowerCollection::count_followers( \get_current_user_id() );
|
||||
$follower = FollowerCollection::get_followers( $this->user_id, $per_page, ( $page_num - 1 ) * $per_page );
|
||||
$counter = FollowerCollection::count_followers( $this->user_id );
|
||||
|
||||
$this->items = array();
|
||||
$this->set_pagination_args(
|
||||
|
@ -104,7 +122,7 @@ class Followers extends WP_List_Table {
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_user', \get_current_user_id() ) ) {
|
||||
if ( ! current_user_can( 'edit_user', $this->user_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -121,4 +139,8 @@ class Followers extends WP_List_Table {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_user_count() {
|
||||
return FollowerCollection::count_followers( $this->user_id );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
<a href="<?php echo \esc_url_raw( admin_url( 'options-general.php?page=activitypub&tab=settings' ) ); ?>" class="activitypub-settings-tab <?php echo \esc_attr( $args['settings'] ); ?>">
|
||||
<?php \esc_html_e( 'Settings', 'activitypub' ); ?>
|
||||
</a>
|
||||
|
||||
<a href="<?php echo \esc_url_raw( admin_url( 'options-general.php?page=activitypub&tab=followers' ) ); ?>" class="activitypub-settings-tab <?php echo \esc_attr( $args['followers'] ); ?>">
|
||||
<?php \esc_html_e( 'Followers', 'activitypub' ); ?>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<hr class="wp-header-end">
|
||||
|
|
|
@ -1,92 +1,10 @@
|
|||
<?php
|
||||
$author_id = \get_the_author_meta( 'ID' );
|
||||
|
||||
$json = new \stdClass();
|
||||
|
||||
$json->{'@context'} = \Activitypub\get_context();
|
||||
$json->id = \get_author_posts_url( $author_id );
|
||||
$json->type = 'Person';
|
||||
$json->name = \get_the_author_meta( 'display_name', $author_id );
|
||||
$json->summary = \html_entity_decode(
|
||||
\Activitypub\get_author_description( $author_id ),
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
);
|
||||
$json->preferredUsername = \get_the_author_meta( 'login', $author_id ); // phpcs:ignore
|
||||
$json->url = \get_author_posts_url( $author_id );
|
||||
$json->icon = array(
|
||||
'type' => 'Image',
|
||||
'url' => \get_avatar_url( $author_id, array( 'size' => 120 ) ),
|
||||
);
|
||||
|
||||
$json->published = \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( \get_the_author_meta( 'registered', $author_id ) ) );
|
||||
|
||||
if ( \has_header_image() ) {
|
||||
$json->image = array(
|
||||
'type' => 'Image',
|
||||
'url' => \get_header_image(),
|
||||
);
|
||||
}
|
||||
|
||||
$json->inbox = \Activitypub\get_rest_url_by_path( sprintf( 'users/%d/inbox', $author_id ) );
|
||||
$json->outbox = \Activitypub\get_rest_url_by_path( sprintf( 'users/%d/outbox', $author_id ) );
|
||||
$json->followers = \Activitypub\get_rest_url_by_path( sprintf( 'users/%d/followers', $author_id ) );
|
||||
$json->following = \Activitypub\get_rest_url_by_path( sprintf( 'users/%d/following', $author_id ) );
|
||||
|
||||
$json->manuallyApprovesFollowers = \apply_filters( 'activitypub_json_manually_approves_followers', \__return_false() ); // phpcs:ignore
|
||||
|
||||
// phpcs:ignore
|
||||
$json->publicKey = array(
|
||||
'id' => \get_author_posts_url( $author_id ) . '#main-key',
|
||||
'owner' => \get_author_posts_url( $author_id ),
|
||||
'publicKeyPem' => \trim( \Activitypub\Signature::get_public_key( $author_id ) ),
|
||||
);
|
||||
|
||||
$json->tag = array();
|
||||
$json->attachment = array();
|
||||
|
||||
$json->attachment['blog_url'] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \__( 'Blog', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \home_url( '/' ) ) . '" target="_blank" href="' . \home_url( '/' ) . '">' . \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) . '</a>',
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
$json->attachment['profile_url'] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \__( 'Profile', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \get_author_posts_url( $author_id ) ) . '" target="_blank" href="' . \get_author_posts_url( $author_id ) . '">' . \wp_parse_url( \get_author_posts_url( $author_id ), \PHP_URL_HOST ) . '</a>',
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
if ( \get_the_author_meta( 'user_url', $author_id ) ) {
|
||||
$json->attachment['user_url'] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \__( 'Website', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \get_the_author_meta( 'user_url', $author_id ) ) . '" target="_blank" href="' . \get_the_author_meta( 'user_url', $author_id ) . '">' . \wp_parse_url( \get_the_author_meta( 'user_url', $author_id ), \PHP_URL_HOST ) . '</a>',
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// filter output
|
||||
$json = \apply_filters( 'activitypub_json_author_array', $json, $author_id );
|
||||
|
||||
// migrate to ActivityPub standard
|
||||
$json->attachment = array_values( $json->attachment );
|
||||
$user = \Activitypub\User_Factory::get_by_id( \get_the_author_meta( 'ID' ) );
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the ActivityPub profile being created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_json_author_pre', $author_id );
|
||||
\do_action( 'activitypub_json_author_pre', $user->get_user_id() );
|
||||
|
||||
$options = 0;
|
||||
// JSON_PRETTY_PRINT added in PHP 5.4
|
||||
|
@ -101,12 +19,12 @@ $options |= \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT;
|
|||
*
|
||||
* @param int $options The current options flags
|
||||
*/
|
||||
$options = \apply_filters( 'activitypub_json_author_options', $options, $author_id );
|
||||
$options = \apply_filters( 'activitypub_json_author_options', $options, $user->get_user_id() );
|
||||
|
||||
\header( 'Content-Type: application/activity+json' );
|
||||
echo \wp_json_encode( $json, $options );
|
||||
echo \wp_json_encode( $user->to_array(), $options );
|
||||
|
||||
/*
|
||||
* Action triggerd after the ActivityPub profile has been created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_json_author_post', $author_id );
|
||||
\do_action( 'activitypub_json_author_post', $user->get_user_id() );
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
<?php
|
||||
if ( get_current_screen()->id === 'settings_page_activitypub' ) {
|
||||
\load_template(
|
||||
\dirname( __FILE__ ) . '/admin-header.php',
|
||||
true,
|
||||
array(
|
||||
'settings' => '',
|
||||
'welcome' => '',
|
||||
'followers' => 'active',
|
||||
)
|
||||
);
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<h1><?php \esc_html_e( 'Followers', 'activitypub' ); ?></h1>
|
||||
<?php Activitypub\Migration::maybe_migrate(); ?>
|
||||
|
|
Loading…
Reference in a new issue