Voting

: eight plus zero?
(Example: nine)

The Note You're Voting On

ulrich at kaldamar dot de
22 years ago
The function imap_fetchbody() seems uncapable of getting subordinate parts of a message/rfc822-part. I had problems with getting an attachment that was forwarded in such a part, because the object given by imap_fetchstructure() would assume that the part was represented by the string "2.1.2.1.2".

So I wrote this set of functions which parses the raw message-body and creates an array with the struture corresponding to the structure given by imap_fetchstructure(). The function mail_fetchpart() (see below) will work on the array and return even those parts that I could not get with imap_fetchbody().

Example usage of this function: mail_fetchpart($mbox, 2, "2.1.2.1.2");

Note: If the message does not contain multiple pars, the body of the message can be accessed by the part-string "1".
I have more functions for parsing and decoding messages, just email me.

// get the body of a part of a message according to the
// string in $part
function mail_fetchpart($mbox, $msgNo, $part) {
$parts = mail_fetchparts($mbox, $msgNo);

$partNos = explode(".", $part);

$currentPart = $parts;
while(list ($key, $val) = each($partNos)) {
$currentPart = $currentPart[$val];
}

if ($currentPart != "") return $currentPart;
else return false;
}

// splits a message given in the body if it is
// a mulitpart mime message and returns the parts,
// if no parts are found, returns false
function mail_mimesplit($header, $body) {
$parts = array();

$PN_EREG_BOUNDARY = "Content-Type:(.*)boundary=\"([^\"]+)\"";

if (eregi ($PN_EREG_BOUNDARY, $header, $regs)) {
$boundary = $regs[2];

$delimiterReg = "([^\r\n]*)$boundary([^\r\n]*)";
if (eregi ($delimiterReg, $body, $results)) {
$delimiter = $results[0];
$parts = explode($delimiter, $body);
$parts = array_slice ($parts, 1, -1);
}

return $parts;
} else {
return false;
}


}

// returns an array with all parts that are
// subparts of the given part
// if no subparts are found, return the body of
// the current part
function mail_mimesub($part) {
$i = 1;
$headDelimiter = "\r\n\r\n";
$delLength = strlen($headDelimiter);

// get head & body of the current part
$endOfHead = strpos( $part, $headDelimiter);
$head = substr($part, 0, $endOfHead);
$body = substr($part, $endOfHead + $delLength, strlen($part));

// check whether it is a message according to rfc822
if (stristr($head, "Content-Type: message/rfc822")) {
$part = substr($part, $endOfHead + $delLength, strlen($part));
$returnParts[1] = mail_mimesub($part);
return $returnParts;
// if no message, get subparts and call function recursively
} elseif ($subParts = mail_mimesplit($head, $body)) {
// got more subparts
while (list ($key, $val) = each($subParts)) {
$returnParts[$i] = mail_mimesub($val);
$i++;
}
return $returnParts;
} else {
return $body;
}
}

// get an array with the bodies all parts of an email
// the structure of the array corresponds to the
// structure that is available with imap_fetchstructure
function mail_fetchparts($mbox, $msgNo) {
$parts = array();
$header = imap_fetchheader($mbox,$msgNo);
$body = imap_body($mbox,$msgNo, FT_INTERNAL);

$i = 1;

if ($newParts = mail_mimesplit($header, $body)) {
while (list ($key, $val) = each($newParts)) {
$parts[$i] = mail_mimesub($val);
$i++;
}
} else {
$parts[$i] = $body;
}
return $parts;

}

<< Back to user notes page

To Top