<?php
/**
* Message.class.php
*
* This file contains functions needed to handle mime messages.
*
* @copyright 2003-2020 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id: Message.class.php 14840 2020年01月07日 07:42:38Z pdontthink $
* @package squirrelmail
* @subpackage mime
* @since 1.3.2
*/
/**
* The object that contains a message.
*
* message is the object that contains messages. It is a recursive object in
* that through the $entities variable, it can contain more objects of type
* message. See documentation in mime.txt for a better description of how this
* works.
* @package squirrelmail
* @subpackage mime
* @since 1.3.0
*/
/**
* rfc822header object
* @var object
*/
/**
* Headers from original email in reply
* @var string
*/
/**
* MessageHeader object
* @var object
*/
/**
* @var mixed
*/
/**
* Media type
* @var string
*/
/**
* Media subtype
* @var string
*/
/**
* Nested mime parts
* @var array
*/
/**
* Message part id
* @var string
*/
/**
* Parent message part id
* @var string
*/
/**
* @var mixed
*/
/**
* @var mixed
*/
/**
* @var string
*/
/**
* Message \seen status
* @var boolean
*/
/**
* Message \answered status
* @var boolean
*/
/**
* Message \deleted status
* @var boolean
*/
/**
* Message \flagged status
* @var boolean
*/
/**
* Message mdn status
* @var boolean
*/
/**
* Message text body
* @var string
*/
/**
* Message part offset
* for fetching body parts out of raw messages
* @var integer
*/
/**
* Message part length
* for fetching body parts out of raw messages
* @var integer
*/
/**
* Local attachment filename location where the tempory attachment is
* stored. For use in delivery class.
* @var string
*/
/**
* @param string $ent entity id
*/
}
/**
* Add nested message part
* @param object $msg
*/
}
/**
* Get file name used for mime part
* @return string file name
* @since 1.3.2
*/
$filename = '';
$header = $this->header;
$filename = $header->disposition->getProperty('filename');
if (trim ($filename) ==
'') {
$name =
decodeHeader ($header->disposition->getProperty('name'));
$name = $header->getParameter('name');
if (!trim ( $header->id )) {
} else {
$filename =
'cid: ' .
$header->id .
'.' .
strtolower ($header->type1);
}
} else {
$filename = $name;
}
} else {
$filename = $name;
}
}
} else {
$filename = $header->getParameter('filename');
$filename = $header->getParameter('name');
if (!trim ( $header->id )) {
} else {
$filename =
'cid: ' .
$header->id .
'.' .
strtolower ($header->type1);
}
}
}
}
return $filename;
}
/**
* Add header object to message object.
* WARNING: Unfinished code. Don't expect it to work in older sm versions.
* @param mixed $read array or string with message headers
* @todo FIXME: rfc822header->parseHeader() does not return rfc822header object
*/
}
/**
* @param string $ent
* @return mixed (object or string?)
*/
$msg = $this;
if (($cur_ent == '') || ($cur_ent == '0')) {
$cur_ent_a = array();
} else {
}
for ($i =
0,$entCount =
count ($ent_a) -
1; $i <
$entCount; ++
$i) {
if (isset($cur_ent_a[$i]) && ($cur_ent_a[$i] != $ent_a[$i])) {
$msg = $msg->parent;
$cur_ent_a =
explode ('.', $msg->entity_id);
--$i;
} else if (!isset($cur_ent_a[$i])) {
if (isset($msg->entities[($ent_a[$i]-1)])) {
$msg = $msg->entities[($ent_a[$i]-1)];
} else {
$msg = $msg->entities[0];
}
}
if (($msg->type0 == 'message') && ($msg->type1 == 'rfc822')) {
/*this is a header for a message/rfc822 entity */
$msg = $msg->entities[0];
}
}
if (($msg->type0 == 'message') && ($msg->type1 == 'rfc822')) {
/*this is a header for a message/rfc822 entity */
$msg = $msg->entities[0];
}
if (isset($msg->entities[($ent_a[$entCount])-1])) {
if (is_object ($msg->entities[($ent_a[$entCount])-
1])) {
$msg = $msg->entities[($ent_a[$entCount]-1)];
}
}
return $msg;
}
/**
* Set message body
* @param string $s message body
*/
}
/**
* Clean message object
*/
$msg = $this;
$msg->body_part = '';
foreach ($msg->entities as $m) {
$m->clean_up();
}
}
/**
* @return string
*/
$msg = $this;
$msg = $msg->parent;
}
return $msg->mailbox;
}
/*
* Bodystructure parser, a recursive function for generating the
* entity-tree with all the mime-parts.
*
* It follows RFC2060 and stores all the described fields in the
* message object.
*
* Question/Bugs:
*
* @param string $read
* @param integer $i
* @param mixed $sub_msg
* @return object Message object
* @todo define argument and return types
*/
if($msg) $msg->setEntIds($msg,false,0);
return $msg;
}
/**
* @param object $msg
* @param mixed $init
* @param integer $i
* @todo document me
* @since 1.4.0
*/
function setEntIds (&$msg,$init=
false,$i=
0) {
$iCnt =
count ($msg->entities);
if ($init !==false) {
$iEntSub = $i+1;
if ($msg->parent->type0 == 'message' &&
$msg->parent->type1 == 'rfc822' &&
$msg->type0 == 'multipart') {
$iEntSub = '0';
}
if ($init) {
$msg->entity_id = "$init.$iEntSub";
} else {
$msg->entity_id = $iEntSub;
}
} else if ($iCnt) {
$msg->entity_id='0';
} else {
$msg->entity_id='1';
}
for ($i=0;$i<$iCnt;++$i) {
$msg->entities[$i]->parent =& $msg;
if (strrchr ($msg->entity_id, '.') !=
'.0') {
$msg->entities[$i]->setEntIds($msg->entities[$i],$msg->entity_id,$i);
} else {
$msg->entities[$i]->setEntIds($msg->entities[$i],$msg->parent->entity_id,$i);
}
}
}
/**
* @param string $read
* @param integer $i
* @param mixed $sub_msg
* @return object Message object
* @todo document me
* @since 1.4.0 (code was part of parseStructure() in 1.3.x)
*/
$arg_no = 0;
$arg_a = array();
if ($sub_msg) {
$message = $sub_msg;
} else {
}
for ($cnt =
strlen ($read); $i <
$cnt; ++
$i) {
switch ($char) {
case '(':
switch($arg_no) {
case 0:
if (!isset($msg)) {
$hdr->type0 = 'text';
$hdr->type1 = 'plain';
$hdr->encoding = '7bit';
$msg->header = $hdr;
} else {
$msg->header->type0 = 'multipart';
$msg->type0 = 'multipart';
while ($read{$i} == '(') {
$msg->addEntity($msg->parseBodyStructure($read, $i, $msg));
}
}
break;
case 1:
/* multipart properties */
++$i;
$arg_a[] = $msg->parseProperties($read, $i);
++$arg_no;
break;
case 2:
if (isset($msg->type0) && ($msg->type0 == 'multipart')) {
++$i;
$arg_a[] = $msg->parseDisposition($read, $i);
} else { /* properties */
$arg_a[] = $msg->parseProperties($read, $i);
}
++$arg_no;
break;
case 3:
if (isset($msg->type0) && ($msg->type0 == 'multipart')) {
++$i;
$arg_a[]= $msg->parseLanguage($read, $i);
}
case 7:
if (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822')) {
$msg->header->type0 = $arg_a[0];
$msg->header->type1 = $arg_a[1];
$msg->type0 = $arg_a[0];
$msg->type1 = $arg_a[1];
$msg->rfc822_header = $msg->parseEnvelope($read, $i, $rfc822_hdr);
while (($i < $cnt) && ($read{$i} != '(')) {
++$i;
}
$msg->addEntity($msg->parseBodyStructure($read, $i,$msg));
}
break;
case 8:
++$i;
$arg_a[] = $msg->parseDisposition($read, $i);
++$arg_no;
break;
case 9:
++$i;
if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) {
$arg_a[] = $msg->parseDisposition($read, $i);
} else {
$arg_a[] = $msg->parseLanguage($read, $i);
}
++$arg_no;
break;
case 10:
if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) {
++$i;
$arg_a[] = $msg->parseLanguage($read, $i);
} else {
$i = $msg->parseParenthesis($read, $i);
$arg_a[] = ''; /* not yet described in rfc2060 */
}
++$arg_no;
break;
default:
/* unknown argument, skip this part */
$i = $msg->parseParenthesis($read, $i);
$arg_a[] = '';
++$arg_no;
break;
} /* switch */
break;
case '"':
/* inside an entity -> start processing */
$arg_s = $msg->parseQuote($read, $i);
++$arg_no;
if ($arg_no < 3) {
$arg_s =
strtolower ($arg_s); /* type0 and type1 */
}
$arg_a[] = $arg_s;
break;
case 'n':
case 'N':
/* probably NIL argument */
if ($tmpnil == 'NIL ' || $tmpnil == 'NIL)') {
$arg_a[] = '';
++$arg_no;
$i += 2;
}
break;
case '{':
/* process the literal value */
$arg_a[] = $msg->parseLiteral($read, $i);
++$arg_no;
break;
case '0':
/* process integers */
if ($read{$i} == ' ') { break; }
++$arg_no;
$arg_a[] = $regs[1];
} else {
$arg_a[] = 0;
}
break;
case ')':
$multipart = (isset($msg->type0) && ($msg->type0 == 'multipart'));
if (!$multipart) {
$shifted_args = (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822')));
$hdr->type0 = $arg_a[0];
$hdr->type1 = $arg_a[1];
$msg->type0 = $arg_a[0];
$msg->type1 = $arg_a[1];
$arr = $arg_a[2];
$hdr->parameters = $arg_a[2];
}
$hdr->description = $arg_a[4];
$hdr->entity_id = $msg->entity_id;
$hdr->size = $arg_a[6];
if ($shifted_args) {
$hdr->lines = $arg_a[7];
$s = 1;
} else {
$s = 0;
}
$hdr->md5 = (isset($arg_a[7+$s]) ? $arg_a[7+$s] : $hdr->md5);
$hdr->disposition = (isset($arg_a[8+$s]) ? $arg_a[8+$s] : $hdr->disposition);
$hdr->language = (isset($arg_a[9+$s]) ? $arg_a[9+$s] : $hdr->language);
$msg->header = $hdr;
} else {
$hdr->type0 = 'multipart';
$hdr->type1 = $arg_a[0];
$msg->type0 = 'multipart';
$msg->type1 = $arg_a[0];
$hdr->parameters = (isset($arg_a[1]) ? $arg_a[1] : $hdr->parameters);
$hdr->disposition = (isset($arg_a[2]) ? $arg_a[2] : $hdr->disposition);
$hdr->language = (isset($arg_a[3]) ? $arg_a[3] : $hdr->language);
$msg->header = $hdr;
}
return $msg;
default: break;
} /* switch */
} /* for */
} /* parsestructure */
/**
* @param string $read
* @param integer $i
* @return array
*/
$properties = array();
$prop_name = '';
for (; $read{$i} != ')'; ++$i) {
$arg_s = '';
if ($read{$i} == '"') {
} else if ($read{$i} == '{') {
}
if ($arg_s != '') {
if ($prop_name == '') {
$properties[$prop_name] = '';
} else if ($prop_name != '') {
$properties[$prop_name] = $arg_s;
$prop_name = '';
}
}
}
return $properties;
}
/**
* @param string $read
* @param integer $i
* @param object $hdr MessageHeader object
* @return object MessageHeader object
*/
$arg_no = 0;
$arg_a = array();
++$i;
for ($cnt =
strlen ($read); ($i <
$cnt) &&
($read{$i} !=
')'); ++
$i) {
switch ($char) {
case '"':
++$arg_no;
break;
case '{':
/* temp bugfix (SM 1.5 will have a working clean version)
too much work to implement that version right now */
// --$i;
++$arg_no;
break;
case 'N':
/* probably NIL argument */
$arg_a[] = '';
++$arg_no;
$i += 2;
}
break;
case '(':
/* Address structure (with group support)
* Note: Group support is useless on SMTP connections
* because the protocol doesn't support it
*/
$addr_a = array();
$group = '';
$a=0;
for (; $i < $cnt && $read{$i} != ')'; ++$i) {
if ($read{$i} == '(') {
if (($addr->host == '') && ($addr->mailbox != '')) {
/* start of group */
$group = $addr->mailbox;
$group_addr = $addr;
$j = $a;
} else if ($group && ($addr->host == '') && ($addr->mailbox == '')) {
/* end group */
if ($a == ($j+1)) { /* no group members */
$group_addr->group = $group;
$group_addr->mailbox = '';
$group_addr->personal = "$group: Undisclosed recipients;";
$addr_a[] = $group_addr;
$group ='';
}
} else {
$addr->group = $group;
$addr_a[] = $addr;
}
++$a;
}
}
$arg_a[] = $addr_a;
break;
default: break;
}
}
if (count ($arg_a) >
9) {
$d =
strtr ($arg_a[0], array(' ' =>
' '));
if (!$arg_a[1]) $arg_a[1] =
_ ("(no subject)");
$hdr->date =
getTimeStamp ($d_parts); /* argument 1: date */
$hdr->date_unparsed =
strtr ($d,'<>',' '); /* original date */
$hdr->subject = $arg_a[1]; /* argument 2: subject */
$hdr->from =
is_array ($arg_a[2]) ?
$arg_a[2][0] :
''; /* argument 3: from */
$hdr->sender =
is_array ($arg_a[3]) ?
$arg_a[3][0] :
''; /* argument 4: sender */
$hdr->reply_to =
is_array ($arg_a[4]) ?
$arg_a[4][0] :
''; /* argument 5: reply-to */
$hdr->to = $arg_a[5]; /* argument 6: to */
$hdr->cc = $arg_a[6]; /* argument 7: cc */
$hdr->bcc = $arg_a[7]; /* argument 8: bcc */
$hdr->in_reply_to = $arg_a[8]; /* argument 9: in-reply-to */
$hdr->message_id = $arg_a[9]; /* argument 10: message-id */
}
return $hdr;
}
/**
* @param string $read
* @param integer $i
* @return string
* @todo document me
*/
$lit_cnt = '';
++$i;
$iPos =
strpos ($read,'}',$i);
if ($iPos) {
$lit_cnt =
substr ($read, $i, $iPos -
$i);
$i +=
strlen ($lit_cnt) +
3; /* skip } + \r + \n */
/* Now read the literal */
$s =
($lit_cnt ?
substr ($read,$i,$lit_cnt):
'');
$i += $lit_cnt;
/* temp bugfix (SM 1.5 will have a working clean version)
too much work to implement that version right now */
--$i;
} else { /* should never happen */
$i += 3; /* } + \r + \n */
$s = '';
}
return $s;
}
/**
* function parseQuote
*
* This extract the string value from a quoted string. After the end-quote
* character is found it returns the string. The offset $i when calling
* this function points to the first double quote. At the end it points to
* The ending quote. This function takes care of escaped double quotes.
* "some \"string\""
* ^ ^
* initial $i end position $i
*
* @param string $read
* @param integer $i offset in $read
* @return string string inbetween the double quotes
* @author Marc Groot Koerkamp
*/
$s = '';
$iPos = ++$i;
$iPosStart = $iPos;
while (true) {
$iPos =
strpos ($read,'"',$iPos);
if (!$iPos) break;
if ($iPos && $read{$iPos -1} != '\\') {
$s =
substr ($read,$i,($iPos-
$i));
$i = $iPos;
break;
} else if ($iPos > 1 && $read{$iPos -1} == '\\' && $read{$iPos-2} == '\\') {
// This is an unique situation where the fast detection of the string
// fails. If the quote string ends with \\ then we need to iterate
// through the entire string to make sure we detect the unexcaped
// double quotes correctly.
$s = '';
$bEscaped = false;
$k = 0;
for ($j=
$iPosStart,$iCnt=
strlen ($read);$j<
$iCnt;++
$j) {
$cChar = $read{$j};
switch ($cChar) {
case '\\':
$bEscaped = !$bEscaped;
$s .= $cChar;
break;
case '"':
if ($bEscaped) {
$s .= $cChar;
$bEscaped = false;
} else {
$i = $j;
break 3;
}
break;
default:
if ($bEscaped) {
$bEscaped = false;
}
$s .= $cChar;
break;
}
}
}
++$iPos;
break;
}
}
return $s;
}
/**
* @param string $read
* @param integer $i
* @return object AddressStructure object
*/
$arg_a = array();
for (; $read{$i} != ')'; ++$i) {
switch ($char) {
case '"':
$arg_a[] =
$this->parseQuote ($read, $i); break;
case '{':
$arg_a[] =
$this->parseLiteral ($read, $i); break;
case 'n':
case 'N':
$arg_a[] = '';
$i += 2;
}
break;
default: break;
}
}
if (count ($arg_a) ==
4) {
$adr->personal = $arg_a[0];
$adr->adl = $arg_a[1];
$adr->mailbox = $arg_a[2];
$adr->host = $arg_a[3];
} else {
$adr = '';
}
return $adr;
}
/**
* @param string $read
* @param integer $i
* @param object Disposition object or empty string
*/
$arg_a = array();
for (; $read{$i} != ')'; ++$i) {
switch ($read{$i}) {
case '"':
$arg_a[] =
$this->parseQuote ($read, $i); break;
case '{':
$arg_a[] =
$this->parseLiteral ($read, $i); break;
default: break;
}
}
if (isset($arg_a[0])) {
if (isset($arg_a[1])) {
$disp->properties = $arg_a[1];
}
}
}
/**
* @param string $read
* @param integer $i
* @return object Language object or empty string
*/
/* no idea how to process this one without examples */
$arg_a = array();
for (; $read{$i} != ')'; ++$i) {
switch ($read{$i}) {
case '"':
$arg_a[] =
$this->parseQuote ($read, $i); break;
case '{':
$arg_a[] =
$this->parseLiteral ($read, $i); break;
default: break;
}
}
if (isset($arg_a[0])) {
if (isset($arg_a[1])) {
$lang->properties = $arg_a[1];
}
}
}
/**
* Parse message text enclosed in parenthesis
* @param string $read
* @param integer $i
* @return integer
*/
for ($i++; $read{$i} != ')'; ++$i) {
switch ($read{$i}) {
default: break;
}
}
return $i;
}
/**
* Function to fill the message structure in case the
* bodystructure is not available
* NOT FINISHED YET
* @param string $read
* @param string $type0 message part type
* @param string $type1 message part subtype
* @return string (only when type0 is not message or multipart)
*/
switch ($type0) {
case 'message':
$rfc822_header = true;
$mime_header = false;
break;
case 'multipart':
$rfc822_header = false;
$mime_header = true;
break;
default: return $read;
}
for ($i = 1; $i < $count; ++$i) {
$line =
trim ($body[$i]);
if (($mime_header || $rfc822_header) &&
(preg_match ("/^.*boundary=\"?(.+(?=\")|.+).*/i", $line, $reg))) {
$bnd = $reg[1];
$bndreg = $bnd;
} else if ($rfc822_header && $line == '') {
$rfc822_header = false;
if ($msg->type0 == 'multipart') {
$mime_header = true;
}
}
if ((($line{0} == '-') || $rfc822_header) && isset($boundaries[0])) {
$cnt =
count ($boundaries)-
1;
$bnd = $boundaries[$cnt]['bnd'];
$bndreg = $boundaries[$cnt]['bndreg'];
$regstr = '/^--'."($bndreg)".".*".'/';
$bndend = false;
if (strlen ($line) >
($bndlen +
3)) {
if (($line{$bndlen+2} == '-') && ($line{$bndlen+3} == '-')) {
$bndend = true;
}
}
if ($bndend) {
/* calc offset and return $msg */
//$entStr = CalcEntity("$entStr", -1);
$mime_header = true;
$bnd_end = true;
} else {
$mime_header = true;
$bnd_end = false;
//$entStr = CalcEntity("$entStr", 0);
++$content_indx;
}
} else {
if ($header) { }
}
}
}
}
/**
* @param array $entity
* @param array $alt_order
* @param boolean $strict
* @return array
*/
function findDisplayEntity ($entity =
array(), $alt_order =
array('text/plain', 'text/html'), $strict=
false) {
$found = false;
if ($this->type0 ==
'multipart') {
if($this->type1 ==
'alternative') {
if (count ($msg->entities) ==
0) {
$entity[] = $msg->entity_id;
} else {
$entity = $msg->findDisplayEntity($entity, $alt_order, $strict);
}
$found = true;
}
} else if ($this->type1 ==
'related') { /* RFC 2387 */
foreach ($msgs as $msg) {
if (count ($msg->entities) ==
0) {
$entity[] = $msg->entity_id;
} else {
$entity = $msg->findDisplayEntity($entity, $alt_order, $strict);
}
}
$found = true;
}
} else { /* Treat as multipart/mixed */
if(!(is_object ($ent->header->disposition) &&
strtolower ($ent->header->disposition->name) ==
'attachment') &&
(!isset($ent->header->parameters['filename'])) &&
(!isset($ent->header->parameters['name'])) &&
(($ent->type0 != 'message') && ($ent->type1 != 'rfc822'))) {
$entity = $ent->findDisplayEntity($entity, $alt_order, $strict);
$found = true;
}
}
}
} else { /* If not multipart, then just compare with each entry from $alt_order */
// $alt_order[] = "message/rfc822";
foreach ($alt_order as $alt) {
if( ($alt ==
$type) && isset
($this->entity_id ) ) {
(!isset($this->header->parameters['filename'])) &&
(!isset($this->header->parameters['name'])) &&
(isset
($this->header->disposition) &&
is_object ($this->header->disposition) &&
strtolower ($this->header->disposition->name) !=
'attachment')) {
$found = true;
}
}
}
}
if(!$found) {
if(!(is_object ($ent->header->disposition) &&
strtolower ($ent->header->disposition->name) ==
'attachment') &&
(($ent->type0 != 'message') && ($ent->type1 != 'rfc822'))) {
$entity = $ent->findDisplayEntity($entity, $alt_order, $strict);
$found = true;
}
}
}
if(!$strict && !$found) {
if (($this->type0 ==
'text') &&
if (!is_object ($this->header->disposition) ||
strtolower ($this->header->disposition->name) !=
'attachment') {
}
}
}
}
return $entity;
}
/**
* @param array $alt_order
* @return entity
*/
/* If we are dealing with alternative parts then we */
/* choose the best viewable message supported by SM. */
$best_view = 0;
$entity = null;
$type = $ent->header->type0 . '/' . $ent->header->type1;
if ($type == 'multipart/related') {
$type = $ent->header->getParameter('type');
// Mozilla bug. Mozilla does not provide the parameter type.
if (!$type) $type = 'text/html';
}
$altCount =
count ($alt_order);
for ($j = $best_view; $j < $altCount; ++$j) {
if (($alt_order[$j] == $type) && ($j >= $best_view)) {
$best_view = $j;
$entity = $ent;
}
}
}
return $entity;
}
/**
* @return array
*/
$msgs = array();
$related_type = $this->header->getParameter('type');
// Mozilla bug. Mozilla does not provide the parameter type.
if (!$related_type) $related_type = 'text/html';
for ($i = 0; $i < $entCount; ++$i) {
$type =
$this->entities [$i]->header->type0.
'/'.
$this->entities [$i]->header->type1;
if ($related_type == $type) {
}
}
return $msgs;
}
/**
* @param array $exclude_id
* @param array $result
* @return array
*/
/*
if (($this->type0 == 'message') &&
($this->type1 == 'rfc822') &&
($this->entity_id) ) {
$this = $this->entities[0];
}
*/
$exclude = false;
foreach ($exclude_id as $excl) {
if ($entity->entity_id === $excl) {
$exclude = true;
}
}
if (!$exclude) {
if ($entity->type0 == 'multipart') {
$result = $entity->getAttachments($exclude_id, $result);
} else if ($entity->type0 != 'multipart') {
$result[] = $entity;
}
}
}
} else {
$exclude = false;
foreach ($exclude_id as $excl) {
$exclude =
$exclude ||
($this->entity_id ==
$excl);
}
if (!$exclude) {
$result[] = $this;
}
}
return $result;
}
/**
* Add attachment to message object
* @param string $type attachment type
* @param string $name attachment name
* @param string $location path to attachment
*/
$mime_header->setParameter('name', $name);
if ($pos > 0) {
$mime_header->type0 =
substr ($type, 0, $pos);
$mime_header->type1 =
substr ($type, $pos+
1);
} else {
$mime_header->type0 = $type;
}
$attachment->att_local_name = $location;
$disposition->properties['filename'] = $name;
$mime_header->disposition = $disposition;
$attachment->mime_header = $mime_header;
}
/**
* Delete all attachments from this object from disk.
* @since 1.4.6
*/
$hashed_attachment_dir =
getHashedDir ($username, $attachment_dir);
}
}
// recursively delete attachments from entities contained in this object
for ($i=
0, $entCount=
count ($this->entities );$i<
$entCount; ++
$i) {
$this->entities [$i]->purgeAttachments();
}
}
}