how to retrive all associated threads of email - php

I am trying to fetch the all email received from a particular email id eg (From: abc#gmail.com),which i am successfully getting.
Now i am looking forward to get all the messages which are in thread to this email ie Re:sub fw:, Re:Re....
Here is how i am trying
$username = 'myemail#gmail.com';
$password = 'mypassword';
$folder = 'INBOX';
$email_resp = $this->config_imap($username,$password,$folder);
$email_list = $email_resp['emails'];
$inbox = $email_resp['inbox'];
$student_email = $useremail;
$email_list = imap_search($inbox, "FROM '{$student_email}'");
$threads = imap_thread($inbox);
rsort($email_list);
if(sizeof($email_list)>0){
foreach ($email_list as $key => $value) {
$overview = imap_fetch_overview($inbox,$value,0);
$message = imap_fetchbody($inbox,$value,2);
$attachment = imap_fetchstructure($inbox,$value);
$threads = imap_thread($inbox);
$thread_detail = array(
$value.".num" => $threads[$value.".num"],
$value.".next" => $threads[$value.".next"],
$value.".branch" => $threads[$value.".branch"],
);
foreach ($thread_detail as $k => $v) {
$tree =explode('.',$k);
if($tree[1]=='num'){
$headerInfo=imap_headerinfo($inbox, $value);
}
}
echo json_encode($headerInfo);
die;
$overview[0]->email =$message;
$overview[0]->attachment =$attachment;
$emails[]=$overview;
}
echo json_encode($emails);
}
else{
return Response::json(array('fail'=>'No Email Found.'));
}
How may i get the associated threads header details and message body too.

Related

Otp is not post in database

after user submit mail id otp will be sent to that email id but my code isn't working it post the email id in database but not the otp. Please can any one help?
Controller Code auth.php
public function register()
{
$alphabet = '1234567890';
$otp = array(); //remember to declare $pass as an array
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < 8; $i++) {
$n = rand(0, $alphaLength);
$otp[] = $alphabet[$n];
}
$newotp = implode($otp);
// $data['otp'] = $newotp;
$to = $this->input->post('email');
$subject = "OTP FOR LOGIN";
$message = '
Dear, User ,<br> <br>
Thanks You For Requesting OTP.<br><br>
Your Username is - ' . $to . ' And <br><br>
Your Password Is - <b>' . $newotp . '</b> <br><br>
Thank you!<br><br>
This is an autogenerated email. Please do not reply to this email.
<br><br>
';
$mail = $this->Others->send_email($to, $subject, $message);
$data = $this->user_model->insert('cred', ['email' => $to], ['otp' => ($newotp)]);
redirect(base_url() . 'auth/login');
}
Model code user_model.php
public function insert($table, $data = array())
{
$this->db->insert('cred', $data);
$afftectedRows = $this->db->affected_rows();
if ($afftectedRows == 1) {
$id = $this->db->insert_id();
return $id;
} else {
return FALSE;
}
}
In your controller you are actually passing three arguments to the $this->user_model->insert() instead of two. Second argument needs to be an array.
Try try updating following line with this:
$data = $this->user_model->insert('cred', ['email' => $to, 'otp' => $newotp]);

Getting Gmail emails in read status with Imap PHP

I take data from Gmail with this code
<?php $data = array(
// email account
'email' => array(
'hostname' => '{imap.gmail.com:993/imap/ssl}INBOX',
'username' => $emailAddress,
'password' => $emailPassword
),
// inbox pagination
'pagination' => array(
'sort' => $sortBy,
'limit' => 10,
'offset' => $offset
)
);
$result = array();
$imap = imap_open($data['email']['hostname'], $data['email']['username'], $data['email']['password']) or die ('Cannot connect to yourdomain.com: ' . imap_last_error());
$read = imap_search($imap, 'ALL');
$overview = imap_fetch_overview($imap, $read[$i], 0);
$header = imap_headerinfo($imap, $read[$i], 0);
$mail = $header->from[0]->mailbox . '#' . $header->from[0]->host;
$image = '';
$structure = imap_fetchstructure($imap, $read[$i]);
if(isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) {
$part = $structure->parts[1];
if($part->encoding == 3) {
$message = imap_fetchbody($imap,$read[$i],1.2);
$message = imap_qprint($message);
} else if($part->encoding == 1) {
$message = imap_8bit($message);
} else {
$message = imap_fetchbody($imap,$read[$i],2);
$message = imap_qprint($message);
}
}else{
$message = imap_body($imap, $read[$i],0);
}
?>
All data I receive correctly, however when I enter Email list page, the received emails turn to read.
It worked fine before, after using for some time, this issue appeared.
Any idea what can be the reason?
In imap_fetchbody, add the FT_PEEK flag to prevent clearing the \Seen flag automatically.
imap_fetchbody($imap, $read[$i], 1.2, FT_PEEK);
See option flag documentation at the official site.

Changing Impresspages to use SMTP

I need to change the code below that belongs to Impresspages CMS to use SMTP instead of sendmail. How can I do this?
<?php
/**
* Queue controls the amount of emails per hour.
* All emails ar placed in queue and send as quiq as possible.
* Parameter "hourlyLimit" defines how much emails can be send in one hour.
* If required amount of emails is bigger than this parameter, part of messages will wait until next hour.
*
* #package ImpressPages
*
*
*/
namespace Ip\Internal\Email;
/**
* Class to send emails. Typically all emails should be send trouht this class.
* #package ImpressPages
*/
class Module
{
/**
* Adds email to the queue
*
* Even if there is a big amount of emails, there is always reserved 20% of traffic for immediate emails.
* Such emails are: registration cofirmation, contact form data and other.
* Newsletters, greetings always can wait a litle. So they are not immediate and will not be send if is less than 20% of traffic left.
*
* #param string $from email address from whish an email should be send
* #param $fromName
* #param string $to email address where an email should be send
* #param $toName
* #param $subject
* #param string $email email html text
* #param bool $immediate indicate hurry of an email.
* #param bool $html true if email message should be send as html
* #param array $files files that should be attached to the email. Files should be accessible for php at this moment. They will be cached until send time.
* #internal param $string #fromName
* #internal param $string #toName
*/
function addEmail($from, $fromName, $to, $toName, $subject, $email, $immediate, $html, $files = null)
{
$cached_files = [];
$cached_fileNames = [];
$cached_fileMimeTypes = [];
if ($files) {
if (is_string($files)) {
$files = array($files);
}
foreach ($files as $fileSetting) {
$file = [];
if (is_array($fileSetting)) {
$file['real_name'] = $fileSetting[0];
$file['required_name'] = basename($fileSetting[1]);
} else {
$file['real_name'] = $fileSetting;
$file['required_name'] = basename($fileSetting);
}
$new_name = 'contact_form_' . rand();
$new_name = \Ip\Internal\File\Functions::genUnoccupiedName($new_name, ipFile('file/tmp/'));
if (copy($file['real_name'], ipFile('file/tmp/' . $new_name))) {
$cached_files[] = ipFile('file/tmp/' . $new_name);
$cached_fileNames[] = $file['required_name'];
$tmpMimeType = \Ip\Internal\File\Functions::getMimeType($file['real_name']);
if ($tmpMimeType == null) {
$tmpMimeType = 'Application/octet-stream';
}
$cached_fileMimeTypes[] = $tmpMimeType;
} else {
trigger_error('File caching failed');
}
}
}
$cachedFilesStr = implode("\n", $cached_files);
$cachedFileNamesStr = implode("\n", $cached_fileNames);
$cachedFileMimeTypesStr = implode("\n", $cached_fileMimeTypes);
$email = str_replace('src="' . ipConfig()->baseUrl(), 'src="', $email);
Db::addEmail(
$from,
$fromName,
$to,
$toName,
$subject,
$email,
$immediate,
$html,
$cachedFilesStr,
$cachedFileNamesStr,
$cachedFileMimeTypesStr
);
}
/**
* Checks if there are some emails waiting in queue and sends them if possible.
*/
function send()
{
$alreadySent = Db::sentOrLockedCount(60);
if ($alreadySent !== false) {
$available = floor(ipGetOption('Email.hourlyLimit') * 0.8 - $alreadySent); //20% for immediate emails
$lockKey = md5(uniqid(rand(), true));
if ($available > 0) {
if ($available > 5 && !defined('CRON')) { //only cron job can send many emails at once.
$available = 5;
}
$locked = Db::lock($available, $lockKey);
} else {
$available = 0;
$locked = 0;
}
if ($locked == $available) { //if in queue left some messages
if (ipGetOption('Email.hourlyLimit') - ($alreadySent + $available) > 0) {
$locked = $locked + Db::lockOnlyImmediate(
ipGetOption('Email.hourlyLimit') - ($alreadySent + $available),
$lockKey
);
}
}
if ($locked) {
$emails = Db::getLocked($lockKey);
foreach ($emails as $key => $email) {
if (function_exists('set_time_limit')) {
set_time_limit((sizeof($emails) - $key) * 10 + 100);
}
$mail = new \PHPMailer();
/* $mail->Sender = $email['from'];
$mail->addCustomHeader("Return-Path: " . $email['from']);*/
$mail->From = $email['from'];
$mail->FromName = $email['fromName'];
$mail->AddReplyTo($email['from'], $email['fromName']);
$mail->WordWrap = 50; // set word wrap
$mail->CharSet = ipConfig()->get('charset');
$mail->Subject = $email['subject'];
/* foreach($this->posted_files as $file){
if(isset($_FILES[$file]['tmp_name']) && $_FILES[$file]['error'] == 0){
$mail->AddAttachment($_FILES[$file]['tmp_name'], $_FILES[$file]['name']);
}
}*/
$files = explode("\n", $email['files']);
$fileNames = explode("\n", $email['fileNames']);
$fileMimeTypes = explode("\n", $email['fileMimeTypes']);
$fileCount = min(count($files), count($fileNames), count($fileMimeTypes));
for ($i = 0; $i < $fileCount; $i++) {
if ($files[$i] != '') {
if ($fileMimeTypes[$i] == '') {
$answer = $mail->AddAttachment($files[$i], $fileNames[$i]);
} else {
$answer = $mail->AddAttachment(
$files[$i],
$fileNames[$i],
"base64",
$fileMimeTypes[$i]
);
}
if (!$answer) {
ipLog()->error(
'Email.addAttachmentFailed: {subject} to {to}',
array(
'to' => $email['to'],
'subject' => $email['subject'],
'filename' => $fileNames[$i],
)
);
return false;
}
}
}
if ($email['html']) {
$mail->IsHTML(true); // send as HTML
$mail->MsgHTML($email['email']);
try {
$altBody = \Ip\Internal\Text\Html2Text::convert($email['email']);
} catch (\Ip\Internal\Text\Html2TextException $e) {
$altBody = $email['email'];
}
$mail->AltBody = $altBody;
} else {
/*$h2t = new \Ip\Internal\Text\Html2Text($content, false);
$mail->Body = $h2t->get_text();*/
$mail->Body = $email['email'];
}
$mail->AddAddress($email['to'], $email['toName']);
$mail = ipFilter('ipSendEmailPHPMailerObject', $mail, $email);
if (!$mail->Send()) {
ipLog()->error(
'Email.sendFailed: {subject} to {to}',
array('to' => $email['to'], 'subject' => $email['subject'], 'body' => $email['email'])
);
return false;
}
if (sizeof($emails) > 5) {
sleep(1);
}
Db::unlockOne($email['id']);
}
}
}
return null;
}
}

CakePHP- Accessing mail using IMAP

Re-visiting this problem specified in my previous question, I tried and tried, also with different accounts (I tried gmail, as well as outlook), but the problem still persists. The error I get is the following if I try to access my google account
Error: Unable to get imap_thread after 4 retries. 'Can't open mailbox {imap.gmail.com:993/ssl/imap/tls/novalidate-cert}INBOX: invalid remote specification'
if I try accessing email on my outlook account, the error is the same :
Error: Unable to get imap_thread after 4 retries. 'Can't open mailbox {outlook.office365.com:993/ssl/imap/tls/novalidate-cert}INBOX: invalid remote specification'
My setup is as follows :
public $emailTicket = array(
'datasource' => 'ImapSource',
'server' => 'outlook.office365.com',
'connect' => 'imap/tls/novalidate-cert',
'username' => 'my email here',
'password' => 'my password here',
'port' => '993', //incoming port
'ssl' => true,
'encoding' => 'UTF-8',
'error_handler' => 'php',
'auto_mark_as' => array(
'Seen',
// 'Answered',
// 'Flagged',
// 'Deleted',
// 'Draft',
),
);
I am working on a local machine, does anyone know if this might be the problem or not? Has anyone ever tried this and worked for him/her? I am open to all input!
I can't seem to find what's wrong here, I've been at this for about 2days now, so if anyone can help, I appreciate it!
Also here's the link for the plugin i'm using, by Nicolas Ramy..
You can use the following implemented code to fulfill your requirements:
public function generate_email_response_pdf()
{
$this->layout = false;
$this->autoRender = false;
$username = EMP_SMTP_MAIL_FROM;
$password = EMP_SMTP_MAIL_PASSWORD;
$imap = imap_open('{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX', $username, $password);
$emails = imap_search($imap, 'ALL');
if(!empty($emails))
{
//put the newest emails on top
rsort($emails);
foreach($emails as $email_number)
{
$flag = 0;
$mail_data = array();
$file_name = array();
$output = array();
$savefilename = null;
$filename = null;
$overview = imap_fetch_overview($imap, $email_number, 0);
//initialize the subject index with -000, considering not receving this will not be received in
//subject line of email
$output['subject'] = '-000x';
if(isset($overview[0] -> subject))
{
$output['subject'] = $overview[0] -> subject;
}
$structure = imap_fetchstructure($imap, $email_number);
if(property_exists($structure, 'parts'))
{
$flag = 1;
$flattened_parts = $this->flatten_parts($structure->parts);
foreach($flattened_parts as $part_number => $part)
{
switch($part->type)
{
case 0:
//the HTML or plain text part of the email
if((isset($part->subtype)=='HTML')&&(isset($part->disposition)=='ATTACHMENT'))
{
$part_number = 1.2;
}
else if(isset($part->subtype)=='HTML')
{
$part_number = $part_number;
}
else
{
$part_number = $part_number;
}
$message = $this->get_part($imap, $email_number, $part_number, $part->encoding);
//now do something with the message, e.g. render it
break;
case 1:
// multi-part headers, can ignore
break;
case 2:
// attached message headers, can ignore
break;
case 3: // application
case 4: // audio
case 5: // image
case 6: // video
case 7: // other
break;
}
if(isset($part->disposition))
{
$filename = $this->get_filename_from_part($part);
if($filename)
{
// it's an attachment
$attachment = $this->get_part($imap, $email_number, $part_number, $part->encoding);
$file_info = pathinfo($filename);
$savefilename = RESPONSE_ATTACHMENT_PREFIX.$file_info['filename'].'_'.$this->_getRandId(4).'.'.$file_info['extension'];
$file_name[] = $savefilename;
$attachment_file_name = $this->save_attachment($attachment, $savefilename, $directory_path);
//imap_fetchbody($imap, $email_number, 2); //This marks message as read
}
else
{
// don't know what it is
}
}
}
}
else
{
$encoding = $structure->encoding;
$message = imap_fetchbody($imap, $email_number, 1.2);
//echo $message; die;
if($message == "")
{
$message = imap_body($imap, $email_number);
if($encoding == 3)
{
$message = base64_decode($message);
}
else if($encoding == 4)
{
$message = quoted_printable_decode($message);
}
}
}
$header = imap_headerinfo($imap, $email_number);
$from_email = $header->from[0]->mailbox."#".$header->from[0]->host;
$to_email = $header->to[0]->mailbox."#".$header->to[0]->host;
$reply_to_email = $header->reply_to[0]->mailbox."#".$header->reply_to[0]->host;
$cc_email = array();
if(isset($header->cc))
{
foreach($header->cc as $ccmail)
{
$cc_email[] = $ccmail->mailbox.'#'.$ccmail->host;
}
$cc_email = implode(", ", $cc_email);
}
$output['to'] = $to_email;
$output['from'] = $from_email;
$output['reply_to'] = $reply_to_email;
$output['cc'] = $cc_email;
$formatted_date = date('D, d M Y h:i A', strtotime($overview[0] -> date));
$output['date'] = $formatted_date;
$output['message'] = $message;
$output['flag'] = $flag;
$mail_data['Attachment'] = $file_name;
$mail_data['Data'] = $output;
$this->set('response_data', $mail_data);
$mail_content = null;
if(!empty($mail_data))
{
$this->viewPath = 'Elements/default';
$mail_content = $this->render('pdf_content');
}
$header = null;
$footer = null;
$html = preg_replace(array('/[^\r\n\t\x20-\x7E\xA0-\xFF]*/'), '', $mail_content);
$pdfFile = $this->_generateWkPdf($html, $directory_path, $new_file_name, $header, $footer);
$image_type = EXT_JPG;
$response_files_array = $this->_generateImagesFromPdf($directory_path.$pdfFile, $directory_path, $new_file_name, $image_type);
}
}
imap_close($imap);
}

PHP Imap reading replies in inbox

I have written/copied a script that reads emails from an inbox and updates a ticket and then moves the email to a proccessed folder. This all works perfectly on new emails to the inbox but when someone replys to an email and it ends up in the inbox my scrtipt reads nothing on the email.
Is there something different to the way an email is structured when its a reply? I need a way of reading whats in the email so I can update a ticket with the contents. Knowing which email it is to update is all taken care of its just purely reading the content Im struggling with.
Here is the code
class Email
{
// imap server connection
public $conn;
// inbox storage and inbox message count
public $inbox;
private $msg_cnt;
// email login credentials
private $server = '????????????';
private $user = '????????';
private $pass = '?????????????';
private $port = ??;
// connect to the server and get the inbox emails
function __construct()
{
$this->connect();
$this->inbox();
}
function getdecodevalue($message,$coding)
{
switch($coding) {
case 0:
case 1:
$message = imap_8bit($message);
break;
case 2:
$message = imap_binary($message);
break;
case 3:
case 5:
$message=imap_base64($message);
break;
case 4:
$message = imap_qprint($message);
break;
}
return $message;
}
// close the server connection
function close()
{
$this->inbox = array();
$this->msg_cnt = 0;
imap_close($this->conn);
}
// open the server connection
// the imap_open function parameters will need to be changed for the particular server
// these are laid out to connect to a Dreamhost IMAP server
function connect()
{
$this->conn = imap_open("{".$this->server.":".$this->port."/imap/novalidate-cert}INBOX", $this->user, $this->pass);
}
// move the message to a new folder
function move($msg_index, $folder='Read')
{
// move on server
imap_mail_move($this->conn, $msg_index, $folder);
// re-read the inbox
//$this->inbox();
}
// get a specific message (1 = first email, 2 = second email, etc.)
function get($msg_index=NULL)
{
if(count($this->inbox) <= 0)
{
return array();
}
elseif( ! is_null($msg_index) && isset($this->inbox[$msg_index]))
{
return $this->inbox[$msg_index];
}
return $this->inbox[0];
}
// read the inbox
function inbox()
{
$this->msg_cnt = imap_num_msg($this->conn);
$in = array();
for($i = 1; $i <= $this->msg_cnt; $i++)
{
$in[] = array(
'index' => $i,
'header' => imap_headerinfo($this->conn, $i),
'body' => $this->cleanBody(imap_fetchbody($this->conn, $i,1)),
'structure' => imap_fetchstructure($this->conn, $i)
);
}
$this->inbox = $in;
}
function cleanBody($body)
{
$delimiter = '#';
$startTag = '----------START REPLY----------';
$endTag = '----------END REPLY----------';
$regex = $delimiter . preg_quote($startTag, $delimiter)
. '(.*?)'
. preg_quote($endTag, $delimiter)
. $delimiter
. 's';
preg_match($regex,$body,$matches);
$ret = trim($matches[1]);
return $ret;
}
}
$emails = new Email();
$email = array();
$emailCount = 1;
foreach($emails->inbox as $ems => $em)
{
$email[$emailCount]['subject'] = $sub = $em['header']->subject;
//echo $sub;
$subParts = explode('-',$sub);
$ticketUniqueCode = trim($subParts[1]);
$sql = "SELECT * FROM ticket_main WHERE uniquecode = '".mysql_escape_string($ticketUniqueCode)."' LIMIT 1";
$query = mysql_query($sql);
if(mysql_num_rows($query))
{
$res = mysql_fetch_object($query);
$ticketBody = $em['body'];
$customerID = $res->customerID;
$sql2 = "INSERT INTO ticket_updates SET ticketID = '".$res->ticketID."' , submitted = NOW() , submittedBy = '".$res->customerID."' , message = '".mysql_escape_string($ticketBody)."' , inhouse = 0";
$query = mysql_query($sql2);
// attachment section
$message_number = $em['index'];
$attachments = array();
if(isset($em['structure']->parts) && count($em['structure']->parts))
{
//echo 'hi';
for($i = 0; $i < count($em['structure']->parts); $i++)
{
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($em['structure']->parts[$i]->ifdparameters) {
foreach($em['structure']->parts[$i]->dparameters as $object)
{
if(strtolower($object->attribute) == 'filename')
{
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($em['structure']->parts[$i]->ifparameters) {
foreach($em['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($emails->conn, $message_number, $i+1);
if($em['structure']->parts[$i]->encoding == 3)
{ // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($em['structure']->parts[$i]->encoding == 4)
{ // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
if(isset($em['structure']->parts[$i]->disposition) && $em['structure']->parts[$i]->disposition == "attachment")
{
$filename = $attachments[$i]['name'];
$mege="";
$data="";
$mege = imap_fetchbody($emails->conn, $message_number, $i+1);
$filename= $filename;
$fp=fopen('???????????????'.$filename,"w");
$data=$emails->getdecodevalue($mege,$em['structure']->parts[$i]->type);
fputs($fp,$data);
fclose($fp);
$email[$emailCount]['attachment'] = $attachments;
}
}
}
}
$emailCount++;
}
$emailNumbers = imap_search($emails->conn,'ALL');
if(!empty($emailNumbers))
{
foreach($emailNumbers as $a)
{
$emails->move($a);
}
imap_expunge($emails->conn);
}
$emails->close();
Hope that makes some sense and someone can actually help.
Many many thanks in advance
Jon
Well the most obvious thing is your code assumes a message is always in part 1, your line:
'body' => $this->cleanBody(imap_fetchbody($this->conn, $i,1)),
Means it's only looking at body 1. If it's a pure text email body 1 will be right, but if it's multipart/alternative (text & html) body 1 would be the base MIME message which tells you that there are sub bodies (body 1.1, 1.2) that actually contain the content.
Further if the reply includes embedded images, or includes the message it's replying to as an attachment then you could have even more bodies/locations.
So how do I find the body? (you ask)... well you can use imap_fetchstructure to learn about all the body parts, then search through it to find a piece with type=0 (text) and then download that body part. (The first found text should be the right one, but note there could be more than one text body type in an email).

Categories