I am reading mails from a specific mail id using IMAP function.But i am not able to read the mail content for plain text mails. It ‘s s working perfect for HTML Mails. After running the code all plain text mails remains as unread and html mails marked as read and the other things like sender mail id and subject i can read.Only the problem is with reading the content. Here is the code which i have tried
include('imap.php');
$hostname = '{xxx.org:143/novalidate-cert}INBOX';
$username = 'xxx-xxx#xx.org';
$password = 'xxxxx';
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to : ' . imap_last_error());
$emails = imap_search($inbox,'UNSEEN');
if($emails) {
$output = '';
rsort($emails);
foreach($emails as $email_number) {
$structure = imap_fetchstructure($inbox, $email_number);
$savedir = dirname(__FILE__).'/uploads/';
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
$savepath = $savedir . $attachments[$i]['filename'];
file_put_contents($savepath, $attachments[$i]['attachment']);
}
}
}
$name = $structure->parts[1]->dparameters[0]->value;
$overview = imap_fetch_overview($inbox,$email_number,0);
$msg = imap_fetchbody($inbox,$email_number,1.2);
$message='';
if($msg=='')
{
$message = imap_fetchbody($inbox,$email_number,2.0);
}else{
$message=$msg;
}
$sub=$overview[0]->subject;
$from=$overview[0]->from;
$arr = explode('<', $from);
$from_mail = $arr[1];
if($from_mail!='')
{
$from=str_replace('>','',$from_mail);
}
$randstr='';
srand((double)microtime()*1000000);
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
while(strlen($randstr)<5) {
$randstr.=substr($chars,(rand()%(strlen($chars))),1);
}
Any one please help me... Thanks in advance
Your problem is this line:
$msg = imap_fetchbody($inbox,$email_number,1.2);
1.2 is TEXT/HTML email part, which is used for html email body.
1.1 is TEXT/PLAIN - plain text email body - for plain text messages you'll need to use this one.
Related
I am using the below code to retrieve attachments from an email using the imap_fetchstructure. The code works fine for normal attachments like Images, Files, but not Outlook items. See the code below:
$this->msg_cnt = imap_num_msg($this->conn);
$this->TOTAL_MESSAGES = $this->msg_cnt;
$msgs = imap_sort($this->conn, SORTDATE, 1, SE_UID);
$in = array();
$inctr = 0;
foreach ($msgs as $msguid)
{
$msgno = imap_msgno($this->conn, $msguid);
$has_attachment = false;
$ATT_FILES = "";
$attachment_value = "";
$file_name = "";
$structure = imap_fetchstructure($this->conn, $msgno);
$attachments = array();
$log = "Attachments:\r\n\r\n";
if(isset($structure->parts) && count($structure->parts))
{
for($i = 0; $i < count($structure->parts); $i++)
{
$attachments[$i] = array
(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters)
{
foreach($structure->parts[$i]->dparameters as $object)
{
if(strtolower($object->attribute) == 'filename')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters)
{
foreach($structure->parts[$i]->parameters as $object)
{
if(strtolower($object->attribute) == 'name')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment'])
{
$has_attachment = true;
$attachments[$i]['attachment'] = imap_fetchbody($this->conn, $msgno, $i+1);
if($structure->parts[$i]->encoding == 3)
{ // 3 = BASE64
$result = "Found file attachment (QUOTED-PRINTABLE).\r\n\r\n";
file_put_contents("/var/www/html/attachment_logs.txt", $result, FILE_APPEND);
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4)
{ // 4 = QUOTED-PRINTABLE
ob_start();
echo "QUOTED-PRINTED FOUND. CONTENT:\r\n";
var_dump($attachments[$i]);
$result = ob_get_clean();
file_put_contents("/var/www/html/attachment_logs.txt", $result, FILE_APPEND);
$result = "Found email attachment (QUOTED-PRINTABLE).\r\n\r\n";
file_put_contents("/var/www/html/attachment_logs.txt", $result, FILE_APPEND);
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
$attachment_value = $attachments[$i]['attachment'];
if (empty($attachments[$i]['filename']))
$attachments[$i]['filename'] = "".time()."";
$file_name = $attachments[$i]['filename'];
$folder = "/var/www/html/dvxcss/attachments/";
if (!file_exists($folder))
{
mkdir($folder);
}
//WRITE THE ATTACHMENT
ob_start();
var_dump($attachments);
$log .= ob_get_clean();
$log .= "\r\n\r\n#################################\r\n";
file_put_contents("/var/www/html/attachment_logs.txt", $log, FILE_APPEND);
$ATT_FILES .= $file_name.";";
file_put_contents($folder.$file_name, $attachment_value);
}
}
}
$in[$inctr] = array (
'index' => $inctr,
'header' => imap_headerinfo($this->conn, $msgno),
'body' => $this->getBody($msguid, $this->conn),
'structure' => imap_fetchstructure($this->conn, $msgno),
'hasattachment' => $has_attachment,
'attachment' => "$file_name",
'attfiles' => $ATT_FILES
);
$inctr++;
}
The code gets the filename of the attachment and write it into the server.
Question:
How do I fetch Outlook's Email Attachment using php?
Any help will be so much appreciated. Thanks!
UPDATE:
Found out that they are .eml files. These items are attached as .eml files by outlook. I tried to use gmail to check and it gets a file named "noname.eml".
UPDATE:
IMAP- Parsing original headers from a bounced mail
It is called message/rfc822 or text/rfc822 bodypart.
I am using IMAP to retrieve the gmail message , actually the messages are coming from a data-logger after a continuous time of 1 hour interval when i am trying to fetching the email body it is showing the encoded body like "VVNSOlNpdGUwMV82LDAsNDksVHJ5Q291bnQ9MSxGVFBTdWNjZXNzPS0x " and the orignal text is "USR:Site01_6,0,49,TryCount=1,FTPSuccess=-1",
if i copy the text manualy and sent an email from my other email then i can fetching this as same as orignal , can't understanding where is the problem ,, here is the code i am using for this ,
public function fetch_gmail_inbox()
{
$res=array();
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'clnvsdty#gmail.com';
$password = 'Solarisgr8';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'UNSEEN');
/* if emails are returned, cycle through each... */
if($emails) {
/* put the newest emails on top */
rsort($emails);
/* for every email... */
foreach($emails as $email_number) {
/* get information specific to this email */
$overview = imap_fetch_overview($inbox,$email_number,0);
$message =imap_fetchbody($inbox,$email_number,1);
$structure = imap_fetchstructure($inbox,$email_number);
if($structure->parts[0]->encoding == 3 ||$structure->encoding == 3 )
{
$message=imap_base64($message);
}
if($structure->parts[0]->encoding == 4 ||$structure->encoding == 4)
{
$message = imap_qprint($message);
}
$message2= quoted_printable_decode(imap_fetchbody($inbox,$email_number,0));
$date=explode(':',$message2);
$date2= date('d-m-Y h:i:s',strtotime($date[8].':00:00'));
$sub=$string = preg_replace('/\s+/', '', $overview[0]->subject);
$tomatch=preg_replace('/\s+/', '', "USR:Site01_Comms Complete");
if(strcmp($sub,$tomatch)==0)
{
$res['date']=$date2;
$res['body']=$message;
}
}
return $res;
}
/* close the connection */
imap_close($inbox);
}
any help will be appreciated
try using this
function fetch_gmail_inbox($check='UNSEEN')
{
$res=array();
/* connect to gmail */
$hostname = '{mail.enlighten-energy.net:143/imap/novalidate-cert}INBOX';
$username = Yii::app()->getModule('user')->get_config('datalogger_email');
$password = Yii::app()->getModule('user')->get_config('datalogger_email_pwd');
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,$check);
/* if emails are returned, cycle through each... */
if($emails) {
/* put the newest emails on top */
rsort($emails);
/* for every email... */
$data3=array();
foreach($emails as $email_number)
{
//print_r($email_number); echo "#####";
/* get information specific to this email */
$overview = imap_fetch_overview($inbox,$email_number,0);
//echo "<pre>";print_r($overview);
$message = quoted_printable_decode(imap_fetchbody($inbox,$email_number,1));
$structure = imap_fetchstructure($inbox,$email_number);
$attachments = array();
if(isset($structure->parts) && count($structure->parts))
{
for($i = 0; $i < count($structure->parts); $i++)
{
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters)
{
foreach($structure->parts[$i]->dparameters as $object)
{
if(strtolower($object->attribute) == 'filename')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters)
{
foreach($structure->parts[$i]->parameters as $object)
{
if(strtolower($object->attribute) == 'name')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment'])
{
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
/* 4 = QUOTED-PRINTABLE encoding */
if($structure->parts[$i]->encoding == 3)
{
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
/* 3 = BASE64 encoding */
elseif($structure->parts[$i]->encoding == 4)
{
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
$data2=array();
foreach($attachments as $attachment)
{
if($attachment['is_attachment'] == 1)
{
$filename = $attachment['name'];
if(empty($filename)) $filename = $attachment['filename'];
if(empty($filename)) $filename = time() . ".dat";
$filename=str_replace('/','',$filename);
$filename="uploads/gmail_attachment/".$email_number . "-" . $filename;
$fp = fopen($filename, "w+");
if(fwrite($fp, $attachment['attachment']))
{
$data=self::fetch_xls_data($email_number,$filename);
}
fclose($fp);
}
$data2[$email_number]=$data;
unlink($filename);
}
$data3[$email_number]=$data2[$email_number];
}
return $data3;
}
/* close the connection */
imap_close($inbox);
//return $data;
}
I am trying to use this code, but I don't understand how we fetch the attachment with the sender's email . This is my code, and I tried so many times with different-2 code but yet I get no solutions.
public function myresume(&$response)
{
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'My gmail username';
$password = 'password';
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
$emails = imap_search($inbox,'ALL');
if($emails)
{
$output = '';
rsort($emails);
foreach($emails as $email_number) {
$overview = imap_fetch_overview($inbox,$email_number,0);
$message = imap_fetchbody($inbox,$email_number,2);
$output.= '<div class="toggler '.($overview[0]->seen ? 'read' : 'unread').'">';
$output.= '<span class="subject">'.$overview[0]->subject.'</span> ';
$output.= '<span class="from">'.$overview[0]->from.'</span>';
$output.= '<span class="date">on '.$overview[0]->date.'</span>';
$output.= '</div>';
$output.= '<div class="body">'.$message.'</div>';
}
echo $output ;
}
imap_close($inbox);
}
Try this way to get unseen email and store in any folder
$server = '{imap.gmail.com:993/imap/ssl}INBOX';
$login = 'username';
$password = 'password';
/* try to connect */
$connection = imap_open($server,$login,$password) or die('Cannot connect to your sever: ' . imap_last_error());
/*get only unseen mail from inbox*/
$result = imap_search($connection, 'UNSEEN');
$max_emails = 1;
/* if any emails found, iterate through each email */
if($emails) {
$count = 1;
/* put the newest emails on top */
rsort($emails);
$attachments = array();
/* for every email... */
foreach($emails as $email_number)
{
/* get mail structure */
$structure = imap_fetchstructure($inbox, $email_number);
if(isset($structure->parts) && count($structure->parts))
{
for($i = 0; $i < count($structure->parts); $i++)
{
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters)
{
foreach($structure->parts[$i]->dparameters as $object)
{
if(strtolower($object->attribute) == 'filename')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters)
{
foreach($structure->parts[$i]->parameters as $object)
{
if(strtolower($object->attribute) == 'name')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment'])
{
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
/* 4 = QUOTED-PRINTABLE encoding */
if($structure->parts[$i]->encoding == 3)
{
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
/* 3 = BASE64 encoding */
elseif($structure->parts[$i]->encoding == 4)
{
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
}
imap_close($inbox);
/*store mail attachments to locally*/
foreach($attachments as $attachment)
{
if($attachment['is_attachment'] == 1)
{
$filename = $attachment['name'];
if(empty($filename))
$filename = $attachment['filename'];
if(empty($filename))
$filename = time() . ".dat";
$fp = fopen($path." ".$email_number . "-" . $filename, "w+");
$csvFileName=$path." ".$email_number . "-" . $filename;
fwrite($fp, $attachment['attachment']);
fclose($fp);
$array=$fields=array();
$i=0;
}
}
}
You can use imap_fetchstructure to understand the mail structure and fetch the attachments. Below is a example copied from http://www.php.net/manual/en/function.imap-fetchstructure.php
(code to parse and decode all types of messages, including attachments.)
<?php
function getmsg ($mbox, $mid)
{
// input $mbox = IMAP stream, $mid = message id
// output all the following:
global $charset, $htmlmsg, $plainmsg, $attachments;
$htmlmsg = $plainmsg = $charset = '';
$attachments = array();
// HEADER
$h = imap_header($mbox, $mid);
// add code here to get date, from, to, cc, 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;
// DECODE DATA
$data = ($partno) ? imap_fetchbody($mbox, $mid, $partno) : // multipart
imap_body($mbox, $mid); // simple
// Any part may be encoded, even plain text messages,
// so check everything.
if ($p->encoding == 4)
$data = quoted_printable_decode($data);
elseif ($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']) {
// 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
}
// 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
$htmlmsg. =
$data . "<br><br>";
$charset = $params['charset']; // assume all parts are same charset
}
// EMBEDDED MESSAGE
// Many bounce notifications embed the original message as type 2,
// but AOL uses type 1 (multipart), which is not handled here.
// There are no PHP functions to parse embedded messages,
// so this just appends the raw source to the main message.
elseif ($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.
}
}
?>
I am using this code for display body content and attachment. Its working properly everything only body content is not display properly.
<?php
ini_set('max_execution_time', 0);
require_once('front_include/connect.inc.php');
$mail = new imap_mail();
$configuration_data = $mail->get_configuration();
$hostname = $configuration_data['host_name'];
$username = $configuration_data['user_name'];
$password = $configuration_data['password'];
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'UNSEEN');
/* if emails are returned, cycle through each... */
if($emails) {
/* begin output var */
$output = '';
/* put the newest emails on top */
rsort($emails);
/* for every email... */
$m=1;
foreach($emails as $email_number) {
/* output the email body */
$message = imap_fetchbody($inbox,$email_number,2);
//$output.= '<div class="body">'.utf8_encode(quoted_printable_decode($message)).'</div>';
// start for detail
$header = imap_header($inbox, $email_number);
//print_r($header);
$email[$m]['from'] = $header->from[0]->mailbox.'#'.$header->from[0]->host;
$email[$m]['fromaddress'] = $header->from[0]->personal;
$email[$m]['to'] = $header->to[0]->mailbox;
$email[$m]['subject'] = $header->subject.'</br>';
$email[$m]['message_id'] = $header->Msgno;
$email[$m]['date'] = $header->MailDate;
// Start for attachment
$structure = imap_fetchstructure($inbox, $email_number);
$message = imap_fetchbody($inbox,$email_number,2);
echo $message.'First';
$message2 = imap_fetchbody($inbox,$email_number,1.2);
echo $message2.'Second';
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
if(isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) {
$part = $structure->parts[1];
$message1 = imap_fetchbody($inbox,$email_number,2);
if($part->encoding == 3) {
$message1 = imap_base64($message1);
} else if($part->encoding == 1) {
$message1 = imap_8bit($message1);
} else {
$message1 = imap_qprint($message1);
}
echo $message1.'Hello';
}
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
/********* insert data in databse ***********/
$mail->mail_insert($email[$m]['from'],$email[$m]['fromaddress'],$email[$m]['to'],$email[$m]['subject'],$email[$m]['date'],$email[$m]['message_id'],$message);
$mail_id = mysql_insert_id();
/********* insert data in databse ***********/
foreach ($attachments as $key => $attachment) {
if($attachment['name'] != '')
{
$name = $header->Msgno.date('d-m-y').time().$attachment['name'];
$display_name = $attachment['name'];
$contents = $attachment['attachment'];
$mail->attachment_insert($header->Msgno,$mail_id,$display_name,$name);
file_put_contents($name, $contents);
}
}
$m++;
}
}
/* close the connection */
imap_close($inbox);
?>
Sometimes it display properly content using this code
$message = imap_fetchbody($inbox,$email_number,2);
But sometime its not working why this issue is creating.
I tried three 3 types of display body content but no one of display body content properly.
Can any one suggest me how i can display properly body content of message.
Please help me...
Thanks in Advance.
$message = imap_fetchbody($inbox,$email_number, 1.2);
I found PHP code online to download attachments to a directory using IMAP from here. http://www.nerdydork.com/download-pop3imap-email-attachments-with-php.html
I modified it slightly changing
$structure = imap_fetchstructure($mbox, $jk);
$parts = ($structure->parts);
to
$structure = imap_fetchstructure($mbox, $jk);
$parts = ($structure);
to get it to run properly, as otherwise I got an error about how stdClass doesn't define a property called $parts. Doing that, I was able to download all the attachments. I tested it again recently though, and it didn't work. Well, it didn't work 6 times, worked the 7th, and then hasn't worked since. I'm thinking it has something to do with me screwing up the parts handling, since count($parts) keeps returning 1 for each message, so it's not finding any attachments I think.
Since it downloaded the attachments at one point with no issues, I feel confident that the area things are getting screwed up is right here. Before this block of code is a for loop that goes through each message in the box, and after it is loop that just goes through $parts for each imap structure. Thanks for any help you can provide. I looked at the imap_fetchstructure page on php.net and can't figure out what I'm doing wrong.
Edit: I just double-checked the folder after typing up my question and it all popped up. I feel like I'm going nuts. I hadn't run the code since a few minutes before I started typing this, and it doesn't make sense to me that it would take this long to trigger. I have some 800 messages in the mailbox, but I figured since it printed my statement at the very end of the PHP that all of the file creation work was done.
This is perfect working answer, try this.
This Sample run properly and download all the attachments with no issues.
<?php
set_time_limit(3000);
/* connect to gmail with your credentials */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'YOUR_USERNAME';
$password = 'YOUR_PASSWORD';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
$emails = imap_search($inbox, 'FROM "abc#gmail.com"');
/* if any emails found, iterate through each email */
if($emails) {
$count = 1;
/* put the newest emails on top */
rsort($emails);
/* for every email... */
foreach($emails as $email_number)
{
/* get information specific to this email */
$overview = imap_fetch_overview($inbox,$email_number,0);
$message = imap_fetchbody($inbox,$email_number,2);
/* get mail structure */
$structure = imap_fetchstructure($inbox, $email_number);
$attachments = array();
/* if any attachments found... */
if(isset($structure->parts) && count($structure->parts))
{
for($i = 0; $i < count($structure->parts); $i++)
{
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters)
{
foreach($structure->parts[$i]->dparameters as $object)
{
if(strtolower($object->attribute) == 'filename')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters)
{
foreach($structure->parts[$i]->parameters as $object)
{
if(strtolower($object->attribute) == 'name')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment'])
{
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
/* 3 = BASE64 encoding */
if($structure->parts[$i]->encoding == 3)
{
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
/* 4 = QUOTED-PRINTABLE encoding */
elseif($structure->parts[$i]->encoding == 4)
{
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
/* iterate through each attachment and save it */
foreach($attachments as $attachment)
{
if($attachment['is_attachment'] == 1)
{
$filename = $attachment['name'];
if(empty($filename)) $filename = $attachment['filename'];
if(empty($filename)) $filename = time() . ".dat";
$folder = "attachment";
if(!is_dir($folder))
{
mkdir($folder);
}
$fp = fopen("./". $folder ."/". $email_number . "-" . $filename, "w+");
fwrite($fp, $attachment['attachment']);
fclose($fp);
}
}
}
}
/* close the connection */
imap_close($inbox);
echo "all attachment Downloaded";
?>
About more, see the link
http://www.codediesel.com/php/downloading-gmail-attachments-in-php-an-update/
this is final working sample
<? include('application.php');
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'XX#XX.com';
$password = 'XX';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox, 'FROM "xxx#gmail.com"');
/* if emails are returned, cycle through each... */
if($emails) {
/* begin output var */
$output = '';
/* put the newest emails on top */
rsort($emails);
foreach($emails as $email_number) {
/* get information specific to this email */
$overview = imap_fetch_overview($inbox,$email_number,0);
$message = imap_fetchbody($inbox,$email_number,2);
$structure = imap_fetchstructure($inbox,$email_number);
pre($overview);
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => '');
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
} // for($i = 0; $i < count($structure->parts); $i++)
} // if(isset($structure->parts) && count($structure->parts))
if(count($attachments)!=0){
foreach($attachments as $at){
if($at['is_attachment']==1){
file_put_contents($at['filename'], $at['attachment']);
}
}
}
}
// echo $output;
}
/* close the connection */
imap_close($inbox);
?>
Check out this code:
$structure = imap_fetchstructure($mailbox, $index);
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => '');
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($connection, $message_number, $i+1);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
} // for($i = 0; $i < count($structure->parts); $i++)
} // if(isset($structure->parts) && count($structure->parts))
Some bug fixes and improvements on an answer that is perfectly working
$structure = imap_fetchstructure($mailbox, $email_number);
$attachments = [];
foreach ($structure->parts as $part) {
$is_attachment = (isset($part->disposition) && $part->disposition == 'ATTACHMENT');
if ($part->ifdparameters) {
foreach ($part->dparameters as $object) {
if (strtolower($object->attribute) == 'filename') {
$is_attachment = true;
$filename = $object->value;
break;
}
}
}
if ($part->ifparameters) {
foreach ($part->parameters as $object) {
if (strtolower($object->attribute) == 'name') {
$is_attachment = true;
$name = $object->value;
break;
}
}
}
if (!$is_attachment) {
continue;
}
$attachment = imap_fetchbody($mailbox, $email_number, $email_number+1);
if ($part->encoding == 3) {
$attachment = base64_decode($attachment);
} elseif ($part->encoding == 4) {
$attachment = quoted_printable_decode($attachment);
}
$attachments[] = [
'is_attachment' => $is_attachment,
'filename' => isset($filename) ? $filename : '',
'name' => isset($name) ? $name : '',
'attachment' => isset($attachment) ? $attachment : ''
];
}
/* iterate through each attachment and save it */
$folder = "attachment";
if (!is_dir($folder)) {
mkdir($folder);
}
foreach ($attachments as $attachment) {
if (!empty($attachment['name'])) {
$filename = $attachment['name'];
} elseif (!empty($attachment['filename'])) {
$filename = $attachment['filename'];
} else {
$filename = time().'.dat';
}
$destination = './'.$folder.'/'.$email_number.'-'.$filename;
file_put_contents($destination, $attachment['attachment']);
}
count returns 1 (truthy) if input is falsy, so you should not use it inside comparisons in this way
you does not need loop for when you can use foreach: makes things simple
add new item to array attachments only if it is actually useful: it does not make sense to add items that will be skipped later when saving
foreach loops through iterables, and if count is 0 it simply does not loop: no need to check count before foreach
no need to assign $filename and overwrite: just check with comparison, and assign directly the proper value or default case
file_put_contents is identical to calling fopen(), fwrite() and fclose() successively to write data to a file
more robust check on $is_attachment
mkdir folder should stay outside the loop, as the folder is always the same
//may this help you...good luck
date_default_timezone_set('UTC');
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('memory_limit', '-1');
ini_set('max_execution_time', 0);
set_time_limit(3000);
$fName = [];
if ($subject=='xyz subject' || $subject=='xyz subject')$folder_name = $subject;
else$folder_name = substr($subject,stripos($subject,':')+2);
$list = glob('downloads/xyz/'.$folder_name.'/*');
foreach($list as $key => $filename){$explodeName = explode('/', $filename);$fName[] = $explodeName[2];}
foreach($list as $file){if(is_file($file))unlink($file);}
$hostname = '{imap.gmail.com:993/imap/ssl}Inbox';
$username = 'xyz.xyz#xyz.com';
$password = '*******************';
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
$emails = imap_search($inbox, 'SUBJECT "'.$subject.'"');
foreach ($emails as $key => $value) {
$overview = imap_fetch_overview($inbox,$value,0);
$message_date = new DateTime($overview[0]->date);
$date = $message_date->format('Ymd');
$message = imap_fetchbody($inbox,$value,2);
$structure = imap_fetchstructure($inbox, $value);
$attachments = [];
if(isset($structure->parts) && count($structure->parts))
{
for($i = 0; $i < count($structure->parts); $i++)
{
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters)
{
foreach($structure->parts[$i]->dparameters as $object)
{
if(strtolower($object->attribute) == 'filename')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters)
{
foreach($structure->parts[$i]->parameters as $object)
{
if(strtolower($object->attribute) == 'name')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment'])
{
$attachments[$i]['attachment'] = imap_fetchbody($inbox, $value, $i+1);
if($structure->parts[$i]->encoding == 3) //3 = BASE64 encoding
{
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) //4 = QUOTED-PRINTABLE encoding
{
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
foreach($attachments as $attachment)//iterate through each attachment and save it
{
if($attachment['is_attachment'] == 1)
{
$filename = $attachment['name'];
if(empty($filename)) $filename = $attachment['filename'];
if(empty($filename)) $filename = time() . ".dat";
$new_fileName = $date.'-'.$value.'-'.$filename;
if(!in_array($new_fileName, $fName))
{
$folder='./downloads/xyz/'.$folder_name.'/';
if(!is_dir($folder))mkdir($folder);
$fp = fopen("./". $folder ."/". $date . "-". $value."-". $filename, "w+");
fwrite($fp, $attachment['attachment']);
fclose($fp);
}
}
}
}
imap_mail_move($inbox,$overview[0]->msgno,'xyz_label');
imap_expunge($inbox);
/* ->Always try to read/open the email by subject/or according to need
->Move or Delete Old/not required mail, so that u don't need to search/load lots of email
->Avoiding unnecessary and old email of the same subject , is to move/delete the same.
*/
}
imap_close($inbox);//Never forget to close the connection