Skip to content

Commit 07a7e08

Browse files
authored
Account for pre-existing image when adding alt text (#1132)
1 parent 47bc1df commit 07a7e08

File tree

4 files changed

+157
-43
lines changed

4 files changed

+157
-43
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
### Fixed
1919

2020
* Undefined array key warnings in various places
21+
* Image captions not being included in the ActivityPub representation when the image is attached to the post
2122

2223
## [4.6.0] - 2024-12-20
2324

includes/transformer/class-post.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,10 +454,21 @@ protected function get_media_from_blocks( $blocks, $media ) {
454454
$alt = $match[2];
455455
}
456456

457-
$media['image'][] = array(
458-
'id' => $block['attrs']['id'],
459-
'alt' => $alt,
460-
);
457+
$found = false;
458+
foreach ( $media['image'] as $i => $image ) {
459+
if ( $image['id'] === $block['attrs']['id'] ) {
460+
$media['image'][ $i ]['alt'] = $alt;
461+
$found = true;
462+
break;
463+
}
464+
}
465+
466+
if ( ! $found ) {
467+
$media['image'][] = array(
468+
'id' => $block['attrs']['id'],
469+
'alt' => $alt,
470+
);
471+
}
461472
}
462473
break;
463474
case 'core/audio':

readme.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ For reasons of data protection, it is not possible to see the followers of other
137137
* Added: A filter to make custom comment types manageable in WP.com Calypso
138138
* Changed: Hide ActivityPub post meta keys from the custom Fields UI
139139
* Fixed: Undefined array key warnings in various places
140+
* Fixed: Image captions not being included in the ActivityPub representation when the image is attached to the post
140141

141142
= 4.6.0 =
142143

tests/includes/transformer/class-test-post.php

Lines changed: 140 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -387,56 +387,105 @@ public function test_block_attachments_with_fallback() {
387387
}
388388

389389
/**
390-
* Saves an attachment.
391-
*
392-
* @param string $file The file name to create attachment object for.
393-
* @param int $parent_id ID of the post to attach the file to.
390+
* Test get_media_from_blocks adds alt text to existing images.
394391
*
395-
* @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
392+
* @covers ::get_media_from_blocks
396393
*/
397-
public function create_upload_object( $file, $parent_id = 0 ) {
398-
if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
399-
require ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
400-
require ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
401-
}
394+
public function test_get_media_from_blocks_adds_alt_text_to_existing_images() {
395+
$post_id = self::factory()->post->create(
396+
array(
397+
'post_content' => '<!-- wp:image {"id":123} --><figure class="wp-block-image"><img src="test.jpg" alt="Test alt text" /></figure><!-- /wp:image -->',
398+
)
399+
);
400+
$post = get_post( $post_id );
402401

403-
$dest = dirname( $file ) . DIRECTORY_SEPARATOR . 'test-temp.jpg';
404-
$fs = new \WP_Filesystem_Direct( array() );
405-
$fs->copy( $file, $dest );
402+
$transformer = new Post( $post );
403+
$media = array(
404+
'image' => array(
405+
array(
406+
'id' => 123,
407+
'alt' => '',
408+
),
409+
),
410+
'audio' => array(),
411+
'video' => array(),
412+
);
406413

407-
$file = $dest;
414+
$reflection = new \ReflectionClass( Post::class );
415+
$method = $reflection->getMethod( 'get_media_from_blocks' );
416+
$method->setAccessible( true );
408417

409-
$file_array = array(
410-
'name' => wp_basename( $file ),
411-
'tmp_name' => $file,
418+
$blocks = parse_blocks( $post->post_content );
419+
$result = $method->invoke( $transformer, $blocks, $media );
420+
421+
$this->assertSame( 'Test alt text', $result['image'][0]['alt'] );
422+
$this->assertSame( 123, $result['image'][0]['id'] );
423+
}
424+
425+
/**
426+
* Test get_media_from_blocks adds new image when none exist.
427+
*
428+
* @covers ::get_media_from_blocks
429+
*/
430+
public function test_get_media_from_blocks_adds_new_image() {
431+
$post_id = self::factory()->post->create(
432+
array(
433+
'post_content' => '<!-- wp:image {"id":123} --><figure class="wp-block-image"><img src="test.jpg" alt="Test alt text" /></figure><!-- /wp:image -->',
434+
)
412435
);
436+
$post = get_post( $post_id );
413437

414-
$upload = wp_handle_sideload( $file_array, array( 'test_form' => false ) );
438+
$transformer = new Post( $post );
439+
$media = array(
440+
'image' => array(),
441+
'audio' => array(),
442+
'video' => array(),
443+
);
415444

416-
$type = '';
417-
if ( ! empty( $upload['type'] ) ) {
418-
$type = $upload['type'];
419-
} else {
420-
$mime = wp_check_filetype( $upload['file'] );
421-
if ( $mime ) {
422-
$type = $mime['type'];
423-
}
424-
}
445+
$reflection = new \ReflectionClass( Post::class );
446+
$method = $reflection->getMethod( 'get_media_from_blocks' );
447+
$method->setAccessible( true );
425448

426-
$attachment = array(
427-
'post_title' => wp_basename( $upload['file'] ),
428-
'post_content' => '',
429-
'post_type' => 'attachment',
430-
'post_parent' => $parent_id,
431-
'post_mime_type' => $type,
432-
'guid' => $upload['url'],
449+
$blocks = parse_blocks( $post->post_content );
450+
$result = $method->invoke( $transformer, $blocks, $media );
451+
452+
$this->assertCount( 1, $result['image'] );
453+
$this->assertSame( 123, $result['image'][0]['id'] );
454+
$this->assertSame( 'Test alt text', $result['image'][0]['alt'] );
455+
}
456+
457+
/**
458+
* Test get_media_from_blocks handles multiple blocks correctly.
459+
*
460+
* @covers ::get_media_from_blocks
461+
*/
462+
public function test_get_media_from_blocks_handles_multiple_blocks() {
463+
$post_id = self::factory()->post->create(
464+
array(
465+
'post_content' => '<!-- wp:image {"id":123} --><figure class="wp-block-image"><img src="test1.jpg" alt="Test alt 1" /></figure><!-- /wp:image --><!-- wp:image {"id":456} --><figure class="wp-block-image"><img src="test2.jpg" alt="Test alt 2" /></figure><!-- /wp:image -->',
466+
)
433467
);
468+
$post = get_post( $post_id );
434469

435-
// Save the data.
436-
$id = wp_insert_attachment( $attachment, $upload['file'], $parent_id );
437-
wp_update_attachment_metadata( $id, @wp_generate_attachment_metadata( $id, $upload['file'] ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
470+
$transformer = new Post( $post );
471+
$media = array(
472+
'image' => array(),
473+
'audio' => array(),
474+
'video' => array(),
475+
);
438476

439-
return $id;
477+
$reflection = new \ReflectionClass( Post::class );
478+
$method = $reflection->getMethod( 'get_media_from_blocks' );
479+
$method->setAccessible( true );
480+
481+
$blocks = parse_blocks( $post->post_content );
482+
$result = $method->invoke( $transformer, $blocks, $media );
483+
484+
$this->assertCount( 2, $result['image'] );
485+
$this->assertSame( 123, $result['image'][0]['id'] );
486+
$this->assertSame( 'Test alt 1', $result['image'][0]['alt'] );
487+
$this->assertSame( 456, $result['image'][1]['id'] );
488+
$this->assertSame( 'Test alt 2', $result['image'][1]['alt'] );
440489
}
441490

442491
/**
@@ -457,7 +506,7 @@ public function test_get_icon() {
457506
$attachment_id = $this->create_upload_object( dirname( __DIR__, 2 ) . '/assets/test.jpg' );
458507

459508
// Set up reflection method.
460-
$reflection = new ReflectionClass( Post::class );
509+
$reflection = new \ReflectionClass( Post::class );
461510
$method = $reflection->getMethod( 'get_icon' );
462511
$method->setAccessible( true );
463512

@@ -513,4 +562,56 @@ public function test_get_icon() {
513562
wp_delete_post( $post_id, true );
514563
wp_delete_attachment( $attachment_id, true );
515564
}
565+
566+
/**
567+
* Saves an attachment.
568+
*
569+
* @param string $file The file name to create attachment object for.
570+
* @param int $parent_id ID of the post to attach the file to.
571+
* @return int|\WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
572+
*/
573+
public function create_upload_object( $file, $parent_id = 0 ) {
574+
if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
575+
require ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
576+
require ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
577+
}
578+
579+
$dest = dirname( $file ) . DIRECTORY_SEPARATOR . 'test-temp.jpg';
580+
$fs = new \WP_Filesystem_Direct( array() );
581+
$fs->copy( $file, $dest );
582+
583+
$file = $dest;
584+
585+
$file_array = array(
586+
'name' => wp_basename( $file ),
587+
'tmp_name' => $file,
588+
);
589+
590+
$upload = wp_handle_sideload( $file_array, array( 'test_form' => false ) );
591+
592+
$type = '';
593+
if ( ! empty( $upload['type'] ) ) {
594+
$type = $upload['type'];
595+
} else {
596+
$mime = wp_check_filetype( $upload['file'] );
597+
if ( $mime ) {
598+
$type = $mime['type'];
599+
}
600+
}
601+
602+
$attachment = array(
603+
'post_title' => wp_basename( $upload['file'] ),
604+
'post_content' => '',
605+
'post_type' => 'attachment',
606+
'post_parent' => $parent_id,
607+
'post_mime_type' => $type,
608+
'guid' => $upload['url'],
609+
);
610+
611+
// Save the data.
612+
$id = wp_insert_attachment( $attachment, $upload['file'], $parent_id );
613+
wp_update_attachment_metadata( $id, @wp_generate_attachment_metadata( $id, $upload['file'] ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
614+
615+
return $id;
616+
}
516617
}

0 commit comments

Comments
 (0)