CollaborationCommentResource.php
100 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Kirki\App\Resources\CollaborationComment; |
| 4 | |
| 5 | use DateTimeInterface; |
| 6 | use Kirki\Framework\Constants\DateTimeFormats; |
| 7 | use Kirki\Framework\Resource; |
| 8 | use function Kirki\Framework\user; |
| 9 | |
| 10 | /** |
| 11 | * Presentation for a collaboration comment (`CollaborationComment`). |
| 12 | * |
| 13 | * Mirrors the legacy `format_single_comment()` behaviour, including its |
| 14 | * asymmetry: a top-level/single comment includes a `read` flag (derived from |
| 15 | * the `seen` relation, eager-loaded and filtered to the current user), while |
| 16 | * comments nested under `replies` never include `read` at all, since the |
| 17 | * legacy replies query never joined the seen table either. |
| 18 | */ |
| 19 | class CollaborationCommentResource extends Resource |
| 20 | { |
| 21 | /** |
| 22 | * Convert the top-level/single comment resource to an array. |
| 23 | * |
| 24 | * @return array<string, mixed> |
| 25 | */ |
| 26 | public function to_array() |
| 27 | { |
| 28 | return array_merge($this->base_array(), [ |
| 29 | 'read' => $this->is_read() ? 1 : 0, |
| 30 | ]); |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * The fields shared by both top-level comments and nested replies. |
| 35 | * |
| 36 | * @return array |
| 37 | */ |
| 38 | protected function base_array() |
| 39 | { |
| 40 | return [ |
| 41 | 'id' => (int) $this->id, |
| 42 | 'user_id' => (int) $this->user_id, |
| 43 | 'post_id' => (int) $this->post_id, |
| 44 | 'parent_id' => (int) $this->parent_id, |
| 45 | 'comment' => $this->comment, |
| 46 | 'meta_data' => $this->meta_data, |
| 47 | 'status' => (int) $this->status, |
| 48 | 'created_at' => $this->format_datetime($this->created_at), |
| 49 | 'updated_at' => $this->format_datetime($this->updated_at), |
| 50 | 'replies' => $this->format_replies(), |
| 51 | 'user_avatar' => user($this->user_id)->get_avatar(), |
| 52 | 'user_name' => user($this->user_id)->get_display_name(), |
| 53 | ]; |
| 54 | } |
| 55 | |
| 56 | /** |
| 57 | * Nested replies never carry a `read` flag, matching legacy behaviour. |
| 58 | * |
| 59 | * @return array |
| 60 | */ |
| 61 | protected function format_replies() |
| 62 | { |
| 63 | $replies = []; |
| 64 | |
| 65 | foreach ($this->replies ?? [] as $reply) { |
| 66 | $replies[] = (new static($reply))->base_array(); |
| 67 | } |
| 68 | |
| 69 | return $replies; |
| 70 | } |
| 71 | |
| 72 | /** |
| 73 | * Whether the eager-loaded `seen` relation (filtered to the current user) is non-empty. |
| 74 | * |
| 75 | * @return bool |
| 76 | */ |
| 77 | protected function is_read() |
| 78 | { |
| 79 | return !empty($this->seen); |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * Whether the eager-loaded `seen` relation (filtered to the current user) is non-empty. |
| 84 | * |
| 85 | * @return mixed |
| 86 | */ |
| 87 | protected function format_datetime($datetime) |
| 88 | { |
| 89 | if (is_string($datetime)) { |
| 90 | return $datetime; |
| 91 | } |
| 92 | |
| 93 | if ($datetime instanceof DateTimeInterface) { |
| 94 | return $datetime->format(DateTimeFormats::DB_DATETIME); |
| 95 | } |
| 96 | |
| 97 | return null; |
| 98 | } |
| 99 | } |
| 100 |