diff --git a/README.md b/README.md index b9e8970..8b8e0b4 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,30 @@ class VacancyData extends PostData $vacancyTypeIcon = $vacancyData->type->first()?->icon; ``` +#### Reading comments for your Data Objects + +If the post type of the data object supports comments, you can retrieve them as a collection of `CommentData` + +```php +$postData->comments()->first()?->authorEmail; +``` + +#### Extending CommentData + +You can add extra meta fields to comments by extending the default CommentData object + +```php +namespace App\Data; + +use Yard\Data\CommentData; + +class LinkedInCommmentData extends CommentDataData { + + #[Meta()] + public string $linkedInUserName; +} +``` + ### UserData Create UserData from current user: diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 13cbc9f..a933ae0 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -15,5 +15,5 @@ parameters: - identifier: function.impossibleType path: src/Traits/HasMeta.php - count: 1 + count: 3 diff --git a/src/CommentData.php b/src/CommentData.php new file mode 100644 index 0000000..f895761 --- /dev/null +++ b/src/CommentData.php @@ -0,0 +1,54 @@ +loadMeta(); + } + + public static function fromComment(\WP_Comment $comment): static + { + return new static( + id: (int) $comment->comment_ID, + post: null !== get_post((int)$comment->comment_post_ID) ? PostData::fromPost(get_post((int)$comment->comment_post_ID)) : null, + author: $comment->comment_author, + authorEmail: $comment->comment_author_email, + authorUrl: $comment->comment_author_url, + authorIp: $comment->comment_author_IP, + date: CarbonImmutable::createFromFormat('Y-m-d H:i:s', $comment->comment_date)?: null, + dateGmt: CarbonImmutable::createFromFormat('Y-m-d H:i:s', $comment->comment_date_gmt)?: null, + content: $comment->comment_content, + approved: '1' === $comment->comment_approved, + agent: $comment->comment_agent, + type: $comment->comment_type, + parent: null !== get_comment((int) $comment->comment_parent) ? CommentData::fromComment(get_comment((int) $comment->comment_parent)) : null, + user: false !== get_userdata((int) $comment->user_id) ? UserData::fromUser(get_userdata((int) $comment->user_id)) : null, + ); + } +} diff --git a/src/Contracts/PostDataInterface.php b/src/Contracts/PostDataInterface.php index f80c9f5..fd30512 100644 --- a/src/Contracts/PostDataInterface.php +++ b/src/Contracts/PostDataInterface.php @@ -23,6 +23,7 @@ public function __construct( string $postType, string $slug, ?ImageData $thumbnail, + ?int $commentCount, ); public function id(): ?int; diff --git a/src/PostData.php b/src/PostData.php index 0fdd57e..02239d6 100644 --- a/src/PostData.php +++ b/src/PostData.php @@ -46,6 +46,7 @@ public function __construct( #[MapInputName('post_name')] public string $slug, public ?ImageData $thumbnail, + public ?int $commentCount, ) { if (null !== $id) { $this->loadMeta(); @@ -67,6 +68,7 @@ public static function fromPost(\WP_Post $post): static postType: $post->post_type, slug: $post->post_name, thumbnail: get_post_thumbnail_id($post->ID) ? new ImageData(get_post_thumbnail_id($post->ID)) : null, + commentCount: post_type_supports($post->post_type, 'comments') ? (int) $post->comment_count : null, ); } @@ -84,6 +86,7 @@ public static function fromCorcel(Post $post): static postType: $post->post_type, slug: $post->post_name, thumbnail: get_post_thumbnail_id($post->ID) ? new ImageData(get_post_thumbnail_id($post->ID)) : null, + commentCount: post_type_supports($post->post_type, 'comments') ? (int) $post->comment_count : null, ); } @@ -311,4 +314,27 @@ public function parent(): ?static return static::fromPost($parent); } + + /** + * @param array $args + * + * @return Collection + */ + public function comments(array $args = []): Collection + { + if (null === $this->id || ! post_type_supports($this->postType, 'comments')) { + return collect(); + } + + $args = wp_parse_args($args, [ + 'post_id' => $this->id, + 'status' => 'approve', + 'type' => 'comment', + ]); + + /** @var array $comments */ + $comments = get_comments($args); + + return CommentData::collect($comments, Collection::class); + } } diff --git a/src/Traits/HasMeta.php b/src/Traits/HasMeta.php index 15e161f..adcb24c 100644 --- a/src/Traits/HasMeta.php +++ b/src/Traits/HasMeta.php @@ -8,6 +8,7 @@ use Spatie\LaravelData\Data; use Yard\Data\Attributes\Meta; use Yard\Data\Attributes\MetaPrefix; +use Yard\Data\CommentData; use Yard\Data\PostData; use Yard\Data\TermData; @@ -76,6 +77,9 @@ private function objectID(): string|int if (is_a($this, TermData::class)) { return $this->taxonomy . '_' . $this->id; } + if (is_a($this, CommentData::class)) { + return 'comment_' . $this->id; + } return 0; } diff --git a/tests/src/PostDataTest.php b/tests/src/PostDataTest.php index 76c4be1..a641b3f 100644 --- a/tests/src/PostDataTest.php +++ b/tests/src/PostDataTest.php @@ -15,6 +15,7 @@ postType: 'post', slug: 'hello-world', thumbnail: null, + commentCount: 0, ); });