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
Related
I found this code under this question PHP - IMAP: Save Attachment to Specific Folder and it works really well. Thanks for that.
I need a little change regarding the filename. Currently the attachments will be saved with the original filename. But i need as filename the timestamp of the mail. How I need to change the code to do that?
<?php
function getFileExtension($fileName){
$parts=explode(".",$fileName);
return $parts[count($parts)-1];
}
$imap = imap_open($server, $username, $password) or die("imap connection error");
$message_count = imap_num_msg($imap);
for ($m = 1; $m <= $message_count; ++$m){
$header = imap_header($imap, $m);
//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;
$email[$m]['message_id'] = $header->message_id;
$email[$m]['date'] = $header->udate;
$from = $email[$m]['fromaddress'];
$from_email = $email[$m]['from'];
$to = $email[$m]['to'];
$subject = $email[$m]['subject'];
echo $from_email . '</br>';
echo $to . '</br>';
echo $subject . '</br>';
$structure = imap_fetchstructure($imap, $m);
$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($imap, $m, $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']);
}
}
}
}
foreach ($attachments as $key => $attachment) {
$name = $attachment['name'];
$contents = $attachment['attachment'];
file_put_contents($name, $contents);
}
//imap_setflag_full($imap, $i, "\\Seen");
//imap_mail_move($imap, $i, 'Trash');
}
imap_close($imap);
?>
I am connecting through IMAP to get the XLSX attachments from a mailbox so I can convert these spreadsheets to PHP array data with PHPExcel, but when I load the file and convert it to array, the array is empty.
This is the function that gets the attachments from the mails matching the criteria:
public function getEmailAttachments($criteria){
$emails = imap_search($this->inbox, $criteria);
$email_attachments = [];
if($emails) {
rsort($emails);
foreach ($emails as $email_number) {
$attachments = [];
//get Email structure
$structure = imap_fetchstructure($this->inbox, $email_number);
/* 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($this->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']);
}
}
}
}
$email_attachments = array_merge($email_attachments, array_filter($attachments, function($attachment){return $attachment['is_attachment'] == 1;}));
}
}
imap_close($this->inbox);
return $email_attachments;
}
Then this is the function that writes the XLSX files to the server and loads them with PHPExcel to convert them to Array data:
public function getEmailReports(){
$this->loadPhpExcel();
$attachments = parent::getEmailAttachments('FROM "example#example.com"');
//iterate through each attachment and save it
foreach($attachments as $attachment){
$filename = $attachment['name'];
if(empty($filename)) $filename = $attachment['filename'];
$folder = "data/excel";
$file_path = "./". $folder ."/". time() . "-" . $filename;
$fp = fopen($file_path, "w");
fwrite($fp, $attachment['attachment']);
$excelReader = PHPExcel_IOFactory::createReaderForFile($file_path);
$excelObj = $excelReader->load($file_path);
foreach ($excelObj->getWorksheetIterator() as $worksheet) {
$worksheets[$worksheet->getTitle()] = $worksheet->toArray();
}
fclose($fp);
print_r($worksheets); //ARRAY IS EMPTY HERE
//unlink($file_path);
}
}
I opened the XLSX file with WinRAR and found out that the xl/worbooks.xml file has a "S" namespace:
<?xml version="1.0"?>
<s:workbook
xmlns:s="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<s:workbookPr/>
<s:bookViews>
<s:workbookView activeTab="0"/>
</s:bookViews>
<s:sheets>
<s:sheet r:id="rId1" sheetId="1" name="Sheet1"/>
<s:sheet r:id="rId2" sheetId="2" name="Sheet2"/>
<s:sheet r:id="rId3" sheetId="3" name="Sheet3"/>
<s:sheet r:id="rId4" sheetId="4" name="Sheet4"/>
</s:sheets>
<s:definedNames/>
<s:calcPr fullCalcOnLoad="1" calcId="124519"/>
</s:workbook>
Then I found this issue on PHPExcel GitHub repo https://github.com/PHPOffice/PHPExcel/issues/571
So all I did was create a class extending from PHPExcel_Reader_Excel2007 to remove the "s" namespace
<?php
class PHPExcel_Reader_Excel2007_XNamespace extends
PHPExcel_Reader_Excel2007
{
public function securityScan($xml)
{
$xml = parent::securityScan($xml);
return str_replace(['<s:', '</s:'], ['<', '</'], $xml);
}
}
and finally replaced this:
$excelReader = PHPExcel_IOFactory::createReaderForFile($file_path);
for this:
$excelReader = new PHPExcel_Reader_Excel2007_XNamespace();
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 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 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.