vendor/ssilence/php-imap-client/ImapClient/ImapClient.php line 660

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright (C) 2016-2017  SSilence
  4.  * For the full license, please see LICENSE. 
  5.  */
  6. namespace SSilence\ImapClient;
  7. /**
  8.  * Class ImapClient is helper class for imap access.
  9.  *
  10.  * @copyright  Copyright (c) Tobias Zeising (http://www.aditu.de)
  11.  * @author     Tobias Zeising <tobias.zeising@aditu.de>
  12.  */
  13. class ImapClient
  14. {
  15.     /**
  16.      * Use the Secure Socket Layer to encrypt the session
  17.      */
  18.     const ENCRYPT_SSL 'ssl';
  19.     /**
  20.      * Force use of start-TLS to encrypt the session, and reject connection to servers that do not support it
  21.      */
  22.     const ENCRYPT_TLS 'tls';
  23.     const CONNECT_ADVANCED 'connectAdvanced';
  24.     const CONNECT_DEFAULT 'connectDefault';
  25.     /**
  26.      * Connect status or advanced or default
  27.      *
  28.      * @var string
  29.      */
  30.     public static $connect;
  31.     /**
  32.      * Config for advanced connect
  33.      *
  34.      * @var array
  35.      */
  36.     public static $connectConfig;
  37.     /**
  38.      * Incoming message
  39.      *
  40.      * @var IncomingMessage
  41.      */
  42.     public $incomingMessage;
  43.     /**
  44.      * Imap connection
  45.      *
  46.      * @var resource ImapConnect
  47.      */
  48.     protected $imap;
  49.     /**
  50.      * Mailbox url
  51.      *
  52.      * @var string
  53.      */
  54.     protected $mailbox "";
  55.     /**
  56.      * Current folder
  57.      *
  58.      * @var string
  59.      */
  60.     protected $folder "INBOX";
  61.     /**
  62.      * Initialize imap helper
  63.      *
  64.      * @param string $mailbox
  65.      * @param string $username
  66.      * @param string $password
  67.      * @param string $encryption use ImapClient::ENCRYPT_SSL or ImapClient::ENCRYPT_TLS
  68.      */
  69.     public function __construct($mailbox null$username null$password null$encryption null)
  70.     {
  71.         if(isset($mailbox) && is_string($mailbox)){
  72.             $this->setConnectDefault();
  73.         };
  74.         if(isset($mailbox) && is_array($mailbox)){
  75.             $this->setConnectAdvanced();
  76.             $this->setConnectConfig($mailbox);
  77.         };
  78.         if(!isset(self::$connect) || self::$connect === self::CONNECT_DEFAULT){
  79.             $this->connectDefault($mailbox$username$password$encryption);
  80.         };
  81.         if(self::$connect === self::CONNECT_ADVANCED){
  82.             $this->connectAdvanced(self::$connectConfig);
  83.         };
  84.     }
  85.     /**
  86.      * Get the imap resource
  87.      *
  88.      * @return resource
  89.      */
  90.     public function getImap()
  91.     {
  92.         return $this->imap;
  93.     }
  94.     /**
  95.      * Set connection to advanced
  96.      *
  97.      * @return void
  98.      */
  99.     public static function setConnectAdvanced()
  100.     {
  101.         static::$connect self::CONNECT_ADVANCED;
  102.     }
  103.     /**
  104.      * Set connection to default
  105.      *
  106.      * @return void
  107.      */
  108.     public static function setConnectDefault()
  109.     {
  110.         static::$connect self::CONNECT_DEFAULT;
  111.     }
  112.     /**
  113.      * Get the imap connection
  114.      *
  115.      * $return imap
  116.      */
  117.     public function getImapConnection() {
  118.         return $this->imap;   
  119.     }
  120.     
  121.     /**
  122.      * Set connection config
  123.      *
  124.      * @param array $config
  125.      * @return void
  126.      */
  127.     public static function setConnectConfig(array $config)
  128.     {
  129.         static::$connectConfig $config;
  130.     }
  131.     /**
  132.      * The default connection.
  133.      * Not used a lot of imap connection options.
  134.      * Use only ENCRYPT_SSL and VALIDATE_CERT.
  135.      *
  136.      * If you need a more advanced connection settings,
  137.      * use connectAdvanced() method.
  138.      *
  139.      * @param string $mailbox
  140.      * @param string $username
  141.      * @param string $password
  142.      * @param string $encryption use ImapClient::ENCRYPT_SSL or ImapClient::ENCRYPT_TLS
  143.      * @return void
  144.      */
  145.     public function connectDefault($mailbox$username$password$encryption null)
  146.     {
  147.         $connect = new ImapConnect();
  148.         if($encryption === ImapClient::ENCRYPT_SSL){
  149.             $connect->prepareFlags(ImapConnect::SERVICE_IMAPImapConnect::ENCRYPT_SSLImapConnect::NOVALIDATE_CERT);
  150.         };
  151.         if($encryption === ImapClient::ENCRYPT_TLS){
  152.             $connect->prepareFlags(ImapConnect::SERVICE_IMAPImapConnect::ENCRYPT_TLSImapConnect::NOVALIDATE_CERT);
  153.         };
  154.         $connect->prepareMailbox($mailbox);
  155.         $connect->connect(null$username$password);
  156.         $this->imap $connect->getImap();
  157.         $this->mailbox $connect->getMailbox();
  158.     }
  159.     /**
  160.      * Advanced connect
  161.      *
  162.      * @param array $config
  163.      * @return void
  164.      * @throws ImapClientException
  165.      */
  166.     public function connectAdvanced(array $config)
  167.     {
  168.         if(!isset($config['flags'])){$config['flags'] = null;};
  169.         if(!isset($config['mailbox'])){$config['mailbox'] = null;};
  170.         if(!isset($config['connect'])){
  171.             throw new ImapClientException('Option connect must be installed');
  172.         };
  173.         $connect = new ImapConnect();
  174.         $connect->prepareFlags($config['flags']);
  175.         $connect->prepareMailbox($config['mailbox']);
  176.         $connect->connect($config['connect']);
  177.         $this->imap $connect->getImap();
  178.         $this->mailbox $connect->getMailbox();
  179.     }
  180.     /**
  181.      * Close connection
  182.      *
  183.      * Also called during garbage collection
  184.      *
  185.      * @return void
  186.      */
  187.     public function __destruct()
  188.     {
  189.         if (is_resource($this->imap))
  190.         {
  191.             imap_close($this->imap);
  192.         }
  193.     }
  194.     /**
  195.      * Returns true after successful connection
  196.      *
  197.      * @return bool true on success
  198.      */
  199.     public function isConnected()
  200.     {
  201.         return $this->imap !== false;
  202.     }
  203.     /**
  204.      * Saves the email into a file
  205.      * Note: If your server does not have alot of RAM, this may break
  206.      *
  207.      * @param string $file
  208.      * @param integer $id
  209.      * @param string $part
  210.      * @return bool true on success
  211.      * @throws ImapClientException
  212.      */
  213.      public function saveEmail($file null$id null$part null)
  214.      {
  215.          // Null checks
  216.          if($file === null)
  217.          {
  218.              throw new ImapClientException('File must be specified for saveEmail()');
  219.          }
  220.          if($id === null)
  221.          {
  222.              throw new ImapClientException('Email id must be specified for saveEmail()');
  223.          }
  224.          if($part === null)
  225.          {
  226.              $parts false;
  227.          }
  228.          else {
  229.              $parts true;
  230.          }
  231.          // Is type checks
  232.          if(!is_string($file))
  233.          {
  234.              throw new ImapClientException('File must be a string for saveEmail()');
  235.          }
  236.          if(!is_int($id))
  237.          {
  238.              throw new ImapClientException('$id must be a integer for saveEmail()');
  239.          }
  240.          $saveFile fopen($file,'w');
  241.          if($parts)
  242.          {
  243.              $ret imap_savebody($this->imap$saveFile$id$part);
  244.          }
  245.          else {
  246.              $ret imap_savebody($this->imap$saveFile$id);
  247.          }
  248.          fclose($saveFile);
  249.          
  250.          return $ret;
  251.      }
  252.      /**
  253.       * Saves the email into a file
  254.       * Note: This is safer then saveEmail for slower servers
  255.       *
  256.       * @param string $file
  257.       * @param integer $id
  258.       * @param string $part
  259.       * @param string $streamFilter
  260.       * @return bool true on success
  261.       * @throws ImapClientException
  262.       */
  263.       public function saveEmailSafe($file null$id null$part null$streamFilter 'convert.base64-decode')
  264.       {
  265.           // Null checks
  266.           if($file === null)
  267.           {
  268.               throw new ImapClientException('File must be specified for saveEmailSafe()');
  269.           }
  270.           if($id === null)
  271.           {
  272.               throw new ImapClientException('Email id must be specified for saveEmailSafe()');
  273.           }
  274.           if($part === null)
  275.           {
  276.               $parts false;
  277.           }
  278.           else {
  279.               $parts true;
  280.           }
  281.           // Is type checks
  282.           if(!is_string($file))
  283.           {
  284.               throw new ImapClientException('File must be a string for saveEmailSafe()');
  285.           }
  286.           if(!is_int($id))
  287.           {
  288.               throw new ImapClientException('$id must be a integer for saveEmailSafe()');
  289.           }
  290.           $saveFile fopen($file,'w');
  291.           stream_filter_append($saveFile$streamFilterSTREAM_FILTER_WRITE);
  292.           if($parts)
  293.           {
  294.               $ret imap_savebody($this->imap$saveFile$id$part);
  295.           }
  296.           else {
  297.               $ret imap_savebody($this->imap$saveFile$id);
  298.           };
  299.           fclose($saveFile);
  300.           return $ret;
  301.       }
  302.     /**
  303.      * Returns the last imap error
  304.      *
  305.      * @return string error message
  306.      */
  307.     public function getError()
  308.     {
  309.         return imap_last_error();
  310.     }
  311.     /**
  312.      * Select the given folder folder
  313.      * and set $this->folder
  314.      *
  315.      * @param string $folder name
  316.      * @return bool successful opened folder
  317.      */
  318.     public function selectFolder($folder)
  319.     {
  320.         $result imap_reopen($this->imap$this->mailbox $folder);
  321.         if ($result === true) {
  322.             $this->folder $folder;
  323.         }
  324.         return $result;
  325.     }
  326.     /**
  327.      * Returns all available folders
  328.      *
  329.      * @param string $separator default is '.'
  330.      * @param integer $type has three meanings 0,1,2.
  331.      * If 0 return nested array, if 1 return an array of strings, if 2 return raw imap_list()
  332.      * @return array with folder names
  333.      */
  334.     public function getFolders($separator null$type 0)
  335.     {
  336.         if(preg_match'/^{.+}/'$this->mailbox$matches)){
  337.             $mailbox $matches[0];
  338.         }else{
  339.             $mailbox $this->mailbox;
  340.         };
  341.         $folders imap_list($this->imap$mailbox"*");
  342.         if ($type == 2) {
  343.             return $folders;
  344.         };
  345.         if ($type == 1) {
  346.             return str_replace($mailbox""$folders);
  347.         };
  348.         if ($type == 0) {
  349.             $arrayRaw str_replace($mailbox""$folders);
  350.             if (!isset($separator)) {
  351.                 $separator '.';
  352.             };
  353.             $arrayNew = [];
  354.             foreach ($arrayRaw as $string) {
  355.                 $array explode($separator$string);
  356.                 $count count($array);
  357.                 $count $count-1;
  358.                 $cache false;
  359.                 for($i=$count$i>=0$i--){
  360.                     if($i == $count){
  361.                         $cache = [$array[$i]=>[]];
  362.                     }else{
  363.                         $cache = [$array[$i] => $cache];
  364.                     };
  365.                 };
  366.                 $arrayNew array_merge_recursive($arrayNew$cache);
  367.             };
  368.             return $arrayNew;
  369.         }
  370.         return null;
  371.     }
  372.     /**
  373.      * Returns the number of messages in the current folder
  374.      *
  375.      * @return int message count
  376.      */
  377.     public function countMessages()
  378.     {
  379.         return imap_num_msg($this->imap);
  380.     }
  381.     /**
  382.      * Returns an array of brief information about each message in the current mailbox.
  383.      *
  384.      * Returns the following structure of the array of arrays.
  385.      * ```php
  386.      * $array = [
  387.      *     [ 'id'=>4, 'info'=>'brief info' ]
  388.      *     [ 'id'=>5, 'info'=>'brief info' ]
  389.      * ]
  390.      *```
  391.      * @return array
  392.      */
  393.     public function getBriefInfoMessages()
  394.     {
  395.         $array imap_headers($this->imap);
  396.         $newArray = [];
  397.         foreach ($array as $key => $string) {
  398.             $newArray[] = ['id'=>$key+1'info' => $string];
  399.         };
  400.         return $newArray;
  401.     }
  402.     /**
  403.      * Returns the number of unread messages in the current folder
  404.      *
  405.      * @return integer Message count
  406.      */
  407.     public function countUnreadMessages() {
  408.         $result imap_search($this->imap'UNSEEN');
  409.         if ($result === false) {
  410.             return 0;
  411.         }
  412.         return count($result);
  413.     }
  414.     /**
  415.      * Returns unseen emails in the current folder
  416.      *
  417.      * @param bool $read Mark message like SEEN or no.
  418.      * @return array objects IncomingMessage
  419.      * @throws ImapClientException
  420.      */
  421.     public function getUnreadMessages($read true) {
  422.         $emails = [];
  423.         $result imap_search($this->imap'UNSEEN');
  424.         if(!$result){
  425.             throw new ImapClientException('No read messages were found.');
  426.         };
  427.         $ids ''$countId count($result);
  428.         foreach($result as $key=>$id) {
  429.             $emails[]= $this->getMessage($id);
  430.             if(($countId-1) == $key){
  431.                 $ids .= $id;
  432.             }else{
  433.                 $ids .= $id.',';
  434.             };
  435.         }
  436.         /* Set flag UNSEEN */
  437.         if(!$read){
  438.             $this->setUnseenMessage($ids);
  439.         }else{
  440.             $this->setSeenMessage($ids);
  441.         };
  442.         return $emails;
  443.     }
  444.     /**
  445.      * Get Messages by Criteria
  446.      *
  447.      * @see http://php.net/manual/en/function.imap-search.php
  448.      * @param string $criteria ALL, UNSEEN, FLAGGED, UNANSWERED, DELETED, UNDELETED, etc (e.g. FROM "joey smith")
  449.      * @param int    $number
  450.      * @param int    $start
  451.      * @param string $order
  452.      * @return array
  453.      * @throws ImapClientException
  454.      */
  455.     public function getMessagesByCriteria($criteria ''$number 0$start 0$order 'DESC')
  456.     {
  457.         $emails = array();
  458.         $result imap_search($this->imap$criteria);
  459.         if(!$result){
  460.             throw new ImapClientException('Messages not found. Or this criteria not supported on your email server.');
  461.         };
  462.         if ($number == 0)
  463.         {
  464.             $number count($result);
  465.         }
  466.         if ($result)
  467.         {
  468.             $ids = array();
  469.             foreach ($result as $k => $i)
  470.             {
  471.                 $ids[] = $i;
  472.             }
  473.             $ids array_chunk($ids$number);
  474.             $ids array_slice($ids[0], $start$number);
  475.             $emails = array();
  476.             foreach ($ids as $id)
  477.             {
  478.                 $emails[] = $this->getMessage($id);
  479.             }
  480.         }
  481.         if ($order == 'DESC')
  482.         {
  483.             $emails array_reverse($emails);
  484.         }
  485.         return $emails;
  486.     }
  487.     /**
  488.      * Save Attachments Messages By Subject
  489.      *
  490.      * @param string $subject
  491.      * @param string $dir for save attachments
  492.      * @param string $charset for search
  493.      * @return void
  494.      * @throws ImapClientException
  495.      */
  496.     public function saveAttachmentsMessagesBySubject($subject$dir null$charset null)
  497.     {
  498.         $criteria 'SUBJECT "'.$subject.'"';
  499.         $ids imap_search($this->imap$criterianull$charset);
  500.         if(!$ids){
  501.             throw new ImapClientException('Messages not found. Or this criteria not supported on your email server.');
  502.         };
  503.         foreach ($ids as $id) {
  504.             $this->getMessage($id);
  505.             if(isset($dir)){
  506.                 $dir = ['dir'=>$dir];
  507.             };
  508.             $this->saveAttachments($dir);
  509.         };
  510.     }
  511.     /**
  512.      * Get messages
  513.      *
  514.      * @param int    $number       Number of messages. 0 to get all
  515.      * @param int    $start        Starting message number
  516.      * @param string $order        ASC or DESC
  517.      * @return array IncomingMessage of objects
  518.      */
  519.     public function getMessages($number 0$start 0$order 'DESC')
  520.     {
  521.         if ($number == 0)
  522.         {
  523.             $number $this->countMessages();
  524.         }
  525.         $emails = array();
  526.         $result imap_search($this->imap'ALL');
  527.         if ($result)
  528.         {
  529.             $ids = array();
  530.             foreach ($result as $k => $i)
  531.             {
  532.                 $ids[] = $i;
  533.             }
  534.             if ($order == 'DESC')
  535.             {
  536.                 $ids array_reverse($ids);
  537.             }
  538.             if (count($ids) > $number) {
  539.                 $ids array_chunk($ids$number);
  540.                 $ids $ids[$start];
  541.             }
  542.             if (isset($ids)) {
  543.                 foreach ($ids as $id) {
  544.                     $emails[] = $this->getMessage($id);
  545.                 }
  546.             }
  547.         }
  548.         return $emails;
  549.     }
  550.     /**
  551.      * Returns one email by given id
  552.      *
  553.      * Examples:
  554.      *
  555.      * 1. Structure
  556.      *  ```php
  557.      *  $imap = new ImapClient();
  558.      *  $imap->getMessage(5);
  559.      *  ```
  560.      *
  561.      *  You can see all structure that
  562.      *  ```php
  563.      *  var_dump($imap->incomingMessage)
  564.      *  ```
  565.      *
  566.      *  But use like this
  567.      *  ```php
  568.      *  $imap->incomingMessage->header->subject
  569.      *  $imap->incomingMessage->header->from
  570.      *  $imap->incomingMessage->header->to
  571.      *  # cc or bcc
  572.      *  $imap->incomingMessage->header->details->cc
  573.      *  $imap->incomingMessage->header->details->bcc
  574.      *  # and other ...
  575.      *  var_dump($imap->incomingMessage->header)
  576.      *  ```
  577.      *
  578.      *  Next Text or Html body
  579.      *  ```php
  580.      *  $imap->incomingMessage->message->html
  581.      *  $imap->incomingMessage->message->plain
  582.      *  # below is array
  583.      *  $imap->incomingMessage->message->info
  584.      *  ```
  585.      *
  586.      *  Array attachments
  587.      *  ```php
  588.      *  $imap->incomingMessage->attachment
  589.      *  ```
  590.      *  Attachment have structure and body
  591.      *  ```php
  592.      *  $imap->incomingMessage->attachment[0]
  593.      *  $imap->incomingMessage->attachment[0]->structure
  594.      *  $imap->incomingMessage->attachment[0]->body
  595.      *  ```
  596.      *
  597.      *  Count section
  598.      *  ```php
  599.      *  $imap->incomingMessage->section
  600.      *  ```
  601.      *
  602.      *  And structure all message
  603.      *  ```php
  604.      *  $imap->incomingMessage->structure
  605.      *  ```
  606.      *
  607.      * 2. Save all attachments
  608.      *  ```php
  609.      *  $imap->getMessage(5);
  610.      *  $imap->saveAttachments();
  611.      *  ```
  612.      * @see IncomingMessage
  613.      * @param integer $id
  614.      * @param string $decode IncomingMessage::DECODE or IncomingMessage::NOT_DECODE
  615.      * @return object IncomingMessage
  616.      */
  617.     public function getMessage($id$decode IncomingMessage::DECODE)
  618.     {
  619.         $this->checkMessageId($id);
  620.         $this->incomingMessage = new IncomingMessage($this->imap$id$decode);
  621.         return $this->incomingMessage;
  622.     }
  623.     /**
  624.      * Get a section of the message
  625.      *
  626.      * @param integer $id
  627.      * @param string $section
  628.      * @return object
  629.      */
  630.     public function getSection($id$section)
  631.     {
  632.         $incomingMessage = new IncomingMessage($this->imap$id);
  633.         return $incomingMessage->getSection($section);
  634.     }
  635.     /**
  636.      * Save attachments one incoming message
  637.      *
  638.      * The allowed types are TypeAttachments
  639.      * You can add your own
  640.      *
  641.      * @param array $options have next parameters
  642.      * ```php
  643.      * # it is directory for save attachments
  644.      * $options['dir']
  645.      * # it is incomingMessage object
  646.      * $options['incomingMessage']
  647.      * ```
  648.      * @return void
  649.      */
  650.     public function saveAttachments($options null)
  651.     {
  652.         if(!isset($options['dir'])){
  653.             $dir __DIR__.DIRECTORY_SEPARATOR;
  654.         }else{
  655.             $dir $options['dir'];
  656.         };
  657.         if(!isset($options['incomingMessage'])){
  658.             $incomingMessage $this->incomingMessage;
  659.         }else{
  660.             $incomingMessage $options['incomingMessage'];
  661.         };
  662.         foreach ($incomingMessage->attachments as $key => $attachment) {
  663.             $newFileName $attachment->name;
  664.             file_put_contents($dir.DIRECTORY_SEPARATOR.$newFileName$attachment->body);
  665.         };
  666.     }
  667.     /**
  668.      * Delete the given message
  669.      *
  670.      * @param int $id of the message
  671.      * @return bool success or not
  672.      */
  673.     public function deleteMessage($id)
  674.     {
  675.         return $this->deleteMessages(array($id));
  676.     }
  677.     /**
  678.      * Delete messages
  679.      *
  680.      * @return bool success or not
  681.      * @param $ids array of ids
  682.      */
  683.     public function deleteMessages($ids)
  684.     {
  685.         foreach ($ids as $id) {
  686.             imap_delete($this->imap$idFT_UID);
  687.         };
  688.         return imap_expunge($this->imap);
  689.     }
  690.     /**
  691.      * Move given message in new folder
  692.      *
  693.      * @param int $id of the message
  694.      * @param string $target new folder
  695.      * @return bool success or not
  696.      */
  697.     public function moveMessage($id$target)
  698.     {
  699.         return $this->moveMessages(array($id), $target);
  700.     }
  701.     /**
  702.      * Move given message in new folder
  703.      *
  704.      * @param array $ids array of message ids
  705.      * @param string $target new folder
  706.      * @return bool success or not
  707.      */
  708.     public function moveMessages($ids$target)
  709.     {
  710.         if (imap_mail_move($this->imapimplode(","$ids), $targetCP_UID) === false)
  711.             return false;
  712.         return imap_expunge($this->imap);
  713.     }
  714.     /**
  715.      * Set flag message SEEN
  716.      *
  717.      * @param int $ids or string like 1,2,3,4,5 or string like 1:5
  718.      * @return bool
  719.      */
  720.     public function setSeenMessage($ids)
  721.     {
  722.         // We need better docs for this
  723.         return imap_setflag_full($this->imap$ids"\\Seen");
  724.     }
  725.     /**
  726.      * Delete flag message SEEN
  727.      *
  728.      * @param int $ids or string like 1,2,3,4,5 or string like 1:5
  729.      * @return bool
  730.      */
  731.     public function setUnseenMessage($ids)
  732.     {
  733.         // We need better docs for this
  734.         return imap_clearflag_full($this->imap$ids"\\Seen");
  735.     }
  736.     /**
  737.      * Add a new folder
  738.      *
  739.      * @param string $name of the folder
  740.      * @param bool|false $subscribe immediately subscribe to folder
  741.      * @return bool success or not
  742.      */
  743.     public function addFolder($name$subscribe false)
  744.     {
  745.         $success imap_createmailbox($this->imap$this->mailbox $name);
  746.         if ($success && $subscribe) {
  747.             $success imap_subscribe($this->imap$this->mailbox $name);
  748.         }
  749.         return $success;
  750.     }
  751.     /**
  752.      * Remove a folder
  753.      *
  754.      * @param string $name of the folder
  755.      * @return bool success or not
  756.      */
  757.     public function removeFolder($name)
  758.     {
  759.         return imap_deletemailbox($this->imap$this->mailbox $name);
  760.     }
  761.     /**
  762.      * Rename a folder
  763.      *
  764.      * @param string $name of the folder
  765.      * @param string $newname of the folder
  766.      * @return bool success or not
  767.      */
  768.     public function renameFolder($name$newname)
  769.     {
  770.         return imap_renamemailbox($this->imap$this->mailbox $name$this->mailbox $newname);
  771.     }
  772.     /**
  773.      * Clean up trash AND spam folder
  774.      *
  775.      * @return bool success or not
  776.      */
  777.     public function purge()
  778.     {
  779.         // delete trash and spam
  780.         if ($this->folder==$this->getTrash() || strtolower($this->folder)=="spam") {
  781.             if (imap_delete($this->imap,'1:*') === false) {
  782.                 return false;
  783.             }
  784.             return imap_expunge($this->imap);
  785.             // move others to trash
  786.         } else {
  787.             if (imap_mail_move($this->imap,'1:*'$this->getTrash()) == false) {
  788.                 return false;
  789.             }
  790.             return imap_expunge($this->imap);
  791.         }
  792.     }
  793.     /**
  794.      * Returns all email addresses in all folders
  795.      *
  796.      * If you have a lot of folders and letters, it can take a long time.
  797.      * And mark all the letters as read.
  798.      *
  799.      * @param array|null $options have options:
  800.      * ```php
  801.      * $options['getFolders']['separator']
  802.      * $options['getFolders']['type']
  803.      * $options['mark'] = SEEN and $options['mark'] = UNSEEN
  804.      * ```
  805.      * @return array with all email addresses or false on error
  806.      */
  807.     public function getAllEmailAddresses(array $options null)
  808.     {
  809.         /* Check Options */
  810.         if(!isset($options['getFolders']['separator'])){
  811.             $options['getFolders']['separator'] = '.';
  812.         };
  813.         if(!isset($options['getFolders']['type'])){
  814.             $options['getFolders']['type'] = 1;
  815.         };
  816.         if(!isset($options['mark'])){
  817.             $options['mark'] = 'SEEN';
  818.         };
  819.         $saveCurrentFolder $this->folder;
  820.         $emails = array();
  821.         foreach($this->getFolders($options['getFolders']['separator'], $options['getFolders']['type']) as $folder) {
  822.             $this->selectFolder($folder);
  823.             /**
  824.              * @var $message IncomingMessage
  825.              */
  826.             foreach($this->getMessages() as $message) {
  827.                 $emails[] = $message->header->from;
  828.                 $emails array_merge($emails$message->header->to);
  829.                 if (isset($message->header->details->cc)) {
  830.                     $emails array_merge($emails$message->header->details->cc);
  831.                 };
  832.                 if(isset($options['mark']) && $options['mark'] == 'UNSEEN'){
  833.                     $this->setUnseenMessage($message->header->msgno);
  834.                 };
  835.             }
  836.         }
  837.         $this->selectFolder($saveCurrentFolder);
  838.         return array_unique($emails);
  839.     }
  840.     /**
  841.      * Returns email addresses in the specified folder
  842.      *
  843.      * @param string $folder Specified folder
  844.      * @param array|null $options have option
  845.      * ```php
  846.      * $options['mark'] = SEEN and $options['mark'] = UNSEEN
  847.      * ```
  848.      * @return array addresses
  849.      */
  850.     public function getEmailAddressesInFolder($folder, array $options null)
  851.     {
  852.         if(!isset($options['mark'])){
  853.             $options['mark'] = 'SEEN';
  854.         };
  855.         $saveCurrentFolder $this->folder;
  856.         $this->selectFolder($folder);
  857.         $emails = array();
  858.         /**
  859.          * @var $message IncomingMessage
  860.          */
  861.         foreach($this->getMessages() as $message) {
  862.             $emails[] = $message->header->from;
  863.             $emails array_merge($emails$message->header->to);
  864.             if (isset($message->header->details->cc)) {
  865.                 $emails array_merge($emails$message->header->details->cc);
  866.             };
  867.             if(isset($options['mark']) && $options['mark'] == 'UNSEEN'){
  868.                 $this->setUnseenMessage($message->header->msgno);
  869.             };
  870.         };
  871.         $this->selectFolder($saveCurrentFolder);
  872.         return array_unique($emails);
  873.     }
  874.     /**
  875.      * Save email in sent
  876.      *
  877.      * @param string $header
  878.      * @param string $body
  879.      * @return bool
  880.      */
  881.     public function saveMessageInSent($header$body) {
  882.         return imap_append($this->imap$this->mailbox $this->getSent(), $header "\r\n" $body "\r\n""\\Seen");
  883.     }
  884.     /**
  885.      * Explicitly close imap connection
  886.      */
  887.     public function close() {
  888.         if ($this->imap !== false) {
  889.             imap_close($this->imap);
  890.         }
  891.     }
  892.     /**
  893.      * Get trash folder
  894.      *
  895.      * @return string trash folder name
  896.      */
  897.     protected function getTrash()
  898.     {
  899.         foreach ($this->getFolders(null1) as $folder) {
  900.             if (in_array(strtolower($folder), array('trash''inbox.trash''papierkorb'))) {
  901.                 return $folder;
  902.             }
  903.         }
  904.         // no trash folder found? create one
  905.         $this->addFolder('Trash');
  906.         return 'Trash';
  907.     }
  908.     /**
  909.      * Get sent
  910.      *
  911.      * @return string sent folder name
  912.      */
  913.     protected function getSent()
  914.     {
  915.         foreach ($this->getFolders(null1) as $folder) {
  916.             if (in_array(strtolower($folder), array('sent''gesendet''inbox.gesendet'))) {
  917.                 return $folder;
  918.             }
  919.         }
  920.         // no sent folder found? create one
  921.         $this->addFolder('Sent');
  922.         return 'Sent';
  923.     }
  924.     /**
  925.      * Fetch message by id
  926.      *
  927.      * @param integer $id of the message
  928.      * @return object|false header
  929.      */
  930.     public function getMessageHeader($id)
  931.     {
  932.         return $this->imapHeaderInfo($id);
  933.     }
  934.     /**
  935.      * Get message overview
  936.      *
  937.      * @see ImapClient::imapFetchOverview()
  938.      * @param integer $id
  939.      * @param null $options
  940.      * @return object
  941.      */
  942.     public function getMessageOverview($id$options null)
  943.     {
  944.         $array $this->imapFetchOverview($id$options);
  945.         return $array[0];
  946.     }
  947.     /**
  948.      * Get messages overview
  949.      *
  950.      * @param string $id
  951.      * @param null $options
  952.      * @return array
  953.      */
  954.     public function getMessagesOverview($id$options null)
  955.     {
  956.         return $this->imapFetchOverview($id$options);
  957.     }
  958.     /**
  959.      * Wrapper for php imap_fetch_overview()
  960.      *
  961.      * @see http://php.net/manual/ru/function.imap-fetch-overview.php
  962.      * @param string $sequence a message sequence description,
  963.      * you can enumerate desired messages with the X,Y syntax,
  964.      * or retrieve all messages within an interval with the X:Y syntax
  965.      * @param int $options sequence will contain a sequence of message indices or UIDs,
  966.      * if this parameter is set to FT_UID.
  967.      * @return array
  968.      */
  969.     public function imapFetchOverview($sequence$options null)
  970.     {
  971.         return imap_fetch_overview($this->imap$sequence$options);
  972.     }
  973.     /**
  974.      * Wrapper for php imap_headerinfo()
  975.      *
  976.      * @see http://php.net/manual/ru/function.imap-headerinfo.php
  977.      * @see http://php.net/manual/en/function.imap-headerinfo.php#98809
  978.      * @param integer $id
  979.      * @return object|false
  980.      */
  981.     public function imapHeaderInfo($id)
  982.     {
  983.         return imap_rfc822_parse_headers(imap_fetchheader($this->imap$id));
  984.     }
  985.     /**
  986.      * Wrapper for imap_fetchstructure()
  987.      *
  988.      * @see http://php.net/manual/ru/function.imap-fetchstructure.php
  989.      * @param integer $id
  990.      * @return object
  991.      */
  992.     public function imapFetchStructure($id)
  993.     {
  994.         return imap_fetchstructure($this->imap$id);
  995.     }
  996.     /**
  997.      * Convert imap given address into string
  998.      *
  999.      * @param object $headerinfos the infos given by imap
  1000.      * @return string in format "Name <email@bla.de>"
  1001.      */
  1002.     protected function toAddress($headerinfos) {
  1003.         $email "";
  1004.         $name "";
  1005.         if (isset($headerinfos->mailbox) && isset($headerinfos->host)) {
  1006.             $email $headerinfos->mailbox "@" $headerinfos->host;
  1007.         }
  1008.         if (!empty($headerinfos->personal)) {
  1009.             $name imap_mime_header_decode($headerinfos->personal);
  1010.             $name $name[0]->text;
  1011.         } else {
  1012.             $name $email;
  1013.         }
  1014.         $name $this->convertToUtf8($name);
  1015.         return $name " <" $email ">";
  1016.     }
  1017.     /**
  1018.      * Converts imap given array of addresses as strings
  1019.      *
  1020.      * @param array $addresses imap given addresses as array
  1021.      * @return array with strings (e.g. ["Name <email@bla.de>", "Name2 <email2@bla.de>"]
  1022.      */
  1023.     protected function arrayToAddress($addresses) {
  1024.         $addressesAsString = array();
  1025.         foreach ($addresses as $address) {
  1026.             $addressesAsString[] = $this->toAddress($address);
  1027.         }
  1028.         return $addressesAsString;
  1029.     }
  1030.     /**
  1031.      * Convert to utf8 if necessary.
  1032.      *
  1033.      * @param string $str utf8 encoded string
  1034.      * @return bool
  1035.      */
  1036.     public function convertToUtf8($str) {
  1037.         if (mb_detect_encoding($str"UTF-8, ISO-8859-1, GBK")!="UTF-8") {
  1038.             $str utf8_encode($str);
  1039.         }
  1040.         $str iconv('UTF-8''UTF-8//IGNORE'$str);
  1041.         return $str;
  1042.     }
  1043.     /**
  1044.     * Identify encoding by charset attribute in header
  1045.     *
  1046.     * @param $id
  1047.     * @return string
  1048.     */
  1049.     protected function getEncoding($id)
  1050.     {
  1051.         $header $this->imapFetchStructure($id);
  1052.         $params $header->parameters ?: [];
  1053.             foreach ($params as $k => $v) {
  1054.                 if (stristr($v->attribute'charset')) {
  1055.                     return $v->value;
  1056.                 }
  1057.             }
  1058.         return 'utf-8';
  1059.     }
  1060.     /**
  1061.      * Return general mailbox statistics
  1062.      *
  1063.      * @return bool|resource object
  1064.      */
  1065.     public function getMailboxStatistics()
  1066.     {
  1067.         return $this->isConnected() ? imap_mailboxmsginfo($this->imap) : false ;
  1068.     }
  1069.     /**
  1070.     * Unsubscribe from a mail box
  1071.     * @return bool
  1072.     */
  1073.     public function unSubscribe()
  1074.     {
  1075.         if (imap_unsubscribe($this->imap$this->mailbox)) {
  1076.             return true;
  1077.         }
  1078.         else {
  1079.             return false;
  1080.         }
  1081.     }
  1082.     /**
  1083.      * Retrieve the quota level settings, and usage statics per mailbox.
  1084.      *
  1085.      * @param string $mailbox
  1086.      *
  1087.      * @return array
  1088.      */
  1089.     public function getQuota($mailbox)
  1090.     {
  1091.         $quota imap_get_quota($this->imap"user.".$mailbox);
  1092.         return $quota;
  1093.     }
  1094.     /**
  1095.      * Retrieve the quota level settings, and usage statics per mailbox.
  1096.      *
  1097.      * @param string $mailbox
  1098.      *
  1099.      * @return array
  1100.      */
  1101.     public function getQuotaRoot($mailbox)
  1102.     {
  1103.         $quota imap_get_quotaroot($this->imap"user.".$mailbox);
  1104.         return $quota;
  1105.     }
  1106.     /**
  1107.      * Get uid from id
  1108.      *
  1109.      * @param integer $id
  1110.      * @return integer
  1111.      */
  1112.     public function getUid($id)
  1113.     {
  1114.         return imap_uid($this->imap$id);
  1115.     }
  1116.     /**
  1117.      * Get id from uid
  1118.      *
  1119.      * @param int $uid
  1120.      * @return integer
  1121.      */
  1122.     public function getId($uid)
  1123.     {
  1124.         return imap_msgno($this->imap$uid);
  1125.     }
  1126.     /**
  1127.      * Send an email
  1128.      *
  1129.      * @return void
  1130.      */
  1131.     public function sendMail()
  1132.     {
  1133.         $outMessage = new AdapterForOutgoingMessage(self::$connectConfig);
  1134.         $outMessage->send();
  1135.     }
  1136.     /**
  1137.      * Check message id
  1138.      *
  1139.      * @param integer $id
  1140.      * @return void
  1141.      * @throws ImapClientException
  1142.      */
  1143.     private function checkMessageId($id)
  1144.     {
  1145.         if(!is_int($id)){
  1146.             throw new ImapClientException('$id must be an integer!');
  1147.         };
  1148.         if($id <= 0){
  1149.             throw new ImapClientException('$id must be greater then 0!');
  1150.         };
  1151.         if($id $this->countMessages()){
  1152.             throw new ImapClientException('$id does not exist');
  1153.         }
  1154.     }
  1155. }