setConfig($config); } /** * Client destructor */ public function __destruct() { $this->disconnect(); } /** * Set the Client configuration * * @param array $config * * @return self */ public function setConfig(array $config) { $defaultAccount = config('imap.default'); $defaultConfig = config("imap.accounts.$defaultAccount"); foreach ($this->validConfigKeys as $key) { $this->$key = isset($config[$key]) ? $config[$key] : $defaultConfig[$key]; } return $this; } /** * Get the current imap resource * * @return bool|resource * @throws ConnectionFailedException */ public function getConnection() { $this->checkConnection(); return $this->connection; } /** * Set read only property and reconnect if it's necessary. * * @param bool $readOnly * * @return self */ public function setReadOnly($readOnly = true) { $this->read_only = $readOnly; return $this; } /** * Determine if connection was established. * * @return bool */ public function isConnected() { return $this->connected; } /** * Determine if connection is in read only mode. * * @return bool */ public function isReadOnly() { return $this->read_only; } /** * Determine if connection was established and connect if not. * * @throws ConnectionFailedException */ public function checkConnection() { if (!$this->isConnected() || $this->connection === false) { $this->connect(); } } /** * Connect to server. * * @param int $attempts * * @return $this * @throws ConnectionFailedException */ public function connect($attempts = 3) { $this->disconnect(); try { $this->connection = imap_open( $this->getAddress(), $this->username, $this->password, $this->getOptions(), $attempts, config('imap.options.open') ); $this->connected = !!$this->connection; } catch (\ErrorException $e) { $errors = imap_errors(); $message = $e->getMessage().'. '.implode("; ", (is_array($errors) ? $errors : array())); throw new ConnectionFailedException($message); } return $this; } /** * Disconnect from server. * * @return $this */ public function disconnect() { if ($this->isConnected() && $this->connection !== false && is_integer($this->connection) === false) { $this->errors = array_merge($this->errors, imap_errors() ?: []); $this->connected = !imap_close($this->connection, CL_EXPUNGE); } return $this; } /** * Get a folder instance by a folder name * --------------------------------------------- * PLEASE NOTE: This is an experimental function * --------------------------------------------- * @param string $folder_name * @param int $attributes * @param null|string $delimiter * * @return Folder */ public function getFolder($folder_name, $attributes = 32, $delimiter = null) { $delimiter = $delimiter === null ? config('imap.options.delimiter', '/') : $delimiter; $oFolder = new Folder($this, (object) [ 'name' => $this->getAddress().$folder_name, 'attributes' => $attributes, 'delimiter' => $delimiter ]); return $oFolder; } /** * Get folders list. * If hierarchical order is set to true, it will make a tree of folders, otherwise it will return flat array. * * @param boolean $hierarchical * @param string|null $parent_folder * * @return FolderCollection * @throws ConnectionFailedException */ public function getFolders($hierarchical = true, $parent_folder = null) { $this->checkConnection(); $folders = FolderCollection::make([]); $pattern = $parent_folder.($hierarchical ? '%' : '*'); $items = imap_getmailboxes($this->connection, $this->getAddress(), $pattern); // FreeScout fix if (!$items) { return $folders; } foreach ($items as $item) { $folder = new Folder($this, $item); if ($hierarchical && $folder->hasChildren()) { $pattern = $folder->fullName.$folder->delimiter.'%'; $children = $this->getFolders(true, $pattern); $folder->setChildren($children); } $folders->push($folder); } return $folders; } /** * Open folder. * * @param Folder $folder * @param int $attempts * * @throws ConnectionFailedException */ public function openFolder(Folder $folder, $attempts = 3) { $this->checkConnection(); if ($this->activeFolder !== $folder) { $this->activeFolder = $folder; imap_reopen($this->getConnection(), $folder->path, $this->getOptions(), $attempts); } } /** * Create a new Folder * @param string $name * @param boolean $expunge * * @return bool * @throws ConnectionFailedException */ public function createFolder($name, $expunge = true) { $this->checkConnection(); $status = imap_createmailbox($this->getConnection(), $this->getAddress() . imap_utf7_encode($name)); if($expunge) $this->expunge(); return $status; } /** * Rename Folder * @param string $old_name * @param string $new_name * @param boolean $expunge * * @return bool * @throws ConnectionFailedException */ public function renameFolder($old_name, $new_name, $expunge = true) { $this->checkConnection(); $status = imap_renamemailbox($this->getConnection(), $this->getAddress() . imap_utf7_encode($old_name), $this->getAddress() . imap_utf7_encode($new_name)); if($expunge) $this->expunge(); return $status; } /** * Delete Folder * @param string $name * @param boolean $expunge * * @return bool * @throws ConnectionFailedException */ public function deleteFolder($name, $expunge = true) { $this->checkConnection(); $status = imap_deletemailbox($this->getConnection(), $this->getAddress() . imap_utf7_encode($name)); if($expunge) $this->expunge(); return $status; } /** * Get messages from folder. * * @param Folder $folder * @param string $criteria * @param int|null $fetch_options * @param boolean $fetch_body * @param boolean $fetch_attachment * * @return MessageCollection * @throws ConnectionFailedException * @throws GetMessagesFailedException * @throws MessageSearchValidationException * * @deprecated 1.0.5.2:2.0.0 No longer needed. Use Folder::getMessages() instead * @see Folder::getMessages() */ public function getMessages(Folder $folder, $criteria = 'ALL', $fetch_options = null, $fetch_body = true, $fetch_attachment = true, $fetch_flags = false) { return $folder->getMessages($criteria, $fetch_options, $fetch_body, $fetch_attachment, $fetch_flags); } /** * Get all unseen messages from folder * * @param Folder $folder * @param string $criteria * @param int|null $fetch_options * @param boolean $fetch_body * @param boolean $fetch_attachment * * @return MessageCollection * @throws ConnectionFailedException * @throws GetMessagesFailedException * @throws MessageSearchValidationException * * @deprecated 1.0.5:2.0.0 No longer needed. Use Folder::getMessages('UNSEEN') instead * @see Folder::getMessages() */ public function getUnseenMessages(Folder $folder, $criteria = 'UNSEEN', $fetch_options = null, $fetch_body = true, $fetch_attachment = true, $fetch_flags = false) { return $folder->getUnseenMessages($criteria, $fetch_options, $fetch_body, $fetch_attachment, $fetch_flags); } /** * Search messages by a given search criteria * * @param array $where * @param Folder $folder * @param int|null $fetch_options * @param boolean $fetch_body * @param string $charset * @param boolean $fetch_attachment * * @return MessageCollection * @throws ConnectionFailedException * @throws GetMessagesFailedException * @throws MessageSearchValidationException * * @deprecated 1.0.5:2.0.0 No longer needed. Use Folder::searchMessages() instead * @see Folder::searchMessages() * */ public function searchMessages(array $where, Folder $folder, $fetch_options = null, $fetch_body = true, $charset = "UTF-8", $fetch_attachment = true, $fetch_flags = false) { return $folder->searchMessages($where, $fetch_options, $fetch_body, $charset, $fetch_attachment, $fetch_flags); } /** * Get option for imap_open and imap_reopen. * It supports only isReadOnly feature. * * @return int */ protected function getOptions() { return ($this->isReadOnly()) ? OP_READONLY : 0; } /** * Get full address of mailbox. * * @return string */ protected function getAddress() { $address = "{".$this->host.":".$this->port."/".($this->protocol ? $this->protocol : 'imap'); if (!$this->validate_cert) { $address .= '/novalidate-cert'; } if (in_array($this->encryption,['tls','ssl'])) { $address .= '/'.$this->encryption; } $address .= '}'; return $address; } /** * Retrieve the quota level settings, and usage statics per mailbox * * @return array * @throws ConnectionFailedException */ public function getQuota() { $this->checkConnection(); return imap_get_quota($this->getConnection(), 'user.'.$this->username); } /** * Retrieve the quota settings per user * * @param string $quota_root * * @return array * @throws ConnectionFailedException */ public function getQuotaRoot($quota_root = 'INBOX') { $this->checkConnection(); return imap_get_quotaroot($this->getConnection(), $quota_root); } /** * Gets the number of messages in the current mailbox * * @return int * @throws ConnectionFailedException */ public function countMessages() { $this->checkConnection(); return imap_num_msg($this->connection); } /** * Gets the number of recent messages in current mailbox * * @return int * @throws ConnectionFailedException */ public function countRecentMessages() { $this->checkConnection(); return imap_num_recent($this->connection); } /** * Returns all IMAP alert messages that have occurred * * @return array */ public function getAlerts() { return imap_alerts(); } /** * Returns all of the IMAP errors that have occurred * * @return array */ public function getErrors() { $this->errors = array_merge($this->errors, imap_errors() ?: []); return $this->errors; } /** * Gets the last IMAP error that occurred during this page request * * @return string */ public function getLastError() { return imap_last_error(); } /** * Delete all messages marked for deletion * * @return bool * @throws ConnectionFailedException */ public function expunge() { $this->checkConnection(); return imap_expunge($this->connection); } /** * Check current mailbox * * @return object { * Date [string(37) "Wed, 8 Mar 2017 22:17:54 +0100 (CET)"] current system time formatted according to ยป RFC2822 * Driver [string(4) "imap"] protocol used to access this mailbox: POP3, IMAP, NNTP * Mailbox ["{root@example.com:993/imap/user="root@example.com"}INBOX"] the mailbox name * Nmsgs [int(1)] number of messages in the mailbox * Recent [int(0)] number of recent messages in the mailbox * } * @throws ConnectionFailedException */ public function checkCurrentMailbox() { $this->checkConnection(); return imap_check($this->connection); } }