Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Image-Handling #999

Merged
merged 9 commits into from
Nov 19, 2024
Merged
16 changes: 16 additions & 0 deletions includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1471,3 +1471,19 @@ function get_attribution_domains() {

return $domains;
}

/**
* Get the base URL for uploads.
*
* @return string The upload base URL.
*/
function get_upload_baseurl() {
$upload_dir = \wp_upload_dir();
pfefferle marked this conversation as resolved.
Show resolved Hide resolved

/**
* Filters the upload base URL.
*
* @param string \wp_upload_dir()['baseurl'] The upload base URL.
*/
return apply_filters( 'activitypub_get_upload_baseurl', $upload_dir['baseurl'] );
}
23 changes: 19 additions & 4 deletions includes/transformer/class-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use function Activitypub\esc_hashtag;
use function Activitypub\is_single_user;
use function Activitypub\get_enclosures;
use function Activitypub\get_upload_baseurl;
use function Activitypub\get_content_warning;
use function Activitypub\site_supports_blocks;
use function Activitypub\generate_post_summary;
Expand Down Expand Up @@ -477,14 +478,22 @@ protected function get_classic_editor_image_embeds( $max_images ) {
}

$images = array();
$base = \wp_get_upload_dir()['baseurl'];
$base = get_upload_baseurl();
$content = \get_post_field( 'post_content', $this->wp_object );
$tags = new \WP_HTML_Tag_Processor( $content );

// This linter warning is a false positive - we have to re-count each time here as we modify $images.
// phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
while ( $tags->next_tag( 'img' ) && ( \count( $images ) <= $max_images ) ) {
$src = $tags->get_attribute( 'src' );
/**
* Filter the image source URL.
*
* This can be used to modify the image source URL before it is used to
* determine the attachment ID.
*
* @param string $src The image source URL.
*/
$src = \apply_filters( 'activitypub_image_src', $tags->get_attribute( 'src' ) );

/*
* If the img source is in our uploads dir, get the
Expand All @@ -499,16 +508,22 @@ protected function get_classic_editor_image_embeds( $max_images ) {
if ( null !== $src && \str_starts_with( $src, $base ) ) {
$img_id = \attachment_url_to_postid( $src );

if ( 0 === $img_id ) {
$count = 0;
$src = \current( \explode( '?', $src ) );
pfefferle marked this conversation as resolved.
Show resolved Hide resolved
$img_id = \attachment_url_to_postid( $src );
}

if ( 0 === $img_id ) {
$count = 0;
$src = preg_replace( '/-(?:\d+x\d+)(\.[a-zA-Z]+)$/', '$1', $src, 1, $count );
$src = \preg_replace( '/-(?:\d+x\d+)(\.[a-zA-Z]+)$/', '$1', $src, 1, $count );
if ( $count > 0 ) {
$img_id = \attachment_url_to_postid( $src );
}
}

if ( 0 === $img_id ) {
$src = preg_replace( '/(\.[a-zA-Z]+)$/', '-scaled$1', $src );
$src = \preg_replace( '/(\.[a-zA-Z]+)$/', '-scaled$1', $src );
$img_id = \attachment_url_to_postid( $src );
}

Expand Down
Binary file added tests/assets/test.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 99 additions & 0 deletions tests/class-test-activitypub-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,103 @@ public function test_content_visibility() {
$this->assertEquals( array(), $object->get_to() );
$this->assertEquals( array(), $object->get_cc() );
}

/**
* Test different variations of Attachment parsing.
*/
public function test_block_attachments_with_fallback() {
$attachment_id = $this->create_upload_object( __DIR__ . '/assets/test.jpg' );
$attachment_src = \wp_get_attachment_image_src( $attachment_id );

$post_id = \wp_insert_post(
array(
'post_author' => 1,
'post_content' => sprintf(
'<!-- wp:image {"id": %1$d,"sizeSlug":"large"} --><figure class="wp-block-image"><img src="%2$s" alt="" class="wp-image-%1$d"/></figure><!-- /wp:image -->',
$attachment_id,
$attachment_src[0]
),
'post_status' => 'publish',
)
);

$object = \Activitypub\Transformer\Post::transform( get_post( $post_id ) )->to_object();

$this->assertEquals(
array(
array(
'type' => 'Image',
'url' => $attachment_src[0],
'mediaType' => 'image/jpeg',
),
),
$object->get_attachment()
);

$post_id = \wp_insert_post(
array(
'post_author' => 1,
'post_content' => sprintf(
'<p>this is a photo</p><p><img src="%2$s" alt="" class="wp-image-%1$d"/></p>',
$attachment_id,
$attachment_src[0]
),
'post_status' => 'publish',
)
);

$object = \Activitypub\Transformer\Post::transform( get_post( $post_id ) )->to_object();

$this->assertEquals(
array(
array(
'type' => 'Image',
'url' => $attachment_src[0],
'mediaType' => 'image/jpeg',
),
),
$object->get_attachment()
);

\wp_delete_attachment( $attachment_id, true );
}

/**
* Saves an attachment.
*
* @param string $file The file name to create attachment object for.
* @param int $parent_id ID of the post to attach the file to.
*
* @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
*/
public function create_upload_object( $file, $parent_id = 0 ) {
$contents = file_get_contents( $file ); // phpcs:ignore
$upload = wp_upload_bits( wp_basename( $file ), null, $contents );
pfefferle marked this conversation as resolved.
Show resolved Hide resolved

$type = '';
if ( ! empty( $upload['type'] ) ) {
$type = $upload['type'];
} else {
$mime = wp_check_filetype( $upload['file'] );
if ( $mime ) {
$type = $mime['type'];
}
}

$attachment = array(
'post_title' => wp_basename( $upload['file'] ),
'post_content' => '',
'post_type' => 'attachment',
'post_parent' => $parent_id,
'post_mime_type' => $type,
'guid' => $upload['url'],
);

// Save the data.
$id = wp_insert_attachment( $attachment, $upload['file'], $parent_id );
// phpcs:ignore
@wp_update_attachment_metadata( $id, @wp_generate_attachment_metadata( $id, $upload['file'] ) );

return $id;
}
}
Loading