Files
laipower/wp-content/plugins/activitypub/includes/rest/class-nodeinfo-controller.php

349 lines
9.3 KiB
PHP

<?php
/**
* NodeInfo controller file.
*
* @package Activitypub
*/
namespace Activitypub\Rest;
use function Activitypub\get_masked_wp_version;
use function Activitypub\get_rest_url_by_path;
/**
* ActivityPub NodeInfo Controller.
*
* @author Matthias Pfefferle
*
* @see https://nodeinfo.diaspora.software/
*/
class Nodeinfo_Controller extends \WP_REST_Controller {
/**
* The namespace of this controller's route.
*
* @var string
*/
protected $namespace = ACTIVITYPUB_REST_NAMESPACE;
/**
* The REST base for this controller's route.
*
* @var string
*/
protected $rest_base = 'nodeinfo';
/**
* Register routes.
*/
public function register_routes() {
\register_rest_route(
$this->namespace,
'/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => '__return_true',
),
)
);
\register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/(?P<version>\d\.\d)',
array(
'args' => array(
'version' => array(
'description' => 'The version of the NodeInfo schema.',
'type' => 'string',
'required' => true,
),
),
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => '__return_true',
),
'schema' => array( $this, 'get_item_schema' ),
)
);
}
/**
* Retrieves the NodeInfo discovery profile.
*
* @param \WP_REST_Request $request The request object.
*
* @return \WP_REST_Response Response object.
*/
public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$response = array(
'links' => array(
/*
* Needs http protocol for spec compliance.
* @ticket https://github.com/Automattic/wordpress-activitypub/pull/1275
*/
array(
'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.0',
'href' => get_rest_url_by_path( '/nodeinfo/2.0' ),
),
array(
'rel' => 'https://nodeinfo.diaspora.software/ns/schema/2.0',
'href' => get_rest_url_by_path( '/nodeinfo/2.0' ),
),
array(
'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.1',
'href' => get_rest_url_by_path( '/nodeinfo/2.1' ),
),
array(
'rel' => 'https://nodeinfo.diaspora.software/ns/schema/2.1',
'href' => get_rest_url_by_path( '/nodeinfo/2.1' ),
),
array(
'rel' => 'https://www.w3.org/ns/activitystreams#Application',
'href' => get_rest_url_by_path( 'application' ),
),
),
);
return \rest_ensure_response( $response );
}
/**
* Retrieves the NodeInfo profile.
*
* @param \WP_REST_Request $request The request object.
* @return \WP_REST_Response Response object.
*/
public function get_item( $request ) {
$version = $request->get_param( 'version' );
/**
* Fires before the NodeInfo data is created and sent to the client.
*
* @param string $version The NodeInfo version.
*/
\do_action( 'activitypub_rest_nodeinfo_pre', $version );
switch ( $version ) {
case '2.0':
case '2.1':
$response = $this->get_version_2_X( $version );
break;
default:
$response = new \WP_Error( 'activitypub_rest_nodeinfo_invalid_version', 'Unsupported NodeInfo version.', array( 'status' => 405 ) );
break;
}
return \rest_ensure_response( $response );
}
/**
* Get the NodeInfo 2.0 data.
*
* @param string $version The NodeInfo version.
*
* @return array The NodeInfo data.
*/
public function get_version_2_X( $version ) {
$posts = \wp_count_posts();
$comments = \wp_count_comments();
$nodeinfo = array(
'version' => $version,
'software' => array(
'name' => 'wordpress',
'version' => get_masked_wp_version(),
),
'openRegistrations' => (bool) get_option( 'users_can_register' ),
'usage' => array(
'localPosts' => (int) $posts->publish,
'localComments' => $comments->approved,
),
'metadata' => array(
'nodeName' => \get_bloginfo( 'name' ),
'nodeDescription' => \get_bloginfo( 'description' ),
'nodeIcon' => \get_site_icon_url(),
),
);
/**
* Filter the NodeInfo data.
*
* @param array $nodeinfo The NodeInfo data.
* @param string $version The NodeInfo version.
*/
return \apply_filters( 'nodeinfo_data', $nodeinfo, $version );
}
/**
* Retrieves the NodeInfo schema, conforming to JSON Schema.
*
* @return array NodeInfo schema data.
*/
public function get_item_schema() {
return array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'nodeinfo',
'type' => 'object',
'properties' => array(
'version' => array(
'description' => 'The version of the NodeInfo schema.',
'type' => 'string',
'enum' => array( '2.0', '2.1' ),
),
'software' => array(
'description' => 'Information about the software.',
'type' => 'object',
'properties' => array(
'name' => array(
'description' => 'The canonical name of this server software.',
'type' => 'string',
),
'version' => array(
'description' => 'The version of this server software.',
'type' => 'string',
),
'homepage' => array(
'description' => 'The url of the homepage of this server software.',
'type' => 'string',
'format' => 'uri',
),
'repository' => array(
'description' => 'The url of the source code repository of this server software.',
'type' => 'string',
'format' => 'uri',
),
),
),
'protocols' => array(
'description' => 'The protocols supported on this server.',
'type' => 'array',
'items' => array(
'type' => 'string',
'enum' => array(
'activitypub',
'buddycloud',
'dfrn',
'diaspora',
'libertree',
'ostatus',
'pumpio',
'tent',
'xmpp',
'zot',
),
),
),
'services' => array(
'description' => 'The third party sites this server can connect to via their application API.',
'type' => 'object',
'properties' => array(
'inbound' => array(
'description' => 'The third party sites this server can retrieve messages from for combined display with regular traffic.',
'type' => 'array',
'items' => array(
'type' => 'string',
'enum' => array(
'atom1.0',
'gnusocial',
'imap',
'pnut',
'pop3',
'pumpio',
'rss2.0',
'twitter',
),
),
),
'outbound' => array(
'description' => 'The third party sites this server can publish messages to on the behalf of a user.',
'type' => 'array',
'items' => array(
'type' => 'string',
'enum' => array(
'atom1.0',
'blogger',
'buddycloud',
'diaspora',
'dreamwidth',
'drupal',
'facebook',
'friendica',
'gnusocial',
'google',
'insanejournal',
'libertree',
'linkedin',
'livejournal',
'mediagoblin',
'myspace',
'pinterest',
'pnut',
'posterous',
'pumpio',
'redmatrix',
'rss2.0',
'smtp',
'tent',
'tumblr',
'twitter',
'wordpress',
'xmpp',
),
),
),
),
),
'openRegistrations' => array(
'description' => 'Whether this server allows open self-registration.',
'type' => 'boolean',
),
'usage' => array(
'description' => 'Usage statistics for this server.',
'type' => 'object',
'properties' => array(
'users' => array(
'description' => 'Statistics about the users of this server.',
'type' => 'object',
'properties' => array(
'total' => array(
'description' => 'The total amount of on this server registered users.',
'type' => 'integer',
'minimum' => 0,
),
'activeMonth' => array(
'description' => 'The amount of users that signed in at least once in the last 30 days.',
'type' => 'integer',
'minimum' => 0,
),
'activeHalfyear' => array(
'description' => 'The amount of users that signed in at least once in the last 180 days.',
'type' => 'integer',
'minimum' => 0,
),
),
),
'localPosts' => array(
'description' => 'The amount of posts that were made by users that are registered on this server.',
'type' => 'integer',
'minimum' => 0,
),
'localComments' => array(
'description' => 'The amount of comments that were made by users that are registered on this server.',
'type' => 'integer',
'minimum' => 0,
),
),
),
'metadata' => array(
'description' => 'Free form key value pairs for software specific values.',
'type' => 'object',
),
),
);
}
}