Skip to content

Commit 6ec77cc

Browse files
pfefferleakirk
andauthored
Improve Image-Handling (#999)
* Improve Image-Handling Allow filtering the image-srcs and upload-baseurl, if upload url might differ or if a CDN is used. * try to fix `exif_read_data(test.jpg): Illegal IFD size` error * silence errors * escape global functions * Update tests/class-test-activitypub-post.php Co-authored-by: Alex Kirk <[email protected]> * Update includes/transformer/class-post.php Co-authored-by: Alex Kirk <[email protected]> * use `wp_get_upload_dir` --------- Co-authored-by: Alex Kirk <[email protected]>
1 parent 7181289 commit 6ec77cc

File tree

4 files changed

+138
-4
lines changed

4 files changed

+138
-4
lines changed

includes/functions.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,3 +1471,19 @@ function get_attribution_domains() {
14711471

14721472
return $domains;
14731473
}
1474+
1475+
/**
1476+
* Get the base URL for uploads.
1477+
*
1478+
* @return string The upload base URL.
1479+
*/
1480+
function get_upload_baseurl() {
1481+
$upload_dir = \wp_get_upload_dir();
1482+
1483+
/**
1484+
* Filters the upload base URL.
1485+
*
1486+
* @param string \wp_get_upload_dir()['baseurl'] The upload base URL.
1487+
*/
1488+
return apply_filters( 'activitypub_get_upload_baseurl', $upload_dir['baseurl'] );
1489+
}

includes/transformer/class-post.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use function Activitypub\esc_hashtag;
1616
use function Activitypub\is_single_user;
1717
use function Activitypub\get_enclosures;
18+
use function Activitypub\get_upload_baseurl;
1819
use function Activitypub\get_content_warning;
1920
use function Activitypub\site_supports_blocks;
2021
use function Activitypub\generate_post_summary;
@@ -477,14 +478,22 @@ protected function get_classic_editor_image_embeds( $max_images ) {
477478
}
478479

479480
$images = array();
480-
$base = \wp_get_upload_dir()['baseurl'];
481+
$base = get_upload_baseurl();
481482
$content = \get_post_field( 'post_content', $this->wp_object );
482483
$tags = new \WP_HTML_Tag_Processor( $content );
483484

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

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

511+
if ( 0 === $img_id ) {
512+
$count = 0;
513+
$src = \strtok( $src, '?' );
514+
$img_id = \attachment_url_to_postid( $src );
515+
}
516+
502517
if ( 0 === $img_id ) {
503518
$count = 0;
504-
$src = preg_replace( '/-(?:\d+x\d+)(\.[a-zA-Z]+)$/', '$1', $src, 1, $count );
519+
$src = \preg_replace( '/-(?:\d+x\d+)(\.[a-zA-Z]+)$/', '$1', $src, 1, $count );
505520
if ( $count > 0 ) {
506521
$img_id = \attachment_url_to_postid( $src );
507522
}
508523
}
509524

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

tests/assets/test.jpg

3.49 KB
Loading

tests/class-test-activitypub-post.php

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,107 @@ public function test_content_visibility() {
7474
$this->assertEquals( array(), $object->get_to() );
7575
$this->assertEquals( array(), $object->get_cc() );
7676
}
77+
78+
/**
79+
* Test different variations of Attachment parsing.
80+
*/
81+
public function test_block_attachments_with_fallback() {
82+
$attachment_id = $this->create_upload_object( __DIR__ . '/assets/test.jpg' );
83+
$attachment_src = \wp_get_attachment_image_src( $attachment_id );
84+
85+
$post_id = \wp_insert_post(
86+
array(
87+
'post_author' => 1,
88+
'post_content' => sprintf(
89+
'<!-- 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 -->',
90+
$attachment_id,
91+
$attachment_src[0]
92+
),
93+
'post_status' => 'publish',
94+
)
95+
);
96+
97+
$object = \Activitypub\Transformer\Post::transform( get_post( $post_id ) )->to_object();
98+
99+
$this->assertEquals(
100+
array(
101+
array(
102+
'type' => 'Image',
103+
'url' => $attachment_src[0],
104+
'mediaType' => 'image/jpeg',
105+
),
106+
),
107+
$object->get_attachment()
108+
);
109+
110+
$post_id = \wp_insert_post(
111+
array(
112+
'post_author' => 1,
113+
'post_content' => sprintf(
114+
'<p>this is a photo</p><p><img src="%2$s" alt="" class="wp-image-%1$d"/></p>',
115+
$attachment_id,
116+
$attachment_src[0]
117+
),
118+
'post_status' => 'publish',
119+
)
120+
);
121+
122+
$object = \Activitypub\Transformer\Post::transform( get_post( $post_id ) )->to_object();
123+
124+
$this->assertEquals(
125+
array(
126+
array(
127+
'type' => 'Image',
128+
'url' => $attachment_src[0],
129+
'mediaType' => 'image/jpeg',
130+
),
131+
),
132+
$object->get_attachment()
133+
);
134+
135+
\wp_delete_attachment( $attachment_id, true );
136+
}
137+
138+
/**
139+
* Saves an attachment.
140+
*
141+
* @param string $file The file name to create attachment object for.
142+
* @param int $parent_id ID of the post to attach the file to.
143+
*
144+
* @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
145+
*/
146+
public function create_upload_object( $file, $parent_id = 0 ) {
147+
$file_array = array(
148+
'name' => wp_basename( $file ),
149+
'tmp_name' => $file,
150+
);
151+
152+
$upload = wp_handle_sideload( $file_array, array( 'test_form' => false ) );
153+
154+
$type = '';
155+
if ( ! empty( $upload['type'] ) ) {
156+
$type = $upload['type'];
157+
} else {
158+
$mime = wp_check_filetype( $upload['file'] );
159+
if ( $mime ) {
160+
$type = $mime['type'];
161+
}
162+
}
163+
164+
$attachment = array(
165+
'post_title' => wp_basename( $upload['file'] ),
166+
'post_content' => '',
167+
'post_type' => 'attachment',
168+
'post_parent' => $parent_id,
169+
'post_mime_type' => $type,
170+
'guid' => $upload['url'],
171+
);
172+
173+
// Save the data.
174+
$id = wp_insert_attachment( $attachment, $upload['file'], $parent_id );
175+
// phpcs:ignore
176+
@wp_update_attachment_metadata( $id, @wp_generate_attachment_metadata( $id, $upload['file'] ) );
177+
178+
return $id;
179+
}
77180
}

0 commit comments

Comments
 (0)