Skip to content

Commit 078e1e2

Browse files
fix
1 parent f4bf891 commit 078e1e2

File tree

2 files changed

+208
-63
lines changed

2 files changed

+208
-63
lines changed

src/BodyStructure.php

+204-58
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ protected static function extractPart($item)
8484
return self::extractPartAsAlternative($item);
8585
}
8686

87+
if ($item[1] == 'RFC822') {
88+
return self::extractPartAsRfc822($item);
89+
}
90+
8791
$attribute = null;
8892
$parameters = [];
8993

@@ -109,6 +113,10 @@ protected static function extractPart($item)
109113
$type = 0;
110114
$linesIndex = 7;
111115
$bytesIndex = 6;
116+
if ($item[0] == 'APPLICATION') {
117+
$type = 3;
118+
$linesIndex = 9;
119+
}
112120
if ($item[0] == 'MESSAGE') {
113121
$type = 2;
114122
$linesIndex = 9;
@@ -117,7 +125,7 @@ protected static function extractPart($item)
117125
$type = 5;
118126
$linesIndex = 9;
119127
}
120-
if ($item[1] == 'JPEG') {
128+
if ($item[1] == 'X-ZIP-COMPRESSED') {
121129
#var_dump($item);
122130
#die();
123131
}
@@ -155,14 +163,14 @@ protected static function extractPart($item)
155163
unset($part->description);
156164
}
157165

158-
if ($type == 5) {
166+
if ($type == 5 || $type == 3) {
159167
unset($part->lines);
160168
}
161169

162170
$dispositionIndex = 9;
163171
if ($type == 2) {
164172
$dispositionIndex = 11;
165-
} elseif ($type == 5) {
173+
} elseif ($type == 5 || $type == 3) {
166174
$dispositionIndex = 8;
167175
}
168176
if (isset($item[$dispositionIndex][0])) {
@@ -279,6 +287,14 @@ protected static function processSubParts($item, $part)
279287

280288
protected static function processSubPartAsMessage($item)
281289
{
290+
#file_put_contents('a3.json', json_encode($item, JSON_PRETTY_PRINT));
291+
292+
if (isset($item[8][3]) && is_array($item[8][3])) {
293+
$parameters = self::extractParameters($item[8][3], []);
294+
} else {
295+
$parameters = self::extractParameters($item[8][4], []);
296+
}
297+
282298
$message = (object) [
283299
'type' => 1,
284300
'encoding' => 0,
@@ -289,73 +305,203 @@ protected static function processSubPartAsMessage($item)
289305
'ifdisposition' => 0,
290306
'ifdparameters' => 0,
291307
'ifparameters' => 1,
292-
'parameters' => [
293-
(object) [
294-
'attribute' => 'BOUNDARY',
295-
'value' => '=_995890bdbf8bd158f2cbae0e8d966000'
296-
]
297-
],
298-
'parts' => [
299-
300-
]
308+
'parameters' => $parameters,
309+
'parts' => []
301310
];
302311

303312
foreach ($item[8] as $itemPart) {
313+
if ($itemPart[2] == 'ALTERNATIVE') {
314+
$message->parts[] = self::extractPartAsAlternative($itemPart);
315+
continue;
316+
}
317+
304318
if (!is_array($itemPart[2])) {
305319
continue;
306320
}
307321

308-
$parameters = self::extractParameters($itemPart[2], []);
309-
310-
$part = (object) [
311-
'type' => 0,
312-
'encoding' => self::getEncoding($itemPart, 5),
313-
'ifsubtype' => 1,
314-
'subtype' => 'PLAIN',
315-
'ifdescription' => 0,
316-
'ifid' => 0,
317-
'lines' => intval($itemPart[7]),
318-
'bytes' => intval($itemPart[6]),
319-
'ifdisposition' => 0,
320-
'disposition' => [],
321-
'ifdparameters' => 0,
322-
'dparameters' => [],
323-
'ifparameters' => 1,
324-
'parameters' => $parameters
325-
];
326-
327-
$dispositionParametersIndex = 9;
328-
329-
if (isset($itemPart[$dispositionParametersIndex][0])) {
330-
$attribute = null;
331-
$dispositionParameters = [];
332-
$part->disposition = $itemPart[$dispositionParametersIndex][0];
333-
if (isset($itemPart[$dispositionParametersIndex][1]) && is_array($itemPart[$dispositionParametersIndex][1])) {
334-
foreach ($itemPart[$dispositionParametersIndex][1] as $value) {
335-
if (empty($attribute)) {
336-
$attribute = [
337-
'attribute' => $value,
338-
'value' => null,
339-
];
340-
} else {
341-
$attribute['value'] = $value;
342-
$dispositionParameters[] = (object) $attribute;
343-
$attribute = null;
344-
}
322+
$message->parts[] = self::extractSubPartFromMessage($itemPart);
323+
}
324+
325+
return $message;
326+
}
327+
328+
protected static function extractSubPartFromMessage($itemPart)
329+
{
330+
$parameters = self::extractParameters($itemPart[2], []);
331+
332+
$type = 0;
333+
if ($itemPart[0] == 'APPLICATION') {
334+
$type = 3;
335+
}
336+
337+
$part = (object) [
338+
'type' => $type,
339+
'encoding' => self::getEncoding($itemPart, 5),
340+
'ifsubtype' => 1,
341+
'subtype' => is_string($itemPart[1]) ? $itemPart[1] : 'PLAIN',
342+
'ifdescription' => 0,
343+
'description' => null,
344+
'ifid' => 0,
345+
'lines' => intval($itemPart[7]),
346+
'bytes' => intval($itemPart[6]),
347+
'ifdisposition' => 0,
348+
'disposition' => [],
349+
'ifdparameters' => 0,
350+
'dparameters' => [],
351+
'ifparameters' => 1,
352+
'parameters' => $parameters
353+
];
354+
355+
if ($itemPart[4]) {
356+
$part->ifdescription = 1;
357+
$part->description = $itemPart[4];
358+
} else {
359+
unset($part->description);
360+
}
361+
362+
if ($type == 3) {
363+
unset($part->lines);
364+
}
365+
366+
$dispositionParametersIndex = 9;
367+
if ($type == 3) {
368+
$dispositionParametersIndex = 8;
369+
}
370+
371+
if (isset($itemPart[$dispositionParametersIndex][0])) {
372+
$attribute = null;
373+
$dispositionParameters = [];
374+
$part->disposition = $itemPart[$dispositionParametersIndex][0];
375+
if (isset($itemPart[$dispositionParametersIndex][1]) && is_array($itemPart[$dispositionParametersIndex][1])) {
376+
foreach ($itemPart[$dispositionParametersIndex][1] as $value) {
377+
if (empty($attribute)) {
378+
$attribute = [
379+
'attribute' => $value,
380+
'value' => null,
381+
];
382+
} else {
383+
$attribute['value'] = $value;
384+
$dispositionParameters[] = (object) $attribute;
385+
$attribute = null;
386+
}
387+
}
388+
}
389+
$part->dparameters = $dispositionParameters;
390+
$part->ifdparameters = 1;
391+
$part->ifdisposition = 1;
392+
} else {
393+
unset($part->disposition);
394+
unset($part->dparameters);
395+
}
396+
397+
return $part;
398+
}
399+
400+
protected static function extractPartAsRfc822($item)
401+
{
402+
$parameters = self::extractParameters($item[2], []);
403+
404+
$part = (object) [
405+
'type' => 2,
406+
'encoding' => self::getEncoding($item, 5),
407+
'ifsubtype' => 1,
408+
'subtype' => 'RFC822',
409+
'ifdescription' => 0,
410+
'ifid' => 0,
411+
'lines' => intval($item[9]),
412+
'bytes' => intval($item[6]),
413+
'ifdisposition' => 0,
414+
'disposition' => null,
415+
'ifdparameters' => 0,
416+
'dparameters' => null,
417+
'ifparameters' => $parameters ? 1 : 0,
418+
'parameters' => $parameters ?: (object) [] ,
419+
'parts' => [
420+
self::processSubPartAsMessage($item)
421+
]
422+
];
423+
424+
$dispositionParametersIndex = 11;
425+
426+
if (isset($item[$dispositionParametersIndex][0])) {
427+
$attribute = null;
428+
$dispositionParameters = [];
429+
$part->disposition = $item[$dispositionParametersIndex][0];
430+
if (isset($item[$dispositionParametersIndex][1]) && is_array($item[$dispositionParametersIndex][1])) {
431+
foreach ($item[$dispositionParametersIndex][1] as $value) {
432+
if (empty($attribute)) {
433+
$attribute = [
434+
'attribute' => $value,
435+
'value' => null,
436+
];
437+
} else {
438+
$attribute['value'] = $value;
439+
$dispositionParameters[] = (object) $attribute;
440+
$attribute = null;
345441
}
346442
}
347-
$part->dparameters = $dispositionParameters;
348-
$part->ifdparameters = 1;
349-
$part->ifdisposition = 1;
350-
} else {
351-
unset($part->disposition);
352-
unset($part->dparameters);
353443
}
444+
$part->dparameters = $dispositionParameters;
445+
$part->ifdparameters = 1;
446+
$part->ifdisposition = 1;
447+
} else {
448+
unset($part->disposition);
449+
unset($part->dparameters);
450+
}
451+
452+
return $part;
453+
}
454+
455+
protected static function extractPartAsPlain($itemPart)
456+
{
457+
$parameters = self::extractParameters($itemPart[2], []);
458+
459+
$part = (object) [
460+
'type' => 0,
461+
'encoding' => self::getEncoding($itemPart, 5),
462+
'ifsubtype' => 1,
463+
'subtype' => 'PLAIN',
464+
'ifdescription' => 0,
465+
'ifid' => 0,
466+
'lines' => intval($itemPart[7]),
467+
'bytes' => intval($itemPart[6]),
468+
'ifdisposition' => 0,
469+
'disposition' => [],
470+
'ifdparameters' => 0,
471+
'dparameters' => [],
472+
'ifparameters' => 1,
473+
'parameters' => $parameters
474+
];
475+
476+
$dispositionParametersIndex = 9;
354477

355-
$message->parts[] = $part;
478+
if (isset($itemPart[$dispositionParametersIndex][0])) {
479+
$attribute = null;
480+
$dispositionParameters = [];
481+
$part->disposition = $itemPart[$dispositionParametersIndex][0];
482+
if (isset($itemPart[$dispositionParametersIndex][1]) && is_array($itemPart[$dispositionParametersIndex][1])) {
483+
foreach ($itemPart[$dispositionParametersIndex][1] as $value) {
484+
if (empty($attribute)) {
485+
$attribute = [
486+
'attribute' => $value,
487+
'value' => null,
488+
];
489+
} else {
490+
$attribute['value'] = $value;
491+
$dispositionParameters[] = (object) $attribute;
492+
$attribute = null;
493+
}
494+
}
495+
}
496+
$part->dparameters = $dispositionParameters;
497+
$part->ifdparameters = 1;
498+
$part->ifdisposition = 1;
499+
} else {
500+
unset($part->disposition);
501+
unset($part->dparameters);
356502
}
357-
358-
return $message;
503+
504+
return $part;
359505
}
360506

361507
protected static function extractParameters($attributes, $parameters)

tests/CompatibilityTest.php

+4-5
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ public function testFetchStructure()
544544
*/
545545

546546
$emlFiles = [
547-
#'embedded_email.eml',
547+
'embedded_email.eml',
548548
'embedded_email_without_content_disposition.eml'
549549
];
550550
foreach ($emlFiles as $file) {
@@ -561,12 +561,11 @@ public function testFetchStructure()
561561
$structure2 = imap2_fetchstructure($imap2, 1);
562562
$headerInfo1 = imap_headerinfo($imap1, 1);
563563
$headerInfo2 = imap2_headerinfo($imap2, 1);
564-
file_put_contents('t1.json', json_encode($structure1, JSON_PRETTY_PRINT));
565-
file_put_contents('t2.json', json_encode($structure2, JSON_PRETTY_PRINT));
566-
die();
564+
#file_put_contents('t1.json', json_encode($structure1, JSON_PRETTY_PRINT));
565+
#file_put_contents('t2.json', json_encode($structure2, JSON_PRETTY_PRINT));
566+
#die();
567567
$this->assertEquals($structure1, $structure2);
568568
$this->assertEquals($headerInfo1, $headerInfo2);
569-
570569
}
571570

572571
imap_close($imap1);

0 commit comments

Comments
 (0)