From da63763ddcba83d3df488c62d9693cf4b100e18e Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Tue, 25 Apr 2023 10:54:21 +0200 Subject: [PATCH 1/4] Compat: only disable Jetpack's image CDN via filter This follows the discussion in #307. 1. Do not disable Jetpack's image CDN in ActivityPub requests by default. 2. Add a new filter, activitypub_images_use_jetpack_image_cdn, that site owners can use to disable Jetpack's Image CDN if they'd like to. 3. Extract image getting into its own method for improved readability. --- includes/model/class-post.php | 87 ++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/includes/model/class-post.php b/includes/model/class-post.php index a69e139..254fb8c 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -305,41 +305,16 @@ class Post { // get URLs for each image foreach ( $image_ids as $id ) { - $alt = \get_post_meta( $id, '_wp_attachment_image_alt', true ); - - /** - * If you use the Jetpack plugin and its Image CDN, aka Photon, - * the image strings returned will use the Photon URL. - * We don't want that since Fediverse instances already do caching on their end. - * Let the CDN only be used for visitors of the site. - * - * Old versions of Jetpack used the Jetpack_Photon class to do this. - * New versions use the Image_CDN class. - * Let's handle both. - */ - if ( \class_exists( '\Automattic\Jetpack\Image_CDN\Image_CDN' ) ) { - \remove_filter( 'image_downsize', array( \Automattic\Jetpack\Image_CDN\Image_CDN::instance(), 'filter_image_downsize' ) ); - } elseif ( \class_exists( 'Jetpack_Photon' ) ) { - \remove_filter( 'image_downsize', array( \Jetpack_Photon::instance(), 'filter_image_downsize' ) ); - } - - $thumbnail = \wp_get_attachment_image_src( $id, 'full' ); - - // Re-enable Photon now that the image URL has been built. - if ( \class_exists( '\Automattic\Jetpack\Image_CDN\Image_CDN' ) ) { - \add_filter( 'image_downsize', array( \Automattic\Jetpack\Image_CDN\Image_CDN::instance(), 'filter_image_downsize' ), 10, 3 ); - } elseif ( \class_exists( 'Jetpack_Photon' ) ) { - \add_filter( 'image_downsize', array( \Jetpack_Photon::instance(), 'filter_image_downsize' ), 10, 3 ); - } - - $mimetype = \get_post_mime_type( $id ); - + $thumbnail = $this->get_image( $id ); if ( $thumbnail ) { - $image = array( - 'type' => 'Image', - 'url' => $thumbnail[0], + $mimetype = \get_post_mime_type( $id ); + $alt = \get_post_meta( $id, '_wp_attachment_image_alt', true ); + $image = array( + 'type' => 'Image', + 'url' => $thumbnail[0], 'mediaType' => $mimetype, ); + if ( $alt ) { $image['name'] = $alt; } @@ -352,6 +327,54 @@ class Post { return $images; } + /** + * Return details about an image attachment. + * + * Can return a CDNized URL if Jetpack's image CDN is active. + * This can be disabled with a filter. + * + * @param int $id The attachment ID. + * + * @return array|false Array of image data, or boolean false if no image is available. + */ + public function get_image( $id ) { + /** + * Allow bypassing Jetpack's Image CDN when returning image URLs. + * + * @param bool $should_use_cdn Whether to use the Jetpack Image CDN. True by default. + */ + $should_use_cdn = apply_filters( 'activitypub_images_use_jetpack_image_cdn', true ); + + if ( $should_use_cdn ) { + // Return the full URL, using a CDN URL if Jetpack's image CDN is active. + return \wp_get_attachment_image_src( $id, 'full' ); + } + + /* + * Disable Jetpacks image CDN image processing for this request. + * + * Note: old versions of Jetpack used the Jetpack_Photon class to do this. + * New versions use the Image_CDN class. + * Let's handle both. + */ + if ( \class_exists( '\Automattic\Jetpack\Image_CDN\Image_CDN' ) ) { + \remove_filter( 'image_downsize', array( \Automattic\Jetpack\Image_CDN\Image_CDN::instance(), 'filter_image_downsize' ) ); + } elseif ( \class_exists( 'Jetpack_Photon' ) ) { + \remove_filter( 'image_downsize', array( \Jetpack_Photon::instance(), 'filter_image_downsize' ) ); + } + + $thumbnail = \wp_get_attachment_image_src( $id, 'full' ); + + // Re-enable Photon now that the image URL has been built. + if ( \class_exists( '\Automattic\Jetpack\Image_CDN\Image_CDN' ) ) { + \add_filter( 'image_downsize', array( \Automattic\Jetpack\Image_CDN\Image_CDN::instance(), 'filter_image_downsize' ), 10, 3 ); + } elseif ( \class_exists( 'Jetpack_Photon' ) ) { + \add_filter( 'image_downsize', array( \Jetpack_Photon::instance(), 'filter_image_downsize' ), 10, 3 ); + } + + return $thumbnail; + } + /** * Returns a list of Tags, used in the Post * From 3fa4a7b58ed3520d567d1d868c8e690db73e271a Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Tue, 25 Apr 2023 10:56:17 +0200 Subject: [PATCH 2/4] Add readme entry --- readme.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.txt b/readme.txt index 9c7661d..b73ec40 100644 --- a/readme.txt +++ b/readme.txt @@ -113,6 +113,10 @@ Where 'blog' is the path to the subdirectory at which your blog resides. Project maintained on GitHub at [pfefferle/wordpress-activitypub](https://github.com/pfefferle/wordpress-activitypub). += Next = + +* Compatibility: add filter to allow disabling Jetpack's image CDN when returning images in ActivityPub requests. + = 0.17.0 = * Fix type-selector From e16e119e6c5a909763e2b31b86331d23181911fe Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Wed, 26 Apr 2023 10:45:35 +0200 Subject: [PATCH 3/4] Switch to general actions and filter As a result, we will not modify the images within the ActivityPub plugin, but the hooks will allow third-parties to do it on their end. See discussion: https://github.com/pfefferle/wordpress-activitypub/pull/309#issuecomment-1521488186 --- includes/model/class-post.php | 58 +++++++++++++++++------------------ readme.txt | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/includes/model/class-post.php b/includes/model/class-post.php index 254fb8c..c4632b6 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -305,7 +305,22 @@ class Post { // get URLs for each image foreach ( $image_ids as $id ) { - $thumbnail = $this->get_image( $id ); + $image_size = 'full'; + + /** + * Filter the image URL returned for each post. + * + * @param array|false $thumbnail The image URL, or false if no image is available. + * @param int $id The attachment ID. + * @param string $image_size The image size to retrieve. Set to 'full' by default. + */ + $thumbnail = apply_filters( + 'activitypub_get_image', + $this->get_image( $id, $image_size ), + $id, + $image_size + ); + if ( $thumbnail ) { $mimetype = \get_post_mime_type( $id ); $alt = \get_post_meta( $id, '_wp_attachment_image_alt', true ); @@ -333,44 +348,29 @@ class Post { * Can return a CDNized URL if Jetpack's image CDN is active. * This can be disabled with a filter. * - * @param int $id The attachment ID. + * @param int $id The attachment ID. + * @param string $image_size The image size to retrieve. Set to 'full' by default. * * @return array|false Array of image data, or boolean false if no image is available. */ - public function get_image( $id ) { + public function get_image( $id, $image_size = 'full' ) { /** - * Allow bypassing Jetpack's Image CDN when returning image URLs. + * Hook into the image retrieval process. Before image retrieval. * - * @param bool $should_use_cdn Whether to use the Jetpack Image CDN. True by default. + * @param int $id The attachment ID. + * @param string $image_size The image size to retrieve. Set to 'full' by default. */ - $should_use_cdn = apply_filters( 'activitypub_images_use_jetpack_image_cdn', true ); + do_action( 'activitypub_get_image_pre', $id, $image_size ); - if ( $should_use_cdn ) { - // Return the full URL, using a CDN URL if Jetpack's image CDN is active. - return \wp_get_attachment_image_src( $id, 'full' ); - } + $thumbnail = \wp_get_attachment_image_src( $id, $image_size ); - /* - * Disable Jetpacks image CDN image processing for this request. + /** + * Hook into the image retrieval process. After image retrieval. * - * Note: old versions of Jetpack used the Jetpack_Photon class to do this. - * New versions use the Image_CDN class. - * Let's handle both. + * @param int $id The attachment ID. + * @param string $image_size The image size to retrieve. Set to 'full' by default. */ - if ( \class_exists( '\Automattic\Jetpack\Image_CDN\Image_CDN' ) ) { - \remove_filter( 'image_downsize', array( \Automattic\Jetpack\Image_CDN\Image_CDN::instance(), 'filter_image_downsize' ) ); - } elseif ( \class_exists( 'Jetpack_Photon' ) ) { - \remove_filter( 'image_downsize', array( \Jetpack_Photon::instance(), 'filter_image_downsize' ) ); - } - - $thumbnail = \wp_get_attachment_image_src( $id, 'full' ); - - // Re-enable Photon now that the image URL has been built. - if ( \class_exists( '\Automattic\Jetpack\Image_CDN\Image_CDN' ) ) { - \add_filter( 'image_downsize', array( \Automattic\Jetpack\Image_CDN\Image_CDN::instance(), 'filter_image_downsize' ), 10, 3 ); - } elseif ( \class_exists( 'Jetpack_Photon' ) ) { - \add_filter( 'image_downsize', array( \Jetpack_Photon::instance(), 'filter_image_downsize' ), 10, 3 ); - } + do_action( 'activitypub_get_image_pre', $id, $image_size ); return $thumbnail; } diff --git a/readme.txt b/readme.txt index 569408f..492942a 100644 --- a/readme.txt +++ b/readme.txt @@ -115,7 +115,7 @@ Project maintained on GitHub at [pfefferle/wordpress-activitypub](https://github = Next = -* Compatibility: add filter to allow disabling Jetpack's image CDN when returning images in ActivityPub requests. +* Compatibility: add hooks to allow modifying images returned in ActivityPub requests. * Compatibility: indicate that the plugin is compatible and has been tested with the latest version of WordPress, 6.2. = 0.17.0 = From bd75603fc77ce746ea7670fd7ee564b5d2f0c9b1 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Wed, 26 Apr 2023 10:47:49 +0200 Subject: [PATCH 4/4] Remove comment about Jetpack's Photon --- includes/model/class-post.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/includes/model/class-post.php b/includes/model/class-post.php index c4632b6..4294996 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -345,9 +345,6 @@ class Post { /** * Return details about an image attachment. * - * Can return a CDNized URL if Jetpack's image CDN is active. - * This can be disabled with a filter. - * * @param int $id The attachment ID. * @param string $image_size The image size to retrieve. Set to 'full' by default. *