Sunday 9 December 2018

PHP EmailMessage class for extracting attachments

Hi, recently I had to create a php program which fetches emails with attachments (including inline). I searched a lot and succeeded with help of :

https://www.electrictoolbox.com/php-email-extract-inline-image-attachments/
https://www.electrictoolbox.com/php-email-message-class-extracting-attachments/

Though i had to make some changes in the EmailMessage.php to make it work. I am uploading the same file with some necessary changes.

Steps to run the program :
1. Download EmailMessageFinal.php.
2. Enter the email id you want to fetch mails from , in the $login variable at line 31.
     Enter password just below it in the $password variable.
     At line 40, enter the emailUID you want to fetch, you can try setting it to 1 and then change it to any emailUID when you get a hold of it.

3. Just run the php file with WampServer or XAMPP or any software of your choice.

The brower should fetch the email and display it in the same browser window, along with attachments (including inline images) like this :

I am grateful to electricToolBox for sharing this awesome code with us.

I know the presentation of program is very rough. But i hope it helps you do the core part and build the decorations yourself.


Here is the code in EmailMessageFinal.php :

<?php
if (!file_exists("debug/")) {
    $oldmask = umask(0);
    mkdir("debug/", 0777, true);
    umask($oldmask);
}
if (!file_exists("email_files/Inlineimages/")) {
    $oldmask = umask(0);
    mkdir("email_files/Inlineimages/", 0777, true);
    umask($oldmask);
}
if (!file_exists("email_files/attachments/")) {
    $oldmask = umask(0);
    mkdir("email_files/attachments/", 0777, true);
    umask($oldmask);
}


// server needs to be full server connection string, as in the example below
// $server = '{imap.gmail.com:993/ssl/novalidate-cert}';
// another example
// $server = '{pop3.example.com:110/pop3}';
$server = '{imap.gmail.com:993/imap/ssl/novalidate-cert}Inbox';
// $serverPOP = '{pop.gmail.com:995/pop3/ssl}Inbox';
// and put your login and password here
/* $login = 'geniusunil1@gmail.com';
$password = 'Boomba2410'; */
$login = 'dummy@gmail.com';
$password = 'dummy';
/* $login = 'geniusunil1@gmail.com';
$password = 'Boomba2410'; */

$connection = imap_open($server, $login, $password);
$emailUID = 25122;//24722;
//$msgno = imap_msgno();
// the number in constructor is the message number
$emailMessage = new EmailMessage($connection,$emailUID);
// set to true to get the message parts (or don't set to false, the default is true)
// $emailMessage->getAttachments = false;
$message=$emailMessage->fetch();
// echo $message;
// print_r($emailMessage->attachments);
preg_match_all('/src="cid:(.*)"/Uims', $emailMessage->bodyHTML, $matches);
// if there are any matches, loop through them and save to filesystem, change the src property
// of the image to an actual URL it can be viewed at
// print_r($matches);
if(count($matches[1])) {
// search and replace arrays will be used in str_replace function below
$search = array();
$replace = array();
foreach($matches[1] as $match) {
// work out some unique filename for it and save to filesystem etc
$uniqueFilename = $emailMessage->attachments[$match]['filename'];
// change /path/to/images to actual path
// $uniqueFilename = "a";
// echo $uniqueFilename;
file_put_contents("email_files/Inlineimages/".$uniqueFilename, $emailMessage->attachments[$match]['data']);
$search[] = "src=\"cid:$match\"";
// change www.example.com etc to actual URL
$replace[] = "src=\"email_files/Inlineimages/$uniqueFilename\"";
}
// now do the replacements
$emailMessage->bodyHTML = str_replace($search, $replace, $emailMessage->bodyHTML);
$message=$emailMessage->bodyHTML;
}
echo "message : ".$message;
$emailMessage->saveAndAttachments();
// $emailMessage->showAttachments();
imap_close($connection);
exit;



class EmailMessage {
protected $connection;
protected $messageNumber;
protected $dates;
protected $emails;
protected $message;
public $bodyHTML = '';
public $bodyPlain = '';
public $attachments;
public $getAttachments = true;
public function __construct($connection, $messageNumber) {
$this->connection = $connection;
/* $this->dates = date("d M Y", strToTime("-6 days"));
$this->emails = imap_search($this->connection, "SINCE \"$this->dates\"", SE_UID);
rsort($this->emails); */
$this->messageNumber = imap_msgno($this->connection,$messageNumber);
}
public function fetch() {
$structure = imap_fetchstructure($this->connection, $this->messageNumber);
file_put_contents("debug/structure.txt", "Structure \n" . date("Y-m-d h:i:sa") . "\n" . print_r($structure, true) . PHP_EOL); //
if(!$structure) {
return false;
}
else {
if(isset($structure->parts))
$this->message= $this->recurse($structure->parts);
else{
$part=$structure;
$structure->parts = Array($part);
$this->message= $this->recurse($structure->parts);
/* if($part->subtype == 'PLAIN') {
$this->bodyPlain .= $this->getPart(1, $part->encoding);
$this->message = $this->bodyPlain;
}
else {
$this->bodyHTML .= $this->getPart(1, $part->encoding);
$this->message = $this->bodyHTML;
} */
/* if ($part->ifdisposition == 0) {
if($part->subtype == 'PLAIN') {
$this->bodyPlain .= $this->getPart(1, $part->encoding);
$this->message = $this->bodyPlain;
}
else {
$this->bodyHTML .= $this->getPart(1, $part->encoding);
$this->message = $this->bodyHTML;
}
} else {
// $attachment = getPart($connection, $messageNumber, $partNumber, $part->encoding);
//get the attachment
} */
}
return $this->message;
}
}
public function recurse($messageParts, $prefix = '', $index = 1, $fullPrefix = true) {
foreach($messageParts as $part) {
$partNumber = $prefix . $index;
if($part->type == 0) {
if(isset($part->ifdisposition)){
if($part->ifdisposition == 1 && $part->disposition == 'ATTACHMENT'){
$this->attachments[] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => $this->getFilenameFromPart($part),
'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
'inline' => false,
);

}
else {
if ($part->subtype == 'PLAIN') {
$this->bodyPlain .= nl2br($this->getPart($partNumber, $part->encoding));
$this->message = $this->bodyPlain;
// echo $this->message;
} else {
$this->bodyHTML .= $this->getPart($partNumber, $part->encoding);
$this->message = $this->bodyHTML;
}
}
}
else {
if ($part->subtype == 'PLAIN') {
$this->bodyPlain .= $this->getPart($partNumber, $part->encoding);
$this->message = $this->bodyPlain;
} else {
$this->bodyHTML .= $this->getPart($partNumber, $part->encoding);
$this->message = $this->bodyHTML;
}
}


}
elseif($part->type == 2) {
$msg = new EmailMessage($this->connection, $this->messageNumber);
$msg->getAttachments = $this->getAttachments;
$msg->recurse($part->parts, $partNumber.'.', 0, false);
$this->attachments[] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => '',
'data' => $msg,
'inline' => false,
);
}
elseif(isset($part->parts)) {
if($fullPrefix) {
$this->recurse($part->parts, $prefix.$index.'.');
}
else {
$this->recurse($part->parts, $prefix);
}
}
elseif($part->type > 2) {
if(isset($part->disposition)) {
if($part->disposition == 'INLINE' && $part->type == 5){
$id = str_replace(array('<', '>'), '', $part->id);
$this->attachments[$id] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => $this->getFilenameFromPart($part),
'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
'inline' => true,
);
}
else{
$this->attachments[] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => $this->getFilenameFromPart($part),
'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
'inline' => false,
);
}
}
else{
$id = str_replace(array('<', '>'), '', $part->id);
$this->attachments[$id] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => $this->getFilenameFromPart($part),
'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
'inline' => true,
);
}
}
$index++;
}
return $this->message;
}
function getPart($partNumber, $encoding) {
$data = imap_fetchbody($this->connection, $this->messageNumber, $partNumber);
switch($encoding) {
case 0: return $data; // 7BIT
case 1: return $data; // 8BIT
case 2: return $data; // BINARY
case 3: return base64_decode($data); // BASE64
case 4: return quoted_printable_decode($data); // QUOTED_PRINTABLE
case 5: return $data; // OTHER
}

}
function getFilenameFromPart($part) {
$filename = '';
if($part->ifdparameters) {
foreach($part->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$filename = $object->value;
}
}
}
if(!$filename && $part->ifparameters) {
foreach($part->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$filename = $object->value;
}
}
}
return $filename;
}
public function saveAndAttachments(){
if(isset($this->attachments)){
foreach ($this->attachments as $attachment) {
// echo "there are attachments";
// print_r($attachment);
if ($attachment['inline'] != true) {
echo "there are attachments";
// echo 'email_files/attachments/'.$attachment['filename'].'did it work:?';
file_put_contents('email_files/attachments/' . $attachment['filename'], $attachment['data']);
echo "<embed src=\"". "email_files/attachments/" . $attachment['filename'] ."\"/>";
}

}
}
}
/* public function showAttachments(){
if(isset($this->attachments)){
foreach ($this->attachments as $attachment) {
if ($attachment['inline'] == false) {
file_put_contents('email_files/attachments/' . $attachment['filename'], $attachment['data']);
}
}
}
} */
}

1 comment:

  1. Is the current status of the SEGAGENESIS and MEGADRIVE
    After the pandemic has been lifted, casinos like Borgata, Atlantic City, Borgata Hotel starvegad Casino & Spa, Atlantic leovegas City, 11bet New Jersey,

    ReplyDelete

Featured Post

PHP EmailMessage class for extracting attachments

Hi, recently I had to create a php program which fetches emails with attachments (including inline). I searched a lot and succeeded with h...