updated plugin ActivityPub
version 3.3.3
This commit is contained in:
@ -1,4 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* Application model file.
|
||||
*
|
||||
* @package Activitypub
|
||||
*/
|
||||
|
||||
namespace Activitypub\Model;
|
||||
|
||||
use WP_Query;
|
||||
@ -8,6 +14,9 @@ use Activitypub\Collection\Users;
|
||||
|
||||
use function Activitypub\get_rest_url_by_path;
|
||||
|
||||
/**
|
||||
* Application class.
|
||||
*/
|
||||
class Application extends Actor {
|
||||
/**
|
||||
* The User-ID
|
||||
@ -17,7 +26,7 @@ class Application extends Actor {
|
||||
protected $_id = Users::APPLICATION_USER_ID; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
|
||||
|
||||
/**
|
||||
* If the User is discoverable.
|
||||
* Whether the Application is discoverable.
|
||||
*
|
||||
* @see https://docs.joinmastodon.org/spec/activitypub/#discoverable
|
||||
*
|
||||
@ -28,7 +37,7 @@ class Application extends Actor {
|
||||
protected $discoverable = false;
|
||||
|
||||
/**
|
||||
* If the User is indexable.
|
||||
* Whether the Application is indexable.
|
||||
*
|
||||
* @context http://joinmastodon.org/ns#indexable
|
||||
*
|
||||
@ -39,18 +48,33 @@ class Application extends Actor {
|
||||
/**
|
||||
* The WebFinger Resource.
|
||||
*
|
||||
* @var string<url>
|
||||
* @var string
|
||||
*/
|
||||
protected $webfinger;
|
||||
|
||||
/**
|
||||
* Returns the type of the object.
|
||||
*
|
||||
* @return string The type of the object.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'Application';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the Application manually approves followers.
|
||||
*
|
||||
* @return true Whether the Application manually approves followers.
|
||||
*/
|
||||
public function get_manually_approves_followers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the Application.
|
||||
*
|
||||
* @return string The ID of the Application.
|
||||
*/
|
||||
public function get_id() {
|
||||
return get_rest_url_by_path( 'application' );
|
||||
}
|
||||
@ -73,24 +97,34 @@ class Application extends Actor {
|
||||
return $this->get_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Username.
|
||||
*
|
||||
* @return string The Username.
|
||||
*/
|
||||
public function get_name() {
|
||||
return 'application';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred username.
|
||||
*
|
||||
* @return string The preferred username.
|
||||
*/
|
||||
public function get_preferred_username() {
|
||||
return $this->get_name();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the User-Icon.
|
||||
*
|
||||
* @return array The User-Icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
// try site icon first
|
||||
// Try site icon first.
|
||||
$icon_id = get_option( 'site_icon' );
|
||||
|
||||
// try custom logo second
|
||||
// Try custom logo second.
|
||||
if ( ! $icon_id ) {
|
||||
$icon_id = get_theme_mod( 'custom_logo' );
|
||||
}
|
||||
@ -105,7 +139,7 @@ class Application extends Actor {
|
||||
}
|
||||
|
||||
if ( ! $icon_url ) {
|
||||
// fallback to default icon
|
||||
// Fallback to default icon.
|
||||
$icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE );
|
||||
}
|
||||
|
||||
@ -131,6 +165,11 @@ class Application extends Actor {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first published date.
|
||||
*
|
||||
* @return string The published date.
|
||||
*/
|
||||
public function get_published() {
|
||||
$first_post = new WP_Query(
|
||||
array(
|
||||
@ -176,18 +215,23 @@ class Application extends Actor {
|
||||
return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the public key.
|
||||
*
|
||||
* @return array The public key.
|
||||
*/
|
||||
public function get_public_key() {
|
||||
return array(
|
||||
'id' => $this->get_id() . '#main-key',
|
||||
'owner' => $this->get_id(),
|
||||
'id' => $this->get_id() . '#main-key',
|
||||
'owner' => $this->get_id(),
|
||||
'publicKeyPem' => Signature::get_public_key_for( Users::APPLICATION_USER_ID ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Description.
|
||||
* Get the User description.
|
||||
*
|
||||
* @return string The User-Description.
|
||||
* @return string The User description.
|
||||
*/
|
||||
public function get_summary() {
|
||||
return \wpautop(
|
||||
@ -198,6 +242,11 @@ class Application extends Actor {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the canonical URL of the object.
|
||||
*
|
||||
* @return string|null The canonical URL of the object.
|
||||
*/
|
||||
public function get_canonical_url() {
|
||||
return \home_url();
|
||||
}
|
||||
|
@ -1,17 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Blog model file.
|
||||
*
|
||||
* @package Activitypub
|
||||
*/
|
||||
|
||||
namespace Activitypub\Model;
|
||||
|
||||
use WP_Query;
|
||||
use WP_Error;
|
||||
|
||||
use Activitypub\Signature;
|
||||
use Activitypub\Activity\Actor;
|
||||
use Activitypub\Collection\Users;
|
||||
use Activitypub\Collection\Extra_Fields;
|
||||
|
||||
use function Activitypub\esc_hashtag;
|
||||
use function Activitypub\is_single_user;
|
||||
use function Activitypub\is_user_disabled;
|
||||
use function Activitypub\is_blog_public;
|
||||
use function Activitypub\get_rest_url_by_path;
|
||||
|
||||
/**
|
||||
* Blog class.
|
||||
*/
|
||||
class Blog extends Actor {
|
||||
/**
|
||||
* The Featured-Posts.
|
||||
@ -55,12 +65,12 @@ class Blog extends Actor {
|
||||
/**
|
||||
* The WebFinger Resource.
|
||||
*
|
||||
* @var string<url>
|
||||
* @var string
|
||||
*/
|
||||
protected $webfinger;
|
||||
|
||||
/**
|
||||
* If the User is discoverable.
|
||||
* Whether the User is discoverable.
|
||||
*
|
||||
* @see https://docs.joinmastodon.org/spec/activitypub/#discoverable
|
||||
*
|
||||
@ -71,7 +81,7 @@ class Blog extends Actor {
|
||||
protected $discoverable;
|
||||
|
||||
/**
|
||||
* Restrict posting to mods
|
||||
* Restrict posting to mods.
|
||||
*
|
||||
* @see https://join-lemmy.org/docs/contributors/05-federation.html
|
||||
*
|
||||
@ -79,18 +89,28 @@ class Blog extends Actor {
|
||||
*/
|
||||
protected $posting_restricted_to_mods;
|
||||
|
||||
/**
|
||||
* Whether the User manually approves followers.
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public function get_manually_approves_followers() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the User is discoverable.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function get_discoverable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-ID.
|
||||
* Get the User ID.
|
||||
*
|
||||
* @return string The User-ID.
|
||||
* @return string The User ID.
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->get_url();
|
||||
@ -112,9 +132,9 @@ class Blog extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Name.
|
||||
* Get the Username.
|
||||
*
|
||||
* @return string The User-Name.
|
||||
* @return string The Username.
|
||||
*/
|
||||
public function get_name() {
|
||||
return \wp_strip_all_tags(
|
||||
@ -127,23 +147,29 @@ class Blog extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Description.
|
||||
* Get the User description.
|
||||
*
|
||||
* @return string The User-Description.
|
||||
* @return string The User description.
|
||||
*/
|
||||
public function get_summary() {
|
||||
$summary = \get_option( 'activitypub_blog_description', null );
|
||||
|
||||
if ( ! $summary ) {
|
||||
$summary = \get_bloginfo( 'description' );
|
||||
}
|
||||
|
||||
return \wpautop(
|
||||
\wp_kses(
|
||||
\get_bloginfo( 'description' ),
|
||||
$summary,
|
||||
'default'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Url.
|
||||
* Get the User url.
|
||||
*
|
||||
* @return string The User-Url.
|
||||
* @return string The User url.
|
||||
*/
|
||||
public function get_url() {
|
||||
return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
|
||||
@ -164,12 +190,12 @@ class Blog extends Actor {
|
||||
* @return string The auto-generated Username.
|
||||
*/
|
||||
public static function get_default_username() {
|
||||
// check if domain host has a subdomain
|
||||
// Check if domain host has a subdomain.
|
||||
$host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST );
|
||||
$host = \preg_replace( '/^www\./i', '', $host );
|
||||
|
||||
/**
|
||||
* Filter the default blog username.
|
||||
* Filters the default blog username.
|
||||
*
|
||||
* @param string $host The default username.
|
||||
*/
|
||||
@ -177,12 +203,12 @@ class Blog extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred User-Name.
|
||||
* Get the preferred Username.
|
||||
*
|
||||
* @return string The User-Name.
|
||||
* @return string The Username.
|
||||
*/
|
||||
public function get_preferred_username() {
|
||||
$username = \get_option( 'activitypub_blog_user_identifier' );
|
||||
$username = \get_option( 'activitypub_blog_identifier' );
|
||||
|
||||
if ( $username ) {
|
||||
return $username;
|
||||
@ -192,15 +218,15 @@ class Blog extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Icon.
|
||||
* Get the User icon.
|
||||
*
|
||||
* @return array The User-Icon.
|
||||
* @return array The User icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
// try site icon first
|
||||
// Try site_logo, falling back to site_icon, first.
|
||||
$icon_id = get_option( 'site_icon' );
|
||||
|
||||
// try custom logo second
|
||||
// Try custom logo second.
|
||||
if ( ! $icon_id ) {
|
||||
$icon_id = get_theme_mod( 'custom_logo' );
|
||||
}
|
||||
@ -215,7 +241,7 @@ class Blog extends Actor {
|
||||
}
|
||||
|
||||
if ( ! $icon_url ) {
|
||||
// fallback to default icon
|
||||
// Fallback to default icon.
|
||||
$icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE );
|
||||
}
|
||||
|
||||
@ -231,16 +257,32 @@ class Blog extends Actor {
|
||||
* @return array|null The User-Header-Image.
|
||||
*/
|
||||
public function get_image() {
|
||||
if ( \has_header_image() ) {
|
||||
$header_image = get_option( 'activitypub_header_image' );
|
||||
$image_url = null;
|
||||
|
||||
if ( $header_image ) {
|
||||
$image_url = \wp_get_attachment_url( $header_image );
|
||||
}
|
||||
|
||||
if ( ! $image_url && \has_header_image() ) {
|
||||
$image_url = \get_header_image();
|
||||
}
|
||||
|
||||
if ( $image_url ) {
|
||||
return array(
|
||||
'type' => 'Image',
|
||||
'url' => esc_url( \get_header_image() ),
|
||||
'url' => esc_url( $image_url ),
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the published date.
|
||||
*
|
||||
* @return string The published date.
|
||||
*/
|
||||
public function get_published() {
|
||||
$first_post = new WP_Query(
|
||||
array(
|
||||
@ -259,10 +301,20 @@ class Blog extends Actor {
|
||||
return \gmdate( 'Y-m-d\TH:i:s\Z', $time );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the canonical URL.
|
||||
*
|
||||
* @return string|null The canonical URL.
|
||||
*/
|
||||
public function get_canonical_url() {
|
||||
return \home_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Moderators endpoint.
|
||||
*
|
||||
* @return string|null The Moderators endpoint.
|
||||
*/
|
||||
public function get_moderators() {
|
||||
if ( is_single_user() || 'Group' !== $this->get_type() ) {
|
||||
return null;
|
||||
@ -271,6 +323,11 @@ class Blog extends Actor {
|
||||
return get_rest_url_by_path( 'collections/moderators' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attributedTo value.
|
||||
*
|
||||
* @return string|null The attributedTo value.
|
||||
*/
|
||||
public function get_attributed_to() {
|
||||
if ( is_single_user() || 'Group' !== $this->get_type() ) {
|
||||
return null;
|
||||
@ -279,14 +336,24 @@ class Blog extends Actor {
|
||||
return get_rest_url_by_path( 'collections/moderators' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the public key information.
|
||||
*
|
||||
* @return array The public key.
|
||||
*/
|
||||
public function get_public_key() {
|
||||
return array(
|
||||
'id' => $this->get_id() . '#main-key',
|
||||
'owner' => $this->get_id(),
|
||||
'id' => $this->get_id() . '#main-key',
|
||||
'owner' => $this->get_id(),
|
||||
'publicKeyPem' => Signature::get_public_key_for( $this->get__id() ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether posting is restricted to mods.
|
||||
*
|
||||
* @return bool|null True if posting is restricted to mods, null if not applicable.
|
||||
*/
|
||||
public function get_posting_restricted_to_mods() {
|
||||
if ( 'Group' === $this->get_type() ) {
|
||||
return true;
|
||||
@ -331,6 +398,11 @@ class Blog extends Actor {
|
||||
return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns endpoints.
|
||||
*
|
||||
* @return array|null The endpoints.
|
||||
*/
|
||||
public function get_endpoints() {
|
||||
$endpoints = null;
|
||||
|
||||
@ -361,45 +433,101 @@ class Blog extends Actor {
|
||||
return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the site is indexable.
|
||||
*
|
||||
* @return bool Whether the site is indexable.
|
||||
*/
|
||||
public function get_indexable() {
|
||||
if ( \get_option( 'blog_public', 1 ) ) {
|
||||
if ( is_blog_public() ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Username.
|
||||
*
|
||||
* @param mixed $value The new value.
|
||||
* @return bool True if the attribute was updated, false otherwise.
|
||||
*/
|
||||
public function update_name( $value ) {
|
||||
return \update_option( 'blogname', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the User description.
|
||||
*
|
||||
* @param mixed $value The new value.
|
||||
* @return bool True if the attribute was updated, false otherwise.
|
||||
*/
|
||||
public function update_summary( $value ) {
|
||||
return \update_option( 'blogdescription', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the User icon.
|
||||
*
|
||||
* @param mixed $value The new value.
|
||||
* @return bool True if the attribute was updated, false otherwise.
|
||||
*/
|
||||
public function update_icon( $value ) {
|
||||
if ( ! wp_attachment_is_image( $value ) ) {
|
||||
return false;
|
||||
}
|
||||
return \update_option( 'site_icon', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the User-Header-Image.
|
||||
*
|
||||
* @param mixed $value The new value.
|
||||
* @return bool True if the attribute was updated, false otherwise.
|
||||
*/
|
||||
public function update_header( $value ) {
|
||||
if ( ! wp_attachment_is_image( $value ) ) {
|
||||
return false;
|
||||
}
|
||||
return \update_option( 'activitypub_header_image', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User - Hashtags.
|
||||
*
|
||||
* @see https://docs.joinmastodon.org/spec/activitypub/#Hashtag
|
||||
*
|
||||
* @return array The User - Hashtags.
|
||||
*/
|
||||
public function get_tag() {
|
||||
$hashtags = array();
|
||||
|
||||
$args = array(
|
||||
'orderby' => 'count',
|
||||
'order' => 'DESC',
|
||||
'number' => 10,
|
||||
);
|
||||
|
||||
$tags = get_tags( $args );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$hashtags[] = array(
|
||||
'type' => 'Hashtag',
|
||||
'href' => \get_tag_link( $tag->term_id ),
|
||||
'name' => esc_hashtag( $tag->name ),
|
||||
);
|
||||
}
|
||||
|
||||
return $hashtags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the User-Output with Attachments.
|
||||
*
|
||||
* @return array The extended User-Output.
|
||||
*/
|
||||
public function get_attachment() {
|
||||
$array = array();
|
||||
|
||||
$array[] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \__( 'Blog', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
sprintf(
|
||||
'<a rel="me" title="%s" target="_blank" href="%s">%s</a>',
|
||||
\esc_attr( \home_url( '/' ) ),
|
||||
\esc_url( \home_url( '/' ) ),
|
||||
\wp_parse_url( \home_url( '/' ), \PHP_URL_HOST )
|
||||
),
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
// Add support for FEP-fb2a, for more information see FEDERATION.md
|
||||
$array[] = array(
|
||||
'type' => 'Link',
|
||||
'name' => \__( 'Blog', 'activitypub' ),
|
||||
'href' => \esc_url( \home_url( '/' ) ),
|
||||
'rel' => array( 'me' ),
|
||||
);
|
||||
|
||||
return $array;
|
||||
$extra_fields = Extra_Fields::get_actor_fields( $this->_id );
|
||||
return Extra_Fields::fields_to_attachments( $extra_fields );
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Follower class file.
|
||||
*
|
||||
* @package Activitypub
|
||||
*/
|
||||
|
||||
namespace Activitypub\Model;
|
||||
|
||||
use WP_Error;
|
||||
use WP_Query;
|
||||
use Activitypub\Activity\Actor;
|
||||
use Activitypub\Collection\Followers;
|
||||
|
||||
/**
|
||||
* ActivityPub Follower Class
|
||||
* ActivityPub Follower Class.
|
||||
*
|
||||
* This Object represents a single Follower.
|
||||
* There is no direct reference to a WordPress User here.
|
||||
@ -19,9 +24,9 @@ use Activitypub\Collection\Followers;
|
||||
*/
|
||||
class Follower extends Actor {
|
||||
/**
|
||||
* The complete Remote-Profile of the Follower
|
||||
* The complete Remote-Profile of the Follower.
|
||||
*
|
||||
* @var array
|
||||
* @var int
|
||||
*/
|
||||
protected $_id; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
|
||||
|
||||
@ -31,13 +36,13 @@ class Follower extends Actor {
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_errors() {
|
||||
return get_post_meta( $this->_id, 'activitypub_errors' );
|
||||
return get_post_meta( $this->_id, 'activitypub_errors', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Summary.
|
||||
*
|
||||
* @return int The Summary.
|
||||
* @return string The Summary.
|
||||
*/
|
||||
public function get_summary() {
|
||||
if ( isset( $this->summary ) ) {
|
||||
@ -51,7 +56,7 @@ class Follower extends Actor {
|
||||
* Getter for URL attribute.
|
||||
*
|
||||
* Falls back to ID, if no URL is set. This is relevant for
|
||||
* Plattforms like Lemmy, where the ID is the URL.
|
||||
* Platforms like Lemmy, where the ID is the URL.
|
||||
*
|
||||
* @return string The URL.
|
||||
*/
|
||||
@ -65,8 +70,6 @@ class Follower extends Actor {
|
||||
|
||||
/**
|
||||
* Reset (delete) all errors.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reset_errors() {
|
||||
delete_post_meta( $this->_id, 'activitypub_errors' );
|
||||
@ -103,21 +106,19 @@ class Follower extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current Follower-Object.
|
||||
*
|
||||
* @return void
|
||||
* Update the current Follower object.
|
||||
*/
|
||||
public function update() {
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the current Follower-Object.
|
||||
* Validate the current Follower object.
|
||||
*
|
||||
* @return boolean True if the verification was successful.
|
||||
*/
|
||||
public function is_valid() {
|
||||
// the minimum required attributes
|
||||
// The minimum required attributes.
|
||||
$required_attributes = array(
|
||||
'id',
|
||||
'preferredUsername',
|
||||
@ -136,9 +137,9 @@ class Follower extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the current Follower-Object.
|
||||
* Save the current Follower object.
|
||||
*
|
||||
* @return int|WP_Error The Post-ID or an WP_Error.
|
||||
* @return int|WP_Error The post ID or an WP_Error.
|
||||
*/
|
||||
public function save() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
@ -148,7 +149,7 @@ class Follower extends Actor {
|
||||
if ( ! $this->get__id() ) {
|
||||
global $wpdb;
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
|
||||
$post_id = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT ID FROM $wpdb->posts WHERE guid=%s",
|
||||
@ -177,37 +178,35 @@ class Follower extends Actor {
|
||||
);
|
||||
|
||||
if ( ! empty( $post_id ) ) {
|
||||
// If this is an update, prevent the "followed" date from being
|
||||
// overwritten by the current date.
|
||||
// If this is an update, prevent the "followed" date from being overwritten by the current date.
|
||||
$post = get_post( $post_id );
|
||||
$args['post_date'] = $post->post_date;
|
||||
$args['post_date_gmt'] = $post->post_date_gmt;
|
||||
}
|
||||
|
||||
$post_id = wp_insert_post( $args );
|
||||
$post_id = wp_insert_post( $args );
|
||||
$this->_id = $post_id;
|
||||
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert the current Follower-Object.
|
||||
* Upsert the current Follower object.
|
||||
*
|
||||
* @return int|WP_Error The Post-ID or an WP_Error.
|
||||
* @return int|WP_Error The post ID or an WP_Error.
|
||||
*/
|
||||
public function upsert() {
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the current Follower-Object.
|
||||
* Delete the current Follower object.
|
||||
*
|
||||
* Beware that this os deleting a Follower for ALL users!!!
|
||||
*
|
||||
* To delete only the User connection (unfollow)
|
||||
* @see \Activitypub\Rest\Followers::remove_follower()
|
||||
*
|
||||
* @return void
|
||||
* @see \Activitypub\Rest\Followers::remove_follower()
|
||||
*/
|
||||
public function delete() {
|
||||
wp_delete_post( $this->_id );
|
||||
@ -215,12 +214,10 @@ class Follower extends Actor {
|
||||
|
||||
/**
|
||||
* Update the post meta.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function get_post_meta_input() {
|
||||
$meta_input = array();
|
||||
$meta_input['activitypub_inbox'] = $this->get_shared_inbox();
|
||||
$meta_input = array();
|
||||
$meta_input['activitypub_inbox'] = $this->get_shared_inbox();
|
||||
$meta_input['activitypub_actor_json'] = $this->to_json();
|
||||
|
||||
return $meta_input;
|
||||
@ -239,9 +236,9 @@ class Follower extends Actor {
|
||||
}
|
||||
|
||||
return array(
|
||||
'type' => 'Image',
|
||||
'type' => 'Image',
|
||||
'mediaType' => 'image/jpeg',
|
||||
'url' => ACTIVITYPUB_PLUGIN_URL . 'assets/img/mp.jpg',
|
||||
'url' => ACTIVITYPUB_PLUGIN_URL . 'assets/img/mp.jpg',
|
||||
);
|
||||
}
|
||||
|
||||
@ -278,7 +275,7 @@ class Follower extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Icon URL (Avatar)
|
||||
* Get the Icon URL (Avatar).
|
||||
*
|
||||
* @return string The URL to the Avatar.
|
||||
*/
|
||||
@ -297,7 +294,7 @@ class Follower extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Icon URL (Avatar)
|
||||
* Get the Icon URL (Avatar).
|
||||
*
|
||||
* @return string The URL to the Avatar.
|
||||
*/
|
||||
@ -333,13 +330,12 @@ class Follower extends Actor {
|
||||
/**
|
||||
* Convert a Custom-Post-Type input to an Activitypub\Model\Follower.
|
||||
*
|
||||
* @return string The JSON string.
|
||||
*
|
||||
* @return array Activitypub\Model\Follower
|
||||
* @param \WP_Post $post The post object.
|
||||
* @return \Activitypub\Activity\Base_Object|WP_Error
|
||||
*/
|
||||
public static function init_from_cpt( $post ) {
|
||||
$actor_json = get_post_meta( $post->ID, 'activitypub_actor_json', true );
|
||||
$object = self::init_from_json( $actor_json );
|
||||
$object = self::init_from_json( $actor_json );
|
||||
$object->set__id( $post->ID );
|
||||
$object->set_id( $post->guid );
|
||||
$object->set_name( $post->post_title );
|
||||
@ -370,10 +366,10 @@ class Follower extends Actor {
|
||||
|
||||
if ( $path ) {
|
||||
if ( \strpos( $name, '@' ) !== false ) {
|
||||
// expected: https://example.com/@user (default URL pattern)
|
||||
// Expected: https://example.com/@user (default URL pattern).
|
||||
$name = \preg_replace( '|^/@?|', '', $path );
|
||||
} else {
|
||||
// expected: https://example.com/users/user (default ID pattern)
|
||||
// Expected: https://example.com/users/user (default ID pattern).
|
||||
$parts = \explode( '/', $path );
|
||||
$name = \array_pop( $parts );
|
||||
}
|
||||
@ -383,7 +379,7 @@ class Follower extends Actor {
|
||||
\strpos( $name, 'acct' ) === 0 ||
|
||||
\strpos( $name, '@' ) === 0
|
||||
) {
|
||||
// expected: user@example.com or acct:user@example (WebFinger)
|
||||
// Expected: user@example.com or acct:user@example (WebFinger).
|
||||
$name = \ltrim( $name, '@' );
|
||||
$name = \ltrim( $name, 'acct:' );
|
||||
$parts = \explode( '@', $name );
|
||||
|
@ -1,136 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Model;
|
||||
|
||||
use Activitypub\Collection\Users;
|
||||
use Activitypub\Transformer\Factory;
|
||||
|
||||
/**
|
||||
* ActivityPub Post Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Post {
|
||||
/**
|
||||
* The \Activitypub\Activity\Base_Object object.
|
||||
*
|
||||
* @var \Activitypub\Activity\Base_Object
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* The WordPress Post Object.
|
||||
*
|
||||
* @var WP_Post
|
||||
*/
|
||||
private $post;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param WP_Post $post
|
||||
* @param int $post_author
|
||||
*/
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
||||
public function __construct( $post, $post_author = null ) {
|
||||
_deprecated_function( __METHOD__, '1.0.0', '\Activitypub\Transformer\Factory::get_transformer' );
|
||||
|
||||
$transformer = Factory::get_transformer( $post );
|
||||
|
||||
if ( ! \is_wp_error( $transformer ) ) {
|
||||
$this->post = $post;
|
||||
$this->object = $transformer->to_object();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the User ID.
|
||||
*
|
||||
* @return int the User ID.
|
||||
*/
|
||||
public function get_user_id() {
|
||||
return apply_filters( 'activitypub_post_user_id', $this->post->post_author, $this->post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this Object into an Array.
|
||||
*
|
||||
* @return array the array representation of a Post.
|
||||
*/
|
||||
public function to_array() {
|
||||
return \apply_filters( 'activitypub_post', $this->object->to_array(), $this->post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Actor of this Object.
|
||||
*
|
||||
* @return string The URL of the Actor.
|
||||
*/
|
||||
public function get_actor() {
|
||||
$user = Users::get_by_id( $this->get_user_id() );
|
||||
|
||||
return $user->get_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this Object into a JSON String
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function to_json() {
|
||||
return \wp_json_encode( $this->to_array(), \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of an Activity Object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_url() {
|
||||
return $this->object->get_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of an Activity Object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->object->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of Image Attachments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_attachments() {
|
||||
return $this->object->get_attachment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of Tags, used in the Post
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_tags() {
|
||||
return $this->object->get_tag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the as2 object-type for a given post
|
||||
*
|
||||
* @return string the object-type
|
||||
*/
|
||||
public function get_object_type() {
|
||||
return $this->object->get_type();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content for the ActivityPub Item.
|
||||
*
|
||||
* @return string the content
|
||||
*/
|
||||
public function get_content() {
|
||||
return $this->object->get_content();
|
||||
}
|
||||
}
|
@ -1,18 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* User model file.
|
||||
*
|
||||
* @package Activitypub
|
||||
*/
|
||||
|
||||
namespace Activitypub\Model;
|
||||
|
||||
use WP_Query;
|
||||
use WP_Error;
|
||||
use Activitypub\Migration;
|
||||
use Activitypub\Signature;
|
||||
use Activitypub\Model\Blog;
|
||||
use Activitypub\Activity\Actor;
|
||||
use Activitypub\Collection\Users;
|
||||
use Activitypub\Collection\Extra_Fields;
|
||||
|
||||
use function Activitypub\is_blog_public;
|
||||
use function Activitypub\is_user_disabled;
|
||||
use function Activitypub\get_rest_url_by_path;
|
||||
use function Activitypub\get_actor_extra_fields;
|
||||
|
||||
/**
|
||||
* User class.
|
||||
*/
|
||||
class User extends Actor {
|
||||
/**
|
||||
* The local User-ID (WP_User).
|
||||
@ -36,7 +42,7 @@ class User extends Actor {
|
||||
protected $featured;
|
||||
|
||||
/**
|
||||
* If the User is discoverable.
|
||||
* Whether the User is discoverable.
|
||||
*
|
||||
* @see https://docs.joinmastodon.org/spec/activitypub/#discoverable
|
||||
*
|
||||
@ -47,7 +53,7 @@ class User extends Actor {
|
||||
protected $discoverable = true;
|
||||
|
||||
/**
|
||||
* If the User is indexable.
|
||||
* Whether the User is indexable.
|
||||
*
|
||||
* @context http://joinmastodon.org/ns#indexable
|
||||
*
|
||||
@ -58,14 +64,26 @@ class User extends Actor {
|
||||
/**
|
||||
* The WebFinger Resource.
|
||||
*
|
||||
* @var string<url>
|
||||
* @var string
|
||||
*/
|
||||
protected $webfinger;
|
||||
|
||||
/**
|
||||
* The type of the object.
|
||||
*
|
||||
* @return string The type of the object.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'Person';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a User object from a WP_User.
|
||||
*
|
||||
* @param int $user_id The user ID.
|
||||
*
|
||||
* @return WP_Error|User The User object or WP_Error if user not found.
|
||||
*/
|
||||
public static function from_wp_user( $user_id ) {
|
||||
if ( is_user_disabled( $user_id ) ) {
|
||||
return new WP_Error(
|
||||
@ -75,37 +93,37 @@ class User extends Actor {
|
||||
);
|
||||
}
|
||||
|
||||
$object = new static();
|
||||
$object = new static();
|
||||
$object->_id = $user_id;
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-ID.
|
||||
* Get the user ID.
|
||||
*
|
||||
* @return string The User-ID.
|
||||
* @return string The user ID.
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->get_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Name.
|
||||
* Get the Username.
|
||||
*
|
||||
* @return string The User-Name.
|
||||
* @return string The Username.
|
||||
*/
|
||||
public function get_name() {
|
||||
return \esc_attr( \get_the_author_meta( 'display_name', $this->_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Description.
|
||||
* Get the User description.
|
||||
*
|
||||
* @return string The User-Description.
|
||||
* @return string The User description.
|
||||
*/
|
||||
public function get_summary() {
|
||||
$description = get_user_meta( $this->_id, 'activitypub_user_description', true );
|
||||
$description = get_user_option( 'activitypub_description', $this->_id );
|
||||
if ( empty( $description ) ) {
|
||||
$description = get_user_meta( $this->_id, 'description', true );
|
||||
}
|
||||
@ -113,28 +131,46 @@ class User extends Actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User-Url.
|
||||
* Get the User url.
|
||||
*
|
||||
* @return string The User-Url.
|
||||
* @return string The User url.
|
||||
*/
|
||||
public function get_url() {
|
||||
return \esc_url( \get_author_posts_url( $this->_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the User-URL with @-Prefix for the username.
|
||||
* Returns the User URL with @-Prefix for the username.
|
||||
*
|
||||
* @return string 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() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred username.
|
||||
*
|
||||
* @return string The preferred username.
|
||||
*/
|
||||
public function get_preferred_username() {
|
||||
return \esc_attr( \get_the_author_meta( 'login', $this->_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User icon.
|
||||
*
|
||||
* @return array The User icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
$icon = \get_user_option( 'activitypub_icon', $this->_id );
|
||||
if ( wp_attachment_is_image( $icon ) ) {
|
||||
return array(
|
||||
'type' => 'Image',
|
||||
'url' => esc_url( wp_get_attachment_url( $icon ) ),
|
||||
);
|
||||
}
|
||||
|
||||
$icon = \esc_url(
|
||||
\get_avatar_url(
|
||||
$this->_id,
|
||||
@ -148,26 +184,51 @@ class User extends Actor {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header image.
|
||||
*
|
||||
* @return array|null The header image.
|
||||
*/
|
||||
public function get_image() {
|
||||
if ( \has_header_image() ) {
|
||||
$image = \esc_url( \get_header_image() );
|
||||
$header_image = get_user_option( 'activitypub_header_image', $this->_id );
|
||||
$image_url = null;
|
||||
|
||||
if ( ! $header_image && \has_header_image() ) {
|
||||
$image_url = \get_header_image();
|
||||
}
|
||||
|
||||
if ( $header_image ) {
|
||||
$image_url = \wp_get_attachment_url( $header_image );
|
||||
}
|
||||
|
||||
if ( $image_url ) {
|
||||
return array(
|
||||
'type' => 'Image',
|
||||
'url' => $image,
|
||||
'url' => esc_url( $image_url ),
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date the user was created.
|
||||
*
|
||||
* @return false|string The date the user was created.
|
||||
*/
|
||||
public function get_published() {
|
||||
return \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( \get_the_author_meta( 'registered', $this->_id ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the public key.
|
||||
*
|
||||
* @return array The public key.
|
||||
*/
|
||||
public function get_public_key() {
|
||||
return array(
|
||||
'id' => $this->get_id() . '#main-key',
|
||||
'owner' => $this->get_id(),
|
||||
'id' => $this->get_id() . '#main-key',
|
||||
'owner' => $this->get_id(),
|
||||
'publicKeyPem' => Signature::get_public_key_for( $this->get__id() ),
|
||||
);
|
||||
}
|
||||
@ -217,6 +278,11 @@ class User extends Actor {
|
||||
return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the endpoints.
|
||||
*
|
||||
* @return array|null The endpoints.
|
||||
*/
|
||||
public function get_endpoints() {
|
||||
$endpoints = null;
|
||||
|
||||
@ -235,74 +301,8 @@ class User extends Actor {
|
||||
* @return array The extended User-Output.
|
||||
*/
|
||||
public function get_attachment() {
|
||||
$extra_fields = get_actor_extra_fields( $this->_id );
|
||||
|
||||
$attachments = array();
|
||||
|
||||
foreach ( $extra_fields as $post ) {
|
||||
$content = \get_the_content( null, false, $post );
|
||||
$content = \make_clickable( $content );
|
||||
$content = \do_blocks( $content );
|
||||
$content = \wptexturize( $content );
|
||||
$content = \wp_filter_content_tags( $content );
|
||||
// replace script and style elements
|
||||
$content = \preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $content );
|
||||
$content = \strip_shortcodes( $content );
|
||||
$content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) );
|
||||
|
||||
$attachments[] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => \get_the_title( $post ),
|
||||
'value' => \html_entity_decode(
|
||||
$content,
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
$link_added = false;
|
||||
|
||||
// Add support for FEP-fb2a, for more information see FEDERATION.md
|
||||
if ( \class_exists( '\WP_HTML_Tag_Processor' ) ) {
|
||||
$tags = new \WP_HTML_Tag_Processor( $content );
|
||||
$tags->next_tag();
|
||||
|
||||
if ( 'P' === $tags->get_tag() ) {
|
||||
$tags->next_tag();
|
||||
}
|
||||
|
||||
if ( 'A' === $tags->get_tag() ) {
|
||||
$tags->set_bookmark( 'link' );
|
||||
if ( ! $tags->next_tag() ) {
|
||||
$tags->seek( 'link' );
|
||||
$attachment = array(
|
||||
'type' => 'Link',
|
||||
'name' => \get_the_title( $post ),
|
||||
'href' => \esc_url( $tags->get_attribute( 'href' ) ),
|
||||
'rel' => explode( ' ', $tags->get_attribute( 'rel' ) ),
|
||||
);
|
||||
|
||||
$link_added = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $link_added ) {
|
||||
$attachment = array(
|
||||
'type' => 'Note',
|
||||
'name' => \get_the_title( $post ),
|
||||
'content' => \html_entity_decode(
|
||||
$content,
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$attachments[] = $attachment;
|
||||
}
|
||||
|
||||
return $attachments;
|
||||
$extra_fields = Extra_Fields::get_actor_fields( $this->_id );
|
||||
return Extra_Fields::fields_to_attachments( $extra_fields );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,23 +314,93 @@ class User extends Actor {
|
||||
return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the canonical URL.
|
||||
*
|
||||
* @return string The canonical URL.
|
||||
*/
|
||||
public function get_canonical_url() {
|
||||
return $this->get_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the streams.
|
||||
*
|
||||
* @return null The streams.
|
||||
*/
|
||||
public function get_streams() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag.
|
||||
*
|
||||
* @return array The tag.
|
||||
*/
|
||||
public function get_tag() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the indexable state.
|
||||
*
|
||||
* @return bool Whether the user is indexable.
|
||||
*/
|
||||
public function get_indexable() {
|
||||
if ( \get_option( 'blog_public', 1 ) ) {
|
||||
if ( is_blog_public() ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the username.
|
||||
*
|
||||
* @param string $value The new value.
|
||||
* @return int|WP_Error The updated user ID or WP_Error on failure.
|
||||
*/
|
||||
public function update_name( $value ) {
|
||||
$userdata = array(
|
||||
'ID' => $this->_id,
|
||||
'display_name' => $value,
|
||||
);
|
||||
return \wp_update_user( $userdata );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the User description.
|
||||
*
|
||||
* @param string $value The new value.
|
||||
* @return bool True if the attribute was updated, false otherwise.
|
||||
*/
|
||||
public function update_summary( $value ) {
|
||||
return \update_user_option( $this->_id, 'activitypub_description', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the User icon.
|
||||
*
|
||||
* @param int $value The new value. Should be an attachment ID.
|
||||
* @return bool True if the attribute was updated, false otherwise.
|
||||
*/
|
||||
public function update_icon( $value ) {
|
||||
if ( ! wp_attachment_is_image( $value ) ) {
|
||||
return false;
|
||||
}
|
||||
return update_user_option( $this->_id, 'activitypub_icon', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the User-Header-Image.
|
||||
*
|
||||
* @param int $value The new value. Should be an attachment ID.
|
||||
* @return bool True if the attribute was updated, false otherwise.
|
||||
*/
|
||||
public function update_header( $value ) {
|
||||
if ( ! wp_attachment_is_image( $value ) ) {
|
||||
return false;
|
||||
}
|
||||
return \update_user_option( $this->_id, 'activitypub_header_image', $value );
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user