PHP IMAP function to detach attachment and save to a directory - php

I'm trying to use IMAP function to detach an attachment received from inbox and save into the server directory specified.
I am doing this for all UNSEEN messages but the problem is that it only does for one message only.
Below is the code (I deleted $host,$login,$password variables for obvious reasons):
$type = 'ReadAttachment';
$obj = new $type;
$obj->getdata($host,$login,$password,$savedirpath,$delete_emails=false);
class ReadAttachment
{
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;
}
function getdata($host,$login,$password,$savedirpath,$delete_emails=false, $read_type="UNSEEN") {
// make sure save path has trailing slash (/)
//print_r("test");
$savedirpath = str_replace('\\', '/', $savedirpath);
if (substr($savedirpath, strlen($savedirpath) - 1) != '/') {
$savedirpath .= '/';
}
$mbox = imap_open ($host, $login, $password) or die("can't connect: " . imap_last_error());
$message = array();
$message["attachment"]["type"][0] = "text";
$message["attachment"]["type"][1] = "multipart";
$message["attachment"]["type"][2] = "message";
$message["attachment"]["type"][3] = "application";
$message["attachment"]["type"][4] = "audio";
$message["attachment"]["type"][5] = "image";
$message["attachment"]["type"][6] = "video";
$message["attachment"]["type"][7] = "other";
//print_r($message);
$emails = imap_search($mbox,$read_type) or die(print_r(imap_last_error()));
print_r($emails);
$e = imap_search($mbox,$read_type, SE_UID) or die(print_r(imap_last_error()));
print_r($e);
$i=0;
foreach($emails as $email_number) {
$structure = imap_fetchstructure($mbox, $e[$i] , FT_UID) or die(print_r(imap_last_error()));
$parts = $structure->parts;
$fpos=2;
for($i = 1; $i < count($parts); $i++) {
$message["pid"][$i] = ($i);
$part = $parts[$i];
if($part->disposition == "attachment") {
$message["type"][$i] = $message["attachment"]["type"][$part->type] . "/" . strtolower($part->subtype);
$message["subtype"][$i] = strtolower($part->subtype);
$ext=$part->subtype;
$params = $part->dparameters;
$filename=$part->dparameters[0]->value;
$mege="";
$data="";
$mege = imap_fetchbody($mbox,$email_number,$fpos);
$filename="$filename";
$fp=fopen($savedirpath.$filename,"w");
$data=$this->getdecodevalue($mege,$part->type);
//print_r($mege);
fputs($fp,$data);
fclose($fp);
$fpos+=1;
}
}
++$i;
}
// imap_expunge deletes all tagged messages
imap_close($mbox);
}
}
Is there something that I could change above?

I'm not sure whether this is the cause of the problem, or if I even understood your code correctly. However I think your $i=0 needs to go inside the foreach loop, and you need to lose the ++$i at the end.
Let's go through it. First, you set $i=0. foreach gets the first message and enters the for loop, which iterates over incrementing values of $i. Let's say that $i is set to 4 when the for loop ends. At that point, ++$i sets it to 5. The foreach iteration ends and the next email should be processed. But this does not happen because $i is still 5, so when you do:
$structure = imap_fetchstructure($mbox, $e[$i] , FT_UID)
You are picking the wrong email.

Actually looking at the script I think he's using $i in 2 places incorrectly. the $i within the foreach should be a different variable.
for the $structure variable he should use the $i as expected ...
but the mail parts should use a separate variable (I used $p)
i know this is an old post, but it helped me a bit.

Related

how to rename the attachment file from from email using php?

I need help,
for example: the attachment name from my message inbox is sample.pdf,
I have an php script to download the attachment!
now my problem is to rename the attachment from inbox using php
i want to make php script that automatically change the attachment name(sample.pdf) into; ahm let say rename it into the subject of the message... so it become subject.pdf...
<?php $hostname = '{xxxxxxpop3/notls}INBOX';
$username = 'xxx#gmail.com';
$password = 'password';
$savedirpath = "/root/Fax";
$type = 'ReadAttachment';
$obj = new
$type;
$obj->getdata($hostname, $username, $password, $savedirpath, $delete_emails = false);
class ReadAttachment
{
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;
}
function getdata ($hostname, $username, $password, $savedirpath, $delete_emails = false)
{
// make sure savepath has trailing slash(/)
$savedirpath = str_replace('\\', '/', $savedirpath);
if (substr($savedirpath, strlen($savedirpath) - 1) != '/')
{
$savedirpath .= '/';
}
$mbox = imap_open($hostname, $username, $password) or die("can't connect: " . imap_last_error());
$message = array();
$message["attachment"]["type"][0] = "text";
$message["attachment"]["type"][1] = "multipart";
$message["attachment"]["type"][2] = "message";
$message["attachment"]["type"][3] = "application";
$message["attachment"]["type"][4] = "audio";
$message["attachment"]["type"][5] = "image";
$message["attachment"]["type"][6] = "video";
$message["attachment"]["type"][7] = "other";
for ($jk = 1; $jk <= imap_num_msg($mbox); $jk++)
{
$structure = imap_fetchstructure($mbox, $jk, FT_UID);
$parts = (isset($structure->parts) ? $structure->parts : false);
$fpos = 2;
for ($i = 1; $i < count($parts); $i++)
{
$message["pid"][$i] = ($i);
$part = $parts[$i];
if ($part->disposition == "ATTACHMENT")
{
$message["type"][$i] = $message["attachment"]["type"][$part->type] . "/" . strtolower($part->subtype);
$message["subtype"][$i] = strtolower($part->subtype);
$ext = $part->subtype;
$params = $part->dparameters;
$filename = $part->dparameters[0]->value;
$mege = "";
$data = "";
$mege = imap_fetchbody($mbox, $jk, $fpos);
$filename = "$filename";
$fp = fopen($savedirpath . $filename, 'w');
$data = $this->getdecodevalue($mege, $part->type);
fputs($fp, $data);
fclose($fp);
$fpos += 1;
}
}
if ($delete_emails)
{
// imap_delete tags a message for deletion
imap_delete($mbox, $jk);
}
} // imap_expunge deletes all tagged messages if ($delete_emails) { imap_expunge($mbox); }
imap_close($mbox);
}
}
?>
Well you set the filename here:
$fp = fopen($savedirpath . $filename, 'w');
so you just need to change the $filename to your desired value

strpos returns true when using clearly different strings

I'm taking data from an excel using phpexcel, like this:
$number = $objPHPExcel->getActiveSheet()->getCell('A3')->getValue();
number is clearly a number, okay? so, after that I want to know if $number exists on the word $elem:
if(strpos($elem,$number) !== false) //está?
{
$answer = true;
}
the problem is that when I test it with this data, the $answer is true, and it shouldn't be:
$number = 11001456
$elem = '10001033.jpg'
So... what's wrong here?
PD: I'm going to post the entire code so you can see it, If I try to do (string)$number then the code crashes, it exceeds time execution.... (using cakephp)
The important thing is located at the function SearchPhoto... you will see the strpos there...
public function admin_load() //esto sirve para cargar un excel...
{
if($this->request->is('post'))
{
$data = $this->request->data;
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');
date_default_timezone_set('Europe/London');
/** Include PHPExcel_IOFactory */
require_once WWW_ROOT . '/excelWorker/Classes/PHPExcel/IOFactory.php';
echo date('H:i:s') , " Load from Excel2007 file" , EOL;
$callStartTime = microtime(true);
$objPHPExcel = PHPExcel_IOFactory::load($data['People']['excel']['tmp_name']);
$dir = WWW_ROOT . "img/photos";
$files = scandir($dir);
$batchPeople = array();
for($i = 2; $i <= $data['People']['num']; $i++)
{
$batchPeople[$i-2]['People']['fullname'] = $objPHPExcel->getActiveSheet()->getCell('B'.$i)->getValue();
$batchPeople[$i-2]['People']['floor'] = $objPHPExcel->getActiveSheet()->getCell('C'.$i)->getValue();
$batchPeople[$i-2]['People']['country'] = $objPHPExcel->getActiveSheet()->getCell('D'.$i)->getValue();
$batchPeople[$i-2]['People']['day'] = $objPHPExcel->getActiveSheet()->getCell('F'.$i)->getValue();
$batchPeople[$i-2]['People']['month'] = $objPHPExcel->getActiveSheet()->getCell('G'.$i)->getValue();
$batchPeople[$i-2]['People']['photo'] = $this->SearchPhoto($objPHPExcel->getActiveSheet()->getCell('A'.$i)->getValue(),$files);
}
// $this->People->saveMany($batchPeople);
}
}
function SearchPhoto($number, $array)
{
$answer = '';
$getOut = false;
foreach($array as $elem)
{
if(strcmp($elem,'.') != 0 && strcmp($elem,'..') != 0)
if(strpos($elem,$number) !== false) //está?
{
echo 'coinciden--> '. $number . ',' . $elem;
echo '<br>';
$answer = $elem;
$getOut = true;
}
if($getOut)
break;
}
return $answer;
}
This should work for you:
(BTW: You use $number in the code and not $num)
<?php
$num = 11001456;
$elem = "10001033.jpg";
if(strpos($elem, (string)$num) !== false) {
echo "yes";
}
?>
For more information about strpos() look into the manual: http://php.net/manual/en/function.strpos.php
And a quote from there:
needle:
If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.
echo chr($number); // p
echo strpos($elem, 'p'); // 10 (which is p in $elem)
I ended up using preg_match to solve my problem... I still don't know what's wrong with using strpos... because it works on all the sites I made expect this particular case!
In case anyone wondering what's the exact solution:
$text = $B;
$pattern = '/'.$A.'/';
preg_match($pattern,$text,$matches);
if(isset($matches[0]))
$answer = true;

Get attachment from mail using php

I need code to monitor my mail inbox and forward the mails with an attachment to another email address. I used the code below to fetch the attachments from the received messages. But I'm getting an error "Notice: Undefined property: stdClass::$disposition in C:\wamp\www\mail\c.php on line 60"
Here is my code
<?php
$host = '{imap.gmail.com:993/imap/ssl/novalidate-cert/norsh}inbox';
$login = 'AAAA#CCC.com';
$password = 'XXXXXXX';
$savedirpath = "../mail";
$type = 'ReadAttachment';
$obj = new $type;
$obj->getdata($host,$login,$password,$savedirpath,$delete_emails=false);
class ReadAttachment{
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;
}
function getdata($host,$login,$password,$savedirpath,$delete_emails=false) {
// make sure save path has trailing slash (/)
//print_r("test");
$savedirpath = str_replace('\\', '/', $savedirpath);
if (substr($savedirpath, strlen($savedirpath) - 1) != '/') {
$savedirpath .= '/';
}
$mbox = imap_open ($host, $login, $password) or die("can't connect: " . imap_last_error());
$message = array();
$message["attachment"]["type"][0] = "text";
$message["attachment"]["type"][1] = "multipart";
$message["attachment"]["type"][2] = "message";
$message["attachment"]["type"][3] = "application";
$message["attachment"]["type"][4] = "audio";
$message["attachment"]["type"][5] = "image";
$message["attachment"]["type"][6] = "video";
$message["attachment"]["type"][7] = "other";
//print_r($message);
$emails = imap_search($mbox,'ALL');
foreach($emails as $email_number) {
$structure = imap_fetchstructure($mbox, $email_number , FT_UID);
$parts = $structure->parts;
$fpos=2;
for($i = 1; $i < count($parts); $i++) {
$message["pid"][$i] = ($i);
$part = $parts[$i];
if($part->disposition == "ATTACHMENT") {
$message["type"][$i] = $message["attachment"]["type"][$part->type] . "/" . strtolower($part->subtype);
$message["subtype"][$i] = strtolower($part->subtype);
$ext=$part->subtype;
$params = $part->dparameters;
$filename=$part->dparameters[0]->value;
$mege="";
$data="";
$mege = imap_fetchbody($mbox,$email_number,$fpos);
$filename="$filename";
$fp=fopen($savedirpath.$filename,"w");
$data=$this->getdecodevalue($mege,$part->type);
//print_r($data);
fputs($fp,$data);
fclose($fp);
$fpos+=1;
}
}
}
// imap_expunge deletes all tagged messages
imap_close($mbox);
}
}
Thanks to the author, but I couldn't get any help further.
I'm getting an error "Notice: Undefined property: stdClass::$disposition in C:\wamp\www\mail\c.php on line 60"
This exactly point out the line if($part->disposition == "ATTACHMENT").
Please provide me with a solution.
I am new to php, struggling to write this mail function,,
Thanks in advance :-)
You need to check if $disposition exists first:
if((isset($part->disposition))&&($part->disposition == "ATTACHMENT"))

IMAP or POP3 server implemented in PHP

Is there any available implementation of POP3/IMAP server in PHP?
I am handling my e-mail service using sendgrid. I am going to store the messages on my server using files/db/whatever and now I'd like to provide full POP3 or IMAP (preferable) access for my users to their mailbox. Is there such implementation in PHP? Or is there any other possibility to run POP3/IMAP in the distributed environment of Windows Azure (assuming I have the mailboxes stored in shared blobs/tables/db)?
Well, just to show that it is in fact possible to write a POP3 server in PHP, here it is. The server does no authentication--or pretty much anything else. It just keep sending the same message over and over. But it works. Thunderbird was able to retrieve messages from it. Totally useless, but sort of cool.
My setup is Apache 2 on Windows with PHP 5.2.
<?php
// echo something so fopen() would return
header("Content-type: text/plain");
echo "OK\n";
flush();
// listen for incoming connection
$listen_socket = socket_create_listen(110, 1);
$r = $w = $e = array($listen_socket);
$n = socket_select($r, $w, $e, 120);
$client_socket = ($n == 1) ? socket_accept($listen_socket) : null;
socket_close($listen_socket);
// spawn copy of myself
$internal_url = "http://{$_SERVER['HTTP_HOST']}:{$_SERVER['SERVER_PORT']}{$_SERVER['SCRIPT_NAME']}";
$stream_context_options = array (
'http' => array (
'method' => 'GET',
'timeout' => 1
)
);
$context = stream_context_create($stream_context_options);
if($f = fopen($internal_url, "rb", 0, $context)) {
fclose($f);
}
if(!$client_socket) {
// timed out
exit;
}
// start handling the session
$read_buffer = "";
$write_buffer = "+OK POP3 server ready\r\n";
$active = true;
$messages = array(
"From: webmaster#example.com\r\nSubject: This is a test\r\n\r\nHello world!\r\n"
);
$idle_start = time();
while(true) {
$r = $w = $e = array($client_socket);
$n = socket_select($r, $w, $e, 60);
if($n) {
if($r) {
// read from the socket
$read_buffer .= socket_read($client_socket, 128);
$idle_start = time();
}
if($w) {
if($write_buffer) {
// write to the socket
$written = socket_write($client_socket, $write_buffer);
$write_buffer = substr($write_buffer, $written);
$idle_start = time();
} else if($active) {
$now = time();
$idle_time = $now - $idle_start;
if($idle_time > 10) {
// exit if nothing happened for 10 seconds
break;
} else if($idle_time > 2) {
// start napping when the client is too slow
sleep(1);
}
} else {
break;
}
}
if($e) {
break;
}
if($read_buffer) {
if(preg_match('/(.*?)(?:\s+(.*?))?[\r\n]+/', $read_buffer, $matches)) {
$read_buffer = substr($read_buffer, strlen($matches[0]));
$command = $matches[1];
$argument = $matches[2];
switch($command) {
case 'USER':
$username = $argument;
$write_buffer .= "+OK $username is welcome here\r\n";
break;
case 'PASS':
$message_count = count($messages);
$write_buffer .= "+OK mailbox has $message_count message(s)\r\n";
break;
case 'QUIT':
$write_buffer .= "+OK POP3 server signing off\r\n";
$active = false;
break;
case 'STAT':
$message_count = count($messages);
$mailbox_size = 0;
foreach($messages as $message) {
$mailbox_size += strlen($message);
}
$write_buffer .= "+OK $message_count $mailbox_size\r\n";
break;
case 'LIST':
$start_index = (int) $argument;
$message_count = count($messages) - $start_index;
$total_size = 0;
for($i = $start_index; $i < count($messages); $i++) {
$total_size += strlen($messages[$i]);
}
$write_buffer .= "+OK $message_count messages ($total_size octets)\r\n";
for($i = $start_index; $i < count($messages); $i++) {
$message_id = $i + 1;
$message_size = strlen($messages[$i]);
$write_buffer .= "$message_id $message_size\r\n";
}
$write_buffer .= ".\r\n";
break;
case 'RETR':
$message_id = (int) $argument;
$message = $messages[$message_id - 1];
$message_size = strlen($message);
$write_buffer .= "+OK $message_size octets\r\n";
$write_buffer .= "$message\r\n";
$write_buffer .= ".\r\n";
break;
case 'DELE':
$write_buffer .= "+OK\r\n";
break;
case 'NOOP':
$write_buffer .= "+OK\r\n";
break;
case 'LAST':
$message_count = count($messages) - $start_index;
$write_buffer .= "+OK $message_count\r\n";
break;
case 'RSET':
$write_buffer .= "+OK\r\n";
break;
default:
$write_buffer .= "-ERR Unknown command '$command'\r\n";
}
}
}
} else {
break;
}
}
?>

PHP Proxy Servers

i was wondering if there is any way to turn my website into a proxy server ..
i found plenty of scripts using PHP but they all require navigating to site in order to use
the proxy, but what i really want is a script that enables me to access the site via browser configuration like in firefox when you enter the IP and port number in the options dialog, is there any kind of scripts that does that ?
any links may help me get quick on the subject are welcomed ..
Thank you,
AB
http://sourceforge.net/projects/poxy/
http://www.phpmyproxy.com/
(and more, ask google)
Is this the kind of proxy software you're looking for? Just plain HTTP proxies in PHP.
Redirect your adapter to this computer's ip and port, its synchronous though so it'll be slow.
$addr = gethostbyname('0.0.0.0'); //ip sensitive :((
$server = stream_socket_server("tcp://" . $addr . ":8000", $errno, $errorMessage);
echo "connected to: $addr:8000";
if ($server === false) {
throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
}
$conns = array( $server ); // connections
$connection = 0;
// loop forever
for (;;) {
$reads = $conns;
// get number of connections with new data
$mod = stream_select($reads, $write, $except, 5);
if ($mod===false) break;
// I have no idea what this does but what im doing here is separating the client ip and port from server 1:1 only!
foreach ($reads as $read) {
if ($read===$server) {
// if a client is connected
if ($client = #stream_socket_accept( $server )) {
echo "\nconnection from " . stream_socket_get_name( $client, true ) . "\n";
$recv = fread($client, 1024);
$rec_arr = explode( ' ', $recv );
echo hex_dump($recv);
if(strpos($recv, "CONNECT ")!==0) {
if( $src = #fopen( $rec_arr[ 1 ], 'rb') ) {
while ($chunk = fread($src, 1024000)) {
#fwrite( $client, $chunk );
}
$chunk = "";
fclose( $src );
}
}
stream_socket_shutdown($client, STREAM_SHUT_RDWR);
}
}
}
}
function hex_dump($data, $newline="\n")
{
$from = '';
$to = '';
$width = 16; # number of bytes per line
$pad = '.'; # padding for non-visible characters
if ($from==='')
{
for ($i=0; $i<=0xFF; $i++)
{
$from .= chr($i);
$to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
}
}
$hex = str_split(bin2hex($data), $width*2);
$chars = str_split(strtr($data, $from, $to), $width);
$offset = 0;
foreach ($hex as $i => $line)
{
$line = strtoupper( $line );
echo sprintf('%6X',$offset).' : '.implode(' ', str_split($line,2)) . ' [' . $chars[$i] . ']' . $newline;
$offset += $width;
}
}

Categories