PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/pear/Net/IMAPProtocol.php

http://akelosframework.googlecode.com/
PHP | 3048 lines | 2063 code | 451 blank | 534 comment | 213 complexity | 810ff8c93bf8d5d3289cc6b619cba3ee MD5 | raw file
Possible License(s): LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar> |
  17. // +----------------------------------------------------------------------+
  18. require_once 'Net/Socket.php';
  19. /**
  20. * Provides an implementation of the IMAP protocol using PEAR's
  21. * Net_Socket:: class.
  22. *
  23. * @package Net_IMAP/Protocol
  24. * @author Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>
  25. */
  26. class Net_IMAPProtocol {
  27. /**
  28. * The auth methods this class support
  29. * @var array
  30. */
  31. var $supportedAuthMethods=array('DIGEST-MD5', 'CRAM-MD5', 'LOGIN');
  32. /**
  33. * The auth methods this class support
  34. * @var array
  35. */
  36. var $supportedSASLAuthMethods=array('DIGEST-MD5', 'CRAM-MD5');
  37. /**
  38. * _serverAuthMethods
  39. * @var boolean
  40. */
  41. var $_serverAuthMethods = null;
  42. /**
  43. * The the current mailbox
  44. * @var string
  45. */
  46. var $currentMailbox = "INBOX" ;
  47. /**
  48. * The socket resource being used to connect to the IMAP server.
  49. * @var resource
  50. */
  51. var $_socket = null;
  52. /**
  53. * To allow class debuging
  54. * @var boolean
  55. */
  56. var $_debug = false;
  57. var $dbgDialog = '';
  58. /**
  59. * Command Number
  60. * @var int
  61. */
  62. var $_cmd_counter = 1;
  63. /**
  64. * Command Number for IMAP commands
  65. * @var int
  66. */
  67. var $_lastCmdID = 1;
  68. /**
  69. * Command Number
  70. * @var boolean
  71. */
  72. var $_unParsedReturn = false;
  73. /**
  74. * _connected: checks if there is a connection made to a imap server or not
  75. * @var boolean
  76. */
  77. var $_connected = false;
  78. /**
  79. * Capabilities
  80. * @var boolean
  81. */
  82. var $_serverSupportedCapabilities = null;
  83. /**
  84. * Use UTF-7 funcionallity
  85. * @var boolean
  86. */
  87. //var $_useUTF_7 = false;
  88. var $_useUTF_7 = true;
  89. /**
  90. * Constructor
  91. *
  92. * Instantiates a new Net_IMAP object.
  93. *
  94. * @since 1.0
  95. */
  96. function Net_IMAPProtocol()
  97. {
  98. $this->_socket = new Net_Socket();
  99. /*
  100. * Include the Auth_SASL package. If the package is not available,
  101. * we disable the authentication methods that depend upon it.
  102. */
  103. if ((@include_once 'Auth/SASL.php') == false) {
  104. foreach($this->supportedSASLAuthMethods as $SASLMethod){
  105. $pos = array_search( $SASLMethod , $this->supportedAuthMethods);
  106. unset($this->supportedAuthMethods[$pos]);
  107. }
  108. }
  109. }
  110. /**
  111. * Attempt to connect to the IMAP server.
  112. *
  113. * @return mixed Returns a PEAR_Error with an error message on any
  114. * kind of failure, or true on success.
  115. * @access public
  116. * @since 1.0
  117. */
  118. function cmdConnect($host= "localhost" , $port = 143)
  119. {
  120. if( $this->_connected ){
  121. return new PEAR_Error( 'already connected, logout first!' );
  122. }
  123. if ( PEAR::isError( $this->_socket->connect( $host , $port ) ) ) {
  124. return new PEAR_Error( 'unable to open socket' );
  125. }
  126. if ( PEAR::isError( $this->_getRawResponse() ) ) {
  127. return new PEAR_Error( 'unable to open socket' );
  128. }
  129. $this->_connected = true;
  130. return true;
  131. }
  132. /**
  133. * get the cmd ID
  134. *
  135. * @return string Returns the CmdID and increment the counter
  136. *
  137. * @access private
  138. * @since 1.0
  139. */
  140. function _getCmdId()
  141. {
  142. $this->_lastCmdID = "A000" . $this->_cmd_counter ;
  143. $this->_cmd_counter++;
  144. return $this->_lastCmdID;
  145. }
  146. /**
  147. * get the last cmd ID
  148. *
  149. * @return string Returns the last cmdId
  150. *
  151. * @access public
  152. * @since 1.0
  153. */
  154. function getLastCmdId()
  155. {
  156. return $this->_lastCmdID;
  157. }
  158. /**
  159. * get current mailbox name
  160. *
  161. * @return string Returns the current mailbox
  162. *
  163. * @access public
  164. * @since 1.0
  165. */
  166. function getCurrentMailbox()
  167. {
  168. return $this->currentMailbox;
  169. }
  170. /**
  171. * Sets the debuging information on or off
  172. *
  173. * @param boolean True or false
  174. *
  175. * @return nothing
  176. * @access public
  177. * @since 1.0
  178. */
  179. function setDebug($debug = true)
  180. {
  181. $this->_debug = $debug;
  182. }
  183. function getDebugDialog()
  184. {
  185. return $this->dbgDialog;
  186. }
  187. /**
  188. * Send the given string of data to the server.
  189. *
  190. * @param string $data The string of data to send.
  191. *
  192. * @return mixed True on success or a PEAR_Error object on failure.
  193. *
  194. * @access private
  195. * @since 1.0
  196. */
  197. function _send($data)
  198. {
  199. if($this->_socket->eof() ){
  200. return new PEAR_Error( 'Failed to write to socket: (connection lost!) ' );
  201. }
  202. if ( PEAR::isError( $error = $this->_socket->write( $data ) ) ) {
  203. return new PEAR_Error( 'Failed to write to socket: ' .
  204. $error->getMessage() );
  205. }
  206. if( $this->_debug ){
  207. // C: means this data was sent by the client (this class)
  208. echo "C: $data";
  209. $this->dbgDialog.="C: $data";
  210. }
  211. return true;
  212. }
  213. /**
  214. * Receive the given string of data from the server.
  215. *
  216. * @return mixed a line of response on success or a PEAR_Error object on failure.
  217. *
  218. * @access private
  219. * @since 1.0
  220. */
  221. function _recvLn()
  222. {
  223. if (PEAR::isError( $this->lastline = $this->_socket->gets( 8192 ) ) ) {
  224. return new PEAR_Error('Failed to write to socket: ' .
  225. $this->lastline->getMessage() );
  226. }
  227. if($this->_debug){
  228. // S: means this data was sent by the IMAP Server
  229. echo "S: " . $this->lastline . "" ;
  230. $this->dbgDialog.="S: " . $this->lastline . "" ;
  231. }
  232. if( $this->lastline == '' ){
  233. return new PEAR_Error('Failed to receive from the socket: ' );
  234. }
  235. return $this->lastline;
  236. }
  237. /**
  238. * Send a command to the server with an optional string of arguments.
  239. * A carriage return / linefeed (CRLF) sequence will be appended to each
  240. * command string before it is sent to the IMAP server.
  241. *
  242. * @param string $commandId The IMAP cmdID to send to the server.
  243. * @param string $command The IMAP command to send to the server.
  244. * @param string $args A string of optional arguments to append
  245. * to the command.
  246. *
  247. * @return mixed The result of the _send() call.
  248. *
  249. * @access private
  250. * @since 1.0
  251. */
  252. function _putCMD($commandId , $command, $args = '')
  253. {
  254. if ( !empty( $args ) ) {
  255. return $this->_send( $commandId . " " . $command . ' ' . $args . "\r\n" );
  256. }
  257. return $this->_send( $commandId . " " . $command . "\r\n" );
  258. }
  259. /**
  260. * Get a response from the server with an optional string of commandID.
  261. * A carriage return / linefeed (CRLF) sequence will be appended to each
  262. * command string before it is sent to the IMAP server.
  263. *
  264. * @param string $commandid The IMAP commandid retrive from the server.
  265. *
  266. * @return string The result response.
  267. *
  268. * @access private
  269. */
  270. function _getRawResponse($commandId = '*')
  271. {
  272. $arguments = '';
  273. while ( !PEAR::isError( $this->_recvLn() ) ) {
  274. $reply_code = strtok( $this->lastline , ' ' );
  275. $arguments.= $this->lastline;
  276. if ( !(strcmp( $commandId , $reply_code ) ) ) {
  277. return $arguments;
  278. }
  279. }
  280. return $arguments;
  281. }
  282. /**
  283. * get the "returning of the unparsed response" feature status
  284. *
  285. * @return boolean return if the unparsed response is returned or not
  286. *
  287. * @access public
  288. * @since 1.0
  289. *
  290. */
  291. function getUnparsedResponse()
  292. {
  293. return $this->_unParsedReturn;
  294. }
  295. /**
  296. * set the "returning of the unparsed response" feature on or off
  297. *
  298. * @param boolean $status: true: feature is on
  299. * @return nothing
  300. *
  301. * @access public
  302. * @since 1.0
  303. */
  304. function setUnparsedResponse($status)
  305. {
  306. $this->_unParsedReturn = $status;
  307. }
  308. /**
  309. * Attempt to login to the iMAP server.
  310. *
  311. * @param string The userid to authenticate as.
  312. * @param string The password to authenticate with.
  313. *
  314. * @return array Returns an array containing the response
  315. *
  316. * @access public
  317. * @since 1.0
  318. */
  319. function cmdLogin($uid , $pwd)
  320. {
  321. $param="\"$uid\" \"$pwd\"";
  322. return $this->_genericCommand('LOGIN', $param);
  323. }
  324. /**
  325. * Attempt to authenticate to the iMAP server.
  326. * @param string The userid to authenticate as.
  327. * @param string The password to authenticate with.
  328. * @param string The cmdID.
  329. *
  330. * @return array Returns an array containing the response
  331. *
  332. * @access public
  333. * @since 1.0
  334. */
  335. function cmdAuthenticate($uid , $pwd , $userMethod = null)
  336. {
  337. if( !$this->_connected ){
  338. return new PEAR_Error('not connected!');
  339. }
  340. $cmdid = $this->_getCmdId();
  341. if ( PEAR::isError( $method = $this->_getBestAuthMethod($userMethod) ) ) {
  342. return $method;
  343. }
  344. switch ($method) {
  345. case 'DIGEST-MD5':
  346. $result = $this->_authDigest_MD5( $uid , $pwd , $cmdid );
  347. break;
  348. case 'CRAM-MD5':
  349. $result = $this->_authCRAM_MD5( $uid , $pwd ,$cmdid );
  350. break;
  351. case 'LOGIN':
  352. $result = $this->_authLOGIN( $uid , $pwd , $cmdid );
  353. break;
  354. default :
  355. $result = new PEAR_Error( "$method is not a supported authentication method" );
  356. break;
  357. }
  358. $args = $this->_getRawResponse( $cmdid );
  359. return $this->_genericImapResponseParser( $args , $cmdid );
  360. }
  361. /* Authenticates the user using the DIGEST-MD5 method.
  362. *
  363. * @param string The userid to authenticate as.
  364. * @param string The password to authenticate with.
  365. * @param string The cmdID.
  366. *
  367. * @return array Returns an array containing the response
  368. *
  369. * @access private
  370. * @since 1.0
  371. */
  372. function _authDigest_MD5($uid , $pwd , $cmdid)
  373. {
  374. if ( PEAR::isError($error = $this->_putCMD( $cmdid ,"AUTHENTICATE" , "DIGEST-MD5") ) ) {
  375. return $error;
  376. }
  377. if (PEAR::isError( $args = $this->_recvLn() ) ) {
  378. return $args;
  379. }
  380. $this->_getNextToken( $args , $plus );
  381. $this->_getNextToken( $args , $space );
  382. $this->_getNextToken( $args , $challenge );
  383. $challenge = base64_decode( $challenge );
  384. $digest = &Auth_SASL::factory('digestmd5');
  385. $auth_str = base64_encode($digest->getResponse($uid, $pwd, $challenge,"localhost", "imap"));
  386. if ( PEAR::isError( $error = $this->_send("$auth_str\r\n"))) {
  387. return $error;
  388. }
  389. if ( PEAR::isError( $args = $this->_recvLn() )) {
  390. return $args;
  391. }
  392. /*
  393. * We don't use the protocol's third step because IMAP doesn't allow
  394. * subsequent authentication, so we just silently ignore it.
  395. */
  396. if ( PEAR::isError( $error = $this->_send( "\r\n" ) ) ) {
  397. return $error;
  398. }
  399. }
  400. /* Authenticates the user using the CRAM-MD5 method.
  401. *
  402. * @param string The userid to authenticate as.
  403. * @param string The password to authenticate with.
  404. * @param string The cmdID.
  405. *
  406. * @return array Returns an array containing the response
  407. *
  408. * @access private
  409. * @since 1.0
  410. */
  411. function _authCRAM_MD5($uid, $pwd, $cmdid)
  412. {
  413. if ( PEAR::isError($error = $this->_putCMD( $cmdid ,"AUTHENTICATE" , "CRAM-MD5") ) ) {
  414. return $error;
  415. }
  416. if ( PEAR::isError( $args = $this->_recvLn() ) ) {
  417. return $args;
  418. }
  419. $this->_getNextToken( $args , $plus );
  420. $this->_getNextToken( $args , $space );
  421. $this->_getNextToken( $args , $challenge );
  422. $challenge = base64_decode( $challenge );
  423. $cram = &Auth_SASL::factory('crammd5');
  424. $auth_str = base64_encode( $cram->getResponse( $uid , $pwd , $challenge ) );
  425. if ( PEAR::isError( $error = $this->_send( $auth_str."\r\n" ) ) ) {
  426. return $error;
  427. }
  428. }
  429. /* Authenticates the user using the LOGIN method.
  430. *
  431. * @param string The userid to authenticate as.
  432. * @param string The password to authenticate with.
  433. * @param string The cmdID.
  434. *
  435. * @return array Returns an array containing the response
  436. *
  437. * @access private
  438. * @since 1.0
  439. */
  440. function _authLOGIN($uid, $pwd, $cmdid)
  441. {
  442. if (PEAR::isError($error = $this->_putCMD($cmdid,"AUTHENTICATE", "LOGIN"))) {
  443. return $error;
  444. }
  445. if (PEAR::isError($args = $this->_recvLn() )) {
  446. return $args;
  447. }
  448. $this->_getNextToken( $args , $plus );
  449. $this->_getNextToken( $args , $space );
  450. $this->_getNextToken( $args , $challenge );
  451. $challenge = base64_decode( $challenge );
  452. $auth_str = base64_encode( "$uid" );
  453. if ( PEAR::isError( $error = $this->_send( $auth_str."\r\n" ) ) ) {
  454. return $error;
  455. }
  456. if (PEAR::isError( $args = $this->_recvLn() ) ) {
  457. return $args;
  458. }
  459. $auth_str = base64_encode( "$pwd" );
  460. if ( PEAR::isError($error = $this->_send( $auth_str."\r\n" ) ) ) {
  461. return $error;
  462. }
  463. }
  464. /**
  465. * Returns the name of the best authentication method that the server
  466. * has advertised.
  467. *
  468. * @param string if !=null,authenticate with this method ($userMethod).
  469. *
  470. * @return mixed Returns a string containing the name of the best
  471. * supported authentication method or a PEAR_Error object
  472. * if a failure condition is encountered.
  473. * @access private
  474. * @since 1.0
  475. */
  476. function _getBestAuthMethod($userMethod = null)
  477. {
  478. $this->cmdCapability();
  479. if($userMethod != null ){
  480. $methods = array();
  481. $methods[] = $userMethod;
  482. }else{
  483. $methods = $this->supportedAuthMethods;
  484. }
  485. if( ($methods != null) && ($this->_serverAuthMethods != null)){
  486. foreach ( $methods as $method ) {
  487. if ( in_array( $method , $this->_serverAuthMethods ) ) {
  488. return $method;
  489. }
  490. }
  491. $serverMethods=implode(',' ,$this->_serverAuthMethods);
  492. $myMethods=implode(',' ,$this->supportedAuthMethods);
  493. return new PEAR_Error("$method NOT supported authentication method!. This IMAP server " .
  494. "supports these methods: $serverMethods, but I support $myMethods");
  495. }else{
  496. return new PEAR_Error("This IMAP server don't support any Auth methods");
  497. }
  498. }
  499. /**
  500. * Attempt to disconnect from the iMAP server.
  501. *
  502. * @return array Returns an array containing the response
  503. *
  504. * @access public
  505. * @since 1.0
  506. */
  507. function cmdLogout()
  508. {
  509. if( !$this->_connected ){
  510. return new PEAR_Error( 'not connected!' );
  511. }
  512. $cmdid = $this->_getCmdId();
  513. if ( PEAR::isError( $error = $this->_putCMD( $cmdid , 'LOGOUT' ) ) ) {
  514. return $error;
  515. }
  516. if ( PEAR::isError($args = $this->_getRawResponse() ) ) {
  517. return $args;
  518. }
  519. if (PEAR::isError( $this->_socket->disconnect() ) ) {
  520. return new PEAR_Error('socket disconnect failed');
  521. }
  522. return $args;
  523. // not for now
  524. //return $this->_genericImapResponseParser($args,$cmdid);
  525. }
  526. /**
  527. * Send the NOOP command.
  528. *
  529. * @return array Returns an array containing the response
  530. *
  531. * @access public
  532. * @since 1.0
  533. */
  534. function cmdNoop()
  535. {
  536. return $this->_genericCommand('NOOP');
  537. }
  538. /**
  539. * Send the CHECK command.
  540. *
  541. * @return array Returns an array containing the response
  542. *
  543. * @access public
  544. * @since 1.0
  545. */
  546. function cmdCheck()
  547. {
  548. return $this->_genericCommand('CHECK');
  549. }
  550. /**
  551. * Send the Select Mailbox Command
  552. *
  553. * @param string The mailbox to select.
  554. *
  555. * @return array Returns an array containing the response
  556. *
  557. * @access public
  558. * @since 1.0
  559. */
  560. function cmdSelect($mailbox)
  561. {
  562. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  563. if( !PEAR::isError( $ret= $this->_genericCommand('SELECT', $mailbox_name) ) ){
  564. $this->currentMailbox = $mailbox;
  565. }
  566. return $ret;
  567. }
  568. /**
  569. * Send the EXAMINE Mailbox Command
  570. *
  571. * @param string The mailbox to examine.
  572. * @return array Returns an array containing the response
  573. *
  574. * @access public
  575. * @since 1.0
  576. */
  577. function cmdExamine($mailbox)
  578. {
  579. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  580. $ret=$this->_genericCommand('EXAMINE', $mailbox_name);
  581. $parsed='';
  582. if(isset( $ret["PARSED"] ) ){
  583. for($i=0;$i<count($ret["PARSED"]); $i++){ $command=$ret["PARSED"][$i]["EXT"];
  584. $parsed[key($command)]=$command[key($command)];
  585. }
  586. }
  587. return array("PARSED"=>$parsed,"RESPONSE"=>$ret["RESPONSE"]);
  588. }
  589. /**
  590. * Send the CREATE Mailbox Command
  591. *
  592. * @param string The mailbox to create.
  593. * @return array Returns an array containing the response
  594. *
  595. * @access public
  596. * @since 1.0
  597. */
  598. function cmdCreate($mailbox)
  599. {
  600. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  601. return $this->_genericCommand('CREATE', $mailbox_name);
  602. }
  603. /**
  604. * Send the RENAME Mailbox Command
  605. *
  606. * @param string The old mailbox name.
  607. * @param string The new (renamed) mailbox name.
  608. *
  609. * @return array Returns an array containing the response
  610. *
  611. * @access public
  612. * @since 1.0
  613. */
  614. function cmdRename($mailbox, $new_mailbox)
  615. {
  616. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  617. $new_mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($new_mailbox) );
  618. return $this->_genericCommand('RENAME', "$mailbox_name $new_mailbox_name" );
  619. }
  620. /**
  621. * Send the DELETE Mailbox Command
  622. *
  623. * @param string The mailbox name to delete.
  624. *
  625. * @return array Returns an array containing the response
  626. *
  627. * @access public
  628. * @since 1.0
  629. */
  630. function cmdDelete($mailbox)
  631. {
  632. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  633. return $this->_genericCommand('DELETE', $mailbox_name);
  634. }
  635. /**
  636. * Send the SUSCRIBE Mailbox Command
  637. *
  638. * @param string The mailbox name to suscribe.
  639. *
  640. * @return array Returns an array containing the response
  641. *
  642. * @access public
  643. * @since 1.0
  644. */
  645. function cmdSubscribe($mailbox)
  646. {
  647. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  648. return $this->_genericCommand('SUBSCRIBE', $mailbox_name );
  649. }
  650. /**
  651. * Send the UNSUSCRIBE Mailbox Command
  652. *
  653. * @return mixed Returns a PEAR_Error with an error message on any
  654. * kind of failure, or true on success.
  655. * @access public
  656. * @since 1.0
  657. */
  658. function cmdUnsubscribe($mailbox)
  659. {
  660. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  661. return $this->_genericCommand('UNSUBSCRIBE', $mailbox_name );
  662. }
  663. /**
  664. * Send the FETCH Command
  665. *
  666. * @return mixed Returns a PEAR_Error with an error message on any
  667. * kind of failure, or true on success.
  668. * @access public
  669. * @since 1.0
  670. */
  671. function cmdFetch($msgset, $fetchparam)
  672. {
  673. return $this->_genericCommand('FETCH' , "$msgset $fetchparam" );
  674. }
  675. /**
  676. * Send the CAPABILITY Command
  677. *
  678. * @return mixed Returns a PEAR_Error with an error message on any
  679. * kind of failure, or true on success.
  680. * @access public
  681. * @since 1.0
  682. */
  683. function cmdCapability()
  684. {
  685. $ret = $this->_genericCommand( 'CAPABILITY' );
  686. if(isset( $ret["PARSED"] ) ){
  687. $ret["PARSED"]=$ret["PARSED"][0]["EXT"]["CAPABILITY"];
  688. //fill the $this->_serverAuthMethods and $this->_serverSupportedCapabilities arrays
  689. foreach( $ret["PARSED"]["CAPABILITIES"] as $auth_method ){
  690. if( strtoupper( substr( $auth_method , 0 ,5 ) ) == "AUTH=" )
  691. $this->_serverAuthMethods[] = substr( $auth_method , 5 );
  692. }
  693. // Keep the capabilities response to use ir later
  694. $this->_serverSupportedCapabilities = $ret["PARSED"]["CAPABILITIES"];
  695. }
  696. return $ret;
  697. }
  698. /**
  699. * Send the STATUS Mailbox Command
  700. *
  701. * @param string $mailbox the mailbox name
  702. * @param string $request the request status it could be:
  703. * MESSAGES | RECENT | UIDNEXT
  704. * UIDVALIDITY | UNSEEN
  705. * @return array Returns a Parsed Response
  706. *
  707. * @access public
  708. * @since 1.0
  709. */
  710. function cmdStatus($mailbox, $request)
  711. {
  712. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  713. if( $request!="MESSAGES" && $request!="RECENT" && $request!="UIDNEXT" &&
  714. $request!="UIDVALIDITY" && $request!="UNSEEN" ){
  715. // TODO: fix this error!
  716. $this->_prot_error("request '$request' is invalid! see RFC2060!!!!" , __LINE__ , __FILE__, false );
  717. }
  718. $ret = $this->_genericCommand('STATUS', "$mailbox_name ($request)" );
  719. if(isset( $ret["PARSED"] ) ){
  720. $ret['PARSED']=$ret["PARSED"][count($ret['PARSED'])-1]["EXT"];
  721. }
  722. return $ret;
  723. }
  724. /**
  725. * Send the LIST Command
  726. *
  727. * @return mixed Returns a PEAR_Error with an error message on any
  728. * kind of failure, or true on success.
  729. * @access public
  730. * @since 1.0
  731. */
  732. function cmdList($mailbox_base, $mailbox)
  733. {
  734. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  735. $mailbox_base=sprintf("\"%s\"",$this->utf_7_encode($mailbox_base) );
  736. return $this->_genericCommand('LIST', "$mailbox_base $mailbox_name" );
  737. }
  738. /**
  739. * Send the LSUB Command
  740. *
  741. * @return mixed Returns a PEAR_Error with an error message on any
  742. * kind of failure, or true on success.
  743. * @access public
  744. * @since 1.0
  745. */
  746. function cmdLsub($mailbox_base, $mailbox)
  747. {
  748. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  749. $mailbox_base=sprintf("\"%s\"",$this->utf_7_encode($mailbox_base) );
  750. return $this->_genericCommand('LSUB', "$mailbox_base $mailbox_name" );
  751. }
  752. /**
  753. * Send the APPEND Command
  754. *
  755. * @return mixed Returns a PEAR_Error with an error message on any
  756. * kind of failure, or true on success.
  757. * @access public
  758. * @since 1.0
  759. */
  760. function cmdAppend($mailbox, $msg , $flags_list = '' ,$time = '')
  761. {
  762. if(!$this->_connected){
  763. return new PEAR_Error('not connected!');
  764. }
  765. $cmdid=$this->_getCmdId();
  766. $msg_size=strlen($msg);
  767. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  768. // TODO:
  769. // Falta el codigo para que flags list y time hagan algo!!
  770. if( $this->hasCapability( "LITERAL+" ) == true ){
  771. $param=sprintf("%s %s%s{%s+}\r\n%s",$mailbox_name,$flags_list,$time,$msg_size,$msg);
  772. if (PEAR::isError($error = $this->_putCMD($cmdid , 'APPEND' , $param ) ) ) {
  773. return $error;
  774. }
  775. }else{
  776. $param=sprintf("%s %s%s{%s}\r\n",$mailbox_name,$flags_list,$time,$msg_size);
  777. if (PEAR::isError($error = $this->_putCMD($cmdid , 'APPEND' , $param ) ) ) {
  778. return $error;
  779. }
  780. if (PEAR::isError($error = $this->_recvLn() ) ) {
  781. return $error;
  782. }
  783. if (PEAR::isError($error = $this->_send( $msg ) ) ) {
  784. return $error;
  785. }
  786. }
  787. $args=$this->_getRawResponse($cmdid);
  788. $ret = $this->_genericImapResponseParser($args,$cmdid);
  789. return $ret;
  790. }
  791. /**
  792. * Send the CLOSE command.
  793. *
  794. * @return mixed Returns a PEAR_Error with an error message on any
  795. * kind of failure, or true on success.
  796. * @access public
  797. * @since 1.0
  798. */
  799. function cmdClose()
  800. {
  801. return $this->_genericCommand('CLOSE');
  802. }
  803. /**
  804. * Send the EXPUNGE command.
  805. *
  806. * @return mixed Returns a PEAR_Error with an error message on any
  807. * kind of failure, or true on success.
  808. * @access public
  809. * @since 1.0
  810. */
  811. function cmdExpunge()
  812. {
  813. $ret=$this->_genericCommand('EXPUNGE');
  814. if(isset( $ret["PARSED"] ) ){
  815. $parsed=$ret["PARSED"];
  816. unset($ret["PARSED"]);
  817. foreach($parsed as $command){
  818. if( strtoupper($command["COMMAND"]) == 'EXPUNGE' ){
  819. $ret["PARSED"][$command["COMMAND"]][]=$command["NRO"];
  820. }else{
  821. $ret["PARSED"][$command["COMMAND"]]=$command["NRO"];
  822. }
  823. }
  824. }
  825. return $ret;
  826. }
  827. /**
  828. * Send the SEARCH command.
  829. *
  830. * @return mixed Returns a PEAR_Error with an error message on any
  831. * kind of failure, or true on success.
  832. * @access public
  833. * @since 1.0
  834. */
  835. function cmdSearch($search_cmd)
  836. {
  837. /* if($_charset != '' )
  838. $_charset = "[$_charset] ";
  839. $param=sprintf("%s%s",$charset,$search_cmd);
  840. */
  841. $ret = $this->_genericCommand('SEARCH', $search_cmd );
  842. if(isset( $ret["PARSED"] ) ){
  843. $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  844. }
  845. return $ret;
  846. }
  847. /**
  848. * Send the STORE command.
  849. *
  850. * @param string $message_set the sessage_set
  851. * @param string $dataitem: the way we store the flags
  852. * FLAGS: replace the flags whith $value
  853. * FLAGS.SILENT: replace the flags whith $value but don't return untagged responses
  854. *
  855. * +FLAGS: Add the flags whith $value
  856. * +FLAGS.SILENT: Add the flags whith $value but don't return untagged responses
  857. *
  858. * -FLAGS: Remove the flags whith $value
  859. * -FLAGS.SILENT: Remove the flags whith $value but don't return untagged responses
  860. *
  861. * @param string $value
  862. * @return mixed Returns a PEAR_Error with an error message on any
  863. * kind of failure, or true on success.
  864. * @access public
  865. * @since 1.0
  866. */
  867. function cmdStore($message_set, $dataitem, $value)
  868. {
  869. /* As said in RFC2060...
  870. C: A003 STORE 2:4 +FLAGS (\Deleted)
  871. S: * 2 FETCH FLAGS (\Deleted \Seen)
  872. S: * 3 FETCH FLAGS (\Deleted)
  873. S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
  874. S: A003 OK STORE completed
  875. */
  876. if( $dataitem!="FLAGS" && $dataitem!="FLAGS.SILENT" && $dataitem!="+FLAGS" &&
  877. $dataitem!="+FLAGS.SILENT" && $dataitem!="-FLAGS" && $dataitem!="-FLAGS.SILENT" ){
  878. $this->_prot_error("dataitem '$dataitem' is invalid! see RFC2060!!!!" , __LINE__ , __FILE__ );
  879. }
  880. $param=sprintf("%s %s (%s)",$message_set,$dataitem,$value);
  881. return $this->_genericCommand('STORE', $param );
  882. }
  883. /**
  884. * Send the COPY command.
  885. *
  886. * @return mixed Returns a PEAR_Error with an error message on any
  887. * kind of failure, or true on success.
  888. * @access public
  889. * @since 1.0
  890. */
  891. function cmdCopy($message_set, $mailbox)
  892. {
  893. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  894. return $this->_genericCommand('COPY', sprintf("%s %s",$message_set,$mailbox_name) );
  895. }
  896. function cmdUidFetch($msgset, $fetchparam)
  897. {
  898. return $this->_genericCommand('UID FETCH', sprintf("%s %s",$msgset,$fetchparam) );
  899. }
  900. function cmdUidCopy($message_set, $mailbox)
  901. {
  902. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  903. return $this->_genericCommand('UID COPY', sprintf("%s %s",$message_set,$mailbox_name) );
  904. }
  905. /**
  906. * Send the UID STORE command.
  907. *
  908. * @param string $message_set the sessage_set
  909. * @param string $dataitem: the way we store the flags
  910. * FLAGS: replace the flags whith $value
  911. * FLAGS.SILENT: replace the flags whith $value but don't return untagged responses
  912. *
  913. * +FLAGS: Add the flags whith $value
  914. * +FLAGS.SILENT: Add the flags whith $value but don't return untagged responses
  915. *
  916. * -FLAGS: Remove the flags whith $value
  917. * -FLAGS.SILENT: Remove the flags whith $value but don't return untagged responses
  918. *
  919. * @param string $value
  920. * @return mixed Returns a PEAR_Error with an error message on any
  921. * kind of failure, or true on success.
  922. * @access public
  923. * @since 1.0
  924. */
  925. function cmdUidStore($message_set, $dataitem, $value)
  926. {
  927. /* As said in RFC2060...
  928. C: A003 STORE 2:4 +FLAGS (\Deleted)
  929. S: * 2 FETCH FLAGS (\Deleted \Seen)
  930. S: * 3 FETCH FLAGS (\Deleted)
  931. S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
  932. S: A003 OK STORE completed
  933. */
  934. if( $dataitem!="FLAGS" && $dataitem!="FLAGS.SILENT" && $dataitem!="+FLAGS" &&
  935. $dataitem!="+FLAGS.SILENT" && $dataitem!="-FLAGS" && $dataitem!="-FLAGS.SILENT" ){
  936. $this->_prot_error("dataitem '$dataitem' is invalid! see RFC2060!!!!" , __LINE__ , __FILE__ );
  937. }
  938. return $this->_genericCommand('UID STORE', sprintf("%s %s (%s)",$message_set,$dataitem,$value) );
  939. }
  940. /**
  941. * Send the SEARCH command.
  942. *
  943. * @return mixed Returns a PEAR_Error with an error message on any
  944. * kind of failure, or true on success.
  945. * @access public
  946. * @since 1.0
  947. */
  948. function cmdUidSearch($search_cmd)
  949. {
  950. $ret=$this->_genericCommand('UID SEARCH', sprintf("%s",$search_cmd) );
  951. if(isset( $ret["PARSED"] ) ){
  952. $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  953. }
  954. return $ret;
  955. }
  956. /**
  957. * Send the X command.
  958. *
  959. * @return mixed Returns a PEAR_Error with an error message on any
  960. * kind of failure, or true on success.
  961. * @access public
  962. * @since 1.0
  963. */
  964. function cmdX($atom, $parameters)
  965. {
  966. return $this->_genericCommand("X$atom", $parameters );
  967. }
  968. /********************************************************************
  969. ***
  970. *** HERE ENDS the RFC2060 IMAPS FUNCTIONS
  971. *** AND BEGIN THE EXTENSIONS FUNCTIONS
  972. ***
  973. ********************************************************************/
  974. /********************************************************************
  975. *** RFC2087 IMAP4 QUOTA extension BEGINS HERE
  976. ********************************************************************/
  977. /**
  978. * Send the GETQUOTA command.
  979. *
  980. * @param string $mailbox_name the mailbox name to query for quota data
  981. * @return mixed Returns a PEAR_Error with an error message on any
  982. * kind of failure, or quota data on success
  983. * @access public
  984. * @since 1.0
  985. */
  986. function cmdGetQuota($mailbox_name)
  987. {
  988. //Check if the IMAP server has QUOTA support
  989. if( ! $this->hasQuotaSupport() ){
  990. return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  991. }
  992. $mailbox_name=sprintf("%s",$this->utf_7_encode($mailbox_name) );
  993. $ret = $this->_genericCommand('GETQUOTA', $mailbox_name );
  994. if(isset( $ret["PARSED"] ) ){
  995. // remove the array index because the quota response returns only 1 line of output
  996. $ret['PARSED']=$ret["PARSED"][0];
  997. }
  998. return $ret;
  999. }
  1000. /**
  1001. * Send the GETQUOTAROOT command.
  1002. *
  1003. * @param string $mailbox_name the mailbox name to query for quota data
  1004. * @return mixed Returns a PEAR_Error with an error message on any
  1005. * kind of failure, or quota data on success
  1006. * @access public
  1007. * @since 1.0
  1008. */
  1009. function cmdGetQuotaRoot($mailbox_name)
  1010. {
  1011. //Check if the IMAP server has QUOTA support
  1012. if( ! $this->hasQuotaSupport() ){
  1013. return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  1014. }
  1015. $mailbox_name=sprintf("%s",$this->utf_7_encode($mailbox_name) );
  1016. $ret = $this->_genericCommand('GETQUOTAROOT', $mailbox_name );
  1017. if(isset( $ret["PARSED"] ) ){
  1018. // remove the array index because the quota response returns only 1 line of output
  1019. $ret['PARSED']=$ret["PARSED"][0];
  1020. }
  1021. return $ret;
  1022. }
  1023. /**
  1024. * Send the SETQUOTA command.
  1025. *
  1026. * @param string $mailbox_name the mailbox name to query for quota data
  1027. * @param string $storageQuota sets the max number of bytes this mailbox can handle
  1028. * @param string $messagesQuota sets the max number of messages this mailbox can handle
  1029. * @return mixed Returns a PEAR_Error with an error message on any
  1030. * kind of failure, or quota data on success
  1031. * @access public
  1032. * @since 1.0
  1033. */
  1034. // TODO: implement the quota by number of emails!!
  1035. function cmdSetQuota($mailbox_name, $storageQuota = null ,$messagesQuota = null )
  1036. {
  1037. //Check if the IMAP server has QUOTA support
  1038. if( ! $this->hasQuotaSupport() ){
  1039. return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  1040. }
  1041. if( ($messagesQuota == null) && ( $storageQuota == null) ){
  1042. return new PEAR_Error('$storageQuota and $messagesQuota parameters can\'t be both null if you want to use quota');
  1043. }
  1044. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1045. //Make the command request
  1046. $param=sprintf("%s (",$mailbox_name);
  1047. if($storageQuota != null ){
  1048. $param=sprintf("%sSTORAGE %s",$param,$storageQuota);
  1049. if( $messagesQuota != null ){
  1050. //if we have both types of quota on the same call we must append an space between
  1051. // those parameters
  1052. $param=sprintf("%s ",$param);
  1053. }
  1054. }
  1055. if($messagesQuota != null ){
  1056. $param=sprintf("%sMESSAGES %s",$param,$messagesQuota);
  1057. }
  1058. $param=sprintf("%s)",$param);
  1059. return $this->_genericCommand('SETQUOTA', $param );
  1060. }
  1061. /**
  1062. * Send the SETQUOTAROOT command.
  1063. *
  1064. * @param string $mailbox_name the mailbox name to query for quota data
  1065. * @param string $storageQuota sets the max number of bytes this mailbox can handle
  1066. * @param string $messagesQuota sets the max number of messages this mailbox can handle
  1067. * @return mixed Returns a PEAR_Error with an error message on any
  1068. * kind of failure, or quota data on success
  1069. * @access public
  1070. * @since 1.0
  1071. */
  1072. function cmdSetQuotaRoot($mailbox_name, $storageQuota = null ,$messagesQuota = null)
  1073. {
  1074. //Check if the IMAP server has QUOTA support
  1075. if( ! $this->hasQuotaSupport() ){
  1076. return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  1077. }
  1078. if( ($messagesQuota == null) && ( $storageQuota == null) ){
  1079. return new PEAR_Error('$storageQuota and $messagesQuota parameters can\'t be both null if you want to use quota');
  1080. }
  1081. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1082. //Make the command request
  1083. $param=sprintf("%s (",$mailbox_name);
  1084. if($storageQuota != null ){
  1085. $param=sprintf("%sSTORAGE %s",$param,$storageQuota);
  1086. if( $messagesQuota != null ){
  1087. //if we have both types of quota on the same call we must append an space between
  1088. // those parameters
  1089. $param=sprintf("%s ",$param);
  1090. }
  1091. }
  1092. if($messagesQuota != null ){
  1093. $param=sprintf("%sMESSAGES %s",$param,$messagesQuota);
  1094. }
  1095. $param=sprintf("%s)",$param);
  1096. return $this->_genericCommand('SETQUOTAROOT', $param );
  1097. }
  1098. /********************************************************************
  1099. *** RFC2087 IMAP4 QUOTA extension ENDS HERE
  1100. ********************************************************************/
  1101. /********************************************************************
  1102. *** RFC2086 IMAP4 ACL extension BEGINS HERE
  1103. ********************************************************************/
  1104. function cmdSetACL($mailbox_name, $user, $acl)
  1105. {
  1106. //Check if the IMAP server has ACL support
  1107. if( ! $this->hasAclSupport() ){
  1108. return new PEAR_Error("This IMAP server does not support ACL's! ");
  1109. }
  1110. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1111. $user_name=sprintf("\"%s\"",$this->utf_7_encode($user) );
  1112. if(is_array($acl)){
  1113. $acl=implode('',$acl);
  1114. }
  1115. return $this->_genericCommand('SETACL', sprintf("%s %s \"%s\"",$mailbox_name,$user_name,$acl) );
  1116. }
  1117. function cmdDeleteACL($mailbox_name, $user)
  1118. {
  1119. //Check if the IMAP server has ACL support
  1120. if( ! $this->hasAclSupport() ){
  1121. return new PEAR_Error("This IMAP server does not support ACL's! ");
  1122. }
  1123. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1124. return $this->_genericCommand('DELETEACL', sprintf("%s \"%s\"",$mailbox_name,$user) );
  1125. }
  1126. function cmdGetACL($mailbox_name)
  1127. {
  1128. //Check if the IMAP server has ACL support
  1129. if( ! $this->hasAclSupport() ){
  1130. return new PEAR_Error("This IMAP server does not support ACL's! ");
  1131. }
  1132. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1133. $ret = $this->_genericCommand('GETACL', sprintf("%s",$mailbox_name) );
  1134. if(isset( $ret["PARSED"] ) ){
  1135. $ret['PARSED']=$ret["PARSED"][0]["EXT"];
  1136. }
  1137. return $ret;
  1138. }
  1139. function cmdListRights($mailbox_name, $user)
  1140. {
  1141. //Check if the IMAP server has ACL support
  1142. if( ! $this->hasAclSupport() ){
  1143. return new PEAR_Error("This IMAP server does not support ACL's! ");
  1144. }
  1145. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1146. $ret = $this->_genericCommand('LISTRIGHTS', sprintf("%s \"%s\"",$mailbox_name,$user) );
  1147. if(isset( $ret["PARSED"] ) ){
  1148. $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  1149. }
  1150. return $ret;
  1151. }
  1152. function cmdMyRights($mailbox_name)
  1153. {
  1154. //Check if the IMAP server has ACL support
  1155. if( ! $this->hasAclSupport() ){
  1156. return new PEAR_Error("This IMAP server does not support ACL's! ");
  1157. }
  1158. $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1159. $ret = $this->_genericCommand('MYRIGHTS', sprintf("%s",$mailbox_name) );
  1160. if(isset( $ret["PARSED"] ) ){
  1161. $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  1162. }
  1163. return $ret;
  1164. }
  1165. /********************************************************************
  1166. *** RFC2086 IMAP4 ACL extension ENDs HERE
  1167. ********************************************************************/
  1168. /*******************************************************************************
  1169. *** draft-daboo-imap-annotatemore-05 IMAP4 ANNOTATEMORE extension BEGINS HERE
  1170. ********************************************************************************/
  1171. function cmdSetAnnotation($mailbox_name, $entry, $values)
  1172. {
  1173. // Check if the IMAP server has ANNOTATEMORE support
  1174. if(!$this->hasAnnotateMoreSupport()) {
  1175. return new PEAR_Error('This IMAP server does not support the ANNOTATEMORE extension!');
  1176. }
  1177. if (!is_array($values)) {
  1178. return new PEAR_Error('Invalid $values argument passed to cmdSetAnnotation');
  1179. }
  1180. $vallist = '';
  1181. foreach ($values as $name => $value) {
  1182. $vallist .= "\"$name\" \"$value\" ";
  1183. }
  1184. $vallist = rtrim($vallist);
  1185. return $this->_genericCommand('SETANNOTATION', sprintf('"%s" "%s" (%s)', $mailbox_name, $entry, $vallist));
  1186. }
  1187. function cmdDeleteAnnotation($mailbox_name, $entry, $values)
  1188. {
  1189. // Check if the IMAP server has ANNOTATEMORE support
  1190. if(!$this->hasAnnotateMoreSupport()) {
  1191. return new PEAR_Error('This IMAP server does not support the ANNOTATEMORE extension!');
  1192. }
  1193. if (!is_array($values)) {
  1194. return new PEAR_Error('Invalid $values argument passed to cmdDeleteAnnotation');
  1195. }
  1196. $vallist = '';
  1197. foreach ($values as $name) {
  1198. $vallist .= "\"$name\" NIL ";
  1199. }
  1200. $vallist = rtrim($vallist);
  1201. return $this->_genericCommand('SETANNOTATION', sprintf('"%s" "%s" (%s)', $mailbox_name, $entry, $vallist));
  1202. }
  1203. function cmdGetAnnotation($mailbox_name, $entries, $values)
  1204. {
  1205. // Check if the IMAP server has ANNOTATEMORE support
  1206. if(!$this->hasAnnotateMoreSupport()) {
  1207. return new PEAR_Error('This IMAP server does not support the ANNOTATEMORE extension!');
  1208. }
  1209. $entlist = '';
  1210. if (!is_array($entries)) {
  1211. $entries = array($entries);
  1212. }
  1213. foreach ($entries as $name) {
  1214. $entlist .= "\"$name\" ";
  1215. }
  1216. $entlist = rtrim($entlist);
  1217. if (count($entries) > 1) {
  1218. $entlist = "($entlist)";
  1219. }
  1220. $vallist = '';
  1221. if (!is_array($values)) {
  1222. $values = array($values);
  1223. }
  1224. foreach ($values as $name) {
  1225. $vallist .= "\"$name\" ";
  1226. }
  1227. $vallist = rtrim($vallist);
  1228. if (count($values) > 1) {
  1229. $vallist = "($vallist)";
  1230. }
  1231. return $this->_genericCommand('GETANNOTATION', sprintf('"%s" %s %s', $mailbox_name, $entlist, $vallist));
  1232. }
  1233. /*****************************************************************************
  1234. *** draft-daboo-imap-annotatemore-05 IMAP4 ANNOTATEMORE extension ENDs HERE
  1235. ******************************************************************************/
  1236. /********************************************************************
  1237. ***
  1238. *** HERE ENDS THE EXTENSIONS FUNCTIONS
  1239. *** AND BEGIN THE AUXILIARY FUNCTIONS
  1240. ***
  1241. ********************************************************************/
  1242. /**
  1243. * tell if the server has capability $capability
  1244. *
  1245. * @return true or false
  1246. *
  1247. * @access public
  1248. * @since 1.0
  1249. */
  1250. function getServerAuthMethods()
  1251. {
  1252. if( $this->_serverAuthMethods == null ){
  1253. $this->cmdCapability();
  1254. return $this->_serverAuthMethods;
  1255. }
  1256. return false;
  1257. }
  1258. /**
  1259. * tell if the server has capability $capability
  1260. *
  1261. * @return true or false
  1262. *
  1263. * @access public
  1264. * @since 1.0
  1265. */
  1266. function hasCapability($capability)
  1267. {
  1268. if( $this->_serverSupportedCapabilities == null ){
  1269. $this->cmdCapability();
  1270. }
  1271. if($this->_serverSupportedCapabilities != null ){
  1272. if( in_array( $capability , $this->_serverSupportedCapabilities ) ){
  1273. return true;
  1274. }
  1275. }
  1276. return false;
  1277. }
  1278. /**
  1279. * tell if the server has Quota support
  1280. *
  1281. * @return true or false
  1282. *
  1283. * @access public
  1284. * @since 1.0
  1285. */
  1286. function hasQuotaSupport()
  1287. {
  1288. return $this->hasCapability('QUOTA');
  1289. }
  1290. /**
  1291. * tell if the server has Quota support
  1292. *
  1293. * @return true or false
  1294. *
  1295. * @access public
  1296. * @since 1.0
  1297. */
  1298. function hasAclSupport()
  1299. {
  1300. return $this->hasCapability('ACL');
  1301. }
  1302. /**
  1303. * tell if the server has support for the ANNOTATEMORE extension
  1304. *
  1305. * @return true or false
  1306. *
  1307. * @access public
  1308. * @since 1.0
  1309. */
  1310. function hasAnnotateMoreSupport()
  1311. {
  1312. return $this->hasCapability('ANNOTATEMORE');
  1313. }
  1314. /**
  1315. * Parses the responses like RFC822.SIZE and INTERNALDATE
  1316. *
  1317. * @param string the IMAP's server response
  1318. *
  1319. * @return string containing the parsed response
  1320. * @access private
  1321. * @since 1.0
  1322. */
  1323. function _parseOneStringResponse(&$str, $line,$file)
  1324. {
  1325. $this->_parseSpace($str , $line , $file );
  1326. $size = $this->_getNextToken($str,$uid);
  1327. return $uid;
  1328. }
  1329. /**
  1330. * Parses the FLAG response
  1331. *
  1332. * @param string the IMAP's server response
  1333. *
  1334. * @return Array containing the parsed response
  1335. * @access private
  1336. * @since 1.0
  1337. */
  1338. function _parseFLAGSresponse(&$str)
  1339. {
  1340. $this->_parseSpace($str , __LINE__ , __FILE__ );
  1341. $params_arr[] = $this->_arrayfy_content($str);
  1342. $flags_arr=array();
  1343. for( $i = 0 ; $i < count($params_arr[0]) ; $i++ ){
  1344. $flags_arr[] = $params_arr[0][$i];
  1345. }
  1346. return $flags_arr;
  1347. }
  1348. /**
  1349. * Parses the BODY response
  1350. *
  1351. * @param string the IMAP's server response
  1352. *
  1353. * @return Array containing the parsed response
  1354. * @access private
  1355. * @since 1.0
  1356. */
  1357. function _parseBodyResponse(&$str, $command){
  1358. $this->_parseSpace($str , __LINE__ , __FILE__ );
  1359. while($str[0] != ')' && $str!=''){
  1360. $params_arr[] = $this->_arrayfy_content($str);
  1361. }
  1362. return $params_arr;
  1363. }
  1364. /**
  1365. * Makes the content an Array
  1366. *
  1367. * @param string the IMAP's server response
  1368. *
  1369. * @return Array containing the parsed response
  1370. * @access private
  1371. * @since 1.0
  1372. */
  1373. function _arrayfy_content(&$str)
  1374. {
  1375. $params_arr=array();
  1376. $this->_getNextToken($str,$params);
  1377. if($params != '(' ){
  1378. return $params;
  1379. }
  1380. $this->_getNextToken($str,$params,false,false);
  1381. while ( $str != '' && $params != ')'){
  1382. if($params != '' ){
  1383. if($params[0] == '(' ){
  1384. $params=$this->_arrayfy_content( $params );
  1385. }
  1386. if($params != ' ' ){
  1387. //I don't remove the colons (") to handle the case of retriving " "
  1388. // If I remove the colons the parser will interpret this field as an imap separator (space)
  1389. // instead of a valid field so I remove the colons here
  1390. if($params=='""'){
  1391. $params='';
  1392. }else{
  1393. if($params[0]=='"'){
  1394. $params=substr($params,1,strlen($params)-2);
  1395. }
  1396. }
  1397. $params_arr[]=$params;
  1398. }
  1399. }else{
  1400. //if params if empty (for example i'm parsing 2 quotes ("")
  1401. // I'll append an array entry to mantain compatibility
  1402. $params_arr[]=$params;
  1403. }
  1404. $this->_getNextToken($str,$params,false,false);
  1405. }
  1406. return $params_arr;
  1407. }
  1408. /**
  1409. * Parses the BODY[],BODY[TEXT],.... responses
  1410. *
  1411. * @param string the IMAP's server response
  1412. *
  1413. * @return Array containing the parsed response
  1414. * @access private
  1415. * @since 1.0
  1416. */
  1417. function _parseContentresponse(&$str, $command)
  1418. {
  1419. $content = '';
  1420. $this->_parseSpace($str , __LINE__ , __FILE__ );
  1421. $size =$this->_getNextToken($str,$content);
  1422. return array( "CONTENT"=> $content , "CONTENT_SIZ…

Large files files are truncated, but you can click here to view the full file