├── .github ├── FUNDING.yml └── workflows │ └── stale.yml ├── JJG └── Imap.php ├── LICENSE.md ├── README.md ├── Resources ├── Imap-Logo.png └── Imap-Logo.svg └── composer.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | --- 3 | github: geerlingguy 4 | patreon: geerlingguy 5 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Close inactive issues 3 | 'on': 4 | schedule: 5 | - cron: "55 22 * * 4" # semi-random time 6 | 7 | jobs: 8 | close-issues: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | issues: write 12 | pull-requests: write 13 | steps: 14 | - uses: actions/stale@v8 15 | with: 16 | days-before-stale: 120 17 | days-before-close: 60 18 | exempt-issue-labels: bug,pinned,security,planned 19 | exempt-pr-labels: bug,pinned,security,planned 20 | stale-issue-label: "stale" 21 | stale-pr-label: "stale" 22 | stale-issue-message: | 23 | This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 24 | 25 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 26 | close-issue-message: | 27 | This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 28 | stale-pr-message: | 29 | This pr has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 30 | 31 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 32 | close-pr-message: | 33 | This pr has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 34 | repo-token: ${{ secrets.GITHUB_TOKEN }} 35 | -------------------------------------------------------------------------------- /JJG/Imap.php: -------------------------------------------------------------------------------- 1 | getMailboxInfo(); 18 | * @endcode 19 | * 20 | * Minimum requirements: PHP 5.6.x, php5-imap 21 | * 22 | * @author Josh Grochowski (josh[at]kastang[dot]com). 23 | * @author Jeff Geerling (geerlingguy). 24 | */ 25 | 26 | namespace JJG; 27 | 28 | class Imap { 29 | 30 | private $host; 31 | private $user; 32 | private $pass; 33 | private $port; 34 | private $folder; 35 | private $ssl; 36 | 37 | private $baseAddress; 38 | private $address; 39 | private $mailbox; 40 | 41 | /** 42 | * Called when the Imap object is created. 43 | * 44 | * Sample of a complete address: {imap.gmail.com:993/imap/ssl}INBOX 45 | * 46 | * @param $host (string) 47 | * The IMAP hostname. Example: imap.gmail.com 48 | * @param $port (int) 49 | * Example: 933 50 | * @param $ssl (bool) 51 | * TRUE to use SSL, FALSE for no SSL. 52 | * @param $folder (string) 53 | * IMAP Folder to open. 54 | * @param $user (string) 55 | * Username used for connection. Gmail uses full username@gmail.com, but 56 | * many providers simply use username. 57 | * @param $pass (string) 58 | * Account password. 59 | * 60 | * @return (empty) 61 | */ 62 | public function __construct($host, $user, $pass, $port, $ssl = true, $folder = 'INBOX') { 63 | if ((!isset($host)) || (!isset($user)) || (!isset($pass)) || (!isset($port))) { 64 | throw new Exception("Error: All Constructor values require a non NULL input."); 65 | } 66 | 67 | $this->host = $host; 68 | $this->user = $user; 69 | $this->pass = $pass; 70 | $this->port = $port; 71 | $this->folder = $folder; 72 | $this->ssl = $ssl; 73 | 74 | $this->changeLoginInfo($host, $user, $pass, $port, $ssl, $folder); 75 | } 76 | 77 | /** 78 | * Change IMAP folders and reconnect to the server. 79 | * 80 | * @param $folderName 81 | * The name of the folder to change to. 82 | * 83 | * @return (empty) 84 | */ 85 | public function changeFolder($folderName) { 86 | if ($this->ssl) { 87 | $address = '{' . $this->host . ':' . $this->port . '/imap/ssl}' . $folderName; 88 | } else { 89 | $address = '{' . $this->host . ':' . $this->port . '/imap}' . $folderName; 90 | } 91 | 92 | $this->address = $address; 93 | $this->reconnect(); 94 | } 95 | 96 | /** 97 | * Log into an IMAP server. 98 | * 99 | * This method is called on the initialization of the class (see 100 | * __construct()), and whenever you need to log into a different account. 101 | * 102 | * Please see __construct() for parameter info. 103 | * 104 | * @return (empty) 105 | * 106 | * @throws Exception when IMAP can't connect. 107 | */ 108 | public function changeLoginInfo($host, $user, $pass, $port, $ssl, $folder) { 109 | if ($ssl) { 110 | $baseAddress = '{' . $host . ':' . $port . '/imap/ssl}'; 111 | $address = $baseAddress . $folder; 112 | } else { 113 | $baseAddress = '{' . $host . ':' . $port . '/imap}'; 114 | $address = $baseAddress . $folder; 115 | } 116 | 117 | // Set the new address and the base address. 118 | $this->baseAddress = $baseAddress; 119 | $this->address = $address; 120 | 121 | // Open new IMAP connection 122 | if ($mailbox = imap_open($address, $user, $pass)) { 123 | $this->mailbox = $mailbox; 124 | } else { 125 | throw new Exception("Error: " . imap_last_error()); 126 | } 127 | } 128 | 129 | /** 130 | * Returns an associative array with detailed information about a given 131 | * message. 132 | * 133 | * @param $messageId (int) 134 | * Message id. 135 | * 136 | * @return Associative array with keys (strings unless otherwise noted): 137 | * raw_header 138 | * to 139 | * from 140 | * cc 141 | * bcc 142 | * reply_to 143 | * sender 144 | * date_sent 145 | * subject 146 | * deleted (bool) 147 | * answered (bool) 148 | * draft (bool) 149 | * body 150 | * original_encoding 151 | * size (int) 152 | * auto_response (bool) 153 | * 154 | * @throws Exception when message with given id can't be found. 155 | */ 156 | public function getMessage($messageId) { 157 | $this->tickle(); 158 | 159 | // Get message details. 160 | $details = imap_headerinfo($this->mailbox, $messageId); 161 | if ($details) { 162 | // Get the raw headers. 163 | $raw_header = imap_fetchheader($this->mailbox, $messageId); 164 | 165 | // Detect whether the message is an autoresponse. 166 | $autoresponse = $this->detectAutoresponder($raw_header); 167 | 168 | // Get some basic variables. 169 | $deleted = ($details->Deleted == 'D'); 170 | $answered = ($details->Answered == 'A'); 171 | $draft = ($details->Draft == 'X'); 172 | 173 | // Get the message body. 174 | $body = imap_fetchbody($this->mailbox, $messageId, 1.2); 175 | if (!strlen($body) > 0) { 176 | $body = imap_fetchbody($this->mailbox, $messageId, 1); 177 | } 178 | 179 | // Get the message body encoding. 180 | $encoding = $this->getEncodingType($messageId); 181 | 182 | // Decode body into plaintext (8bit, 7bit, and binary are exempt). 183 | if ($encoding == 'BASE64') { 184 | $body = $this->decodeBase64($body); 185 | } 186 | elseif ($encoding == 'QUOTED-PRINTABLE') { 187 | $body = $this->decodeQuotedPrintable($body); 188 | } 189 | elseif ($encoding == '8BIT') { 190 | $body = $this->decode8Bit($body); 191 | } 192 | elseif ($encoding == '7BIT') { 193 | $body = $this->decode7Bit($body); 194 | } 195 | 196 | // Build the message. 197 | $message = array( 198 | 'raw_header' => $raw_header, 199 | 'to' => $details->toaddress, 200 | 'from' => $details->fromaddress, 201 | 'cc' => isset($details->ccaddress) ? $details->ccaddress : '', 202 | 'bcc' => isset($details->bccaddress) ? $details->bccaddress : '', 203 | 'reply_to' => isset($details->reply_toaddress) ? $details->reply_toaddress : '', 204 | 'sender' => $details->senderaddress, 205 | 'date_sent' => $details->date, 206 | 'subject' => $details->subject, 207 | 'deleted' => $deleted, 208 | 'answered' => $answered, 209 | 'draft' => $draft, 210 | 'body' => $body, 211 | 'original_encoding' => $encoding, 212 | 'size' => $details->Size, 213 | 'auto_response' => $autoresponse, 214 | ); 215 | } 216 | else { 217 | throw new Exception("Message could not be found: " . imap_last_error()); 218 | } 219 | 220 | return $message; 221 | } 222 | 223 | /** 224 | * Deletes an email matching the specified $messageId. 225 | * 226 | * @param $messageId (int) 227 | * Message id. 228 | * @param $immediate (bool) 229 | * Set TRUE if message should be deleted immediately. Otherwise, message 230 | * will not be deleted until disconnect() is called. Normally, this is a 231 | * bad idea, as other message ids will change if a message is deleted. 232 | * 233 | * @return (empty) 234 | * 235 | * @throws Exception when message can't be deleted. 236 | */ 237 | public function deleteMessage($messageId, $immediate = FALSE) { 238 | $this->tickle(); 239 | 240 | // Mark message for deletion. 241 | if (!imap_delete($this->mailbox, $messageId)) { 242 | throw new Exception("Message could not be deleted: " . imap_last_error()); 243 | } 244 | 245 | // Immediately delete the message if $immediate is TRUE. 246 | if ($immediate) { 247 | imap_expunge($this->mailbox); 248 | } 249 | } 250 | 251 | /** 252 | * Moves an email into the given mailbox. 253 | * 254 | * @param $messageId (int) 255 | * Message id. 256 | * @param $folder (string) 257 | * The name of the folder (mailbox) into which messages should be moved. 258 | * $folder could either be the folder name or 'INBOX.foldername'. 259 | * 260 | * @return (bool) 261 | * Returns TRUE on success, FALSE on failure. 262 | */ 263 | public function moveMessage($messageId, $folder) { 264 | $messageRange = $messageId . ':' . $messageId; 265 | return imap_mail_move($this->mailbox, $messageRange, $folder); 266 | } 267 | 268 | /** 269 | * Returns an associative array with email subjects and message ids for all 270 | * messages in the active $folder. 271 | * 272 | * @return Associative array with message id as key and subject as value. 273 | */ 274 | public function getMessageIds() { 275 | $this->tickle(); 276 | 277 | // Fetch overview of mailbox. 278 | $number_messages = imap_num_msg($this->mailbox); 279 | if ($number_messages) { 280 | $overviews = imap_fetch_overview($this->mailbox, "1:" . imap_num_msg($this->mailbox), 0); 281 | } 282 | else { 283 | $overviews = array(); 284 | } 285 | $messageArray = array(); 286 | 287 | // Loop through message overviews, build message array. 288 | foreach($overviews as $overview) { 289 | $messageArray[$overview->msgno] = $overview->subject; 290 | } 291 | 292 | return $messageArray; 293 | } 294 | 295 | /** 296 | * Return an associative array containing the number of recent, unread, and 297 | * total messages. 298 | * 299 | * @return Associative array with keys: 300 | * unread 301 | * recent 302 | * total 303 | */ 304 | public function getCurrentMailboxInfo() { 305 | $this->tickle(); 306 | 307 | // Get general mailbox information. 308 | $info = imap_status($this->mailbox, $this->address, SA_ALL); 309 | $mailInfo = array( 310 | 'unread' => $info->unseen, 311 | 'recent' => $info->recent, 312 | 'total' => $info->messages, 313 | ); 314 | return $mailInfo; 315 | } 316 | 317 | /** 318 | * Return an array of objects containing mailbox information. 319 | * 320 | * @return Array of mailbox names. 321 | */ 322 | public function getMailboxInfo() { 323 | $this->tickle(); 324 | 325 | // Get all mailbox information. 326 | $mailboxInfo = imap_getmailboxes($this->mailbox, $this->baseAddress, '*'); 327 | $mailboxes = array(); 328 | foreach ($mailboxInfo as $mailbox) { 329 | // Remove baseAddress from mailbox name. 330 | $mailboxes[] = array( 331 | 'mailbox' => $mailbox->name, 332 | 'name' => str_replace($this->baseAddress, '', $mailbox->name), 333 | ); 334 | } 335 | 336 | return $mailboxes; 337 | } 338 | 339 | /** 340 | * Decodes Base64-encoded text. 341 | * 342 | * @param $text (string) 343 | * Base64 encoded text to convert. 344 | * 345 | * @return (string) 346 | * Decoded text. 347 | */ 348 | public function decodeBase64($text) { 349 | $this->tickle(); 350 | return imap_base64($text); 351 | } 352 | 353 | /** 354 | * Decodes quoted-printable text. 355 | * 356 | * @param $text (string) 357 | * Quoted printable text to convert. 358 | * 359 | * @return (string) 360 | * Decoded text. 361 | */ 362 | public function decodeQuotedPrintable($text) { 363 | return quoted_printable_decode($text); 364 | } 365 | 366 | /** 367 | * Decodes 8-Bit text. 368 | * 369 | * @param $text (string) 370 | * 8-Bit text to convert. 371 | * 372 | * @return (string) 373 | * Decoded text. 374 | */ 375 | public function decode8Bit($text) { 376 | return quoted_printable_decode(imap_8bit($text)); 377 | } 378 | 379 | /** 380 | * Decodes 7-Bit text. 381 | * 382 | * PHP seems to think that most emails are 7BIT-encoded, therefore this 383 | * decoding method assumes that text passed through may actually be base64- 384 | * encoded, quoted-printable encoded, or just plain text. Instead of passing 385 | * the email directly through a particular decoding function, this method 386 | * runs through a bunch of common encoding schemes to try to decode everything 387 | * and simply end up with something *resembling* plain text. 388 | * 389 | * Results are not guaranteed, but it's pretty good at what it does. 390 | * 391 | * @param $text (string) 392 | * 7-Bit text to convert. 393 | * 394 | * @return (string) 395 | * Decoded text. 396 | */ 397 | public function decode7Bit($text) { 398 | // If there are no spaces on the first line, assume that the body is 399 | // actually base64-encoded, and decode it. 400 | $lines = explode("\r\n", $text); 401 | $first_line_words = explode(' ', $lines[0]); 402 | if ($first_line_words[0] == $lines[0]) { 403 | $text = base64_decode($text); 404 | } 405 | 406 | // Manually convert common encoded characters into their UTF-8 equivalents. 407 | $characters = array( 408 | '=20' => ' ', // space. 409 | '=2C' => ',', // comma. 410 | '=E2=80=99' => "'", // single quote. 411 | '=0A' => "\r\n", // line break. 412 | '=0D' => "\r\n", // carriage return. 413 | '=A0' => ' ', // non-breaking space. 414 | '=B9' => '$sup1', // 1 superscript. 415 | '=C2=A0' => ' ', // non-breaking space. 416 | "=\r\n" => '', // joined line. 417 | '=E2=80=A6' => '…', // ellipsis. 418 | '=E2=80=A2' => '•', // bullet. 419 | '=E2=80=93' => '–', // en dash. 420 | '=E2=80=94' => '—', // em dash. 421 | ); 422 | 423 | // Loop through the encoded characters and replace any that are found. 424 | foreach ($characters as $key => $value) { 425 | $text = str_replace($key, $value, $text); 426 | } 427 | 428 | return $text; 429 | } 430 | 431 | /** 432 | * Strips quotes (older messages) from a message body. 433 | * 434 | * This function removes any lines that begin with a quote character (>). 435 | * Note that quotes in reply bodies will also be removed by this function, 436 | * so only use this function if you're okay with this behavior. 437 | * 438 | * @param $message (string) 439 | * The message to be cleaned. 440 | * @param $plain_text_output (bool) 441 | * Set to TRUE to also run the text through strip_tags() (helpful for 442 | * cleaning up HTML emails). 443 | * 444 | * @return (string) 445 | * Same as message passed in, but with all quoted text removed. 446 | * 447 | * @see http://stackoverflow.com/a/12611562/100134 448 | */ 449 | public function cleanReplyEmail($message, $plain_text_output = FALSE) { 450 | // Strip markup if $plain_text_output is set. 451 | if ($plain_text_output) { 452 | $message = strip_tags($message); 453 | } 454 | 455 | // Remove quoted lines (lines that begin with '>'). 456 | $message = preg_replace("/(^\w.+:\n)?(^>.*(\n|$))+/mi", '', $message); 457 | 458 | // Remove lines beginning with 'On' and ending with 'wrote:' (matches 459 | // Mac OS X Mail, Gmail). 460 | $message = preg_replace("/^(On).*(wrote:).*$/sm", '', $message); 461 | 462 | // Remove lines like '----- Original Message -----' (some other clients). 463 | // Also remove lines like '--- On ... wrote:' (some other clients). 464 | $message = preg_replace("/^---.*$/mi", '', $message); 465 | 466 | // Remove lines like '____________' (some other clients). 467 | $message = preg_replace("/^____________.*$/mi", '', $message); 468 | 469 | // Remove blocks of text with formats like: 470 | // - 'From: Sent: To: Subject:' 471 | // - 'From: To: Sent: Subject:' 472 | // - 'From: Date: To: Reply-to: Subject:' 473 | $message = preg_replace("/From:.*^(To:).*^(Subject:).*/sm", '', $message); 474 | 475 | // Remove any remaining whitespace. 476 | $message = trim($message); 477 | 478 | return $message; 479 | } 480 | 481 | /** 482 | * Takes in a string of email addresses and returns an array of addresses 483 | * as objects. For example, passing in 'John Doe ' 484 | * returns the following array: 485 | * 486 | * Array ( 487 | * [0] => stdClass Object ( 488 | * [mailbox] => johndoe 489 | * [host] => sample.com 490 | * [personal] => John Doe 491 | * ) 492 | * ) 493 | * 494 | * You can pass in a string with as many addresses as you'd like, and each 495 | * address will be parsed into a new object in the returned array. 496 | * 497 | * @param $addresses (string) 498 | * String of one or more email addresses to be parsed. 499 | * 500 | * @return (array) 501 | * Array of parsed email addresses, as objects. 502 | * 503 | * @see imap_rfc822_parse_adrlist(). 504 | */ 505 | public function parseAddresses($addresses) { 506 | return imap_rfc822_parse_adrlist($addresses, '#'); 507 | } 508 | 509 | /** 510 | * Create an email address to RFC822 specifications. 511 | * 512 | * @param $username (string) 513 | * Name before the @ sign in an email address (example: 'johndoe'). 514 | * @param $host (string) 515 | * Address after the @ sign in an email address (example: 'sample.com'). 516 | * @param $name (string) 517 | * Name of the entity (example: 'John Doe'). 518 | * 519 | * @return (string) Email Address in the following format: 520 | * 'John Doe ' 521 | */ 522 | public function createAddress($username, $host, $name) { 523 | return imap_rfc822_write_address($username, $host, $name); 524 | } 525 | 526 | /** 527 | * Returns structured information for a given message id. 528 | * 529 | * @param $messageId 530 | * Message id for which structure will be returned. 531 | * 532 | * @return (object) 533 | * See imap_fetchstructure() return values for details. 534 | * 535 | * @see imap_fetchstructure(). 536 | */ 537 | public function getStructure($messageId) { 538 | return imap_fetchstructure($this->mailbox, $messageId); 539 | } 540 | 541 | /** 542 | * Returns the primary body type for a given message id. 543 | * 544 | * @param $messageId (int) 545 | * Message id. 546 | * @param $numeric (bool) 547 | * Set to true for a numerical body type. 548 | * 549 | * @return (mixed) 550 | * Integer value of body type if numeric, string if not numeric. 551 | */ 552 | public function getBodyType($messageId, $numeric = false) { 553 | // See imap_fetchstructure() documentation for explanation. 554 | $types = array( 555 | 0 => 'Text', 556 | 1 => 'Multipart', 557 | 2 => 'Message', 558 | 3 => 'Application', 559 | 4 => 'Audio', 560 | 5 => 'Image', 561 | 6 => 'Video', 562 | 7 => 'Other', 563 | ); 564 | 565 | // Get the structure of the message. 566 | $structure = $this->getStructure($messageId); 567 | 568 | // Return a number or a string, depending on the $numeric value. 569 | if ($numeric) { 570 | return $structure->type; 571 | } else { 572 | return $types[$structure->type]; 573 | } 574 | } 575 | 576 | /** 577 | * Returns the encoding type of a given $messageId. 578 | * 579 | * @param $messageId (int) 580 | * Message id. 581 | * @param $numeric (bool) 582 | * Set to true for a numerical encoding type. 583 | * 584 | * @return (mixed) 585 | * Integer value of body type if numeric, string if not numeric. 586 | */ 587 | public function getEncodingType($messageId, $numeric = false) { 588 | // See imap_fetchstructure() documentation for explanation. 589 | $encodings = array( 590 | 0 => '7BIT', 591 | 1 => '8BIT', 592 | 2 => 'BINARY', 593 | 3 => 'BASE64', 594 | 4 => 'QUOTED-PRINTABLE', 595 | 5 => 'OTHER', 596 | ); 597 | 598 | // Get the structure of the message. 599 | $structure = $this->getStructure($messageId); 600 | 601 | // Return a number or a string, depending on the $numeric value. 602 | if ($numeric) { 603 | return $structure->encoding; 604 | } else { 605 | return $encodings[$structure->encoding]; 606 | } 607 | } 608 | 609 | /** 610 | * Closes an active IMAP connection. 611 | * 612 | * @return (empty) 613 | */ 614 | public function disconnect() { 615 | // Close the connection, deleting all messages marked for deletion. 616 | imap_close($this->mailbox, CL_EXPUNGE); 617 | } 618 | 619 | /** 620 | * Reconnect to the IMAP server. 621 | * 622 | * @return (empty) 623 | * 624 | * @throws Exception when IMAP can't reconnect. 625 | */ 626 | private function reconnect() { 627 | $this->mailbox = imap_open($this->address, $this->user, $this->pass); 628 | if (!$this->mailbox) { 629 | throw new Exception("Reconnection Failure: " . imap_last_error()); 630 | } 631 | } 632 | 633 | /** 634 | * Checks to see if the connection is alive. If not, reconnects to server. 635 | * 636 | * @return (empty) 637 | */ 638 | private function tickle() { 639 | if (!imap_ping($this->mailbox)) { 640 | $this->reconnect; 641 | } 642 | } 643 | 644 | /** 645 | * Determines whether the given message is from an auto-responder. 646 | * 647 | * This method checks whether the header contains any auto response headers as 648 | * outlined in RFC 3834, and also checks to see if the subject line contains 649 | * certain strings set by different email providers to indicate an automatic 650 | * response. 651 | * 652 | * @see http://tools.ietf.org/html/rfc3834 653 | * 654 | * @param $header (string) 655 | * Message header as returned by imap_fetchheader(). 656 | * 657 | * @return (bool) 658 | * TRUE if this message comes from an autoresponder. 659 | */ 660 | private function detectAutoresponder($header) { 661 | $autoresponder_strings = array( 662 | 'X-Autoresponse:', // Other email servers. 663 | 'X-Autorespond:', // LogSat server. 664 | 'Subject: Auto Response', // Yahoo mail. 665 | 'Out of office', // Generic. 666 | 'Out of the office', // Generic. 667 | 'out of the office', // Generic. 668 | 'Auto-reply', // Generic. 669 | 'Autoreply', // Generic. 670 | 'autoreply', // Generic. 671 | ); 672 | 673 | // Check for presence of different autoresponder strings. 674 | foreach ($autoresponder_strings as $string) { 675 | if (strpos($header, $string) !== false) { 676 | return true; 677 | } 678 | } 679 | 680 | return false; 681 | } 682 | 683 | } 684 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2011 by Josh Grochowski (josh[dot]kastang[at]gmail[dot]com). 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | IMAP for PHP Logo 2 | 3 | # Imap 4 | 5 | A PHP wrapper class for PHP's IMAP-related email handling functions. 6 | 7 | This class includes many convenience methods to help take the headache out of 8 | dealing with emails in PHP. For example, email handling method names make more 9 | sense (e.g. `getMessage`, `deleteMessage`, and `moveMessage` along with a 10 | message id, rather than passing around IMAP streams, using many 11 | difficult-to-remember `imap_*` functions). 12 | 13 | Also, this class adds some convenient helpful information to emails, like the 14 | full message header (in `raw_header`), and whether or not the email was sent by 15 | an autoresponder (see `detectAutoresponder` for details). 16 | 17 | If you have any issues or feature suggestions, please post a new issue on 18 | GitHub. 19 | 20 | ## Usage 21 | 22 | Connect to an IMAP account by creating a new Imap object with the required 23 | parameters: 24 | 25 | ```php 26 | $host = 'imap.example.com'; 27 | $user = 'johndoe'; 28 | $pass = '12345'; 29 | $port = 993; 30 | $ssl = true; 31 | $folder = 'INBOX'; 32 | $mailbox = new Imap($host, $user, $pass, $port, $ssl, $folder); 33 | ``` 34 | 35 | Get a list of all mailboxes: 36 | 37 | ```php 38 | $mailbox->getMailboxInfo(); 39 | ``` 40 | 41 | Get an array of message counts (recent, unread, and total): 42 | 43 | ```php 44 | $mailbox->getCurrentMailboxInfo(); 45 | ``` 46 | 47 | Get an associative array of message ids and subjects: 48 | 49 | ```php 50 | $mailbox->getMessageIds(); 51 | ``` 52 | 53 | Load details for a message by id. 54 | 55 | ```php 56 | $id = 2; 57 | $mailbox->getMessage($id); 58 | ``` 59 | 60 | Delete a message by id. 61 | 62 | ```php 63 | $id = 2; 64 | $mailbox->deleteMessage($id); 65 | ``` 66 | 67 | Disconnect from the server (necessary after deleting or moving messages): 68 | 69 | ```php 70 | $mailbox->disconnect(); 71 | ``` 72 | 73 | More methods and documentation can be found in the Imap.php class file. 74 | 75 | ## License 76 | 77 | Imap is licensed under the MIT (Expat) license. See included LICENSE.md. 78 | -------------------------------------------------------------------------------- /Resources/Imap-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geerlingguy/Imap/51631c730d88c66aaf971623773650f5ded5d959/Resources/Imap-Logo.png -------------------------------------------------------------------------------- /Resources/Imap-Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 22 | 23 | IMAP 24 | for PHP 25 | 26 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geerlingguy/imap", 3 | "description": "A PHP wrapper class for PHP's IMAP-related email handling functions.", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Jeff Geerling", 8 | "email": "jeff@jeffgeerling.com" 9 | } 10 | ], 11 | "autoload": { 12 | "classmap": [ "JJG/Imap.php" ] 13 | } 14 | } 15 | --------------------------------------------------------------------------------