_id ); } /** * Clear the errors for the current Follower. * * @return bool True on success, false on failure. */ public function clear_errors() { return Remote_Actors::clear_errors( $this->_id ); } /** * Get the Summary. * * @return string The Summary. */ public function get_summary() { if ( isset( $this->summary ) ) { return $this->summary; } return ''; } /** * Getter for URL attribute. * * Falls back to ID, if no URL is set. This is relevant for * Platforms like Lemmy, where the ID is the URL. * * @return string The URL. */ public function get_url() { if ( $this->url ) { return $this->url; } return $this->id; } /** * Reset (delete) all errors. * * @return bool True on success, false on failure. */ public function reset_errors() { return Remote_Actors::clear_errors( $this->_id ); } /** * Count the errors. * * @return int The number of errors. */ public function count_errors() { return Remote_Actors::count_errors( $this->_id ); } /** * Return the latest error message. * * @return string The error message. */ public function get_latest_error_message() { $errors = $this->get_errors(); if ( \is_array( $errors ) && ! empty( $errors ) ) { return \reset( $errors ); } return ''; } /** * Update the current Follower object. */ public function update() { $this->save(); } /** * Validate the current Follower object. * * @return boolean True if the verification was successful. */ public function is_valid() { // The minimum required attributes. $required_attributes = array( 'id', 'preferredUsername', 'inbox', 'publicKey', 'publicKeyPem', ); foreach ( $required_attributes as $attribute ) { if ( ! $this->get( $attribute ) ) { return false; } } return true; } /** * Save the current Follower object. * * @return int|\WP_Error The post ID or an WP_Error. */ public function save() { if ( ! $this->is_valid() ) { return new \WP_Error( 'activitypub_invalid_follower', __( 'Invalid Follower', 'activitypub' ), array( 'status' => 400 ) ); } $id = Remote_Actors::upsert( $this ); if ( \is_wp_error( $id ) ) { return $id; } $this->set__id( $id ); return $id; } /** * Upsert the current Follower object. * * @return int|\WP_Error The post ID or an WP_Error. */ public function upsert() { return $this->save(); } /** * 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() */ public function delete() { Followers::remove_follower( $this->_id, $this->get_id() ); } /** * Get the icon. * * Sets a fallback to better handle API and HTML outputs. * * @return string[] The icon. */ public function get_icon() { if ( isset( $this->icon['url'] ) ) { return $this->icon; } return array( 'type' => 'Image', 'mediaType' => 'image/jpeg', 'url' => ACTIVITYPUB_PLUGIN_URL . 'assets/img/mp.jpg', ); } /** * Get Name. * * Tries to extract a name from the URL or ID if not set. * * @return string The name. */ public function get_name() { if ( $this->name ) { return $this->name; } elseif ( $this->preferred_username ) { return $this->preferred_username; } return $this->extract_name_from_uri(); } /** * The preferred Username. * * Tries to extract a name from the URL or ID if not set. * * @return string The preferred Username. */ public function get_preferred_username() { if ( $this->preferred_username ) { return $this->preferred_username; } return $this->extract_name_from_uri(); } /** * Get the Icon URL (Avatar). * * @return string The URL to the Avatar. */ public function get_icon_url() { $icon = $this->get_icon(); if ( ! $icon ) { return ''; } if ( \is_array( $icon ) ) { return $icon['url']; } return $icon; } /** * Get the Icon URL (Avatar). * * @return string The URL to the Avatar. */ public function get_image_url() { $image = $this->get_image(); if ( ! $image ) { return ''; } if ( \is_array( $image ) ) { return $image['url']; } return $image; } /** * Get the shared inbox, with a fallback to the inbox. * * @return string|null The URL to the shared inbox, the inbox or null. */ public function get_shared_inbox() { if ( ! empty( $this->get_endpoints()['sharedInbox'] ) ) { return $this->get_endpoints()['sharedInbox']; } elseif ( ! empty( $this->get_inbox() ) ) { return $this->get_inbox(); } return null; } /** * Convert a Custom-Post-Type input to an Activitypub\Model\Follower. * * @param \WP_Post $post The post object. * @return Follower|false The Follower object or false on failure. */ public static function init_from_cpt( $post ) { if ( empty( $post->post_content ) ) { $json = \get_post_meta( $post->ID, '_activitypub_actor_json', true ); } else { $json = $post->post_content; } /* @var Follower $object Follower object. */ $object = self::init_from_json( $json ); if ( \is_wp_error( $object ) ) { return false; } $object->set__id( $post->ID ); $object->set_id( $post->guid ); $object->set_name( $post->post_title ); $object->set_summary( $post->post_excerpt ); $object->set_published( gmdate( 'Y-m-d H:i:s', strtotime( $post->post_date ) ) ); $object->set_updated( gmdate( 'Y-m-d H:i:s', strtotime( $post->post_modified ) ) ); return $object; } /** * Infer a shortname from the Actor ID or URL. Used only for fallbacks, * we will try to use what's supplied. * * @return string Hopefully the name of the Follower. */ protected function extract_name_from_uri() { // prefer the URL, but fall back to the ID. if ( $this->url ) { $uri = $this->url; } else { $uri = $this->id; } return extract_name_from_uri( $uri ); } }