wordpress-activitypub/includes/model/class-blog.php

406 lines
7.9 KiB
PHP
Raw Normal View History

<?php
namespace Activitypub\Model;
use WP_Query;
Add/event objects (#629) * remove redundant property definitions * Add redused context for actors. * Add classes to construct Moblizon compatible events * Bind the context to the activitypub object - change the propertyname which stores the json-ld context from context to _context, because context is already reserved in the ActivityStreams vocabulary. - cleanup currently unused code * fix phpcs * Remove PostalAddress object: it's enough (at least atm) to directly write the array in transformers. * Remove _context property from ActivityPub objects in favour of getter function get_json_ld_context() * fix unit tests: ActivityPub Activity objects have a custom getter for the JsonLD context * fix phpcs * fix unit-tests to also support php5.6 * fix phpcs * add param include_json_ld_context to to_array function This allows to not set the @context in the resulting array. * propagate the param include_json_ld_context to nested calls of to_array. * fix phpcs * Nested AcitivityPub objects: never build context in inner items in to_array function * fix: param of set_address may also be an array * fix typo in comment * always prefix json-ld context with json-ld and move event class to sub-namespace * fix usage of reserved object keyword seems it should not be used as a namespace either * Merge commit 'b2271cda6b857f879e0abd4f3c6683642d725267' into add/event-objects * Fix calling non-static function as static Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com> * Partly fix Json-LD contexts in collections * Update includes/activity/class-base-object.php * this is implicit We already set the correct user with `$transformer->change_wp_user_id( $user_id );` so the Actor will be generated properly. We can change the behaviour, but we should not use both. * this change prevents the Activity to re-use Object vars this should stay as is, because it pre-fills the Activity with data (for example cc and to) and it will no longer be done with your change. It is on purpose that it first sets the object and then replaces it with the URI. See: https://github.com/Automattic/wordpress-activitypub/blob/master/includes/activity/class-activity.php#L195 * add `$include_json_ld_context` support to `to_json` * disable some more contexts * remove whitespace * Add php-comment for 7ed17c042a2651e08afc790adbdfc5ccf46c2708 * Fix JSON-LD context for ActivityPub objects: child classes may override it. * coding standards * call folder/namespace `Extended_Object` to be consistent with folder names in singular * fix: unnessesary nesting of extended-objects * remove license I hope this is fine, to have the complete plugin under the MIT @Menrath ?!? --------- Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com>
2024-01-18 15:35:52 +00:00
use WP_Error;
use Activitypub\Signature;
use Activitypub\Activity\Actor;
2023-07-03 09:20:44 +00:00
use Activitypub\Collection\Users;
use function Activitypub\is_single_user;
2023-06-28 14:43:41 +00:00
use function Activitypub\is_user_disabled;
use function Activitypub\get_rest_url_by_path;
2023-06-28 14:43:41 +00:00
class Blog extends Actor {
/**
* The Featured-Posts.
*
* @see https://docs.joinmastodon.org/spec/activitypub/#featured
*
* @context {
* "@id": "http://joinmastodon.org/ns#featured",
* "@type": "@id"
* }
*
* @var string
*/
protected $featured;
/**
* Moderators endpoint.
*
* @see https://join-lemmy.org/docs/contributors/05-federation.html
*
* @var string
*/
protected $moderators;
/**
* The User-ID
*
* @var int
*/
2023-07-03 09:20:44 +00:00
protected $_id = Users::BLOG_USER_ID; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
/**
* If the User is indexable.
*
* @context http://joinmastodon.org/ns#indexable
*
* @var boolean
*/
protected $indexable;
/**
* The WebFinger Resource.
*
* @var string<url>
*/
protected $webfinger;
/**
* If the User is discoverable.
*
* @see https://docs.joinmastodon.org/spec/activitypub/#discoverable
*
* @context http://joinmastodon.org/ns#discoverable
*
* @var boolean
*/
protected $discoverable;
/**
* Restrict posting to mods
*
* @see https://join-lemmy.org/docs/contributors/05-federation.html
*
* @var boolean
*/
protected $posting_restricted_to_mods;
Add/event objects (#629) * remove redundant property definitions * Add redused context for actors. * Add classes to construct Moblizon compatible events * Bind the context to the activitypub object - change the propertyname which stores the json-ld context from context to _context, because context is already reserved in the ActivityStreams vocabulary. - cleanup currently unused code * fix phpcs * Remove PostalAddress object: it's enough (at least atm) to directly write the array in transformers. * Remove _context property from ActivityPub objects in favour of getter function get_json_ld_context() * fix unit tests: ActivityPub Activity objects have a custom getter for the JsonLD context * fix phpcs * fix unit-tests to also support php5.6 * fix phpcs * add param include_json_ld_context to to_array function This allows to not set the @context in the resulting array. * propagate the param include_json_ld_context to nested calls of to_array. * fix phpcs * Nested AcitivityPub objects: never build context in inner items in to_array function * fix: param of set_address may also be an array * fix typo in comment * always prefix json-ld context with json-ld and move event class to sub-namespace * fix usage of reserved object keyword seems it should not be used as a namespace either * Merge commit 'b2271cda6b857f879e0abd4f3c6683642d725267' into add/event-objects * Fix calling non-static function as static Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com> * Partly fix Json-LD contexts in collections * Update includes/activity/class-base-object.php * this is implicit We already set the correct user with `$transformer->change_wp_user_id( $user_id );` so the Actor will be generated properly. We can change the behaviour, but we should not use both. * this change prevents the Activity to re-use Object vars this should stay as is, because it pre-fills the Activity with data (for example cc and to) and it will no longer be done with your change. It is on purpose that it first sets the object and then replaces it with the URI. See: https://github.com/Automattic/wordpress-activitypub/blob/master/includes/activity/class-activity.php#L195 * add `$include_json_ld_context` support to `to_json` * disable some more contexts * remove whitespace * Add php-comment for 7ed17c042a2651e08afc790adbdfc5ccf46c2708 * Fix JSON-LD context for ActivityPub objects: child classes may override it. * coding standards * call folder/namespace `Extended_Object` to be consistent with folder names in singular * fix: unnessesary nesting of extended-objects * remove license I hope this is fine, to have the complete plugin under the MIT @Menrath ?!? --------- Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com>
2024-01-18 15:35:52 +00:00
public function get_manually_approves_followers() {
return false;
}
Add/event objects (#629) * remove redundant property definitions * Add redused context for actors. * Add classes to construct Moblizon compatible events * Bind the context to the activitypub object - change the propertyname which stores the json-ld context from context to _context, because context is already reserved in the ActivityStreams vocabulary. - cleanup currently unused code * fix phpcs * Remove PostalAddress object: it's enough (at least atm) to directly write the array in transformers. * Remove _context property from ActivityPub objects in favour of getter function get_json_ld_context() * fix unit tests: ActivityPub Activity objects have a custom getter for the JsonLD context * fix phpcs * fix unit-tests to also support php5.6 * fix phpcs * add param include_json_ld_context to to_array function This allows to not set the @context in the resulting array. * propagate the param include_json_ld_context to nested calls of to_array. * fix phpcs * Nested AcitivityPub objects: never build context in inner items in to_array function * fix: param of set_address may also be an array * fix typo in comment * always prefix json-ld context with json-ld and move event class to sub-namespace * fix usage of reserved object keyword seems it should not be used as a namespace either * Merge commit 'b2271cda6b857f879e0abd4f3c6683642d725267' into add/event-objects * Fix calling non-static function as static Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com> * Partly fix Json-LD contexts in collections * Update includes/activity/class-base-object.php * this is implicit We already set the correct user with `$transformer->change_wp_user_id( $user_id );` so the Actor will be generated properly. We can change the behaviour, but we should not use both. * this change prevents the Activity to re-use Object vars this should stay as is, because it pre-fills the Activity with data (for example cc and to) and it will no longer be done with your change. It is on purpose that it first sets the object and then replaces it with the URI. See: https://github.com/Automattic/wordpress-activitypub/blob/master/includes/activity/class-activity.php#L195 * add `$include_json_ld_context` support to `to_json` * disable some more contexts * remove whitespace * Add php-comment for 7ed17c042a2651e08afc790adbdfc5ccf46c2708 * Fix JSON-LD context for ActivityPub objects: child classes may override it. * coding standards * call folder/namespace `Extended_Object` to be consistent with folder names in singular * fix: unnessesary nesting of extended-objects * remove license I hope this is fine, to have the complete plugin under the MIT @Menrath ?!? --------- Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com>
2024-01-18 15:35:52 +00:00
public function get_discoverable() {
return true;
}
/**
* Get the User-ID.
*
* @return string The User-ID.
*/
public function get_id() {
return $this->get_url();
}
/**
* Get the type of the object.
*
* If the Blog is in "single user" mode, return "Person" insted of "Group".
*
* @return string The type of the object.
*/
public function get_type() {
if ( is_single_user() ) {
return 'Person';
} else {
return 'Group';
}
}
/**
* Get the User-Name.
*
* @return string The User-Name.
*/
public function get_name() {
return \wp_strip_all_tags(
\html_entity_decode(
\get_bloginfo( 'name' ),
\ENT_QUOTES,
'UTF-8'
)
);
}
/**
* Get the User-Description.
*
* @return string The User-Description.
*/
public function get_summary() {
2023-06-14 13:02:45 +00:00
return \wpautop(
\wp_kses(
\get_bloginfo( 'description' ),
'default'
)
);
}
/**
* Get the User-Url.
*
* @return string The User-Url.
*/
public function get_url() {
return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
}
/**
* Get blog's homepage URL.
*
* @return string The User-Url.
*/
public function get_alternate_url() {
return \esc_url( \trailingslashit( get_home_url() ) );
}
2023-05-30 09:22:20 +00:00
/**
2023-07-11 12:34:11 +00:00
* Generate a default Username.
2023-05-30 09:22:20 +00:00
*
* @return string The auto-generated Username.
*/
public static function get_default_username() {
// check if domain host has a subdomain
$host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST );
$host = \preg_replace( '/^www\./i', '', $host );
2023-05-30 09:22:20 +00:00
2023-07-11 12:34:11 +00:00
/**
* Filter the default blog username.
*
2023-07-14 09:29:03 +00:00
* @param string $host The default username.
2023-07-11 12:34:11 +00:00
*/
2023-07-14 09:29:03 +00:00
return apply_filters( 'activitypub_default_blog_username', $host );
2023-05-30 09:22:20 +00:00
}
2023-07-11 12:34:11 +00:00
/**
* Get the preferred User-Name.
*
* @return string The User-Name.
*/
2023-07-05 13:32:26 +00:00
public function get_preferred_username() {
2023-07-11 07:21:16 +00:00
$username = \get_option( 'activitypub_blog_user_identifier' );
if ( $username ) {
return $username;
}
2023-05-30 09:22:20 +00:00
return self::get_default_username();
}
2023-07-11 12:34:11 +00:00
/**
* Get the User-Icon.
*
* @return array The User-Icon.
2023-07-11 12:34:11 +00:00
*/
2023-07-05 13:32:26 +00:00
public function get_icon() {
// try site icon first
$icon_id = get_option( 'site_icon' );
// try custom logo second
if ( ! $icon_id ) {
$icon_id = get_theme_mod( 'custom_logo' );
}
$icon_url = false;
if ( $icon_id ) {
$icon = wp_get_attachment_image_src( $icon_id, 'full' );
if ( $icon ) {
$icon_url = $icon[0];
}
}
if ( ! $icon_url ) {
// fallback to default icon
$icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE );
2023-07-05 13:32:26 +00:00
}
return array(
'type' => 'Image',
'url' => esc_url( $icon_url ),
);
}
2023-07-11 12:34:11 +00:00
/**
* Get the User-Header-Image.
*
* @return array|null The User-Header-Image.
*/
2024-07-15 21:20:09 +00:00
public function get_image() {
if ( \has_header_image() ) {
2023-07-05 13:32:26 +00:00
return array(
'type' => 'Image',
'url' => 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 );
}
2023-05-24 15:27:46 +00:00
public function get_canonical_url() {
return \home_url();
}
public function get_moderators() {
if ( is_single_user() || 'Group' !== $this->get_type() ) {
return null;
}
return get_rest_url_by_path( 'collections/moderators' );
}
2023-09-27 09:08:55 +00:00
public function get_attributed_to() {
if ( is_single_user() || 'Group' !== $this->get_type() ) {
return null;
}
return get_rest_url_by_path( 'collections/moderators' );
}
public function get_public_key() {
return array(
'id' => $this->get_id() . '#main-key',
'owner' => $this->get_id(),
'publicKeyPem' => Signature::get_public_key_for( $this->get__id() ),
);
}
public function get_posting_restricted_to_mods() {
if ( 'Group' === $this->get_type() ) {
return true;
}
return null;
}
/**
* Returns the Inbox-API-Endpoint.
*
* @return string The Inbox-Endpoint.
*/
public function get_inbox() {
return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) );
}
/**
* Returns the Outbox-API-Endpoint.
*
* @return string The Outbox-Endpoint.
*/
public function get_outbox() {
return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) );
}
/**
* Returns the Followers-API-Endpoint.
*
* @return string The Followers-Endpoint.
*/
public function get_followers() {
return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) );
}
/**
* Returns the Following-API-Endpoint.
*
* @return string The Following-Endpoint.
*/
public function get_following() {
return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) );
}
public function get_endpoints() {
$endpoints = null;
if ( ACTIVITYPUB_SHARED_INBOX_FEATURE ) {
$endpoints = array(
'sharedInbox' => get_rest_url_by_path( 'inbox' ),
);
}
return $endpoints;
}
/**
* Returns a user@domain type of identifier for the user.
*
* @return string The Webfinger-Identifier.
*/
public function get_webfinger() {
return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
}
/**
* Returns the Featured-API-Endpoint.
*
* @return string The Featured-Endpoint.
*/
public function get_featured() {
return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
}
public function get_indexable() {
if ( \get_option( 'blog_public', 1 ) ) {
return true;
} else {
return false;
}
}
/**
* 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;
}
}