|
12 | 12 |
|
13 | 13 | class Message implements Arrayable, JsonSerializable, MessageInterface |
14 | 14 | { |
15 | | - use HasFlags, HasParsedMessage; |
| 15 | + use HasFlags, HasParsedMessage { |
| 16 | + text as protected getParsedText; |
| 17 | + html as protected getParsedHtml; |
| 18 | + attachments as protected getParsedAttachments; |
| 19 | + } |
16 | 20 |
|
17 | 21 | /** |
18 | 22 | * The parsed body structure. |
@@ -108,12 +112,16 @@ public function hasBody(): bool |
108 | 112 | /** |
109 | 113 | * Get the message's body structure. |
110 | 114 | */ |
111 | | - public function bodyStructure(): ?BodyStructureCollection |
| 115 | + public function bodyStructure(bool $lazy = false): ?BodyStructureCollection |
112 | 116 | { |
113 | 117 | if ($this->bodyStructure) { |
114 | 118 | return $this->bodyStructure; |
115 | 119 | } |
116 | 120 |
|
| 121 | + if (! $this->bodyStructureData && $lazy) { |
| 122 | + $this->bodyStructureData = $this->fetchBodyStructureData(); |
| 123 | + } |
| 124 | + |
117 | 125 | if (! $tokens = $this->bodyStructureData?->tokens()) { |
118 | 126 | return null; |
119 | 127 | } |
@@ -218,6 +226,67 @@ public function move(string $folder, bool $expunge = false): ?int |
218 | 226 | } |
219 | 227 | } |
220 | 228 |
|
| 229 | + /** |
| 230 | + * Get the message's text content. |
| 231 | + */ |
| 232 | + public function text(bool $lazy = false): ?string |
| 233 | + { |
| 234 | + if ($lazy && ! $this->hasBody()) { |
| 235 | + if ($part = $this->bodyStructure(lazy: true)?->text()) { |
| 236 | + return Support\BodyPartDecoder::text($part, $this->bodyPart($part->partNumber())); |
| 237 | + } |
| 238 | + } |
| 239 | + |
| 240 | + return $this->getParsedText(); |
| 241 | + } |
| 242 | + |
| 243 | + /** |
| 244 | + * Get the message's HTML content. |
| 245 | + */ |
| 246 | + public function html(bool $lazy = false): ?string |
| 247 | + { |
| 248 | + if ($lazy && ! $this->hasBody()) { |
| 249 | + if ($part = $this->bodyStructure(lazy: true)?->html()) { |
| 250 | + return Support\BodyPartDecoder::text($part, $this->bodyPart($part->partNumber())); |
| 251 | + } |
| 252 | + } |
| 253 | + |
| 254 | + return $this->getParsedHtml(); |
| 255 | + } |
| 256 | + |
| 257 | + /** |
| 258 | + * Get the message's attachments. |
| 259 | + * |
| 260 | + * @return Attachment[] |
| 261 | + */ |
| 262 | + public function attachments(bool $lazy = false): array |
| 263 | + { |
| 264 | + if ($lazy && ! $this->hasBody()) { |
| 265 | + return $this->getLazyAttachments(); |
| 266 | + } |
| 267 | + |
| 268 | + return $this->getParsedAttachments(); |
| 269 | + } |
| 270 | + |
| 271 | + /** |
| 272 | + * Get attachments using lazy loading from body structure. |
| 273 | + * |
| 274 | + * @return Attachment[] |
| 275 | + */ |
| 276 | + protected function getLazyAttachments(): array |
| 277 | + { |
| 278 | + return array_map( |
| 279 | + fn (BodyStructurePart $part) => new Attachment( |
| 280 | + $part->filename(), |
| 281 | + $part->id(), |
| 282 | + $part->contentType(), |
| 283 | + $part->disposition()?->type()?->value, |
| 284 | + new Support\LazyBodyPartStream($this, $part), |
| 285 | + ), |
| 286 | + $this->bodyStructure(lazy: true)?->attachments() ?? [] |
| 287 | + ); |
| 288 | + } |
| 289 | + |
221 | 290 | /** |
222 | 291 | * Fetch a specific body part by part number. |
223 | 292 | */ |
@@ -296,4 +365,27 @@ public function isEmpty(): bool |
296 | 365 | { |
297 | 366 | return ! $this->hasHead() && ! $this->hasBody(); |
298 | 367 | } |
| 368 | + |
| 369 | + /** |
| 370 | + * Fetch the body structure data from the server. |
| 371 | + */ |
| 372 | + protected function fetchBodyStructureData(): ?ListData |
| 373 | + { |
| 374 | + $response = $this->folder |
| 375 | + ->mailbox() |
| 376 | + ->connection() |
| 377 | + ->bodyStructure($this->uid); |
| 378 | + |
| 379 | + if ($response->isEmpty()) { |
| 380 | + return null; |
| 381 | + } |
| 382 | + |
| 383 | + $data = $response->first()->tokenAt(3); |
| 384 | + |
| 385 | + if (! $data instanceof ListData) { |
| 386 | + return null; |
| 387 | + } |
| 388 | + |
| 389 | + return $data->lookup('BODYSTRUCTURE'); |
| 390 | + } |
299 | 391 | } |
0 commit comments