You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

449 lines
9.4 KiB
PHP

<?php
/**
* Class Story
*
* @link https://github.com/googleforcreators/web-stories-wp
*
* @copyright 2020 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
*/
/**
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare(strict_types = 1);
namespace Google\Web_Stories\Model;
use Google\Web_Stories\Media\Image_Sizes;
use Google\Web_Stories\Shopping\Product;
use Google\Web_Stories\Shopping\Product_Meta;
use Google\Web_Stories\Story_Post_Type;
use WP_Post;
/**
* Class Story
*
* @phpstan-import-type ProductData from \Google\Web_Stories\Shopping\Product
*/
class Story {
/**
* Story ID.
*/
protected int $id = 0;
/**
* Title.
*/
protected string $title = '';
/**
* Excerpt.
*/
protected string $excerpt = '';
/**
* URL.
*/
protected string $url = '';
/**
* Markup.
*/
protected string $markup = '';
/**
* Publisher name.
*/
protected string $publisher_name = '';
/**
* Publisher logo.
*/
protected string $publisher_logo = '';
/**
* Poster source set sizes.
*/
protected string $poster_sizes = '';
/**
* Poster source set.
*/
protected string $poster_srcset = '';
/**
* Publisher logo size.
*
* @var int[]
* @phpstan-var array{0?: int, 1?: int}
*/
protected array $publisher_logo_size = [];
/**
* Poster portrait logo size.
*
* @var int[]
* @phpstan-var array{0?: int, 1?: int}
*/
protected array $poster_portrait_size = [];
/**
* Array of product data.
*
* @var Product[]
*/
protected array $products = [];
/**
* Poster url - portrait.
*/
protected string $poster_portrait = '';
/**
* Date for the story.
*/
protected string $date = '';
/**
* Author of story.
*/
protected string $author = '';
/**
* Story constructor.
*
* @since 1.0.0
*
* @param array<string,mixed> $story Array of attributes.
*/
public function __construct( array $story = [] ) {
foreach ( $story as $key => $value ) {
if ( property_exists( $this, $key ) ) {
$this->$key = $value;
}
}
}
/**
* Load story from post.
*
* @since 1.0.0
*
* @param int|null|WP_Post $_post Post id or Post object.
*/
public function load_from_post( $_post ): bool {
/**
* Filters the publisher's name
*
* @since 1.7.0
*
* @param string $name Publisher Name.
*/
$this->publisher_name = apply_filters( 'web_stories_publisher_name', get_bloginfo( 'name' ) );
$post = get_post( $_post );
if ( ! $post instanceof WP_Post ) {
return false;
}
// At this point we assume being passed a legit web-story post or perhaps a web-story revision.
$this->id = $post->ID;
$this->title = get_the_title( $post );
$this->excerpt = $post->post_excerpt;
$this->markup = $post->post_content;
$this->url = (string) get_permalink( $post );
$thumbnail_id = (int) get_post_thumbnail_id( $post );
if ( 0 !== $thumbnail_id ) {
$poster_src = wp_get_attachment_image_src( $thumbnail_id, Image_Sizes::POSTER_PORTRAIT_IMAGE_DIMENSIONS );
if ( $poster_src ) {
[ $poster_url, $width, $height ] = $poster_src;
$this->poster_portrait = $poster_url;
$this->poster_portrait_size = [ (int) $width, (int) $height ];
$image_meta = wp_get_attachment_metadata( $thumbnail_id );
if ( $image_meta ) {
$size_array = [ $image_meta['width'], $image_meta['height'] ];
$this->poster_sizes = (string) wp_calculate_image_sizes( $size_array, $poster_url, $image_meta, $thumbnail_id );
$this->poster_srcset = (string) wp_calculate_image_srcset( $size_array, $poster_url, $image_meta, $thumbnail_id );
}
}
} else {
/**
* Poster.
*
* @var array{url?:string, width?: int, height?: int}|false $poster
*/
$poster = get_post_meta( $post->ID, Story_Post_Type::POSTER_META_KEY, true );
if ( ! empty( $poster ) ) {
$this->poster_portrait = $poster['url'];
$this->poster_portrait_size = [ (int) $poster['width'], (int) $poster['height'] ];
}
}
/**
* Publisher logo ID.
*
* @var string|int $publisher_logo_id
*/
$publisher_logo_id = get_post_meta( $this->id, Story_Post_Type::PUBLISHER_LOGO_META_KEY, true );
if ( ! empty( $publisher_logo_id ) ) {
$img_src = wp_get_attachment_image_src( (int) $publisher_logo_id, Image_Sizes::PUBLISHER_LOGO_IMAGE_DIMENSIONS );
if ( $img_src ) {
[ $src, $width, $height ] = $img_src;
$this->publisher_logo_size = [ $width, $height ];
$this->publisher_logo = $src;
}
}
/**
* Product data.
*
* @var ProductData[]|false $products
*/
$products = get_post_meta( $this->id, Product_Meta::PRODUCTS_POST_META_KEY, true );
if ( \is_array( $products ) ) {
$product_objects = [];
foreach ( $products as $product ) {
$product_objects[] = Product::load_from_array( $product );
}
$this->products = $product_objects;
}
return true;
}
/**
* Setter for poster set sizes.
*
* @since 1.21.0
*
* @param string $poster_sizes Poster sizes.
*/
public function set_poster_sizes( string $poster_sizes ): void {
$this->poster_sizes = $poster_sizes;
}
/**
* Setter for poster source set.
*
* @since 1.21.0
*
* @param string $poster_srcset Poster source set.
*/
public function set_poster_srcset( string $poster_srcset ): void {
$this->poster_srcset = $poster_srcset;
}
/**
* Setter for title.
*
* @since 1.21.0
*
* @param string $title Title.
*/
public function set_title( string $title ): void {
$this->title = $title;
}
/**
* Getter for poster source set sizes.
*
* @since 1.18.0
*/
public function get_poster_sizes(): string {
return $this->poster_sizes;
}
/**
* Getter for poster source set.
*
* @since 1.18.0
*/
public function get_poster_srcset(): string {
return $this->poster_srcset;
}
/**
* Getter for title attribute.
*
* @since 1.0.0
*/
public function get_title(): string {
return $this->title;
}
/**
* Getter for excerpt attribute.
*/
public function get_excerpt(): string {
return $this->excerpt;
}
/**
* Getter for url attribute.
*
* @since 1.0.0
*/
public function get_url(): string {
return $this->url;
}
/**
* Getter for markup attribute.
*
* @since 1.0.0
*/
public function get_markup(): string {
return $this->markup;
}
/**
* Getter for poster portrait attribute.
*
* @since 1.0.0
*/
public function get_poster_portrait(): string {
return $this->poster_portrait;
}
/**
* Get the story ID.
*/
public function get_id(): int {
return $this->id;
}
/**
* Get author of the story.
*/
public function get_author(): string {
return $this->author;
}
/**
* Date for the story.
*/
public function get_date(): string {
return $this->date;
}
/**
* Returns the publisher name.
*
* @since 1.12.0
*
* @return string Publisher Name.
*/
public function get_publisher_name(): string {
return $this->publisher_name;
}
/**
* Returns the story's publisher logo URL.
*
* @since 1.12.0
*
* @return string|null Publisher logo URL or null if not set.
*/
public function get_publisher_logo_url(): ?string {
/**
* Filters the publisher logo URL.
*
* @since 1.0.0
* @since 1.1.0 The second parameter was deprecated.
* @since 1.12.0 The second parameter was repurposed to provide the current story ID.
*
* @param string|null $url Publisher logo URL or null if not set.
* @param int|null $id Story ID if available.
*/
return apply_filters( 'web_stories_publisher_logo', $this->publisher_logo, $this->id );
}
/**
* Returns the story's publisher logo size.
*
* @since 1.12.0
*
* @return array {
* Publisher logo size.
*
* Array of image data, or empty array if no image is available.
*
* @type int $1 Image width in pixels.
* @type int $2 Image height in pixels.
* }
*
* @phpstan-return array{0?: int, 1?: int}
*/
public function get_publisher_logo_size(): array {
/**
* Filters the publisher logo size.
*
* @since 1.12.0
*
* @param array $size {
* Publisher logo size.
*
* Array of image data, or empty array if no image is available.
*
* @type int $1 Image width in pixels.
* @type int $2 Image height in pixels.
* }
* @param int|null $id Story ID if available.
*/
return apply_filters( 'web_stories_publisher_logo_size', $this->publisher_logo_size, $this->id );
}
/**
* Get poster portrait size.
*
* @since 1.23.0
*
* @return array {
* Poster portrait logo size.
*
* Array of image data, or empty array if no image is available.
*
* @type int $1 Image width in pixels.
* @type int $2 Image height in pixels.
* }
*
* @phpstan-return array{0?: int, 1?: int}
*/
public function get_poster_portrait_size(): array {
return $this->poster_portrait_size;
}
/**
* Get product data.
*
* @since 1.26.0
*
* @return Product[]
*/
public function get_products(): array {
return $this->products;
}
}