Downloading Attachments to Directory with Imap in PHP, Randomly Works

imap - get attached file

You are not providing the correct section number for nested attachments. You need to pass in the section number in the recursive step.

function parse_parts($parts, $parentsection = ""){
foreach($parts as $subsection => $part){
$section = $parentsection . ($subsection + 1);
if(isset($part->parts)){

// some mails have one extra dimension
$this->parse_parts($part->parts, $section . "." );

}
elseif(isset($part->disposition)){
if(in_array(strtolower($part->disposition), array('attachment','inline'))){
$data = imap_fetchbody($this->stream, $this->msgno, $section );
echo 'Getting section ' . $section;
echo $part->dparameters[0]->value.' '.strlen($data)."\n";
}
}
}
}

(Untested, but should do the right thing...)

How to extract the attachments from an IMAP message?

I think what you are saying by a "plain IMAP message" is that you have a sequence of bytes that represent an IMAP message. I'm not aware of any classes built-in to FoundationKit or AppKit which will parse this format and expose the elements of the message (such as the attachment) in the way that you seek. You'll have to either find an existing library for working with IMAP data, or roll up your sleeves and write some code to parse the contents of the email according to the IMAP spec.

How to Download all mail with attachments to server using PHP IMAP?

Please try this code to fetch the email and store attachments in a directory.

You can also delete the mail using imap_delete and imap_expunge, after you have fetched it from the mailbox.

In the below code set your website name, mailbox username, password and path for storing attachments.

if( $mbox = imap_open("{yoursitename.com:110/pop3/notls}INBOX", "username of mailbox", "password of mailbox")){
$path = "set path here for where the attachments are store";
$check = imap_mailboxmsginfo($mbox);
function getmsg($mbox,$mid) {
global $charset,$htmlmsg,$plainmsg,$attachments,$from,$to,$subj,$timages,$path;
$htmlmsg = $plainmsg = $charset = '';
$attachments = array();
// HEADER
$h = imap_headerinfo($mbox,$mid);
// add code here to get date, from, to, cc, subject...
$date = $h->date;
$from = $h->fromaddress;
$to = $h->toaddress;
$subj = htmlspecialchars($h->Subject);
// BODY
$s = imap_fetchstructure($mbox,$mid);
if (!$s->parts) // simple
getpart($mbox,$mid,$s,0); // pass 0 as part-number
else { // multipart: cycle through each part
foreach ($s->parts as $partno0=>$p)
getpart($mbox,$mid,$p,$partno0+1);
}
}

function getpart($mbox,$mid,$p,$partno) {
// $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
global $htmlmsg,$plainmsg,$charset,$attachments,$partid,$last_mail_id,$patterns,$pic,$newstr,$c,$ok,$timages,$subj,$path;
$patterns = array();
$pic = array();
$image=array();
$data = ($partno) ? imap_fetchbody($mbox,$mid,$partno) : imap_body($mbox,$mid); // simple
if ($p->encoding==4)
$data = quoted_printable_decode($data);
else if ($p->encoding==3)
$data = base64_decode($data);
// PARAMETERS // get all parameters, like charset, filenames of attachments, etc.
$params = array();
if ($p->parameters)
foreach ($p->parameters as $x)
$params[strtolower($x->attribute)] = $x->value;
if ($p->dparameters)
foreach ($p->dparameters as $x)
$params[strtolower($x->attribute)] = $x->value;

// ATTACHMENT // Any part with a filename is an attachment,
// so an attached text file (type 0) is not mistaken as the message.
if ($params['filename'] || $params['name']) {
$partid = htmlentities($p->id,ENT_QUOTES);

// filename may be given as 'Filename' or 'Name' or both
$filename = ($params['filename'])? $params['filename'] : $params['name'];
// filename may be encoded, so see imap_mime_header_decode()
$attachments[$filename] = $data; // this is a problem if two files have same name
//store id and filename in array
$image[$key] = $filename;

}
//save the attachments in the directory
foreach( $attachments as $key => $val){
$fname = $key;
$fp = fopen("$path/$fname","w");
fwrite($fp, $val);
fclose($fp);
}
// TEXT
if ($p->type==0 && $data) {
// Messages may be split in different parts because of inline attachments, // so append parts together with blank row.
if (strtolower($p->subtype)=='plain')
$plainmsg .= trim($data)."\n\n";
else
//preg_match_all('/<img[^>]+>/i',$data, $result);
$htmlmsg .= $data."<br><br>";
$charset = $params['charset']; // assume all parts are same charset
}

// There are no PHP functions to parse embedded messages, so this just appends the raw source to the main message.
else if ($p->type==2 && $data) {
$plainmsg .= $data."\n\n";
}
// SUBPART RECURSION
if ($p->parts) {
foreach ($p->parts as $partno0=>$p2)
getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc.
}
}

$attachments = array();
$num_msg = imap_num_msg($mbox);
if($num_msg>0) {
getmsg($mbox,1);
}else {
echo "Sorry!...No Messages in MailBox...<br>";
}

//imap_delete and imap_expunge are used to delete the mail after fetching....Uncomment it if you want to delete the mail from mailbox
//imap_delete($mbox,1);
//imap_expunge($mbox);
imap_close($mbox);

}else { exit ("Can't connect: " . imap_last_error() ."\n"); echo "FAIL!\n"; };


Related Topics



Leave a reply



Submit