diff --git a/readme.md b/readme.md index 28fbb99..2e98d88 100644 --- a/readme.md +++ b/readme.md @@ -151,6 +151,7 @@ Standard features of the following plugins will be manipulated or extended. ### WP REST CACHE * Fade out Icon @ Admin Bar +* ActivityPub Endpoints Caching ### wpRocket @@ -215,6 +216,7 @@ This project is licensed under the GPL3 License. Release pending. +* Added: Caching of ActivityPub Endpoints in WP REST API * Added: Fade out WB REST CACHE Icon @ Admin Bar * Added: Disable UpdraftPlus @ Admin Bar diff --git a/unmus.php b/unmus.php index 2c1cbd4..05a2a4e 100644 --- a/unmus.php +++ b/unmus.php @@ -47,6 +47,7 @@ require_once('unmus_activitypub.php'); require_once('unmus_widgets.php'); require_once('unmus_visibility.php'); +require_once('unmus_cache.php'); // Ensure that all required functions are available during setup require_once( ABSPATH . 'wp-admin/includes/upgrade.php'); diff --git a/unmus_cache.php b/unmus_cache.php new file mode 100644 index 0000000..7013ddf --- /dev/null +++ b/unmus_cache.php @@ -0,0 +1,171 @@ + [ + '', + 'actors', + 'application', + 'collections', + 'comments', + 'inbox', + 'interactions', + 'nodeinfo', + 'posts', + 'users', + 'webfinger' + ]]; + + return $endpoints; +} + +/** + * Add ActivityPub Endpoints to Cache + * + * @since 0.9 + * + * @param array Endpoints that are allowed to be cached + * @return array Allowed Endpoints extended with ActivityPub + */ + +function unmus_cache_add_activitypub_endpoints( $allowed_endpoints ) { + + $activitypub_api_namespace = unmus_cache_get_activitypub_restapi_namespace(); + $endpoints = unmus_cache_get_activitypub_endpoints(); + + if(!isset($allowed_endpoints[$activitypub_api_namespace])) { + $allowed_endpoints[$activitypub_api_namespace] = $endpoints[$activitypub_api_namespace]; + } + + return $allowed_endpoints; + +} +add_filter( 'wp_rest_cache/allowed_endpoints', 'unmus_cache_add_activitypub_endpoints', 10, 1); + +/** + * Is ActivityPub Endpoint + * + * @param string $uri URI to test + * @return bool Whether the current endpoint is an ActivityPub endpoint + */ + +function unmus_is_activitypub_endpoint( string $uri ) :bool { + + $search = '/' . unmus_cache_get_activitypub_restapi_namespace() . '/'; + + return \str_contains( $uri, $search ) || \str_contains( $uri, 'rest_route=' . \rawurlencode( $search ) ); +} + +/** + * Determine Object Type + * + * @since 0.9 + * + * @param string $object_type Object type + * @param string $cache_key Object key + * @param mixed $data Data to cache + * @param string $uri Request URI + * @return string Updated object type + */ + +function unmus_cache_determine_object_type( $object_type, $cache_key, $data, $uri ) { + + if (unmus_is_activitypub_endpoint( $uri ) ) { + $object_type = 'ActivityPub'; + return $object_type; + } +} +add_filter( 'wp_rest_cache/determine_object_type', 'unmus_cache_determine_object_type', 10, 4 ); + +/** + * Reset Cache by Transition Post Status + * + * @since 0.9 + * + * @param string $new_status New post status + * @param string $old_status Old post status + * @param \WP_Post $post Post object + */ + +function unmus_cache_reset_by_transition_post_status( string $new_status, string $old_status, \WP_Post $post ): void { + + if ( $new_status !== 'publish' && $old_status !== 'publish' ) { + return; + } + + $supported_post_types = (array) \get_option( 'activitypub_support_post_types', [] ); + + if ( ! \in_array( $post->post_type, $supported_post_types, true ) ) { + return; + } + + if ( ! \class_exists( 'WP_Rest_Cache_Plugin\Includes\Caching\Caching' ) ) { + return; + } + + Caching::get_instance()->delete_object_type_caches( 'ActivityPub' ); +} +add_action( 'transition_post_status', 'unmus_cache_reset_by_transition_post_status', 10, 3 ); + +/** + * Set whether the cache represents a single item. + * + * Always return false for ActivityPub endpoints, + * since cache entries cannot be flushed otherwise. + * + * @param bool $is_single Whether the current cache represents a single item + * @param mixed $data Data to cache + * @param string $uri Request URI + * @return bool Whether the cache represents a single item + */ + +function set_is_single_item( bool $is_single, mixed $data, string $uri ): bool { + if ( unmus_is_activitypub_endpoint( $uri ) ) { + return false; + } + + return $is_single; +} +add_filter( 'wp_rest_cache/is_single_item', 'set_is_single_item' , 10, 3 ); + +?> \ No newline at end of file