protected static function _getStructure($header, $body, array $opts = array())
{
$opts = array_merge(array('ctype' => 'text/plain', 'forcemime' => false, 'level' => 0, 'no_body' => false), $opts);
/* Parse headers text into a Horde_Mime_Headers object. */
$hdrs = Horde_Mime_Headers::parseHeaders($header);
$ob = new Horde_Mime_Part();
/* This is not a MIME message. */
if (!$opts['forcemime'] && !isset($hdrs['MIME-Version'])) {
$ob->setType('text/plain');
if ($len = strlen($body)) {
if ($opts['no_body']) {
$ob->setBytes($len);
} else {
$ob->setContents($body);
}
}
return $ob;
}
/* Content type. */
if ($tmp = $hdrs['Content-Type']) {
$ob->setType($tmp->value);
foreach ($tmp->params as $key => $val) {
$ob->setContentTypeParameter($key, $val);
}
} else {
$ob->setType($opts['ctype']);
}
/* Content transfer encoding. */
if ($tmp = $hdrs['Content-Transfer-Encoding']) {
$ob->setTransferEncoding(strval($tmp));
}
/* Content-Description. */
if ($tmp = $hdrs['Content-Description']) {
$ob->setDescription(strval($tmp));
}
/* Content-Disposition. */
if ($tmp = $hdrs['Content-Disposition']) {
$ob->setDisposition($tmp->value);
foreach ($tmp->params as $key => $val) {
$ob->setDispositionParameter($key, $val);
}
}
/* Content-Duration */
if ($tmp = $hdrs['Content-Duration']) {
$ob->setDuration(strval($tmp));
}
/* Content-ID. */
if ($tmp = $hdrs['Content-Id']) {
$ob->setContentId(strval($tmp));
}
if (($len = strlen($body)) && $ob->getPrimaryType() != 'multipart') {
if ($opts['no_body']) {
$ob->setBytes($len);
} else {
$ob->setContents($body);
}
}
if (++$opts['level'] >= self::NESTING_LIMIT) {
return $ob;
}
/* Process subparts. */
switch ($ob->getPrimaryType()) {
case 'message':
if ($ob->getSubType() == 'rfc822') {
$ob[] = self::parseMessage($body, array('forcemime' => true, 'no_body' => $opts['no_body']));
}
break;
case 'multipart':
$boundary = $ob->getContentTypeParameter('boundary');
if (!is_null($boundary)) {
foreach (self::_findBoundary($body, 0, $boundary) as $val) {
if (!isset($val['length'])) {
break;
}
$subpart = substr($body, $val['start'], $val['length']);
$hdr_pos = self::_findHeader($subpart, self::EOL);
$ob[] = self::_getStructure(substr($subpart, 0, $hdr_pos), substr($subpart, $hdr_pos + 2), array('ctype' => $ob->getSubType() == 'digest' ? 'message/rfc822' : 'text/plain', 'forcemime' => true, 'level' => $opts['level'], 'no_body' => $opts['no_body']));
}
}
break;
}
return $ob;
}