GOSTRA_FX

Untitled

Feb 2nd, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. /**
  3.  * Example usage:
  4.  *
  5.  * // Initalize the client
  6.  * $imap = DIOIMAP::init();
  7.  *
  8.  * // Initalize the email client without a postfix and search for the latest unread email
  9.  * $emailMessage = DIOIMAP::init()->findEmail();
  10.  *
  11.  * // Reinitalize the stream, and find the latest email with the subject "Test 123"
  12.  * $secondEmail = $imap->reinit()->findEmail("Test 123");
  13.  *
  14.  * // Occasionally, the stream needs to be reset if the instance has done nothing for a while
  15.  * $imap = $imap->reinit();
  16.  * $imap->reinit()->findEmail();
  17.  *
  18.  */
  19. class DIOIMAP {
  20.     const _IMAP_HOST = '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX';
  21.     private $imapStream;
  22.     private $user;
  23.     private $password;
  24.     private $expectedRecipient;
  25.     private $subject;
  26.     private $latestId;
  27.    
  28.     private static $lastPostfix = '';
  29.     /**
  30.      * Bootstrap a DIOIMAP object
  31.      * @param $postfix (string) RFC 2822 email tag ex: $postfix = "testTag" -> $expectedRecipient = "myGmailAcct+testTag@gmail.com"
  32.      */    
  33.     public static function init($postfix = '')
  34.     {
  35.         $key = 'myGmailAcct%s@gmail.com';
  36.         $user = sprintf($key, "");
  37.         $expectedRecipient = empty($postfix) ? $user : sprintf($key, "+$postfix");
  38.         self::$lastPostfix = $postfix;
  39.  
  40.         return new self($user, 'password!@', $expectedRecipient);
  41.     }
  42.    
  43.     /**
  44.      * @param $user (string) IMAP Server username
  45.      * @param $pass (string) IMAP Server password
  46.      * @param $expectedRecipient (string) Expected recipient (in the "TO" field) of a set of email in the inbox
  47.      */
  48.     public function __construct($user, $pass, $expectedRecipient)
  49.     {
  50.         date_default_timezone_set("UTC");
  51.         $this->user = $user;
  52.         $this->password = $pass;
  53.         $this->expectedRecipient = $expectedRecipient;
  54.         $this->openConnection();
  55.     }
  56.  
  57.     private static $TEMP_lastDate;
  58.     /**
  59.      * Return the latest email id meeting the specified recipient and subject criteria
  60.      * @param $iteration (int) OPTIONAL The number used to identify the recursive position
  61.      * @param $maxDepth (int) OPTIONAL The number used to limit the recursive depth.
  62.      * @throws Exception No new emails found matching search criteria
  63.      * @return (int) IMAP server id of the found email
  64.      */
  65.     private function refresh($iteration = 0, $maxDepth = 5)
  66.     {
  67.         $theNow = new DateTime();
  68.         $emailStack = imap_search(
  69.             $this->imapStream,
  70.             sprintf("TO %s %s UNSEEN NEW",
  71.                 $this->expectedRecipient,
  72.                 empty($this->subject) ? "" : sprintf('SUBJECT "%s"', $this->subject)
  73.             ),
  74.             SE_UID
  75.         );
  76.         $this->close();
  77.         $this->openConnection();
  78.        
  79.         var_dump("Returned Email Stack");
  80.         var_dump($emailStack);
  81.         if (!$emailStack)
  82.         {
  83.             if ($iteration < $maxDepth)
  84.             {
  85.                 sleep(10);
  86.                 var_dump($this->imapStream);
  87.                 var_dump("Iteration: $iteration");
  88.                 var_dump("Time diff:\n");
  89.                 var_dump(self::$TEMP_lastDate->diff($theNow)->format("%h:%i:%s"));
  90.                 var_dump("\n\n");
  91.                 self::$TEMP_lastDate = $theNow;
  92.                 $this->refresh($iteration+1, $maxDepth);
  93.                
  94.             }
  95.             throw new Exception(
  96.                 sprintf(
  97.                     "No new emails found matching criteria: user=%s subject=%s attempt=%s depth=%s",
  98.                     $this->expectedRecipient,
  99.                     $this->subject,
  100.                     $iteration,
  101.                     $maxDepth
  102.                 )
  103.             );
  104.         }
  105.         $this->latestId = array_pop($emailStack); // Get latest email only
  106.         // foreach($emailStack as $mailId)
  107.         // {
  108.         //     imap_clearflag_full($this->imapStream, $mailId, "//Seen");
  109.         // }
  110.         return $this->latestId;
  111.     }
  112.  
  113.     /**
  114.      * Find and return the latest email meeting the specified recipient and subject criteria
  115.      * @return (string) The email body
  116.      */
  117.     public function findEmail($subject = '')
  118.     {
  119.         $this->subject = $subject;
  120.         self::$TEMP_lastDate = new DateTime();
  121.         $this->refresh(0, 30);
  122.         $emailBody = $this->fetch($this->latestId);
  123.         $emailBody = $this->decode($emailBody);
  124.         return $emailBody;
  125.     }
  126.  
  127.     public function reinit()
  128.     {
  129.         $this->close();
  130.         return self::init(self::$lastPostfix);
  131.     }
  132.  
  133.     /**
  134.      * Close the connection to the IMAP server
  135.      */
  136.     public function close()
  137.     {
  138.         imap_close($this->imapStream);
  139.     }
  140.  
  141.     /**
  142.      * Return the expected recipient
  143.      * @return (string) The expected recipient
  144.      */
  145.     public function getRecipient()
  146.     {
  147.         return $this->expectedRecipient;
  148.     }
  149.  
  150.     private function decode($emailBody)
  151.     {
  152.         $structure = imap_fetchstructure($this->imapStream, $this->latestId);
  153.         switch ($structure->encoding)
  154.         {
  155.             case 3:
  156.                 $emailBody = imap_base64($emailBody);
  157.                 break;
  158.             case 4:
  159.             case 0:
  160.                 $emailBody = imap_qprint($emailBody);
  161.                 break;
  162.             default:
  163.                 throw new Exception(
  164.                     sprintf("Unknown encoding of email body encoding=%s", $structure->encoding)
  165.                 );
  166.         }
  167.         return $emailBody;
  168.     }
  169.  
  170.     private function openConnection()
  171.     {
  172.         $this->imapStream = imap_open(self::_IMAP_HOST, $this->user, $this->password);
  173.         if (!$this->imapStream) throw new Exception("Cannot connect to " . self::_IMAP_HOST);
  174.     }
  175.  
  176.     private function fetch($msgNumber)
  177.     {
  178.         return imap_fetchbody($this->imapStream, $msgNumber, "2", FT_UID);
  179.     }
  180. }
Add Comment
Please, Sign In to add comment