diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0579de6af..1f8c3318a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,9 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added a filter to make custom comment types manageable in WP.com Calypso
+### Changed
+
+* Hide ActivityPub post meta keys from the custom Fields UI
+
### Fixed
* Undefined array key warnings in various places
+* Image captions not being included in the ActivityPub representation when the image is attached to the post
### Changed
* Print `_activityPubOptions` in the `wp_footer` action on the frontend.
diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php
index bdd6641d0..bf94e303c 100644
--- a/includes/class-activitypub.php
+++ b/includes/class-activitypub.php
@@ -339,7 +339,7 @@ public static function get_avatar_url( $comment ) {
public static function trash_post( $post_id ) {
\add_post_meta(
$post_id,
- 'activitypub_canonical_url',
+ '_activitypub_canonical_url',
\get_permalink( $post_id ),
true
);
@@ -351,7 +351,7 @@ public static function trash_post( $post_id ) {
* @param string $post_id The Post ID.
*/
public static function untrash_post( $post_id ) {
- \delete_post_meta( $post_id, 'activitypub_canonical_url' );
+ \delete_post_meta( $post_id, '_activitypub_canonical_url' );
}
/**
@@ -482,7 +482,7 @@ private static function register_post_types() {
\register_post_meta(
Followers::POST_TYPE,
- 'activitypub_inbox',
+ '_activitypub_inbox',
array(
'type' => 'string',
'single' => true,
@@ -492,7 +492,7 @@ private static function register_post_types() {
\register_post_meta(
Followers::POST_TYPE,
- 'activitypub_errors',
+ '_activitypub_errors',
array(
'type' => 'string',
'single' => false,
@@ -508,7 +508,7 @@ private static function register_post_types() {
\register_post_meta(
Followers::POST_TYPE,
- 'activitypub_user_id',
+ '_activitypub_user_id',
array(
'type' => 'string',
'single' => false,
@@ -520,7 +520,7 @@ private static function register_post_types() {
\register_post_meta(
Followers::POST_TYPE,
- 'activitypub_actor_json',
+ '_activitypub_actor_json',
array(
'type' => 'string',
'single' => true,
diff --git a/includes/class-migration.php b/includes/class-migration.php
index fe352b478..0ad7ccf83 100644
--- a/includes/class-migration.php
+++ b/includes/class-migration.php
@@ -161,6 +161,9 @@ public static function maybe_migrate() {
if ( \version_compare( $version_from_db, '4.5.0', '<' ) ) {
\wp_schedule_single_event( \time() + MINUTE_IN_SECONDS, 'activitypub_update_comment_counts' );
}
+ if ( \version_compare( $version_from_db, '4.6.0', '<' ) ) {
+ self::migrate_to_4_6_0();
+ }
/**
* Fires when the system has to be migrated.
@@ -387,6 +390,26 @@ public static function migrate_to_4_1_0() {
);
}
+ /**
+ * Updates post meta keys to be prefixed with an underscore.
+ */
+ public static function migrate_to_4_6_0() {
+ global $wpdb;
+
+ $meta_keys = array(
+ 'activitypub_actor_json',
+ 'activitypub_canonical_url',
+ 'activitypub_errors',
+ 'activitypub_inbox',
+ 'activitypub_user_id',
+ );
+
+ foreach ( $meta_keys as $meta_key ) {
+ // phpcs:ignore WordPress.DB
+ $wpdb->update( $wpdb->postmeta, array( 'meta_key' => '_' . $meta_key ), array( 'meta_key' => $meta_key ) );
+ }
+ }
+
/**
* Update comment counts for posts in batches.
*
diff --git a/includes/collection/class-actors.php b/includes/collection/class-actors.php
index 9e862e028..88ad59462 100644
--- a/includes/collection/class-actors.php
+++ b/includes/collection/class-actors.php
@@ -100,7 +100,7 @@ public static function get_by_username( $username ) {
'meta_query' => array(
'relation' => 'OR',
array(
- 'key' => 'activitypub_user_identifier',
+ 'key' => '_activitypub_user_identifier',
'value' => $username,
'compare' => 'LIKE',
),
diff --git a/includes/collection/class-followers.php b/includes/collection/class-followers.php
index dc4e31507..d6f8b0727 100644
--- a/includes/collection/class-followers.php
+++ b/includes/collection/class-followers.php
@@ -52,11 +52,11 @@ public static function add_follower( $user_id, $actor ) {
return $id;
}
- $post_meta = get_post_meta( $id, 'activitypub_user_id', false );
+ $post_meta = get_post_meta( $id, '_activitypub_user_id', false );
// phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
if ( is_array( $post_meta ) && ! in_array( $user_id, $post_meta ) ) {
- add_post_meta( $id, 'activitypub_user_id', $user_id );
+ add_post_meta( $id, '_activitypub_user_id', $user_id );
wp_cache_delete( sprintf( self::CACHE_KEY_INBOXES, $user_id ), 'activitypub' );
}
@@ -89,7 +89,7 @@ public static function remove_follower( $user_id, $actor ) {
*/
do_action( 'activitypub_followers_pre_remove_follower', $follower, $user_id, $actor );
- return delete_post_meta( $follower->get__id(), 'activitypub_user_id', $user_id );
+ return delete_post_meta( $follower->get__id(), '_activitypub_user_id', $user_id );
}
/**
@@ -106,7 +106,7 @@ public static function get_follower( $user_id, $actor ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$post_id = $wpdb->get_var(
$wpdb->prepare(
- "SELECT DISTINCT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->postmeta pm ON p.ID = pm.post_id WHERE p.post_type = %s AND pm.meta_key = 'activitypub_user_id' AND pm.meta_value = %d AND p.guid = %s",
+ "SELECT DISTINCT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->postmeta pm ON p.ID = pm.post_id WHERE p.post_type = %s AND pm.meta_key = '_activitypub_user_id' AND pm.meta_value = %d AND p.guid = %s",
array(
esc_sql( self::POST_TYPE ),
esc_sql( $user_id ),
@@ -188,7 +188,7 @@ public static function get_followers_with_count( $user_id, $number = -1, $page =
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
'meta_query' => array(
array(
- 'key' => 'activitypub_user_id',
+ 'key' => '_activitypub_user_id',
'value' => $user_id,
),
),
@@ -219,11 +219,11 @@ public static function get_all_followers() {
'meta_query' => array(
'relation' => 'AND',
array(
- 'key' => 'activitypub_inbox',
+ 'key' => '_activitypub_inbox',
'compare' => 'EXISTS',
),
array(
- 'key' => 'activitypub_actor_json',
+ 'key' => '_activitypub_actor_json',
'compare' => 'EXISTS',
),
),
@@ -247,15 +247,15 @@ public static function count_followers( $user_id ) {
'meta_query' => array(
'relation' => 'AND',
array(
- 'key' => 'activitypub_user_id',
+ 'key' => '_activitypub_user_id',
'value' => $user_id,
),
array(
- 'key' => 'activitypub_inbox',
+ 'key' => '_activitypub_inbox',
'compare' => 'EXISTS',
),
array(
- 'key' => 'activitypub_actor_json',
+ 'key' => '_activitypub_actor_json',
'compare' => 'EXISTS',
),
),
@@ -290,15 +290,15 @@ public static function get_inboxes( $user_id ) {
'meta_query' => array(
'relation' => 'AND',
array(
- 'key' => 'activitypub_inbox',
+ 'key' => '_activitypub_inbox',
'compare' => 'EXISTS',
),
array(
- 'key' => 'activitypub_user_id',
+ 'key' => '_activitypub_user_id',
'value' => $user_id,
),
array(
- 'key' => 'activitypub_inbox',
+ 'key' => '_activitypub_inbox',
'value' => '',
'compare' => '!=',
),
@@ -318,7 +318,7 @@ public static function get_inboxes( $user_id ) {
$wpdb->prepare(
"SELECT DISTINCT meta_value FROM {$wpdb->postmeta}
WHERE post_id IN (" . implode( ', ', array_fill( 0, count( $posts ), '%d' ) ) . ")
- AND meta_key = 'activitypub_inbox'
+ AND meta_key = '_activitypub_inbox'
AND meta_value IS NOT NULL",
$posts
)
@@ -378,24 +378,24 @@ public static function get_faulty_followers( $number = 20 ) {
'meta_query' => array(
'relation' => 'OR',
array(
- 'key' => 'activitypub_errors',
+ 'key' => '_activitypub_errors',
'compare' => 'EXISTS',
),
array(
- 'key' => 'activitypub_inbox',
+ 'key' => '_activitypub_inbox',
'compare' => 'NOT EXISTS',
),
array(
- 'key' => 'activitypub_actor_json',
+ 'key' => '_activitypub_actor_json',
'compare' => 'NOT EXISTS',
),
array(
- 'key' => 'activitypub_inbox',
+ 'key' => '_activitypub_inbox',
'value' => '',
'compare' => '=',
),
array(
- 'key' => 'activitypub_actor_json',
+ 'key' => '_activitypub_actor_json',
'value' => '',
'compare' => '=',
),
@@ -437,7 +437,7 @@ public static function add_error( $post_id, $error ) {
return add_post_meta(
$post_id,
- 'activitypub_errors',
+ '_activitypub_errors',
$error_message
);
}
diff --git a/includes/functions.php b/includes/functions.php
index a06a09b7f..19d1af2c1 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -620,7 +620,7 @@ function is_json( $data ) {
}
/**
- * Check whther a blog is public based on the `blog_public` option.
+ * Check whether a blog is public based on the `blog_public` option.
*
* @return bool True if public, false if not
*/
@@ -1071,7 +1071,7 @@ function ( $enclosure ) {
*
* @param int|\WP_Comment $comment Comment ID or comment object.
*
- * @return \WP_Comment[] Array of ancestor comments or empty array if there are none.
+ * @return int[] Array of ancestor IDs.
*/
function get_comment_ancestors( $comment ) {
$comment = \get_comment( $comment );
diff --git a/includes/model/class-follower.php b/includes/model/class-follower.php
index 45ef6157b..bcf5d39dd 100644
--- a/includes/model/class-follower.php
+++ b/includes/model/class-follower.php
@@ -36,7 +36,7 @@ class Follower extends Actor {
* @return mixed
*/
public function get_errors() {
- return get_post_meta( $this->_id, 'activitypub_errors', false );
+ return get_post_meta( $this->_id, '_activitypub_errors', false );
}
/**
@@ -72,7 +72,7 @@ public function get_url() {
* Reset (delete) all errors.
*/
public function reset_errors() {
- delete_post_meta( $this->_id, 'activitypub_errors' );
+ delete_post_meta( $this->_id, '_activitypub_errors' );
}
/**
@@ -216,9 +216,9 @@ public function delete() {
* Update the post meta.
*/
protected function get_post_meta_input() {
- $meta_input = array();
- $meta_input['activitypub_inbox'] = $this->get_shared_inbox();
- $meta_input['activitypub_actor_json'] = $this->to_json();
+ $meta_input = array();
+ $meta_input['_activitypub_inbox'] = $this->get_shared_inbox();
+ $meta_input['_activitypub_actor_json'] = $this->to_json();
return $meta_input;
}
@@ -334,7 +334,7 @@ public function get_shared_inbox() {
* @return \Activitypub\Activity\Base_Object|WP_Error
*/
public static function init_from_cpt( $post ) {
- $actor_json = get_post_meta( $post->ID, 'activitypub_actor_json', true );
+ $actor_json = get_post_meta( $post->ID, '_activitypub_actor_json', true );
$object = self::init_from_json( $actor_json );
$object->set__id( $post->ID );
$object->set_id( $post->guid );
diff --git a/includes/transformer/class-post.php b/includes/transformer/class-post.php
index d01c121c4..f3cbcf960 100644
--- a/includes/transformer/class-post.php
+++ b/includes/transformer/class-post.php
@@ -152,7 +152,7 @@ public function get_url() {
switch ( \get_post_status( $post ) ) {
case 'trash':
- $permalink = \get_post_meta( $post->ID, 'activitypub_canonical_url', true );
+ $permalink = \get_post_meta( $post->ID, '_activitypub_canonical_url', true );
break;
case 'draft':
// Get_sample_permalink is in wp-admin, not always loaded.
@@ -454,10 +454,21 @@ protected function get_media_from_blocks( $blocks, $media ) {
$alt = $match[2];
}
- $media['image'][] = array(
- 'id' => $block['attrs']['id'],
- 'alt' => $alt,
- );
+ $found = false;
+ foreach ( $media['image'] as $i => $image ) {
+ if ( $image['id'] === $block['attrs']['id'] ) {
+ $media['image'][ $i ]['alt'] = $alt;
+ $found = true;
+ break;
+ }
+ }
+
+ if ( ! $found ) {
+ $media['image'][] = array(
+ 'id' => $block['attrs']['id'],
+ 'alt' => $alt,
+ );
+ }
}
break;
case 'core/audio':
diff --git a/integration/class-jetpack.php b/integration/class-jetpack.php
index f4cf31e40..5586cf79e 100644
--- a/integration/class-jetpack.php
+++ b/integration/class-jetpack.php
@@ -35,9 +35,9 @@ public static function add_sync_meta( $allow_list ) {
return $allow_list;
}
$activitypub_meta_keys = array(
- 'activitypub_user_id',
- 'activitypub_inbox',
- 'activitypub_actor_json',
+ '_activitypub_user_id',
+ '_activitypub_inbox',
+ '_activitypub_actor_json',
);
return \array_merge( $allow_list, $activitypub_meta_keys );
}
diff --git a/readme.txt b/readme.txt
index 40500b814..5b69986c2 100644
--- a/readme.txt
+++ b/readme.txt
@@ -135,7 +135,9 @@ For reasons of data protection, it is not possible to see the followers of other
= Unreleased =
* Added: A filter to make custom comment types manageable in WP.com Calypso
+* Changed: Hide ActivityPub post meta keys from the custom Fields UI
* Fixed: Undefined array key warnings in various places
+* Fixed: Image captions not being included in the ActivityPub representation when the image is attached to the post
* Changed: Print `_activityPubOptions` in the `wp_footer` action on the frontend.
= 4.6.0 =
diff --git a/tests/includes/class-test-migration.php b/tests/includes/class-test-migration.php
index 73384c240..00589fe2f 100644
--- a/tests/includes/class-test-migration.php
+++ b/tests/includes/class-test-migration.php
@@ -186,6 +186,79 @@ public function test_migrate_to_4_1_0() {
$this->assertFalse( $content_type );
}
+ /**
+ * Test migrate to 4.6.0.
+ *
+ * @covers ::migrate_to_4_6_0
+ */
+ public function test_migrate_to_4_6_0() {
+ $post1 = \wp_insert_post(
+ array(
+ 'post_author' => 1,
+ 'post_content' => 'Test post 1',
+ )
+ );
+
+ $post2 = \wp_insert_post(
+ array(
+ 'post_author' => 1,
+ 'post_content' => 'Test post 2',
+ )
+ );
+
+ // Set up test meta data.
+ $meta_data = array(
+ 'activitypub_actor_json' => '{"type":"Person"}',
+ 'activitypub_canonical_url' => 'https://example.com/post-1',
+ 'activitypub_errors' => 'Test error',
+ 'activitypub_inbox' => 'https://example.com/inbox',
+ 'activitypub_user_id' => '123',
+ 'unrelated_meta' => 'should not change',
+ );
+
+ foreach ( $meta_data as $key => $value ) {
+ \update_post_meta( $post1, $key, $value );
+ \update_post_meta( $post2, $key, $value . '-2' );
+ }
+
+ // Run migration.
+ Migration::migrate_to_4_6_0();
+
+ // Clean post cache to ensure fresh meta data.
+ \clean_post_cache( $post1 );
+ \clean_post_cache( $post2 );
+
+ // Check post 1 meta.
+ $this->assertEmpty( \get_post_meta( $post1, 'activitypub_actor_json', true ), 'Old actor_json meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post1, 'activitypub_canonical_url', true ), 'Old canonical_url meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post1, 'activitypub_errors', true ), 'Old errors meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post1, 'activitypub_inbox', true ), 'Old inbox meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post1, 'activitypub_user_id', true ), 'Old user_id meta should be empty' );
+
+ $this->assertEquals( '{"type":"Person"}', \get_post_meta( $post1, '_activitypub_actor_json', true ), 'New actor_json meta should match' );
+ $this->assertEquals( 'https://example.com/post-1', \get_post_meta( $post1, '_activitypub_canonical_url', true ), 'New canonical_url meta should match' );
+ $this->assertEquals( 'Test error', \get_post_meta( $post1, '_activitypub_errors', true ), 'New errors meta should match' );
+ $this->assertEquals( 'https://example.com/inbox', \get_post_meta( $post1, '_activitypub_inbox', true ), 'New inbox meta should match' );
+ $this->assertEquals( '123', \get_post_meta( $post1, '_activitypub_user_id', true ), 'New user_id meta should match' );
+
+ // Check post 2 meta.
+ $this->assertEmpty( \get_post_meta( $post2, 'activitypub_actor_json', true ), 'Old actor_json meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post2, 'activitypub_canonical_url', true ), 'Old canonical_url meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post2, 'activitypub_errors', true ), 'Old errors meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post2, 'activitypub_inbox', true ), 'Old inbox meta should be empty' );
+ $this->assertEmpty( \get_post_meta( $post2, 'activitypub_user_id', true ), 'Old user_id meta should be empty' );
+
+ $this->assertEquals( '{"type":"Person"}-2', \get_post_meta( $post2, '_activitypub_actor_json', true ), 'New actor_json meta should match' );
+ $this->assertEquals( 'https://example.com/post-1-2', \get_post_meta( $post2, '_activitypub_canonical_url', true ), 'New canonical_url meta should match' );
+ $this->assertEquals( 'Test error-2', \get_post_meta( $post2, '_activitypub_errors', true ), 'New errors meta should match' );
+ $this->assertEquals( 'https://example.com/inbox-2', \get_post_meta( $post2, '_activitypub_inbox', true ), 'New inbox meta should match' );
+ $this->assertEquals( '123-2', \get_post_meta( $post2, '_activitypub_user_id', true ), 'New user_id meta should match' );
+
+ // Verify unrelated meta is unchanged.
+ $this->assertEquals( 'should not change', \get_post_meta( $post1, 'unrelated_meta', true ), 'Unrelated meta should not change' );
+ $this->assertEquals( 'should not change-2', \get_post_meta( $post2, 'unrelated_meta', true ), 'Unrelated meta should not change' );
+ }
+
/**
* Tests that a new migration lock can be successfully acquired when no lock exists.
*
diff --git a/tests/includes/collection/class-test-followers.php b/tests/includes/collection/class-test-followers.php
index e19dca592..cd54412ed 100644
--- a/tests/includes/collection/class-test-followers.php
+++ b/tests/includes/collection/class-test-followers.php
@@ -291,7 +291,7 @@ public function test_get_faulty_followers() {
$follower = Followers::get_follower( 1, 'http://sally.example.org' );
for ( $i = 1; $i <= 15; $i++ ) {
- add_post_meta( $follower->get__id(), 'activitypub_errors', 'error ' . $i );
+ add_post_meta( $follower->get__id(), '_activitypub_errors', 'error ' . $i );
}
$follower = Followers::get_follower( 1, 'http://sally.example.org' );
@@ -332,7 +332,7 @@ public function test_add_duplicate_follower() {
$this->assertContains( $follower, $db_followers );
$follower = current( $db_followers );
- $meta = get_post_meta( $follower->get__id(), 'activitypub_user_id', false );
+ $meta = get_post_meta( $follower->get__id(), '_activitypub_user_id', false );
$this->assertCount( 1, $meta );
}
@@ -477,7 +477,7 @@ public function test_get_inboxes() {
$id = $follower->upsert();
- add_post_meta( $id, 'activitypub_user_id', 1 );
+ add_post_meta( $id, '_activitypub_user_id', 1 );
}
$inboxes = Followers::get_inboxes( 1 );
@@ -503,7 +503,7 @@ public function test_get_inboxes() {
$id = $follower->upsert();
- add_post_meta( $id, 'activitypub_user_id', 1 );
+ add_post_meta( $id, '_activitypub_user_id', 1 );
}
$inboxes2 = Followers::get_inboxes( 1 );
@@ -533,7 +533,7 @@ public function test_get_all_followers() {
$id = $follower->upsert();
- add_post_meta( $id, 'activitypub_user_id', 1 );
+ add_post_meta( $id, '_activitypub_user_id', 1 );
}
$followers = Followers::get_all_followers();
diff --git a/tests/includes/transformer/class-test-post.php b/tests/includes/transformer/class-test-post.php
index 63cb574cf..a6a07202c 100644
--- a/tests/includes/transformer/class-test-post.php
+++ b/tests/includes/transformer/class-test-post.php
@@ -286,7 +286,7 @@ public function test_to_object() {
$this->assertEquals( $permalink, $activitypub_post->get_id() );
- $cached = \get_post_meta( $post, 'activitypub_canonical_url', true );
+ $cached = \get_post_meta( $post, '_activitypub_canonical_url', true );
$this->assertEquals( $cached, $activitypub_post->get_id() );
}
@@ -387,56 +387,105 @@ public function test_block_attachments_with_fallback() {
}
/**
- * 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.
+ * Test get_media_from_blocks adds alt text to existing images.
*
- * @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
+ * @covers ::get_media_from_blocks
*/
- public function create_upload_object( $file, $parent_id = 0 ) {
- if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
- require ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
- require ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
- }
+ public function test_get_media_from_blocks_adds_alt_text_to_existing_images() {
+ $post_id = self::factory()->post->create(
+ array(
+ 'post_content' => '',
+ )
+ );
+ $post = get_post( $post_id );
- $dest = dirname( $file ) . DIRECTORY_SEPARATOR . 'test-temp.jpg';
- $fs = new \WP_Filesystem_Direct( array() );
- $fs->copy( $file, $dest );
+ $transformer = new Post( $post );
+ $media = array(
+ 'image' => array(
+ array(
+ 'id' => 123,
+ 'alt' => '',
+ ),
+ ),
+ 'audio' => array(),
+ 'video' => array(),
+ );
- $file = $dest;
+ $reflection = new \ReflectionClass( Post::class );
+ $method = $reflection->getMethod( 'get_media_from_blocks' );
+ $method->setAccessible( true );
- $file_array = array(
- 'name' => wp_basename( $file ),
- 'tmp_name' => $file,
+ $blocks = parse_blocks( $post->post_content );
+ $result = $method->invoke( $transformer, $blocks, $media );
+
+ $this->assertSame( 'Test alt text', $result['image'][0]['alt'] );
+ $this->assertSame( 123, $result['image'][0]['id'] );
+ }
+
+ /**
+ * Test get_media_from_blocks adds new image when none exist.
+ *
+ * @covers ::get_media_from_blocks
+ */
+ public function test_get_media_from_blocks_adds_new_image() {
+ $post_id = self::factory()->post->create(
+ array(
+ 'post_content' => '',
+ )
);
+ $post = get_post( $post_id );
- $upload = wp_handle_sideload( $file_array, array( 'test_form' => false ) );
+ $transformer = new Post( $post );
+ $media = array(
+ 'image' => array(),
+ 'audio' => array(),
+ 'video' => array(),
+ );
- $type = '';
- if ( ! empty( $upload['type'] ) ) {
- $type = $upload['type'];
- } else {
- $mime = wp_check_filetype( $upload['file'] );
- if ( $mime ) {
- $type = $mime['type'];
- }
- }
+ $reflection = new \ReflectionClass( Post::class );
+ $method = $reflection->getMethod( 'get_media_from_blocks' );
+ $method->setAccessible( true );
- $attachment = array(
- 'post_title' => wp_basename( $upload['file'] ),
- 'post_content' => '',
- 'post_type' => 'attachment',
- 'post_parent' => $parent_id,
- 'post_mime_type' => $type,
- 'guid' => $upload['url'],
+ $blocks = parse_blocks( $post->post_content );
+ $result = $method->invoke( $transformer, $blocks, $media );
+
+ $this->assertCount( 1, $result['image'] );
+ $this->assertSame( 123, $result['image'][0]['id'] );
+ $this->assertSame( 'Test alt text', $result['image'][0]['alt'] );
+ }
+
+ /**
+ * Test get_media_from_blocks handles multiple blocks correctly.
+ *
+ * @covers ::get_media_from_blocks
+ */
+ public function test_get_media_from_blocks_handles_multiple_blocks() {
+ $post_id = self::factory()->post->create(
+ array(
+ 'post_content' => '',
+ )
);
+ $post = get_post( $post_id );
- // Save the data.
- $id = wp_insert_attachment( $attachment, $upload['file'], $parent_id );
- wp_update_attachment_metadata( $id, @wp_generate_attachment_metadata( $id, $upload['file'] ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
+ $transformer = new Post( $post );
+ $media = array(
+ 'image' => array(),
+ 'audio' => array(),
+ 'video' => array(),
+ );
- return $id;
+ $reflection = new \ReflectionClass( Post::class );
+ $method = $reflection->getMethod( 'get_media_from_blocks' );
+ $method->setAccessible( true );
+
+ $blocks = parse_blocks( $post->post_content );
+ $result = $method->invoke( $transformer, $blocks, $media );
+
+ $this->assertCount( 2, $result['image'] );
+ $this->assertSame( 123, $result['image'][0]['id'] );
+ $this->assertSame( 'Test alt 1', $result['image'][0]['alt'] );
+ $this->assertSame( 456, $result['image'][1]['id'] );
+ $this->assertSame( 'Test alt 2', $result['image'][1]['alt'] );
}
/**
@@ -457,7 +506,7 @@ public function test_get_icon() {
$attachment_id = $this->create_upload_object( dirname( __DIR__, 2 ) . '/assets/test.jpg' );
// Set up reflection method.
- $reflection = new ReflectionClass( Post::class );
+ $reflection = new \ReflectionClass( Post::class );
$method = $reflection->getMethod( 'get_icon' );
$method->setAccessible( true );
@@ -513,4 +562,56 @@ public function test_get_icon() {
wp_delete_post( $post_id, true );
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 ) {
+ if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
+ require ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
+ require ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
+ }
+
+ $dest = dirname( $file ) . DIRECTORY_SEPARATOR . 'test-temp.jpg';
+ $fs = new \WP_Filesystem_Direct( array() );
+ $fs->copy( $file, $dest );
+
+ $file = $dest;
+
+ $file_array = array(
+ 'name' => wp_basename( $file ),
+ 'tmp_name' => $file,
+ );
+
+ $upload = wp_handle_sideload( $file_array, array( 'test_form' => false ) );
+
+ $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 );
+ wp_update_attachment_metadata( $id, @wp_generate_attachment_metadata( $id, $upload['file'] ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
+
+ return $id;
+ }
}