Advertisement
Guest User

Untitled

a guest
Oct 25th, 2019
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 14.90 KB | None | 0 0
  1. <?php
  2.  
  3. /*
  4.  * This class can be used to retrieve messages from an IMAP, POP3 and NNTP server
  5.  * @author Kiril Kirkov
  6.  * GitHub: https://github.com/kirilkirkov
  7.  * Usage example:
  8.   1. $imap = new Imap();
  9.   2. $connection_result = $imap->connect('{imap.gmail.com:993/imap/ssl}INBOX', 'user@gmail.com', 'secret_password');
  10.   if ($connection_result !== true) {
  11.   echo $connection_result; //Error message!
  12.   exit;
  13.   }
  14.   3. $messages = $imap->getMessages('text'); //Array of messages
  15.  * in $attachments_dir property set directory for attachments
  16.  * in the __destructor set errors log
  17.  */
  18.  
  19. class Imap {
  20.     private $imapStream;
  21.     private $plaintextMessage;
  22.     private $htmlMessage;
  23.     private $emails;
  24.     private $errors = array();
  25.     private $attachments = array();
  26.     private $attachments_dir = 'attachments';
  27.     public function connect($hostname, $username, $password) {
  28.         $connection = imap_open($hostname, $username, $password) or die('Cannot connect to Mail: ' . imap_last_error());
  29.         if (!preg_match("/Resource.id.*/", (string) $connection)) {
  30.             return $connection; //return error message
  31.         }
  32.         $this->imapStream = $connection;
  33.         return true;
  34.     }
  35.     public function getMessages($type = 'text') {
  36.         $this->attachments_dir = rtrim($this->attachments_dir, '/');
  37.         $stream = $this->imapStream;
  38.         $emails = imap_search($stream, 'ALL');
  39.         $messages = array();
  40.         if ($emails) {
  41.             $this->emails = $emails;
  42.             foreach ($emails as $email_number) {
  43.                 $this->attachments = array();
  44.                 $uid = imap_uid($stream, $email_number);
  45.                 $cabeca = imap_headerinfo($stream,  $email_number);
  46.                 $messages[] = $this->loadMessage($uid, $type);
  47.                 $assunto_decodificado = imap_mime_header_decode($cabeca->subject);
  48.                 $remetente_decodificado = imap_mime_header_decode($cabeca->fromaddress);
  49.                 $messages[$email_number]["subject"] = $assunto_decodificado[0]->text;
  50.                 $messages[$email_number]["from"]["name"] = $remetente_decodificado[0]->text;
  51.  
  52.                 /* tentando pegar os anexos */
  53.                 /*Codigo funcional porém pega todos os anexos dos emails de uma vez só*/
  54.                 /*
  55.                 $structure = imap_fetchstructure($stream,  $email_number);
  56.                 $attachments = array();
  57.                 if(isset($structure->parts) && count($structure->parts))
  58.                 {
  59.                     for($i = 0; $i < count($structure->parts); $i++)
  60.                     {
  61.                         $attachments[$i] = array(
  62.                             'is_attachment' => false,
  63.                             'filename' => '',
  64.                             'name' => '',
  65.                             'attachment' => ''
  66.                         );
  67.  
  68.                         if($structure->parts[$i]->ifdparameters)
  69.                         {
  70.                             foreach($structure->parts[$i]->dparameters as $object)
  71.                             {
  72.                                 if(strtolower($object->attribute) == 'filename')
  73.                                 {
  74.                                     $attachments[$i]['is_attachment'] = true;
  75.                                     $attachments[$i]['filename'] = $object->value;
  76.                                 }
  77.                             }
  78.                         }
  79.  
  80.                         if($structure->parts[$i]->ifparameters)
  81.                         {
  82.                             foreach($structure->parts[$i]->parameters as $object)
  83.                             {
  84.                                 if(strtolower($object->attribute) == 'name')
  85.                                 {
  86.                                     $attachments[$i]['is_attachment'] = true;
  87.                                     $attachments[$i]['name'] = $object->value;
  88.                                 }
  89.                             }
  90.                         }
  91.  
  92.                         if($attachments[$i]['is_attachment'])
  93.                         {
  94.                             $attachments[$i]['attachment'] = imap_fetchbody($stream,  $email_number, $i+1);
  95.  
  96.                             // 3 = BASE64 encoding
  97.                             if($structure->parts[$i]->encoding == 3)
  98.                             {
  99.                                 $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
  100.                             }
  101.                             // 4 = QUOTED-PRINTABLE encoding
  102.                             elseif($structure->parts[$i]->encoding == 4)
  103.                             {
  104.                                 $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
  105.                             }
  106.                         }
  107.                     }
  108.                 }
  109.  
  110.                 //iterate through each attachment and save it
  111.                 foreach($attachments as $attachment)
  112.                 {
  113.                     if($attachment['is_attachment'] == 1)
  114.                     {
  115.                         $filename = $attachment['name'];
  116.                         if(empty($filename)) $filename = $attachment['filename'];
  117.  
  118.                         if(empty($filename)) $filename = time() . ".dat";
  119.                         $folder = "attachment";
  120.                         if(!is_dir($folder))
  121.                         {
  122.                              mkdir($folder);
  123.                         }
  124.                         $fp = fopen("./". $assunto_decodificado ."/". $email_number . "-" . $filename, "w+");
  125.                         fwrite($fp, $attachment['attachment']);
  126.                         fclose($fp);
  127.                     }
  128.                 } */
  129.  
  130.  
  131.             }
  132.         }
  133.         return array(
  134.             "status" => "success",
  135.             "data" => array_reverse($messages)
  136.         );
  137.     }
  138.     public function getFiles($r) { //save attachments to directory
  139.         $pullPath = $this->attachments_dir . '/' . $r['file'];
  140.         $res = true;
  141.         if (file_exists($pullPath)) {
  142.             $res = false;
  143.         } elseif (!is_dir($this->attachments_dir)) {
  144.             $this->errors[] = 'Cant find directory for email attachments! Message ID:' . $r['uid'];
  145.             return false;
  146.         } elseif (!is_writable($this->attachments_dir)) {
  147.             $this->errors[] = 'Attachments directory is not writable! Message ID:' . $r['uid'];
  148.             return false;
  149.         }
  150.         if($res && !preg_match('/\.php/i', $r['file']) && !preg_match('/\.cgi/i', $r['file']) && !preg_match('/\.exe/i', $r['file']) && !preg_match('/\.dll/i', $r['file']) && !preg_match('/\.mobileconfig/i', $r['file'])){
  151.             if (($filePointer = fopen($pullPath, 'w')) == false) {
  152.                 $this->errors[] = 'Cant open file at imap class to save attachment file! Message ID:' . $r['uid'];
  153.                 return false;
  154.             }
  155.             switch ($r['encoding']) {
  156.                 case 3: //base64
  157.                     $streamFilter = stream_filter_append($filePointer, 'convert.base64-decode', STREAM_FILTER_WRITE);
  158.                     break;
  159.                 case 4: //quoted-printable
  160.                     $streamFilter = stream_filter_append($filePointer, 'convert.quoted-printable-decode', STREAM_FILTER_WRITE);
  161.                     break;
  162.                 default:
  163.                     $streamFilter = null;
  164.             }
  165.             imap_savebody($this->imapStream, $filePointer, $r['uid'], $r['part'], FT_UID);
  166.             if ($streamFilter) {
  167.                 stream_filter_remove($streamFilter);
  168.             }
  169.             fclose($filePointer);
  170.             return array("status" => "success", "path" => $pullPath);
  171.         }else{
  172.             return array("status" => "success", "path" => $pullPath);
  173.         }
  174.     }
  175.     private function loadMessage($uid, $type) {
  176.         $overview = $this->getOverview($uid);
  177.         $array = array();
  178.         $array['uid'] = $overview->uid;
  179.         $array['subject'] = isset($overview->subject) ? $this->decode($overview->subject) : '';
  180.         $array['date'] = date('Y-m-d h:i:sa', strtotime($overview->date));
  181.         $headers = $this->getHeaders($uid);
  182.         $array['from'] = isset($headers->from) ? $this->processAddressObject($headers->from) : array('');
  183.         $structure = $this->getStructure($uid);
  184.         if (!isset($structure->parts)) { // not multipart
  185.             $this->processStructure($uid, $structure);
  186.         } else { // multipart
  187.             foreach ($structure->parts as $id => $part) {
  188.                 $this->processStructure($uid, $part, $id + 1);
  189.             }
  190.         }
  191.         $array['message'] = $type == 'text' ? $this->plaintextMessage : $this->htmlMessage;
  192.         $array['attachments'] = $this->attachments;
  193.         return $array;
  194.     }
  195.     private function processStructure($uid, $structure, $partIdentifier = null) {
  196.         $parameters = $this->getParametersFromStructure($structure);
  197.        // var_dump($parameters);
  198.         if ((isset($parameters['name']) || isset($parameters['filename'])) || (isset($structure->subtype) && strtolower($structure->subtype) == 'rfc822')
  199.         ) {
  200.             if (isset($parameters['filename'])) {
  201.                 $this->setFileName($parameters['filename']);
  202.             } elseif (isset($parameters['name'])) {
  203.                 $this->setFileName($parameters['name']);
  204.             }
  205.             $this->encoding = $structure->encoding;
  206.             $result_save = $this->saveToDirectory($uid, $partIdentifier);
  207.             $this->attachments[] = $result_save;
  208.         } elseif ($structure->type == 0 || $structure->type == 1) {
  209.             $messageBody = isset($partIdentifier) ?
  210.                     imap_fetchbody($this->imapStream, $uid, $partIdentifier, FT_UID | FT_PEEK) : imap_body($this->imapStream, $uid, FT_UID | FT_PEEK);
  211.             $messageBody = $this->decodeMessage($messageBody, $structure->encoding);
  212.             if (!empty($parameters['charset']) && $parameters['charset'] !== 'UTF-8') {
  213.                 if (function_exists('mb_convert_encoding')) {
  214.                     if (!in_array($parameters['charset'], mb_list_encodings())) {
  215.                         if ($structure->encoding === 0) {
  216.                             $parameters['charset'] = 'US-ASCII';
  217.                         } else {
  218.                             $parameters['charset'] = 'UTF-8';
  219.                         }
  220.                     }
  221.                     $messageBody = mb_convert_encoding($messageBody, 'UTF-8', $parameters['charset']);
  222.                 } else {
  223.                     $messageBody = iconv($parameters['charset'], 'UTF-8//TRANSLIT', $messageBody);
  224.                 }
  225.             }
  226.             if (strtolower($structure->subtype) === 'plain' || ($structure->type == 1 && strtolower($structure->subtype) !== 'alternative')) {
  227.                 $this->plaintextMessage = '';
  228.                 $this->plaintextMessage .= trim(htmlentities($messageBody));
  229.                 $this->plaintextMessage = nl2br($this->plaintextMessage);
  230.             } elseif (strtolower($structure->subtype) === 'html') {
  231.                 $this->htmlMessage = '';
  232.                 $this->htmlMessage .= $messageBody;
  233.             }
  234.         }
  235.         if (isset($structure->parts)) {
  236.             foreach ($structure->parts as $partIndex => $part) {
  237.                 $partId = $partIndex + 1;
  238.                 if (isset($partIdentifier))
  239.                     $partId = $partIdentifier . '.' . $partId;
  240.                 $this->processStructure($uid, $part, $partId);
  241.             }
  242.         }
  243.     }
  244.     private function setFileName($text) {
  245.        // $this->filename = $this->decode($text);
  246.         $this->filename = $text;
  247.     }
  248.     private function saveToDirectory($uid, $partIdentifier) { //save attachments to directory
  249.         $array = array();
  250.         $array['part'] = $partIdentifier;
  251.         $array['file'] = $this->filename;
  252.         $array['encoding'] = $this->encoding;
  253.         return $array;
  254.     }
  255.     private function decodeMessage($data, $encoding) {
  256.         if (!is_numeric($encoding)) {
  257.             $encoding = strtolower($encoding);
  258.         }
  259.         switch (true) {
  260.             case $encoding === 'quoted-printable':
  261.             case $encoding === 4:
  262.                 return quoted_printable_decode($data);
  263.             case $encoding === 'base64':
  264.             case $encoding === 3:
  265.                 return base64_decode($data);
  266.             default:
  267.                 return $data;
  268.         }
  269.     }
  270.     private function getParametersFromStructure($structure) {
  271.         $parameters = array();
  272.         if (isset($structure->parameters))
  273.             foreach ($structure->parameters as $parameter)
  274.                 $parameters[strtolower($parameter->attribute)] = $parameter->value;
  275.         if (isset($structure->dparameters))
  276.             foreach ($structure->dparameters as $parameter)
  277.                 $parameters[strtolower($parameter->attribute)] = $parameter->value;
  278.         return $parameters;
  279.     }
  280.     private function getOverview($uid) {
  281.         $results = imap_fetch_overview($this->imapStream, $uid, FT_UID);
  282.         $messageOverview = array_shift($results);
  283.         if (!isset($messageOverview->date)) {
  284.             $messageOverview->date = null;
  285.         }
  286.         return $messageOverview;
  287.     }
  288.     private function decode($text) {
  289.         if (null === $text) {
  290.             return null;
  291.         }
  292.         $result = '';
  293.         foreach (imap_mime_header_decode($text) as $word) {
  294.             $ch = 'default' === $word->charset ? 'ascii' : $word->charset;
  295.           //  $result .= iconv($ch, 'utf-8', $word->text);
  296.         }
  297.         return $result;
  298.     }
  299.     private function processAddressObject($addresses) {
  300.         $outputAddresses = array();
  301.         if (is_array($addresses))
  302.             foreach ($addresses as $address) {
  303.                 if (property_exists($address, 'mailbox') && $address->mailbox != 'undisclosed-recipients') {
  304.                     $currentAddress = array();
  305.                     $currentAddress['address'] = $address->mailbox . '@' . $address->host;
  306.                     if (isset($address->personal)) {
  307.                         $currentAddress['name'] = $this->decode($address->personal);
  308.                     }
  309.                     $outputAddresses = $currentAddress;
  310.                 }
  311.             }
  312.         return $outputAddresses;
  313.     }
  314.     private function getHeaders($uid) {
  315.         $rawHeaders = $this->getRawHeaders($uid);
  316.         $headerObject = imap_rfc822_parse_headers($rawHeaders);
  317.         if (isset($headerObject->date)) {
  318.             $headerObject->udate = strtotime($headerObject->date);
  319.         } else {
  320.             $headerObject->date = null;
  321.             $headerObject->udate = null;
  322.         }
  323.         $this->headers = $headerObject;
  324.         return $this->headers;
  325.     }
  326.     private function getRawHeaders($uid) {
  327.         $rawHeaders = imap_fetchheader($this->imapStream, $uid, FT_UID);
  328.         return $rawHeaders;
  329.     }
  330.     private function getStructure($uid) {
  331.         $structure = imap_fetchstructure($this->imapStream, $uid, FT_UID);
  332.         return $structure;
  333.     }
  334.     public function __destruct() {
  335.         if (!empty($this->errors)) {
  336.             foreach ($this->errors as $error) {
  337.                 echo $error;
  338.             }
  339.         }
  340.     }
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement