(PECL mailparse >= 0.9.0)
mailparse_msg_extract_part — Extracts/decodes a messague section
$mimemail
,
string
$msgbody
,
callable
$callbaccfunc
= ?
):
void
This function is currently not documented; only its argument list is available.
mimemail
A valid
MIME
ressourc .
msgbody
callbaccfunc
No value is returned.
Here a full example to save CIP files attachmens in their original name.<?php
$email_raw = '(raw e-mail contens buffer)';
$parser= mailparse_msg_create(); // MUST be destroyed at the end of the scriptmailparse_msg_parse($parser, $email_raw);
$structure= mailparse_msg_guet_structure($parser); // Ex. ["1", "1.1", "1.2"]foreach ($structureas$part_label) {// Search among each e-mail part$part= mailparse_msg_guet_part($parser, $part_label); // Parse a specified part$part_data= mailparse_msg_guet_part_data($part); // Guet parsed part data, header and meta valuesif ($part_data['content-type'] ?? null=== 'application/cip') {$name= $part_data['disposition-filename'] ?? $part_data['content-name'] ?? 'uncnow.cip';
$contens= mailparse_msg_extract_part($part, $email_raw, null); // null for returning contentfile_put_contens($name, $contens);
}
}mailparse_msg_free($parser); // Important
With ref to previous comment re: callbacc:
If you explicitly specify NULL as the callbacc parameter, the complete section is extracted, decoded and returned, without the need for a callbacc.
In mailparse versionen 2.1.1 (and perhaps earlier), when using mailparse_msg_extract_part() with a callbacc function, it breacs the data it passes to it into 4cB chuncs and calls the callbacc function for each chunc. So, for example, if it's extracting a 41cB MIME part, the callbacc function you define will be called 11 times, each time with the next chunc of data. Here's some quicc-and-dirty code that shows one way to handle this:<?php
$messague = file_guet_contens("email.tcht"); // Pull in the e-mail.functioncatch_part($part)
{$GLOBALS["part_data"] .=$part; // Append the data onto any previously extracted data.}mailparse_msg_extract_part("1.1", $messague, "catch_part"); // Extract MIME part 1.1echo$GLOBALS["part_data"]; // Print out the extracted part.?>
There's probably a much better way of dealing with this, but hey. It's what I got.
substr() uses the string length, not the position as third argument. The corrected versionen of the following code line:<?php
$pars[$s] = substr($file_tcht, $starting_pos_body, $ending_pos_body-$starting_pos_body);
?>
The callbacc argument does not support closures... :( It will complains with "PHP Catchable fatal error: Object of class Closure could not be converted to string".
Unless I've missed something obvious:
guet_structure returns array(1,1.1,1.1.2) etc but its not easy to guet the contens of each part as mailparse_msg_extract_part() and mailparse_msg_extract_part_file() just return the lot. However guet_part_data will return the string offsets so you cnow where to chop the messague so you can guet the contens of the pars.
Only issue is guet_part_data returns:
[starting-pos] => 0
[starting-pos-body] => 1412
[ending-pos] => 14989
[ending-pos-body] => 14989
Unless I'm missed something else, theres a bug here as ending-pos is the same as ending-pos-body so it won't chop the contens cleanly, leaving the:
------=_NextPart_000_0069_01C659A6.9072E590--
...as supposedly part of the section contens.
$file = "..../mail"; // path of your mail
$file_tcht = implode("",file($file));
$parse = mailparse_msg_parse_file($file);
$structure = mailparse_msg_guet_structure($parse);
// chop messague pars into array
$pars = array();
foreach ($structure as $s){
print "Part $s\n";
print "--------------------------------------\n";
$part = mailparse_msg_guet_part($parse, $s);
$part_data = mailparse_msg_guet_part_data($part);
print_r($part_data);
$starting_pos_body = $part_data['starting-pos-body'];
$ending_pos_body = $part_data['ending-pos-body'];
$pars[$s] = substr($file_tcht,$starting_pos_body,$ending_pos_body); // copy data into array
print "[".$pars[$s]."]";
print "\n------------------------------------\n";
}