Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions src/php/Application/Presenter/MetadataPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,30 @@ public function generate( WP_Post $post, array $existing_metadata = array() ): a

$metadata = $existing_metadata;

$metadata['@context'] = 'https://schema.org';
$metadata['@type'] = 'LiveBlogPosting';
$metadata['headline'] = get_the_title( $post );
$metadata['url'] = get_permalink( $post );
$metadata['datePublished'] = get_post_datetime( $post, 'date', 'gmt' )->format( 'c' );
$metadata['dateModified'] = get_post_datetime( $post, 'modified', 'gmt' )->format( 'c' );

// Add coverage times for LiveBlogPosting (helps with Google's "LIVE" badge).
$metadata['coverageStartTime'] = $metadata['datePublished'];

// Add coverageEndTime only if the liveblog is archived.
if ( LiveblogPost::STATE_ARCHIVED === $liveblog_state ) {
$metadata['coverageEndTime'] = $metadata['dateModified'];
$metadata['@context'] = 'https://schema.org';
$metadata['@type'] = 'LiveBlogPosting';
$metadata['headline'] = get_the_title( $post );
$metadata['url'] = get_permalink( $post );

// Unpublished posts (drafts, pending, auto-drafts) store a `0000-00-00 00:00:00`
// GMT date, for which get_post_datetime() returns false. Guard against calling
// format() on false to avoid a fatal when such a post is previewed.
$published_datetime = get_post_datetime( $post, 'date', 'gmt' );
if ( false !== $published_datetime ) {
$metadata['datePublished'] = $published_datetime->format( 'c' );

// Add coverage times for LiveBlogPosting (helps with Google's "LIVE" badge).
$metadata['coverageStartTime'] = $metadata['datePublished'];
}

$modified_datetime = get_post_datetime( $post, 'modified', 'gmt' );
if ( false !== $modified_datetime ) {
$metadata['dateModified'] = $modified_datetime->format( 'c' );

// Add coverageEndTime only if the liveblog is archived.
if ( LiveblogPost::STATE_ARCHIVED === $liveblog_state ) {
$metadata['coverageEndTime'] = $metadata['dateModified'];
}
}

$metadata['liveBlogUpdate'] = $blog_updates;
Expand Down
51 changes: 51 additions & 0 deletions tests/Integration/SchemaMetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,57 @@ public function test_entries_present_for_password_protected_post_with_password()
$this->assertNotEmpty( $metadata['liveBlogUpdate'] );
}

/**
* Test that metadata generation does not fatal for an unpublished post.
*
* Drafts (and pending/auto-draft posts) store a `0000-00-00 00:00:00` GMT
* date, for which get_post_datetime() returns false. Previously this caused
* a fatal `Call to a member function format() on false` when such a post was
* previewed. See https://github.com/Automattic/liveblog/issues/919.
*
* @covers ::generate
*/
public function test_metadata_omits_dates_for_unpublished_post(): void {
$draft_id = self::factory()->post->create(
array(
'post_title' => 'Draft Liveblog',
'post_status' => 'draft',
)
);
update_post_meta( $draft_id, LiveblogConfiguration::KEY, 'enable' );

// Confirm the fixture reproduces the original conditions: the GMT date is
// unavailable, so get_post_datetime() returns false.
$this->assertFalse( get_post_datetime( $draft_id, 'date', 'gmt' ) );

$metadata_presenter = Container::instance()->metadata_presenter();
$metadata = $metadata_presenter->generate( get_post( $draft_id ), array() );

// The metadata is still generated (proving the date code did not fatal)...
$this->assertEquals( 'LiveBlogPosting', $metadata['@type'] );

// ...but the date-derived properties are omitted rather than fatalling.
$this->assertArrayNotHasKey( 'datePublished', $metadata );
$this->assertArrayNotHasKey( 'dateModified', $metadata );
$this->assertArrayNotHasKey( 'coverageStartTime', $metadata );
}

/**
* Test that a published post still includes the date-derived properties.
*
* @covers ::generate
*/
public function test_metadata_includes_dates_for_published_post(): void {
$this->insert_entry( array( 'content' => '<p>Test entry</p>' ) );

$metadata_presenter = Container::instance()->metadata_presenter();
$metadata = $metadata_presenter->generate( get_post( $this->post_id ), array() );

$this->assertArrayHasKey( 'datePublished', $metadata );
$this->assertArrayHasKey( 'dateModified', $metadata );
$this->assertArrayHasKey( 'coverageStartTime', $metadata );
}

/**
* Insert a liveblog entry.
*
Expand Down
Loading