Parse and validate AT Protocol Lexicons with DTO generation for Laravel
1<?php
2
3namespace SocialDept\AtpSchema\Data;
4
5use Illuminate\Contracts\Support\Arrayable;
6use SocialDept\AtpSchema\Exceptions\SchemaValidationException;
7
8/**
9 * @implements Arrayable<string, mixed>
10 */
11class BlobReference implements Arrayable
12{
13 /**
14 * CID of the blob.
15 */
16 public readonly string $ref;
17
18 /**
19 * MIME type of the blob.
20 */
21 public readonly string $mimeType;
22
23 /**
24 * Size of the blob in bytes.
25 */
26 public readonly int $size;
27
28 /**
29 * Create a new BlobReference.
30 */
31 public function __construct(
32 string $ref,
33 string $mimeType,
34 int $size
35 ) {
36 $this->ref = $ref;
37 $this->mimeType = $mimeType;
38 $this->size = $size;
39 }
40
41 /**
42 * Create from array data.
43 */
44 public static function fromArray(array $data): self
45 {
46 // Extract ref - can be a string or array with $link
47 $ref = null;
48 if (isset($data['ref'])) {
49 if (is_string($data['ref'])) {
50 $ref = $data['ref'];
51 } elseif (is_array($data['ref']) && isset($data['ref']['$link'])) {
52 $ref = $data['ref']['$link'];
53 }
54 }
55
56 if ($ref === null) {
57 throw SchemaValidationException::missingField('blob', 'ref');
58 }
59
60 if (! isset($data['mimeType'])) {
61 throw SchemaValidationException::missingField('blob', 'mimeType');
62 }
63
64 if (! isset($data['size'])) {
65 throw SchemaValidationException::missingField('blob', 'size');
66 }
67
68 return new self(
69 ref: $ref,
70 mimeType: $data['mimeType'],
71 size: (int) $data['size']
72 );
73 }
74
75 /**
76 * Convert to array.
77 */
78 public function toArray(): array
79 {
80 return [
81 '$type' => 'blob',
82 'ref' => [
83 '$link' => $this->ref,
84 ],
85 'mimeType' => $this->mimeType,
86 'size' => $this->size,
87 ];
88 }
89
90 /**
91 * Get the CID.
92 */
93 public function getCid(): string
94 {
95 return $this->ref;
96 }
97
98 /**
99 * Get the MIME type.
100 */
101 public function getMimeType(): string
102 {
103 return $this->mimeType;
104 }
105
106 /**
107 * Get the size in bytes.
108 */
109 public function getSize(): int
110 {
111 return $this->size;
112 }
113
114 /**
115 * Check if blob is an image.
116 */
117 public function isImage(): bool
118 {
119 return str_starts_with($this->mimeType, 'image/');
120 }
121
122 /**
123 * Check if blob is a video.
124 */
125 public function isVideo(): bool
126 {
127 return str_starts_with($this->mimeType, 'video/');
128 }
129
130 /**
131 * Check if blob matches a MIME type pattern.
132 */
133 public function matchesMimeType(string $pattern): bool
134 {
135 if (str_contains($pattern, '*')) {
136 $regex = '/^'.str_replace('\\*', '.*', preg_quote($pattern, '/')).'$/';
137
138 return (bool) preg_match($regex, $this->mimeType);
139 }
140
141 return $this->mimeType === $pattern;
142 }
143}