Source for file IMAP.php
Documentation is available at IMAP.php
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar> |
// +----------------------------------------------------------------------+
require_once 'Net/IMAPProtocol.php';
* Provides an implementation of the IMAP protocol using PEAR's
* @author Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>
* Instantiates a new Net_SMTP object, overriding any defaults
* with parameters that are passed in.
* @param string The server to connect to.
* @param int The port to connect to.
* @param string The value to give when sending EHLO or HELO.
function Net_IMAP($host = 'localhost', $port = 143 )
$ret = $this->connect( $host , $port );
* Attempt to connect to the IMAP server located at $host $port
* @param string $host The IMAP server
* @param string $port The IMAP port
* It is only useful in a very few circunstances
* because the contructor already makes this job
* @return true on success or PEAR_Error
// Determine server capabilities
// check if we can enable TLS via STARTTLS
return new PEAR_Error ("Unexpected response on connection");
if(PEAR ::isError ($ret) ){
if(isset ( $ret["RESPONSE"]["CODE"] ) ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Attempt to authenticate to the IMAP server.
* @param string $user The userid to authenticate as.
* @param string $pass The password to authenticate with.
* @param string $useauthenticate true: authenticate using
* the IMAP AUTHENTICATE command. false: authenticate using
* the IMAP AUTHENTICATE command. 'string': authenticate using
* the IMAP AUTHENTICATE command but using the authMethod in 'string'
* @param boolean $selectMailbox automaticaly select inbox on login (false does not)
* @return true on success or PEAR_Error
function login($user, $pass, $useauthenticate = true , $selectMailbox=true )
//$useauthenticate is a string if the user hardcodes an AUTHMethod
// (the user calls $imap->login("user","password","CRAM-MD5"); for example!
$method = is_string( $useauthenticate ) ? $useauthenticate : null;
//Try the selected Auth method
if ( PEAR ::isError ( $ret = $this->cmdAuthenticate( $user , $pass , $method ) ) ) {
// Verify the methods that we have in common with the server
if(is_array($this->_serverAuthMethods)){
$this->_serverAuthMethods=null;
// The server does not have any auth method, so I try LOGIN
if ( PEAR ::isError ( $ret = $this->cmdLogin( $user, $pass ) ) ) {
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
//The user request "PLAIN" auth, we use the login command
if ( PEAR ::isError ( $ret = $this->cmdLogin( $user, $pass ) ) ) {
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Disconnect function. Sends the QUIT command
* @return bool Success/Failure
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Changes the default/current mailbox th $mailbox
* @return bool Success/Pear_Error Failure
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Checks the mailbox $mailbox
* @return bool Success/Pear_Error Failure
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
//$ret_aux["EXISTS"]=$ret["PARSED"]["EXISTS"];
//$ret_aux["RECENT"]=$ret["PARSED"]["RECENT"];
* Returns the raw headers of the specified message.
* @param $msg_id Message number
* @param bool $uidFetch msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed Either raw headers or false on error
function getRawHeaders($msg_id, $part_id = '', $uidFetch = false )
$command = " BODY[$part_id.HEADER]";
$command = "BODY[HEADER]";
$ret= $this->cmdFetch($msg_id, $command);
if(strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
$ret= $ret["PARSED"][0 ]["EXT"][$command]["CONTENT"];
* Returns the headers of the specified message in an
* associative array. Array keys are the header names, array
* values are the header values. In the case of multiple headers
* having the same names, eg Received:, the array value will be
* an indexed array of all the header values.
* @param int $msg_id Message number
* @param boolean $keysToUpper false (default) original header names
* true change keys (header names) toupper
* @param bool $uidFetch msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed Either array of headers or false on error
function getParsedHeaders($msg_id, $keysToUpper = false , $part_id = '', $uidFetch = false )
$raw_headers = rtrim($ret);
$raw_headers = preg_replace("/\r\n[ \t]+/", ' ', $raw_headers); // Unfold headers
$raw_headers = explode("\r\n", $raw_headers);
foreach ($raw_headers as $value) {
if (isset ($headers[$name]) && is_array($headers[$name])) {
$headers[$name][] = $value;
} elseif (isset ($headers[$name])) {
$headers[$name] = array ($headers[$name], $value);
$headers[$name] = $value;
* Returns an array containing the message ID, the size and the UID
* of each message selected.
* message selection can be a valid IMAP command, a number or an array of
* @param $msg_id Message number
* @return mixed Either array of message data or PearError on error
$message_set= $this->_getSearchListFromArray ($msg_id);
$ret= $this->cmdFetch($message_set,"(RFC822.SIZE UID)");
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
foreach($ret["PARSED"] as $msg){
$ret_aux[]=array ("msg_id"=> $msg["NRO"],"size" => $msg["EXT"]["RFC822.SIZE"],"uidl"=> $msg["EXT"]["UID"]);
* @param mixed $msg_id Message number
* @param bool $uidFetch msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed Either array of headers or PEAR::Error on error
function getSummary($msg_id = null , $uidFetch = false )
$message_set= $this->_getSearchListFromArray ($msg_id);
$ret= $this->cmdUidFetch($message_set,"(RFC822.SIZE UID FLAGS ENVELOPE INTERNALDATE BODY.PEEK[HEADER.FIELDS (CONTENT-TYPE)])");
$ret= $this->cmdFetch($message_set,"(RFC822.SIZE UID FLAGS ENVELOPE INTERNALDATE BODY.PEEK[HEADER.FIELDS (CONTENT-TYPE)])");
#$ret=$this->cmdFetch($message_set,"(RFC822.SIZE UID FLAGS ENVELOPE INTERNALDATE BODY[1.MIME])");
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
#print "<hr>"; var_dump($ret["PARSED"]); print "<hr>";
if(isset ( $ret["PARSED"] ) ){
for($i=0; $i< count($ret["PARSED"]) ; $i++ ){
$a= $ret["PARSED"][$i]['EXT']['ENVELOPE'];
$a['MSG_NUM']= $ret["PARSED"][$i]['NRO'];
$a['UID']= $ret["PARSED"][$i]['EXT']['UID'];
$a['FLAGS']= $ret["PARSED"][$i]['EXT']['FLAGS'];
$a['INTERNALDATE']= $ret["PARSED"][$i]['EXT']['INTERNALDATE'];
$a['SIZE']= $ret["PARSED"][$i]['EXT']['RFC822.SIZE'];
if(preg_match('/^content-type: (.*);/iU', $ret["PARSED"][$i]['EXT']['BODY[HEADER.FIELDS (CONTENT-TYPE)]']['CONTENT'], $matches)) {
* Returns the body of the message with given message number.
* @param $msg_id Message number
* @param bool $uidFetch msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed Either message body or false on error
function getBody($msg_id, $uidFetch = false )
$ret= $this->cmdFetch($msg_id,"BODY[TEXT]");
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
$ret= $ret["PARSED"][0 ]["EXT"]["BODY[TEXT]"]["CONTENT"];
//$ret=$resp["PARSED"][0]["EXT"]["RFC822"]["CONTENT"];
* Returns the body of the message with given message number.
* @param $msg_id Message number
* @param string $partId Message number
* @param bool $uidFetch msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed Either message body or false on error
function getBodyPart($msg_id, $partId, $uidFetch = false )
$ret= $this->cmdFetch($msg_id," BODY[$partId]" );
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
$ret= $ret["PARSED"][0 ]["EXT"][" BODY[$partId]" ]["CONTENT"];
//$ret=$resp["PARSED"][0]["EXT"]["RFC822"]["CONTENT"];
* Returns the body of the message with given message number.
* @param $msg_id Message number
* @param bool $uidFetch msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed Either message body or false on error
#print "IMAP.php::getStructure<pre>";
$ret= $this->cmdFetch($msg_id,"BODYSTRUCTURE");
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
$ret= $ret["PARSED"][0 ]["EXT"]["BODYSTRUCTURE"][0 ];
$this->_parseStructureArray ($ret, $mimeParts);
function _parseStructureArray ($_structure, &$_mimeParts, $_partID = '')
#print "<hr>Net_IMAP::_parseStructureArray _partID: $_partID<br>";
$partID = ($_partID == '') ? '' : $_partID. '.';
$this->_parseStructureMultipartArray ($_structure, $_mimeParts, $_partID);
$this->_parseStructureTextArray ($_structure, $_mimeParts, $partID. $subPartID);
$this->_parseStructureMessageArray ($_structure, $_mimeParts, $partID. $subPartID);
function _parseStructureMultipartArray ($_structure, &$_mimeParts, $_partID, $_parentIsMessage = false )
#print "Net_IMAP::_parseStructureMultipartArray _partID: $_partID<br>";
// a multipart/mixed get's no own id, if the parent is message/rfc822
// and multipart/report also not
if($_parentIsMessage == true && is_array($_structure[0 ]) && ($_structure[count($_structure)-5 ] == 'mixed' || $_structure[count($_structure)-5 ] == 'report')) {
$partID = ($_partID == '') ? '' : $_partID. '.';
foreach($_structure as $structurePart) {
// another multipart inside the multipart
$this->_parseStructureMultipartArray ($structurePart, $subMimeParts, $partID. $subPartID);
$this->_parseStructureApplicationArray ($structurePart, $subMimeParts, $partID. $subPartID);
$this->_parseStructureImageArray ($structurePart, $subMimeParts, $partID. $subPartID);
$this->_parseStructureMessageArray ($structurePart, $subMimeParts, $partID. $subPartID);
$this->_parseStructureTextArray ($structurePart, $subMimeParts, $partID. $subPartID);
$part->type = 'MULTIPART';
$part->subParts = $subMimeParts;
$_mimeParts = array (0 => $part);
$part->partID = $_partID;
$_mimeParts = array ($_partID => $part);
function _parseStructureImageArray ($_structure, &$_mimeParts, $_partID)
#print "Net_IMAP::_parseStructureImageArray _partID: $_partID<br>";
$part = $this->_parseStructureCommonFields ($_structure);
$part->cid = $_structure[3 ];
$part->partID = $_partID;
$_mimeParts[$_partID] = $part;
function _parseStructureApplicationArray ($_structure, &$_mimeParts, $_partID)
#print "Net_IMAP::_parseStructureApplicationArray _partID: $_partID<br>";
$part = $this->_parseStructureCommonFields ($_structure);
if(isset ($_structure[8 ][0 ]) && $_structure[8 ][0 ] != 'NIL') {
$part->disposition = strtoupper($_structure[8 ][0 ]);
foreach($_structure[8 ][1 ] as $key => $value) {
$part->dparameters [strtoupper($_structure[8 ][1 ][$key])] = $_structure[8 ][1 ][$key+1 ];
$part->partID = $_partID;
$_mimeParts[$_partID] = $part;
function _parseStructureMessageArray ($_structure, &$_mimeParts, $_partID)
#print "Net_IMAP::_parseStructureMessageArray _partID: $_partID<br>";
$part = $this->_parseStructureCommonFields ($_structure);
$this->_parseStructureMultipartArray ($_structure[8 ], $subMimeParts, $_partID. '.1', true );
$this->_parseStructureArray ($_structure[8 ], $subMimeParts, $_partID);
$part->subParts = $subMimeParts;
$part->partID = $_partID;
$_mimeParts[$_partID] = $part;
function _parseStructureTextArray ($_structure, &$_mimeParts, $_partID)
#print "Net_IMAP::_parseStructureTextArray _partID: $_partID<br>";
$part = $this->_parseStructureCommonFields ($_structure);
$part->lines = $_structure[7 ];
if(isset ($_structure[8 ][0 ]) && $_structure[8 ][0 ] != 'NIL') {
$part->disposition = strtoupper($_structure[8 ][0 ]);
foreach($_structure[8 ][1 ] as $key => $value) {
$part->dparameters [strtoupper($_structure[8 ][1 ][$key])] = $_structure[8 ][1 ][$key+1 ];
$part->partID = $_partID;
$_mimeParts[$_partID] = $part;
function _parseStructureCommonFields (&$_structure)
#print "Net_IMAP::_parseStructureTextArray _partID: $_partID<br>";
foreach($_structure[2 ] as $key => $value) {
$part->parameters [strtoupper($_structure[2 ][$key])] = $_structure[2 ][$key+1 ];
$part->bytes = $_structure[6 ];
* Returns the entire message with given message number.
* @param $msg_id Message number
* @return mixed Either entire message or false on error
function getMessages($msg_id = null , $indexIsMessageNumber=true )
//$resp=$this->cmdFetch($msg_id,"(BODY[TEXT] BODY[HEADER])");
$message_set= $this->_getSearchListFromArray ($msg_id);
$ret= $this->cmdFetch($message_set,"RFC822");
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if(isset ($ret["PARSED"])){
foreach($ret["PARSED"] as $msg){
if(isset ($msg["EXT"]["RFC822"]["CONTENT"])){
if($indexIsMessageNumber){
$ret_aux[$msg["NRO"]]= $msg["EXT"]["RFC822"]["CONTENT"];
$ret_aux[]= $msg["EXT"]["RFC822"]["CONTENT"];
* Returns number of messages in this mailbox
* @param string $mailbox the mailbox
* @return mixed Either number of messages or Pear_Error on error
if ( $mailbox == '' || $mailbox == null ){
$ret= $this->cmdStatus( $mailbox , "MESSAGES" );
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ($ret["PARSED"]["STATUS"]["ATTRIBUTES"]["MESSAGES"] ) ){
if( !is_numeric( $ret["PARSED"]["STATUS"]["ATTRIBUTES"]["MESSAGES"] ) ){
// if this array does not exists means that there is no messages in the mailbox
return $ret["PARSED"]["STATUS"]["ATTRIBUTES"]["MESSAGES"];
* Returns number of UnSeen messages in this mailbox
* @param string $mailbox the mailbox
* @return mixed Either number of messages or Pear_Error on error
$ret= $this->cmdStatus( $mailbox , "UNSEEN" );
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ($ret["PARSED"]["STATUS"]["ATTRIBUTES"]["UNSEEN"] ) ){
if( !is_numeric( $ret["PARSED"]["STATUS"]["ATTRIBUTES"]["UNSEEN"] ) ){
// if this array does not exists means that there is no messages in the mailbox
return $ret["PARSED"]["STATUS"]["ATTRIBUTES"]["UNSEEN"];
* Returns number of UnSeen messages in this mailbox
* @param string $mailbox the mailbox
* @return mixed Either number of messages or Pear_Error on error
$ret= $this->cmdStatus( $mailbox , "RECENT" );
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ($ret["PARSED"]["STATUS"]["ATTRIBUTES"]["RECENT"] ) ){
if( !is_numeric( $ret["PARSED"]["STATUS"]["ATTRIBUTES"]["RECENT"] ) ){
// if this array does not exists means that there is no messages in the mailbox
return $ret["PARSED"]["STATUS"]["ATTRIBUTES"]["RECENT"];
* Returns number of UnSeen messages in this mailbox
* @param string $mailbox the mailbox
* @return mixed Either number of messages or Pear_Error on error
$ret= $this->cmdStatus( $mailbox , array ('MESSAGES', 'RECENT', 'UIDNEXT', 'UIDVALIDITY', 'UNSEEN') );
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ($ret["PARSED"]["STATUS"]["ATTRIBUTES"]["RECENT"] ) ){
return $ret["PARSED"]["STATUS"]["ATTRIBUTES"];
* Returns an array containing the message envelope
* @todo $mailbox get's not used anywhere
* @param mixed $msg_id Message number
* @param bool $uidFetch msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed Either the envelopes or Pear_Error on error
function getEnvelope($mailbox = '', $msg_id = null , $uidFetch = false )
$message_set= $this->_getSearchListFromArray ($msg_id);
$ret= $this->cmdFetch($message_set,"ENVELOPE");
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if(isset ( $ret["PARSED"] ) ){
for($i=0; $i< count($ret["PARSED"]) ; $i++ ){
$a= $ret["PARSED"][$i]['EXT']['ENVELOPE'];
$a['MSG_NUM']= $ret["PARSED"][$i]['NRO'];
return new PEAR_Error ('Error, undefined number of messages');
* Returns the sum of all the sizes of messages in $mailbox
* WARNING!!! The method's performance is not good
* if you have a lot of messages in the mailbox
* @return mixed Either size of maildrop or false on error
// store the actual selected mailbox name
if ( PEAR ::isError ( $ret = $this->selectMailbox( $mailbox ) ) ) {
$ret= $this->cmdFetch("1:*","RFC822.SIZE");
// Restore the default mailbox if it was changed
if ( PEAR ::isError ( $ret = $this->selectMailbox( $mailbox_aux ) ) ) {
// return 0 because the server says that there is no message in the mailbox
if(!isset ($ret["PARSED"]) ){
// if the server does not return a "PARSED" part
// we think that it does not suppoprt select or has no messages in it.
foreach($ret["PARSED"] as $msgSize){
if( isset ($msgSize["EXT"]["RFC822.SIZE"]) ){
$sum+= $msgSize["EXT"]["RFC822.SIZE"];
if ( PEAR ::isError ( $ret = $this->selectMailbox( $mailbox_aux ) ) ) {
* Marks a message for deletion. Only will be deleted if the
* disconnect() method is called with auto-expunge on true or expunge()
* @param $msg_id Message to delete
* @param bool $uidStore msg_id contains UID's instead of Message Sequence Number if set to true
* @return bool Success/Failure
C: A003 STORE 2:4 +FLAGS (\Deleted)
S: * 2 FETCH FLAGS (\Deleted \Seen)
S: * 3 FETCH FLAGS (\Deleted)
S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
S: A003 OK STORE completed
//Called without parammeters deletes all the messages in the mailbox
// You can also provide an array of numbers to delete those emails
$message_set= $this->_getSearchListFromArray ($msg_id);
$dataitem= "+FLAGS.SILENT";
$ret= $this->cmdUidStore($message_set,$dataitem,$value);
$ret= $this->cmdStore($message_set,$dataitem,$value);
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Copies mail from one folder to another
* @param string $dest_mailbox mailbox name to copy sessages to
* @param mixed $msg_id the messages that I want to copy (all by default) it also
* @param string $source_mailbox mailbox name from where the messages are copied
* @param bool $uidCopy msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed true on Success/PearError on Failure
function copyMessages($dest_mailbox, $msg_id = null , $source_mailbox = null , $uidCopy = false )
if($source_mailbox == null ){
if ( PEAR ::isError ( $ret = $this->selectMailbox( $source_mailbox ) ) ) {
//Called without parammeters copies all messages in the mailbox
// You can also provide an array of numbers to copy those emails
$message_set= $this->_getSearchListFromArray ($msg_id);
$ret = $this->cmdUidCopy($message_set, $dest_mailbox );
$ret = $this->cmdCopy($message_set, $dest_mailbox );
if ( PEAR ::isError ( $ret ) ) {
* Appends a mail to a mailbox
* @param string $rfc_message the message to append in RFC822 format
* @param string $mailbox mailbox name to append to
* @return mixed true on Success/PearError on Failure
function appendMessage($rfc_message, $mailbox = null , $flags_list = '')
$ret= $this->cmdAppend($mailbox,$rfc_message,$flags_list);
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Appends a mail to a mailbox
* @param string $rfc_message the message to append in RFC822 format
* @param string $mailbox mailbox name to append to
* @return mixed true on Success/PearError on Failure
if(strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
foreach($ret["PARSED"]["NAMESPACES"] as $type => $singleNameSpace) {
foreach ($singleNameSpace as $nameSpaceData) {
$nameSpaces[$type][] = array (
/******************************************************************
** MAILBOX RELATED METHODS **
******************************************************************/
* Gets the HierachyDelimiter character used to create subfolders cyrus users "."
* $param string the mailbox to get the hierarchy from
* @return string the hierarchy delimiter
/* RFC2060 says: "the command LIST "" "" means get the hierachy delimiter:
An empty ("" string) mailbox name argument is a special request to
return the hierarchy delimiter and the root name of the name given
in the reference. The value returned as the root MAY be null if
the reference is non-rooted or is null. In all cases, the
hierarchy delimiter is returned. This permits a client to get the
hierarchy delimiter even when no mailboxes by that name currently
if( PEAR ::isError ( $ret = $this->cmdList( $mailbox , '' ) ) ){
if(isset ($ret["PARSED"][0 ]["EXT"]["LIST"]["HIERACHY_DELIMITER"]) ){
return $ret["PARSED"][0 ]["EXT"]["LIST"]["HIERACHY_DELIMITER"];
return new PEAR_Error ( 'the IMAP Server does not support HIERACHY_DELIMITER!' );
* Returns an array containing the names of the selected mailboxes
* @param string $mailbox_base base mailbox to start the search
* $mailbox_base if $mailbox_base == '' then $mailbox_base is the curent selected mailbox
* @param string $restriction_search false or 0 means return all mailboxes true or 1 return only the mailbox that contains that exact name
2 return all mailboxes in that hierarchy level
* @param string $returnAttributes true means return an assoc array containing mailbox names and mailbox attributes
false - the default - means return an array of mailboxes
* @return mixed true on Success/PearError on Failure
function getMailboxes($reference = '' , $restriction_search = 0 , $returnAttributes=false )
if ( is_bool($restriction_search) ){
$restriction_search = (int) $restriction_search;
if ( is_int( $restriction_search ) ){
switch ( $restriction_search ) {
$mailbox = $restriction_search;
return new PEAR_Error ("UPS... you ");
if( PEAR ::isError ( $ret = $this->cmdList($reference, $mailbox) ) ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ($ret["PARSED"]) ){
foreach( $ret["PARSED"] as $mbox ){
//If the folder has the \NoSelect atribute we don't put in the list
// it solves a bug in wu-imap that crash the IMAP server if we select that mailbox
if( isset ($mbox["EXT"]["LIST"]["NAME_ATTRIBUTES"]) ){
if( !in_array('\NoSelect',$mbox["EXT"]["LIST"]["NAME_ATTRIBUTES"]) ){
$ret_aux[]=array ( 'MAILBOX' => $mbox["EXT"]["LIST"]["MAILBOX_NAME"],
'ATTRIBUTES' => $mbox["EXT"]["LIST"]["NAME_ATTRIBUTES"] ,
'HIERACHY_DELIMITER' => $mbox["EXT"]["LIST"]["HIERACHY_DELIMITER"] ) ;
$ret_aux[]= $mbox["EXT"]["LIST"]["MAILBOX_NAME"];
* check if the mailbox name exists
* @param string $mailbox mailbox name to check existance
* @return boolean true on Success/false on Failure
// true means do an exact match
if( PEAR ::isError ( $ret = $this->getMailboxes( $mailbox , true ) ) ){
foreach ($ret as $mailbox_name) {
if ($mailbox_name == $mailbox) {
* Creates the mailbox $mailbox
* @param string $mailbox mailbox name to create
* @param array $options options to pass to create
* @return mixed true on Success/PearError on Failure
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Deletes the mailbox $mailbox
* @param string $mailbox mailbox name to delete
* @return mixed true on Success/PearError on Failure
// TODO verificar que el mailbox se encuentra vacio y, sino borrar los mensajes antes~!!!!!!
if (PEAR ::isError ($ret)) {
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Renames the mailbox $mailbox
* @param string $mailbox mailbox name to rename
* @param array $options options to pass to rename
* @return mixed true on Success/PearError on Failure
function renameMailbox($oldmailbox, $newmailbox, $options = null )
$ret= $this->cmdRename($oldmailbox,$newmailbox,$options);
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
/******************************************************************
** SUBSCRIPTION METHODS **
******************************************************************/
* Subscribes to the selected mailbox
* @param string $mailbox mailbox name to subscribe
* @return mixed true on Success/PearError on Failure
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Removes the subscription to a mailbox
* @param string $mailbox mailbox name to unsubscribe
* @return mixed true on Success/PearError on Failure
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* Lists the subscription to mailboxes
* @param string $mailbox_base mailbox name start the search (see to getMailboxes() )
* @param string $mailbox_name mailbox name filter the search (see to getMailboxes() )
* @return mixed true on Success/PearError on Failure
if ( is_bool($restriction_search) ){
$restriction_search = (int) $restriction_search;
if ( is_int( $restriction_search ) ){
switch ( $restriction_search ) {
$mailbox = $restriction_search;
return new PEAR_Error ("UPS... you ");
if( PEAR ::isError ( $ret= $this->cmdLsub($reference, $mailbox) ) ){
//$ret=$this->cmdLsub($mailbox_base, $mailbox_name);
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ($ret["PARSED"]) ){
foreach( $ret["PARSED"] as $mbox ){
if( isset ($mbox["EXT"]["LSUB"]["MAILBOX_NAME"]) ){
'MAILBOX' => $mbox["EXT"]["LSUB"]["MAILBOX_NAME"],
'ATTRIBUTES' => $mbox["EXT"]["LSUB"]["NAME_ATTRIBUTES"],
'HIERACHY_DELIMITER' => $mbox["EXT"]["LSUB"]["HIERACHY_DELIMITER"]
$ret_aux[]= $mbox["EXT"]["LSUB"]["MAILBOX_NAME"];
/******************************************************************
******************************************************************/
* Lists the flags of the selected messages
* @param mixes $msg_id the message list
* @return mixed array on Success/PearError on Failure
// You can also provide an array of numbers to those emails
$message_set= $this->_getSearchListFromArray ($msg_id);
$ret= $this->cmdFetch($message_set,"FLAGS");
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if(isset ($ret["PARSED"])){
foreach($ret["PARSED"] as $msg_flags){
if(isset ($msg_flags["EXT"]["FLAGS"])){
$flags[]= $msg_flags["EXT"]["FLAGS"];
* Sets the flags of the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @param mixed $flags flags to set (space separated String or array)
* @param string $mod "set" to set flags (default)
* "remove" to remove flags
* @param $uidStore bool msg_id contains UID's instead of Message Sequence Number if set to true
* @return mixed true on success/PearError on failure
function setFlags($msg_id, $flags, $mod = 'set', $uidStore = false )
// you can also provide an array of numbers to those emails
$message_set = $this->_getSearchListFromArray ($msg_id);
return new PEAR_Error ('wrong input $mod');
$ret= $this->cmdUidStore($message_set, $dataitem, $flaglist);
$ret= $this->cmdStore($message_set, $dataitem, $flaglist);
if (strtoupper($ret['RESPONSE']['CODE']) != 'OK') {
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* adds flags to the selected messages
* @param mixed $flags flags to set (space separated String or array)
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, $flags, $mod = 'add');
* adds the Seen flag (\Seen) to the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Seen', $mod = 'add');
* adds the Answered flag (\Answered) to the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Answered', $mod = 'add');
* adds the Deleted flag (\Deleted) to the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Deleted', $mod = 'add');
* adds the Flagged flag (\Flagged) to the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Flagged', $mod = 'add');
* adds the Draft flag (\Draft) to the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Draft', $mod = 'add');
* remove flags from the selected messages
* @param mixed $flags flags to remove (space separated string or array)
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, $flags, $mod = 'remove');
* remove the Seen flag (\Seen) from the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Seen', $mod = 'remove');
* remove the Answered flag (\Answered) from the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Answered', $mod = 'remove');
* remove the Deleted flag (\Deleted) from the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Deleted', $mod = 'remove');
* remove the Flagged flag (\Flagged) from the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Flagged', $mod = 'remove');
* remove the Draft flag (\Draft) from the selected messages
* @param mixed $msg_id the message list or string "all" for all
* @return mixed true on success/PearError on failure
return $this->setFlags($msg_id, '\Draft', $mod = 'remove');
* @param mixes $message_nro the message to check
* @return mixed true or false if the flag is sert PearError on Failure
return $this->hasFlag( $message_nro, "\\Seen" );
* check the Answered flag
* @param mixes $message_nro the message to check
* @return mixed true or false if the flag is sert PearError on Failure
return $this->hasFlag( $message_nro, "\\Answered" );
* @param mixes $message_nro the message to check
* @return mixed true or false if the flag is sert PearError on Failure
return $this->hasFlag( $message_nro, "\\Flagged" );
* @param mixes $message_nro the message to check
* @return mixed true or false if the flag is sert PearError on Failure
return $this->hasFlag( $message_nro, "\\Draft" );
* @param mixes $message_nro the message to check
* @return mixed true or false if the flag is sert PearError on Failure
return $this->hasFlag( $message_nro, "\\Deleted" );
function hasFlag($message_nro,$flag)
if ( PEAR ::isError ( $resp = $this->getFlags( $message_nro ) ) ) {
/******************************************************************
******************************************************************/
* expunge function. Sends the EXPUNGE command
* @return bool Success/Failure
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* search function. Sends the SEARCH command
* @return bool Success/Failure
function search($search_list, $uidSearch = false )
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
return $ret["PARSED"]["SEARCH"]["SEARCH_LIST"];
/******************************************************************
******************************************************************/
* Returns STORAGE quota details
* @param string $mailbox_name Mailbox to get quota info.
* @return assoc array contaning the quota info on success or PEAR_Error
if($mailbox_name == null ){
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
// if the error is that the user does not have quota set return an array
return array ('USED'=> 'NOT SET', 'QMAX'=> 'NOT SET');
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ( $ret['PARSED']['EXT']['QUOTA']['STORAGE'] ) ){
return $ret['PARSED']['EXT']['QUOTA']['STORAGE'];
return array ('USED'=> 'NOT SET', 'QMAX'=> 'NOT SET');
* Returns STORAGE quota details
* @param string $mailbox_name Mailbox to get quota info.
* @return assoc array contaning the quota info on success or PEAR_Error
if($mailbox_name == null ){
if ( PEAR ::isError ( $ret = $this->cmdGetQuota($mailbox_name) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
// if the error is that the user does not have quota set return an array
return array ('USED'=> 'NOT SET', 'QMAX'=> 'NOT SET');
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ( $ret['PARSED']['EXT']['QUOTA']['STORAGE'] ) ){
return $ret['PARSED']['EXT']['QUOTA']['STORAGE'];
return array ('USED'=> 'NOT SET', 'QMAX'=> 'NOT SET');
* Returns MESSAGES quota details
* @param string $mailbox_name Mailbox to get quota info.
* @return assoc array contaning the quota info on success or PEAR_Error
if($mailbox_name == null ){
if ( PEAR ::isError ( $ret = $this->cmdGetQuota($mailbox_name) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
// if the error is that the user does not have quota set return an array
return array ('USED'=> 'NOT SET', 'QMAX'=> 'NOT SET');
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ( $ret['PARSED']['EXT']['QUOTA']['MESSAGES'] ) ){
return $ret['PARSED']['EXT']['QUOTA']['MESSAGES'];
return array ('USED'=> 'NOT SET', 'QMAX'=> 'NOT SET');
* sets STORAGE quota details
* @param string $mailbox_name Mailbox to get quota info.
* @return true on success or PEAR_Error
if ( PEAR ::isError ( $ret = $this->cmdSetQuota($mailbox_name,$quota) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* sets MESSAGES quota details
* @param string $mailbox_name Mailbox to get quota info.
* @return true on success or PEAR_Error
if ( PEAR ::isError ( $ret = $this->cmdSetQuota($mailbox_name,'',$quota) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
/******************************************************************
******************************************************************/
* get the Access Control List details
* @param string $mailbox_name Mailbox to get ACL info.
* @return string on success or PEAR_Error
function getACL($mailbox_name = null )
if($mailbox_name == null ){
if ( PEAR ::isError ( $ret = $this->cmdGetACL($mailbox_name) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if( isset ($ret['PARSED']['USERS']) ){
return $ret['PARSED']['USERS'];
* @param string $mailbox_name the mailbox
* @param string $user user to set the ACL
* @param string $acl ACL list
* @return mixed True on success, or PEAR_Error on false
function setACL($mailbox_name, $user, $acl)
if ( PEAR ::isError ( $ret = $this->cmdSetACL($mailbox_name, $user, $acl) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* deletes the ACL on a mailbox
* @param string $mailbox_name the mailbox
* @param string $user user to set the ACL
* @return mixed True on success, or PEAR_Error on false
if ( PEAR ::isError ( $ret = $this->cmdDeleteACL($mailbox_name, $user) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
* returns the rights that the user logged on has on the mailbox
* this method can be used by any user, not only the administrator
* @param string $mailbox_name the mailbox to query rights
* @return mixed string contailing the list of rights on success, or PEAR_Error on failure
if($mailbox_name == null ){
if ( PEAR ::isError ( $ret = $this->cmdMyRights($mailbox_name) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if(isset ($ret['PARSED']['GRANTED'])){
return $ret['PARSED']['GRANTED'];
return new PEAR_Error ('Bogus response from server!' );
* returns an array containing the rights that a user logged on has on the mailbox
* this method can be used by any user, not only the administrator
* @param string $mailbox_name the mailbox to query rights
* @return mixed string contailing the list of rights on success, or PEAR_Error on failure
if($mailbox_name == null ){
if ( PEAR ::isError ( $ret = $this->cmdListRights($mailbox_name, $user) ) ) {
return new PEAR_Error ($ret->getMessage ());
if( strtoupper( $ret["RESPONSE"]["CODE"]) != "OK" ){
return new PEAR_Error ($ret["RESPONSE"]["CODE"] . ", " . $ret["RESPONSE"]["STR_CODE"]);
if(isset ($ret['PARSED']['GRANTED'])){
return $ret['PARSED']['GRANTED'];
return new PEAR_Error ('Bogus response from server!' );
/******************************************************************
** ANNOTATEMORE METHODS **
******************************************************************/
if($mailbox_name == null ){
if (PEAR ::isError ($ret = $this->cmdSetAnnotation($mailbox_name, $entry, $values))) {
return new PEAR_Error ($ret->getMessage ());
if (strtoupper($ret['RESPONSE']['CODE']) != 'OK') {
return new PEAR_Error ($ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']);
if($mailbox_name == null ){
return new PEAR_Error ($ret->getMessage ());
if (strtoupper($ret['RESPONSE']['CODE']) != 'OK') {
return new PEAR_Error ($ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']);
if($mailbox_name == null ){
$entries = array ($entries);
$values = array ($values);
if (PEAR ::isError ($ret = $this->cmdGetAnnotation($mailbox_name, $entries, $values))) {
return new PEAR_Error ($ret->getMessage ());
if (strtoupper($ret['RESPONSE']['CODE']) != 'OK') {
return new PEAR_Error ($ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']);
if (isset ($ret['PARSED'])) {
foreach ($ret['PARSED'] as $mbox) {
$rawvalues = $mbox['EXT']['ATTRIBUTES'];
for ($i = 0; $i < count($rawvalues); $i += 2 ) {
$values[$rawvalues[$i]] = $rawvalues[$i + 1 ];
$mbox['EXT']['ATTRIBUTES'] = $values;
$ret_aux[] = $mbox['EXT'];
if (count($ret_aux) == 1 && $ret_aux[0 ]['MAILBOX'] == $mailbox_name) {
if (count($entries) == 1 && $ret_aux[0 ]['ENTRY'] == $entries[0 ]) {
if (count($ret_aux[0 ]['ATTRIBUTES']) == 1 && count($values) == 1 ) {
if ($attrs[0 ] == $vals[0 ]) {
return $ret_aux[0 ]['ATTRIBUTES'][$attrs[0 ]];
* Transform an array to a list to be used in the cmdFetch method
function _getSearchListFromArray ($arr){
/*****************************************************
Net_POP3 Compatibility functions:
Those functions could dissapear in the future
*********************************************************/
function numMsg($mailbox = null ){
* Returns the entire message with given message number.
* @param $msg_id Message number
* @return mixed Either entire message or false on error
// false means that getMessages() must not use the msg number as array key
Documentation generated on Mon, 11 Mar 2019 14:54:13 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|