88use DirectoryTree \ImapEngine \Connection \Responses \Data \ListData ;
99use DirectoryTree \ImapEngine \Connection \Responses \MessageResponseParser ;
1010use DirectoryTree \ImapEngine \Exceptions \ImapCapabilityException ;
11+ use DirectoryTree \ImapEngine \Support \BodyPartDecoder ;
1112use DirectoryTree \ImapEngine \Support \Str ;
1213use Illuminate \Contracts \Support \Arrayable ;
14+ use InvalidArgumentException ;
1315use JsonSerializable ;
1416use ZBateson \MailMimeParser \Header \DateHeader ;
1517use ZBateson \MailMimeParser \Header \HeaderConsts ;
@@ -398,7 +400,7 @@ public function text(bool $fetch = false): ?string
398400 {
399401 if ($ fetch && ! $ this ->hasBody ()) {
400402 if ($ part = $ this ->bodyStructure (fetch: true )?->text()) {
401- return Support \ BodyPartDecoder::text ($ part , $ this ->bodyPart ($ part ->partNumber ()));
403+ return BodyPartDecoder::text ($ part , $ this ->bodyPart ($ part ->partNumber ()));
402404 }
403405 }
404406
@@ -416,7 +418,7 @@ public function html(bool $fetch = false): ?string
416418 {
417419 if ($ fetch && ! $ this ->hasBody ()) {
418420 if ($ part = $ this ->bodyStructure (fetch: true )?->html()) {
419- return Support \ BodyPartDecoder::text ($ part , $ this ->bodyPart ($ part ->partNumber ()));
421+ return BodyPartDecoder::text ($ part , $ this ->bodyPart ($ part ->partNumber ()));
420422 }
421423 }
422424
@@ -466,25 +468,39 @@ public function attachmentCount(): int
466468 }
467469
468470 /**
469- * Fetch a specific body part by part number .
471+ * Fetch a body section, optionally limited to a transfer-encoded byte range .
470472 */
471- public function bodyPart (string $ partNumber , bool $ peek = true ): ?string
473+ public function bodyPart (string $ partNumber , bool $ peek = true , int $ offset = 0 , ? int $ length = null ): ?string
472474 {
473- $ key = " BODY[ $ partNumber] " ;
475+ $ item = MessageData:: section ( $ partNumber) ;
474476
475- if ($ peek && $ this ->data ->has ($ key )) {
477+ if ($ length !== null ) {
478+ $ item = $ item ->partial ($ offset , $ length );
479+ } elseif ($ offset !== 0 ) {
480+ throw new InvalidArgumentException ('A partial fetch requires a length. ' );
481+ }
482+
483+ $ key = $ item ->key ();
484+
485+ if ($ length === null && $ peek && $ this ->data ->has ($ key )) {
476486 return $ this ->data ->get ($ key );
477487 }
478488
489+ if ($ length !== null ) {
490+ $ this ->folder ->select ();
491+ }
492+
479493 $ response = $ this ->folder ->mailbox ()
480494 ->connection ()
481- ->fetch ($ this ->uid (), $ peek ? " BODY.PEEK[ $ partNumber ] " : " BODY[ $ partNumber ] " );
495+ ->fetch ($ this ->uid (), ( $ peek ? $ item -> peek () : $ item )-> toImap () );
482496
483497 if (! $ data = $ response ->messages ()[0 ] ?? null ) {
484498 return null ;
485499 }
486500
487- $ this ->data = $ this ->data ->merge ($ data );
501+ if ($ length === null ) {
502+ $ this ->data = $ this ->data ->merge ($ data );
503+ }
488504
489505 return $ data ->get ($ key );
490506 }
0 commit comments