Follower object should not make any remote calls
This commit is contained in:
parent
b8c86915b5
commit
ec822535c9
5 changed files with 105 additions and 54 deletions
|
@ -10,6 +10,7 @@ use Activitypub\Model\Follower;
|
||||||
|
|
||||||
use function Activitypub\safe_remote_get;
|
use function Activitypub\safe_remote_get;
|
||||||
use function Activitypub\safe_remote_post;
|
use function Activitypub\safe_remote_post;
|
||||||
|
use function Activitypub\get_remote_metadata_by_actor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityPub Followers Collection
|
* ActivityPub Followers Collection
|
||||||
|
@ -193,7 +194,14 @@ class Followers {
|
||||||
* @return array|WP_Error The Follower (WP_Term array) or an WP_Error
|
* @return array|WP_Error The Follower (WP_Term array) or an WP_Error
|
||||||
*/
|
*/
|
||||||
public static function add_follower( $user_id, $actor ) {
|
public static function add_follower( $user_id, $actor ) {
|
||||||
|
$meta = get_remote_metadata_by_actor( $actor );
|
||||||
|
|
||||||
|
if ( ! $meta || is_wp_error( $meta ) || ! is_array( $meta ) ) {
|
||||||
|
return $meta;
|
||||||
|
}
|
||||||
|
|
||||||
$follower = new Follower( $actor );
|
$follower = new Follower( $actor );
|
||||||
|
$follower->from_meta( $meta );
|
||||||
$follower->upsert();
|
$follower->upsert();
|
||||||
|
|
||||||
$result = wp_set_object_terms( $user_id, $follower->get_actor(), self::TAXONOMY, true );
|
$result = wp_set_object_terms( $user_id, $follower->get_actor(), self::TAXONOMY, true );
|
||||||
|
@ -286,8 +294,6 @@ class Followers {
|
||||||
* @return array The Term list of Followers, the format depends on $output
|
* @return array The Term list of Followers, the format depends on $output
|
||||||
*/
|
*/
|
||||||
public static function get_followers( $user_id, $output = ARRAY_N, $number = null, $offset = null ) {
|
public static function get_followers( $user_id, $output = ARRAY_N, $number = null, $offset = null ) {
|
||||||
//self::migrate_followers( $user_id );
|
|
||||||
|
|
||||||
$terms = new WP_Term_Query(
|
$terms = new WP_Term_Query(
|
||||||
array(
|
array(
|
||||||
'taxonomy' => self::TAXONOMY,
|
'taxonomy' => self::TAXONOMY,
|
||||||
|
|
|
@ -102,12 +102,10 @@ function get_webfinger_resource( $user_id ) {
|
||||||
* Requests the Meta-Data from the Actors profile
|
* Requests the Meta-Data from the Actors profile
|
||||||
*
|
*
|
||||||
* @param string $actor The Actor URL
|
* @param string $actor The Actor URL
|
||||||
* @param bool $cache Enable/Disable caching of the meta.
|
|
||||||
* This does not effect Error-Caching.
|
|
||||||
*
|
*
|
||||||
* @return array The Actor profile as array
|
* @return array The Actor profile as array
|
||||||
*/
|
*/
|
||||||
function get_remote_metadata_by_actor( $actor, $cache = false ) {
|
function get_remote_metadata_by_actor( $actor ) {
|
||||||
$pre = apply_filters( 'pre_get_remote_metadata_by_actor', false, $actor );
|
$pre = apply_filters( 'pre_get_remote_metadata_by_actor', false, $actor );
|
||||||
if ( $pre ) {
|
if ( $pre ) {
|
||||||
return $pre;
|
return $pre;
|
||||||
|
@ -161,9 +159,7 @@ function get_remote_metadata_by_actor( $actor, $cache = false ) {
|
||||||
$metadata = \wp_remote_retrieve_body( $response );
|
$metadata = \wp_remote_retrieve_body( $response );
|
||||||
$metadata = \json_decode( $metadata, true );
|
$metadata = \json_decode( $metadata, true );
|
||||||
|
|
||||||
if ( true === $cache ) {
|
|
||||||
\set_transient( $transient_key, $metadata, WEEK_IN_SECONDS );
|
\set_transient( $transient_key, $metadata, WEEK_IN_SECONDS );
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $metadata ) {
|
if ( ! $metadata ) {
|
||||||
$metadata = new \WP_Error( 'activitypub_invalid_json', \__( 'No valid JSON data', 'activitypub' ), $actor );
|
$metadata = new \WP_Error( 'activitypub_invalid_json', \__( 'No valid JSON data', 'activitypub' ), $actor );
|
||||||
|
|
|
@ -3,8 +3,6 @@ namespace Activitypub\Model;
|
||||||
|
|
||||||
use Activitypub\Collection\Followers;
|
use Activitypub\Collection\Followers;
|
||||||
|
|
||||||
use function Activitypub\get_remote_metadata_by_actor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityPub Follower Class
|
* ActivityPub Follower Class
|
||||||
*
|
*
|
||||||
|
@ -111,16 +109,14 @@ class Follower {
|
||||||
* @param WP_Post $post
|
* @param WP_Post $post
|
||||||
*/
|
*/
|
||||||
public function __construct( $actor ) {
|
public function __construct( $actor ) {
|
||||||
$term = get_term_by( 'name', $actor, Followers::TAXONOMY );
|
|
||||||
|
|
||||||
$this->actor = $actor;
|
$this->actor = $actor;
|
||||||
|
|
||||||
|
$term = get_term_by( 'name', $actor, Followers::TAXONOMY );
|
||||||
|
|
||||||
if ( $term ) {
|
if ( $term ) {
|
||||||
$this->id = $term->term_id;
|
$this->id = $term->term_id;
|
||||||
$this->slug = $term->slug;
|
$this->slug = $term->slug;
|
||||||
$this->meta = json_decode( $term->meta );
|
$this->meta = json_decode( $term->meta );
|
||||||
} else {
|
|
||||||
$this->slug = sanitize_title( $actor );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,46 +143,72 @@ class Follower {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function from_meta( $meta ) {
|
||||||
|
$this->meta = $meta;
|
||||||
|
|
||||||
|
foreach ( $this->map_meta as $remote => $internal ) {
|
||||||
|
if ( ! empty( $meta[ $remote ] ) ) {
|
||||||
|
$this->$internal = $meta[ $remote ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $meta['icon']['url'] ) ) {
|
||||||
|
$this->avatar = $meta['icon']['url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $meta['endpoints']['sharedInbox'] ) ) {
|
||||||
|
$this->shared_inbox = $meta['endpoints']['sharedInbox'];
|
||||||
|
} elseif ( ! empty( $meta['inbox'] ) ) {
|
||||||
|
$this->shared_inbox = $meta['inbox'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->updated_at = \strtotime( 'now' );
|
||||||
|
}
|
||||||
|
|
||||||
public function get( $attribute ) {
|
public function get( $attribute ) {
|
||||||
if ( $this->$attribute ) {
|
if ( $this->$attribute ) {
|
||||||
return $this->$attribute;
|
return $this->$attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $this->id ) {
|
$attribute = get_term_meta( $this->id, $attribute, true );
|
||||||
$this->$attribute = $this->get_meta_by( $attribute );
|
if ( $attribute ) {
|
||||||
return $this->$attribute;
|
$this->$attribute = $attribute;
|
||||||
|
return $attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->$attribute = get_term_meta( $this->id, $attribute, true );
|
$attribute = $this->get_meta_by( $attribute );
|
||||||
return $this->$attribute;
|
if ( $attribute ) {
|
||||||
|
$this->$attribute = $attribute;
|
||||||
|
return $attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_meta_by( $attribute, $force = false ) {
|
return null;
|
||||||
$meta = $this->get_meta( $force );
|
}
|
||||||
|
|
||||||
|
public function get_meta_by( $attribute ) {
|
||||||
|
$meta = $this->get_meta();
|
||||||
|
|
||||||
|
// try mapped data ($this->map_meta)
|
||||||
foreach ( $this->map_meta as $remote => $local ) {
|
foreach ( $this->map_meta as $remote => $local ) {
|
||||||
if ( $attribute === $local && isset( $meta[ $remote ] ) ) {
|
if ( $attribute === $local && isset( $meta[ $remote ] ) ) {
|
||||||
return $meta[ $remote ];
|
return $meta[ $remote ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try ActivityPub attribtes
|
||||||
|
if ( ! empty( $this->map_meta[ $attribute ] ) ) {
|
||||||
|
return $this->map_meta[ $attribute ];
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_meta( $force = false ) {
|
public function get_meta() {
|
||||||
if ( $this->meta && false === (bool) $force ) {
|
if ( $this->meta ) {
|
||||||
return $this->meta;
|
return $this->meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
$remote_data = get_remote_metadata_by_actor( $this->actor );
|
return null;
|
||||||
|
|
||||||
if ( ! $remote_data || is_wp_error( $remote_data ) || ! is_array( $remote_data ) ) {
|
|
||||||
$remote_data = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->meta = $remote_data;
|
|
||||||
|
|
||||||
return $this->meta;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update() {
|
public function update() {
|
||||||
|
@ -225,28 +247,12 @@ class Follower {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function update_term_meta() {
|
protected function update_term_meta() {
|
||||||
$meta = $this->get_meta();
|
$attributes = array( 'inbox', 'shared_inbox', 'avatar', 'updated_at', 'name', 'username' );
|
||||||
|
|
||||||
foreach ( $this->map_meta as $remote => $internal ) {
|
foreach ( $attributes as $attribute ) {
|
||||||
if ( ! empty( $meta[ $remote ] ) ) {
|
if ( $this->get( $attribute ) ) {
|
||||||
update_term_meta( $this->id, $internal, $meta[ $remote ], true );
|
update_term_meta( $this->id, $attribute, $this->get( $attribute ), true );
|
||||||
$this->$internal = $meta[ $remote ];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $meta['icon']['url'] ) ) {
|
|
||||||
update_term_meta( $this->id, 'avatar', $meta['icon']['url'], true );
|
|
||||||
$this->avatar = $meta['icon']['url'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! empty( $meta['endpoints']['sharedInbox'] ) ) {
|
|
||||||
update_term_meta( $this->id, 'shared_inbox', $meta['endpoints']['sharedInbox'], true );
|
|
||||||
$this->shared_inbox = $meta['endpoints']['sharedInbox'];
|
|
||||||
} elseif ( ! empty( $meta['inbox'] ) ) {
|
|
||||||
update_term_meta( $this->id, 'shared_inbox', $meta['inbox'], true );
|
|
||||||
$this->shared_inbox = $meta['inbox'];
|
|
||||||
}
|
|
||||||
|
|
||||||
update_term_meta( $this->id, 'updated_at', \strtotime( 'now' ), true );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,14 @@ class Followers extends WP_List_Table {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function column_identifier( $item ) {
|
||||||
|
return sprintf(
|
||||||
|
'<a href="%s" target="_blank">%s</a>',
|
||||||
|
$item['identifier'],
|
||||||
|
$item['identifier']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function column_cb( $item ) {
|
public function column_cb( $item ) {
|
||||||
return sprintf( '<input type="checkbox" name="followers[]" value="%s" />', esc_attr( $item['identifier'] ) );
|
return sprintf( '<input type="checkbox" name="followers[]" value="%s" />', esc_attr( $item['identifier'] ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,37 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
|
||||||
'name' => 'jon',
|
'name' => 'jon',
|
||||||
'prefferedUsername' => 'jon',
|
'prefferedUsername' => 'jon',
|
||||||
),
|
),
|
||||||
|
'doe@example.org' => array(
|
||||||
|
'url' => 'https://example.org/author/doe',
|
||||||
|
'inbox' => 'https://example.org/author/doe/inbox',
|
||||||
|
'name' => 'doe',
|
||||||
|
'prefferedUsername' => 'doe',
|
||||||
|
),
|
||||||
'sally@example.org' => array(
|
'sally@example.org' => array(
|
||||||
'url' => 'http://sally.example.org',
|
'url' => 'http://sally.example.org',
|
||||||
'inbox' => 'http://sally.example.org/inbox',
|
'inbox' => 'http://sally.example.org/inbox',
|
||||||
'name' => 'jon',
|
'name' => 'jon',
|
||||||
'prefferedUsername' => 'jon',
|
'prefferedUsername' => 'jon',
|
||||||
),
|
),
|
||||||
|
'12345@example.com' => array(
|
||||||
|
'url' => 'https://12345.example.com',
|
||||||
|
'inbox' => 'https://12345.example.com/inbox',
|
||||||
|
'name' => '12345',
|
||||||
|
'prefferedUsername' => '12345',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public function set_up() {
|
||||||
|
parent::set_up();
|
||||||
|
add_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ), 10, 2 );
|
||||||
|
_delete_all_posts();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tear_down() {
|
||||||
|
remove_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ) );
|
||||||
|
parent::tear_down();
|
||||||
|
}
|
||||||
|
|
||||||
public function test_get_followers() {
|
public function test_get_followers() {
|
||||||
$followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' );
|
$followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' );
|
||||||
|
|
||||||
|
@ -28,7 +51,7 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
|
||||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||||
|
|
||||||
foreach ( $followers as $follower ) {
|
foreach ( $followers as $follower ) {
|
||||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
$response = \Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||||
}
|
}
|
||||||
|
|
||||||
$db_followers = \Activitypub\Collection\Followers::get_followers( 1 );
|
$db_followers = \Activitypub\Collection\Followers::get_followers( 1 );
|
||||||
|
@ -42,7 +65,7 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
|
||||||
$pre_http_request = new MockAction();
|
$pre_http_request = new MockAction();
|
||||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||||
|
|
||||||
$follower = 'https://example.com/author/' . \time();
|
$follower = 'https://12345.example.com';
|
||||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||||
|
|
||||||
$db_followers = \Activitypub\Collection\Followers::get_followers( 1 );
|
$db_followers = \Activitypub\Collection\Followers::get_followers( 1 );
|
||||||
|
@ -95,4 +118,16 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
|
||||||
public static function http_response( $response, $args, $url ) {
|
public static function http_response( $response, $args, $url ) {
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function pre_get_remote_metadata_by_actor( $pre, $actor ) {
|
||||||
|
if ( isset( self::$users[ $actor ] ) ) {
|
||||||
|
return self::$users[ $actor ];
|
||||||
|
}
|
||||||
|
foreach ( self::$users as $username => $data ) {
|
||||||
|
if ( $data['url'] === $actor ) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $pre;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue