From 91401e537b6f5fa603f9b4d161e7d0ad9bc97611 Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Sun, 15 Feb 2026 11:50:18 +0100 Subject: [PATCH] feat: add post featured media methods --- src/Posts/Post.php | 23 ++++++++++++ src/Posts/Type/Attachment.php | 69 ++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/Posts/Post.php b/src/Posts/Post.php index 5b7ff07..5defaad 100644 --- a/src/Posts/Post.php +++ b/src/Posts/Post.php @@ -107,6 +107,29 @@ return Term::from_post($this); } + /** + * Get, set, or unset featured media for this Post + * + * @param Attachment|false|null $attachment Pass Attachment to set featured media, false to unset, and null (or nothing) to get featured media + * @return Attachment|null Returns an Attachment if featured media is set. Null if no featured media is set + */ + public function featured_media(Attachment|false|null $featured_media = null): ?Attachment { + // Remove featured media from this Post + if ($featured_media === false) { + Attachment::remove_post_featured_media($this); + return null; + } + + // Set Attachment as the featured media for this Post + if ($featured_media instanceof Attachment) { + $featured_media->set_post_featured($this); + + return $featured_media; + } + + return Attachment::from_post_featured($this); + } + public int $post_author { get => $this->get(Posts::POST_AUTHOR->value); set (int $post_author) => $this->set(Posts::POST_AUTHOR->value, $post_author); diff --git a/src/Posts/Type/Attachment.php b/src/Posts/Type/Attachment.php index c5bf0a6..9de28af 100644 --- a/src/Posts/Type/Attachment.php +++ b/src/Posts/Type/Attachment.php @@ -3,14 +3,64 @@ namespace vlw\WP\Posts\Type; use vlw\WP\Posts\Post; + use vlw\WP\Posts\PostMeta; use function vlw\WP\Support\slugify; require_once dirname(__DIR__, 1) . "/Post.php"; + require_once dirname(__DIR__, 1) . "/PostMeta.php"; require_once dirname(__DIR__, 2) . "/Support/Slugify.php"; class Attachment { + private const META_KEY_THUMBNAIL_ID = "_thumbnail_id"; + private const META_KEY_FEATURED_MEDIA = "_featured_media"; + private readonly Post $post; + /** + * Return featured media for a Post if it exists + * + * @param Post $post + * @param bool $thumbnail Thumbnail is the same as the featured meta. Default to true + * @return Attachment|null + */ + public static function from_post_featured(Post $post, bool $thumbnail = true): ?Attachment { + // Check the thumbnail for an attachment ID. This operation is slightly less demanding than unserialize + if ($thumbnail) { + $post_meta = PostMeta::get_post_meta($post, self::META_KEY_THUMBNAIL_ID); + + if ($post_meta) { + return new static($post_meta->id); + } + } + + $post_meta = PostMeta::get_post_meta($post, self::META_KEY_FEATURED_MEDIA); + + // Bail out, the target Post does not have any featured media + if (!$post_meta) { + return null; + } + + // New instance from post ID in featured media serialized object + return new static((int) unserialize($post_meta->meta_value)[0]); + } + + /** + * Remove featured media from a Post + * + * @param Post $post + * @return void + */ + public static function remove_post_featured_media(Post $post): void { + foreach ([ + PostMeta::get_post_meta($post, self::META_KEY_THUMBNAIL_ID), + PostMeta::get_post_meta($post, self::META_KEY_FEATURED_MEDIA) + ] as $post_meta) { + if ($post_meta) { + $post_meta->delete(); + } + } + } + /** * Create a new post * @@ -20,8 +70,10 @@ */ public static function new(string $title, string $url): static { $post = Post::new($title); + $post->post_title = slugify($title); $post->guid = $url; + $post->post_type = "attachment"; return new static($post->id); } @@ -30,7 +82,20 @@ $this->post = new Post($id); } - public function get_attachment(): string { - return file_get_contents($this->post->guid); + /** + * Make this Attachment the featured media of a Post + * + * @param Post $post + * @return object + */ + public function set_post_featured(Post $post): object { + return (object) [ + "thumbnail" => PostMeta::new($post, self::META_KEY_THUMBNAIL_ID, $this->id), + "featured_media" => PostMeta::new($post, self::META_KEY_FEATURED_MEDIA, "a:1:{i:0;s:3:\"{$this->id}\";}") + ]; + } + + public string|false $content { + get => file_get_contents($this->post->guid); } }