99
1010use Sazanof \PhpImapSockets \Collections \AddressesCollection ;
1111use Sazanof \PhpImapSockets \Collections \MessageHeadersCollection ;
12+ use Sazanof \PhpImapSockets \Parts \AttachmentPart ;
1213use Sazanof \PhpImapSockets \Parts \TextPart ;
1314use Sazanof \PhpImapSockets \Query \FetchQuery ;
1415use Sazanof \PhpImapSockets \Response \AttachmentBodyResponse ;
@@ -151,6 +152,22 @@ public function getBody(TextPart $part): bool|string|null
151152 return null ;
152153 }
153154
155+ /**
156+ * @param AttachmentPart $part
157+ * @return string
158+ * @throws \ReflectionException
159+ */
160+ public function getInlineImage (AttachmentPart $ part )
161+ {
162+ if (!is_null ($ this ->mailbox )) {
163+ $ q = new FetchQuery ();
164+ $ body = $ this ->mailbox ->fetch ([$ this ->num ], $ q ->body ($ part ->getSection ()))->asCollection (BodyResponse::class);
165+ $ body = $ body ->getContent ();
166+ return 'data: ' . $ part ->getMimeType () . '; ' . $ part ->getEncoding () . ', ' . str_replace (["\r\n" , "\r" , "\n" ], '' , $ body );
167+ }
168+ return '' ;
169+ }
170+
154171 /**
155172 * @return bool|string|null
156173 * @throws \ReflectionException
@@ -159,12 +176,54 @@ public function getHtmlText(): bool|string|null
159176 {
160177 foreach ($ this ->getBodyStructure ()->getTextParts () as $ textPart ) {
161178 if ($ textPart ->getMimeType () === 'text/html ' ) {
162- return $ this ->getBody ($ textPart );
179+ $ body = $ this ->getBody ($ textPart );
180+ $ contentIds = $ this ->findContentIds ($ body );
181+ if (!empty ($ contentIds )) {
182+ // html part contains inline images
183+ foreach ($ contentIds as $ cid ) {
184+ $ inlinePart = $ this ->getPartByContentId ($ cid );
185+ $ inlineContent = $ this ->getInlineImage ($ inlinePart );
186+ $ body = str_replace ("cid: $ cid " , $ inlineContent , $ body );
187+ }
188+ }
189+ return $ body ;
163190 }
164191 }
165192 return null ;
166193 }
167194
195+ /**
196+ * @param string $cid
197+ * @param MultiPart|null $_part
198+ * @return AttachmentPart|null
199+ */
200+ public function getPartByContentId (string $ cid , MultiPart $ _part = null )
201+ {
202+ $ parts = is_null ($ _part ) ? $ this ->getBodyStructure ()->getParts () : $ _part ->getParts ();
203+ /** @var AttachmentPart $part */
204+ foreach ($ parts ->items () as $ part ) {
205+ if ($ part instanceof AttachmentPart) {
206+ if (strtolower ($ part ->getDisposition ()) === 'inline ' && $ part ->getContentId () === "< $ cid> " ) {
207+ return $ part ;
208+ }
209+ } elseif ($ part instanceof MultiPart) {
210+ return $ this ->getPartByContentId ($ cid , $ part );
211+ }
212+ }
213+ return null ;
214+ }
215+
216+ /**
217+ * @param string $html
218+ * @return mixed|void
219+ */
220+ protected function findContentIds (string $ html )
221+ {
222+ if (preg_match_all ('/src="cid:(.*?)"/ ' , $ html , $ matches )) {
223+ return $ matches [1 ];
224+ }
225+ }
226+
168227 /**
169228 * @param int|null $length
170229 * @return bool|string|null
0 commit comments