| <?php |
| /** |
| * File containing the ezcMailPop3Transport class. |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| * @package Mail |
| * @version //autogen// |
| * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved. |
| * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
| */ |
| |
| /** |
| * The class ezcMailPop3Transport implements functionality for handling POP3 |
| * mail servers. |
| * |
| * The implementation supports most of the commands specified in: |
| * - {@link http://www.faqs.org/rfcs/rfc1939.html} (POP3) |
| * - {@link http://www.faqs.org/rfcs/rfc1734.html} (POP3 AUTH) |
| * |
| * The POP3 server can be in different states. Most POP3 commands require |
| * that a connection is established and a user is authenticated. |
| * |
| * The POP3 transport class allows developers to interface with a POP3 server. |
| * |
| * Basic commands: |
| * - connect to a POP3 server ({@link __construct()}) |
| * - authenticate a user with a username and password ({@link authenticate()}) |
| * - disconnect from the POP3 server ({@link disconnect()}) |
| * |
| * Work with message numbers: |
| * - get the message numbers and sizes of all the messages ({@link listMessages()}) |
| * - get the message numbers and IDs of all the messages ({@link listUniqueIdentifiers()}) |
| * - get the headers of a certain message ({@link top()}) |
| * - delete a message ({@link delete()}) |
| * |
| * Work with ezcMailPop3Set sets (parseable with ezcMailParser): |
| * - create a set from all messages ({@link fetchAll()}) |
| * - create a set from a certain message ({@link fetchByMessageNr()}) |
| * - create a set from a range of messages ({@link fetchFromOffset()}) |
| * |
| * Miscellaneous commands: |
| * - get the status of messages on the server ({@link status()}) |
| * - issue a NOOP command to keep the connection alive ({@link noop()}) |
| * |
| * The usual operation with a POP3 server is illustrated by this example: |
| * <code> |
| * // create a new POP3 transport object by specifying the server name, optional |
| * // port and optional SSL mode |
| * $options = new ezcMailPop3TransportOptions(); |
| * $options->ssl = true; |
| * |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com', null, $options ); |
| * |
| * // Authenticate to the POP3 server |
| * $pop3->authenticate( 'username', 'password' ); |
| * |
| * // issue commands to the POP3 server |
| * // for example get the headers of the first message, which can be |
| * // parsed with ezcMailVariableSet and ezcMailParser |
| * $headers = $pop3->top( 1 ); |
| * |
| * // see the above list of commands or consult the online documentation for |
| * // the full list of commands you can issue to an POP3 server and examples |
| * |
| * // disconnect from the POP3 server |
| * $pop3->disconnect(); |
| * </code> |
| * |
| * See {@link ezcMailPop3TransportOptions} for options you can specify for POP3. |
| * |
| * @todo ignore messages of a certain size? |
| * @todo // support for signing? |
| * |
| * @property ezcMailPop3TransportOptions $options |
| * Holds the options you can set to the POP3 transport. |
| * |
| * @package Mail |
| * @version //autogen// |
| * @mainclass |
| */ |
| class ezcMailPop3Transport |
| { |
| /** |
| * Internal state set when the POP3 transport is not connected to a server. |
| * |
| * @access private |
| */ |
| const STATE_NOT_CONNECTED = 1; |
| |
| /** |
| * Internal state set when the POP3 transport is connected to the server |
| * but no successful authentication has been performed. |
| * |
| * @access private |
| */ |
| const STATE_AUTHORIZATION = 2; |
| |
| /** |
| * Internal state set when the POP3 transport is connected to the server |
| * and authenticated. |
| * |
| * @access private |
| */ |
| const STATE_TRANSACTION = 3; |
| |
| /** |
| * Internal state set when the QUIT command has been issued to the POP3 server |
| * but before the disconnect has taken place. |
| * |
| * @access private |
| */ |
| const STATE_UPDATE = 4; |
| |
| /** |
| * Plain text authorization. |
| */ |
| const AUTH_PLAIN_TEXT = 1; |
| |
| /** |
| * APOP authorization. |
| */ |
| const AUTH_APOP = 2; |
| |
| /** |
| * Holds the connection state. |
| * |
| * $var int {@link STATE_NOT_CONNECTED}, |
| * {@link STATE_AUTHORIZATION}, |
| * {@link STATE_TRANSACTION} or |
| * {@link STATE_UPDATE}. |
| */ |
| protected $state = self::STATE_NOT_CONNECTED; |
| |
| /** |
| * The connection to the POP3 server. |
| * |
| * @var ezcMailTransportConnection |
| */ |
| protected $connection = null; |
| |
| /** |
| * Holds the initial greeting from the POP3 server when connecting. |
| * |
| * @var string |
| */ |
| protected $greeting = null; |
| |
| /** |
| * Options for a POP3 transport connection. |
| * |
| * @var ezcMailPop3TransportOptions |
| */ |
| private $options; |
| |
| /** |
| * Creates a new POP3 transport and connects to the $server at $port. |
| * |
| * You can specify the $port if the POP3 server is not on the default |
| * port 995 (for SSL connections) or 110 (for plain connections). Use the |
| * $options parameter to specify an SSL connection. |
| * |
| * For options you can specify for POP3 see {@link ezcMailPop3TransportOptions}. |
| * |
| * Example of creating a POP3 transport: |
| * <code> |
| * // replace with your POP3 server address |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com' ); |
| * |
| * // if you want to use SSL: |
| * $options = new ezcMailPop3TransportOptions(); |
| * $options->ssl = true; |
| * |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com', null, $options ); |
| * </code> |
| * |
| * @throws ezcMailTransportException |
| * if it was not possible to connect to the server |
| * @throws ezcBaseExtensionNotFoundException |
| * if trying to use SSL and the extension openssl is not installed |
| * @throws ezcBasePropertyNotFoundException |
| * if $options contains a property not defined |
| * @throws ezcBaseValueException |
| * if $options contains a property with a value not allowed |
| * @param string $server |
| * @param int $port |
| * @param ezcMailPop3TransportOptions|array(string=>mixed) $options |
| */ |
| public function __construct( $server, $port = null, $options = array() ) |
| { |
| if ( $options instanceof ezcMailPop3TransportOptions ) |
| { |
| $this->options = $options; |
| } |
| else if ( is_array( $options ) ) |
| { |
| $this->options = new ezcMailPop3TransportOptions( $options ); |
| } |
| else |
| { |
| throw new ezcBaseValueException( "options", $options, "ezcMailPop3TransportOptions|array" ); |
| } |
| |
| if ( $port === null ) |
| { |
| $port = ( $this->options->ssl === true ) ? 995 : 110; |
| } |
| $this->connection = new ezcMailTransportConnection( $server, $port, $this->options ); |
| $this->greeting = $this->connection->getLine(); |
| if ( !$this->isPositiveResponse( $this->greeting ) ) |
| { |
| throw new ezcMailTransportException( "The connection to the POP3 server is ok, but a negative response from server was received: '{$this->greeting}'. Try again later." ); |
| } |
| $this->state = self::STATE_AUTHORIZATION; |
| } |
| |
| /** |
| * Destructs the POP3 transport object. |
| * |
| * If there is an open connection to the POP3 server it is closed. |
| */ |
| public function __destruct() |
| { |
| if ( $this->state != self::STATE_NOT_CONNECTED ) |
| { |
| try |
| { |
| $this->connection->sendData( 'QUIT' ); |
| $this->connection->getLine(); // discard |
| $this->connection->close(); |
| } |
| catch ( ezcMailTransportException $e ) |
| { |
| // Ignore occuring transport exceptions. |
| } |
| } |
| } |
| |
| /** |
| * Sets the value of the property $name to $value. |
| * |
| * @throws ezcBasePropertyNotFoundException |
| * if the property $name does not exist |
| * @throws ezcBaseValueException |
| * if $value is not accepted for the property $name |
| * @param string $name |
| * @param mixed $value |
| * @ignore |
| */ |
| public function __set( $name, $value ) |
| { |
| switch ( $name ) |
| { |
| case 'options': |
| if ( !( $value instanceof ezcMailPop3TransportOptions ) ) |
| { |
| throw new ezcBaseValueException( 'options', $value, 'instanceof ezcMailPop3TransportOptions' ); |
| } |
| $this->options = $value; |
| break; |
| |
| default: |
| throw new ezcBasePropertyNotFoundException( $name ); |
| } |
| } |
| |
| /** |
| * Returns the value of the property $name. |
| * |
| * @throws ezcBasePropertyNotFoundException |
| * if the property $name does not exist |
| * @param string $name |
| * @return mixed |
| * @ignore |
| */ |
| public function __get( $name ) |
| { |
| switch ( $name ) |
| { |
| case 'options': |
| return $this->options; |
| |
| default: |
| throw new ezcBasePropertyNotFoundException( $name ); |
| } |
| } |
| |
| /** |
| * Returns true if the property $name is set, otherwise false. |
| * |
| * @param string $name |
| * @return bool |
| * @ignore |
| */ |
| public function __isset( $name ) |
| { |
| switch ( $name ) |
| { |
| case 'options': |
| return true; |
| |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * Disconnects the transport from the POP3 server. |
| */ |
| public function disconnect() |
| { |
| if ( $this->state != self::STATE_NOT_CONNECTED ) |
| { |
| $this->connection->sendData( 'QUIT' ); |
| $this->connection->getLine(); // discard |
| $this->state = self::STATE_UPDATE; |
| |
| $this->connection->close(); |
| $this->connection = null; |
| $this->state = self::STATE_NOT_CONNECTED; |
| } |
| } |
| |
| /** |
| * Authenticates the user to the POP3 server with $user and $password. |
| * |
| * You can choose the authentication method with the $method parameter. |
| * The default is to use plaintext username and password (specified in the |
| * ezcMailPop3TransportOptions class). |
| * |
| * This method should be called directly after the construction of this |
| * object. |
| * |
| * Example: |
| * <code> |
| * // replace with your POP3 server address |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com' ); |
| * |
| * // replace the values with your username and password for the POP3 server |
| * $pop3->authenticate( 'username', 'password' ); |
| * </code> |
| * |
| * @throws ezcMailTransportException |
| * if there is no connection to the server |
| * or if already authenticated |
| * or if the authentication method is not accepted by the server |
| * or if the provided username/password combination did not work |
| * @param string $user |
| * @param string $password |
| * @param int $method |
| */ |
| public function authenticate( $user, $password, $method = null ) |
| { |
| if ( $this->state != self::STATE_AUTHORIZATION ) |
| { |
| throw new ezcMailTransportException( "Tried to authenticate when there was no connection or when already authenticated." ); |
| } |
| |
| if ( is_null( $method ) ) |
| { |
| $method = $this->options->authenticationMethod; |
| } |
| |
| if ( $method == self::AUTH_PLAIN_TEXT ) // normal plain text login |
| { |
| // authenticate ourselves |
| $this->connection->sendData( "USER {$user}" ); |
| $response = $this->connection->getLine(); |
| if ( !$this->isPositiveResponse( $response ) ) |
| { |
| throw new ezcMailTransportException( "The POP3 server did not accept the username: {$response}." ); |
| } |
| $this->connection->sendData( "PASS {$password}" ); |
| $response = $this->connection->getLine(); |
| if ( !$this->isPositiveResponse( $response ) ) |
| { |
| throw new ezcMailTransportException( "The POP3 server did not accept the password: {$response}." ); |
| } |
| } |
| else if ( $method == self::AUTH_APOP ) // APOP login |
| { |
| // fetch the timestamp from the greeting |
| $timestamp = ''; |
| preg_match( '/.*(<.*>).*/', |
| $this->greeting, |
| $timestamp ); |
| // check if there was a greeting. If not, apop is not supported |
| if ( count( $timestamp ) < 2 ) |
| { |
| throw new ezcMailTransportException( "The POP3 server did not accept the APOP login: No greeting." ); |
| } |
| |
| $hash = md5( $timestamp[1] . $password ); |
| $this->connection->sendData( "APOP {$user} {$hash}" ); |
| $response = $this->connection->getLine(); |
| if ( !$this->isPositiveResponse( $response ) ) |
| { |
| throw new ezcMailTransportException( "The POP3 server did not accept the APOP login: {$response}." ); |
| } |
| } |
| else |
| { |
| throw new ezcMailTransportException( "Invalid authentication method provided." ); |
| } |
| $this->state = self::STATE_TRANSACTION; |
| } |
| |
| /** |
| * Returns an array of the message numbers on the server and the size of the |
| * messages in bytes. |
| * |
| * The format of the returned array is: |
| * <code> |
| * array( message_id => message_size ); |
| * </code> |
| * |
| * Example: |
| * <code> |
| * array( 2 => 1700, 5 => 1450, 6 => 21043 ); |
| * </code> |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @return array(int) |
| */ |
| public function listMessages() |
| { |
| if ( $this->state != self::STATE_TRANSACTION ) |
| { |
| throw new ezcMailTransportException( "Can't call listMessages() on the POP3 transport when not successfully logged in." ); |
| } |
| |
| // send the command |
| $this->connection->sendData( "LIST" ); |
| $response = $this->connection->getLine(); |
| if ( !$this->isPositiveResponse( $response ) ) |
| { |
| throw new ezcMailTransportException( "The POP3 server sent a negative response to the LIST command: {$response}." ); |
| } |
| |
| // fetch the data from the server and prepare it to be returned. |
| $messages = array(); |
| while ( ( $response = $this->connection->getLine( true ) ) !== "." ) |
| { |
| list( $num, $size ) = explode( ' ', $response ); |
| $messages[$num] = $size; |
| } |
| return $messages; |
| } |
| |
| /** |
| * Returns the unique identifiers for messages on the POP3 server. |
| * |
| * You can fetch the unique identifier for a specific message by providing |
| * the $msgNum parameter. |
| * |
| * The unique identifier can be used to recognize mail from servers |
| * between requests. In contrast to the message numbers the unique numbers |
| * assigned to an email usually never changes. |
| * |
| * Note: POP3 servers are not required to support this command and it may fail. |
| * |
| * The format of the returned array is: |
| * <code> |
| * array( message_num => unique_id ); |
| * </code> |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * Example: |
| * <code> |
| * array( 1 => '000001fc4420e93a', 2 => '000001fd4420e93a' ); |
| * </code> |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @param int $msgNum |
| * @return array(string) |
| */ |
| public function listUniqueIdentifiers( $msgNum = null ) |
| { |
| if ( $this->state != self::STATE_TRANSACTION ) |
| { |
| throw new ezcMailTransportException( "Can't call ListUniqueIdentifiers() on the POP3 transport when not successfully logged in." ); |
| } |
| |
| // send the command |
| $result = array(); |
| if ( $msgNum !== null ) |
| { |
| $this->connection->sendData( "UIDL {$msgNum}" ); |
| $response = $this->connection->getLine( true ); |
| if ( $this->isPositiveResponse( $response ) ) |
| { |
| // get the single response line from the server |
| list( $dummy, $num, $id ) = explode( ' ', $response ); |
| $result[(int)$num] = $id; |
| } |
| else |
| { |
| throw new ezcMailTransportException( "The POP3 server sent a negative response to the UIDL command: {$response}." ); |
| } |
| } |
| else |
| { |
| $this->connection->sendData( "UIDL" ); |
| $response = $this->connection->getLine(); |
| if ( $this->isPositiveResponse( $response ) ) |
| { |
| // fetch each of the result lines and add it to the result |
| while ( ( $response = $this->connection->getLine( true ) ) !== "." ) |
| { |
| list( $num, $id ) = explode( ' ', $response ); |
| $result[(int)$num] = $id; |
| } |
| } |
| else |
| { |
| throw new ezcMailTransportException( "The POP3 server sent a negative response to the UIDL command: {$response}." ); |
| } |
| } |
| return $result; |
| } |
| |
| /** |
| * Returns information about the messages on the server. |
| * |
| * The information returned through the parameters is: |
| * - $numMessages = number of messages |
| * - $sizeMessages = sum of the messages sizes |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * Example of returning the status of messages on the server: |
| * <code> |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com' ); |
| * $pop3->authenticate( 'username', 'password' ); |
| * |
| * $pop3->status( $numMessages, $sizeMessages ); |
| * </code> |
| * |
| * After running the above code, $numMessages and $sizeMessages will be |
| * populated with values. |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @param int &$numMessages |
| * @param int &$sizeMessages |
| */ |
| public function status( &$numMessages, &$sizeMessages ) |
| { |
| if ( $this->state != self::STATE_TRANSACTION ) |
| { |
| throw new ezcMailTransportException( "Can't call status() on the POP3 transport when not successfully logged in." ); |
| } |
| |
| $this->connection->sendData( "STAT" ); |
| $response = $this->connection->getLine(); |
| if ( $this->isPositiveResponse( $response ) ) |
| { |
| // get the single response line from the server |
| list( $dummy, $numMessages, $sizeMessages ) = explode( ' ', $response ); |
| $numMessages = (int)$numMessages; |
| $sizeMessages = (int)$sizeMessages; |
| } |
| else |
| { |
| throw new ezcMailTransportException( "The POP3 server did not respond with a status message: {$response}." ); |
| } |
| } |
| |
| /** |
| * Deletes the message with the message number $msgNum from the server. |
| * |
| * The message number must be a valid identifier fetched with (example) |
| * {@link listMessages()}. |
| * |
| * Any future reference to the message-number associated with the message |
| * in a command generates an error. |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @param int $msgNum |
| */ |
| public function delete( $msgNum ) |
| { |
| if ( $this->state != self::STATE_TRANSACTION ) |
| { |
| throw new ezcMailTransportException( "Can't call delete() on the POP3 transport when not successfully logged in." ); |
| } |
| |
| $this->connection->sendData( "DELE {$msgNum}" ); |
| $response = $this->connection->getLine(); |
| |
| if ( !$this->isPositiveResponse( $response ) ) |
| { |
| throw new ezcMailTransportException( "The POP3 server could not delete the message: {$response}." ); |
| } |
| } |
| |
| /** |
| * Returns the headers and the $numLines first lines of the body of the mail with |
| * the message number $msgNum. |
| * |
| * If the command failed or if it was not supported by the server an empty string is |
| * returned. |
| * |
| * Note: POP3 servers are not required to support this command and it may fail. |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * Example of listing the mail headers of all the messages from the server: |
| * <code> |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com' ); |
| * $pop3->authenticate( 'username', 'password' ); |
| * |
| * $parser = new ezcMailParser(); |
| * $messages = $pop3->listMessages(); |
| * foreach ( $messages as $messageNr => $size ) |
| * { |
| * $set = new ezcMailVariableSet( $pop3->top( $messageNr ) ); |
| * $mail = $parser->parseMail( $set ); |
| * $mail = $mail[0]; |
| * echo "From: {$mail->from}, Subject: {$mail->subject}, Size: {$size}\n"; |
| * } |
| * </code> |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @param int $msgNum |
| * @param int $numLines |
| * @return string |
| */ |
| public function top( $msgNum, $numLines = 0 ) |
| { |
| if ( $this->state != self::STATE_TRANSACTION ) |
| { |
| throw new ezcMailTransportException( "Can't call top() on the POP3 transport when not successfully logged in." ); |
| } |
| |
| // send the command |
| $this->connection->sendData( "TOP {$msgNum} {$numLines}" ); |
| $response = $this->connection->getLine(); |
| if ( !$this->isPositiveResponse( $response ) ) |
| { |
| throw new ezcMailTransportException( "The POP3 server sent a negative response to the TOP command: {$response}." ); |
| } |
| |
| // fetch the data from the server and prepare it to be returned. |
| $message = ""; |
| while ( ( $response = $this->connection->getLine( true ) ) !== "." ) |
| { |
| $message .= $response . "\n"; |
| } |
| return $message; |
| } |
| |
| /** |
| * Returns an ezcMailPop3Set with all the messages on the server. |
| * |
| * If $deleteFromServer is set to true the mail will be removed from the |
| * server after retrieval. If not it will be left. |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * Example: |
| * <code> |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com' ); |
| * $pop3->authenticate( 'username', 'password' ); |
| * |
| * $set = $pop3->fetchAll(); |
| * |
| * // parse $set with ezcMailParser |
| * $parser = new ezcMailParser(); |
| * $mails = $parser->parseMail( $set ); |
| * foreach ( $mails as $mail ) |
| * { |
| * // process $mail which is an ezcMail object |
| * } |
| * </code> |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @param bool $deleteFromServer |
| * @return ezcMailParserSet |
| */ |
| public function fetchAll( $deleteFromServer = false ) |
| { |
| $messages = $this->listMessages(); |
| return new ezcMailPop3Set( $this->connection, array_keys( $messages ), $deleteFromServer ); |
| } |
| |
| /** |
| * Returns an ezcMailPop3Set containing only the $number -th message from |
| * the server. |
| * |
| * If $deleteFromServer is set to true the mail will be removed from the |
| * server after retrieval. If not it will be left. |
| * |
| * Note: for POP3 the first message is 1 (so for $number = 0 the exception |
| * will be thrown). |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * Example: |
| * <code> |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com' ); |
| * $pop3->authenticate( 'username', 'password' ); |
| * |
| * $set = $pop3->fetchByMessageNr( 1 ); |
| * |
| * // $set can be parsed with ezcMailParser |
| * </code> |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @throws ezcMailNoSuchMessageException |
| * if the message $number is out of range |
| * @param int $number |
| * @param bool $deleteFromServer |
| * @return ezcMailPop3Set |
| */ |
| public function fetchByMessageNr( $number, $deleteFromServer = false ) |
| { |
| $messages = $this->listMessages(); |
| if ( !isset( $messages[$number] ) ) |
| { |
| throw new ezcMailNoSuchMessageException( $number ); |
| } |
| return new ezcMailPop3Set( $this->connection, array( $number ), $deleteFromServer ); |
| } |
| |
| /** |
| * Returns an ezcMailPop3Set with $count messages starting from $offset from |
| * the server. |
| * |
| * Fetches $count messages starting from the $offset and returns them as a |
| * ezcMailPop3Set. If $count is not specified or if it is 0, it fetches |
| * all messages starting from the $offset. |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * Example: |
| * <code> |
| * $pop3 = new ezcMailPop3Transport( 'pop3.example.com' ); |
| * $pop3->authenticate( 'username', 'password' ); |
| * |
| * $set = $pop3->fetchFromOffset( 1, 10 ); |
| * |
| * // $set can be parsed with ezcMailParser |
| * </code> |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| * @throws ezcMailInvalidLimitException |
| * if $count is negative |
| * @throws ezcMailOffsetOutOfRangeException |
| * if $offset is outside of the existing range of messages |
| * @param int $offset |
| * @param int $count |
| * @param bool $deleteFromServer |
| * @return ezcMailPop3Set |
| */ |
| public function fetchFromOffset( $offset, $count = 0, $deleteFromServer = false ) |
| { |
| if ( $count < 0 ) |
| { |
| throw new ezcMailInvalidLimitException( $offset, $count ); |
| } |
| $messages = array_keys( $this->listMessages() ); |
| if ( $count == 0 ) |
| { |
| $range = array_slice( $messages, $offset - 1, count( $messages ), true ); |
| } |
| else |
| { |
| $range = array_slice( $messages, $offset - 1, $count, true ); |
| } |
| if ( !isset( $range[$offset - 1] ) ) |
| { |
| throw new ezcMailOffsetOutOfRangeException( $offset, $count ); |
| } |
| return new ezcMailPop3Set( $this->connection, $range, $deleteFromServer ); |
| } |
| |
| /** |
| * Sends a NOOP command to the server, use it to keep the connection alive. |
| * |
| * Before calling this method, a connection to the POP3 server must be |
| * established and a user must be authenticated successfully. |
| * |
| * @throws ezcMailTransportException |
| * if there was no connection to the server |
| * or if not authenticated |
| * or if the server sent a negative response |
| */ |
| public function noop() |
| { |
| if ( $this->state != self::STATE_TRANSACTION ) |
| { |
| throw new ezcMailTransportException( "Can't call noop() on the POP3 transport when not successfully logged in." ); |
| } |
| |
| // send the command |
| $this->connection->sendData( "NOOP" ); |
| $response = $this->connection->getLine(); |
| if ( !$this->isPositiveResponse( $response ) ) |
| { |
| throw new ezcMailTransportException( "The POP3 server sent a negative response to the NOOP command: {$response}." ); |
| } |
| } |
| |
| /** |
| * Returns true if the response from the server is a positive one. |
| * |
| * @param string $line |
| * @return bool |
| */ |
| protected function isPositiveResponse( $line ) |
| { |
| if ( strpos( $line, "+OK" ) === 0 ) |
| { |
| return true; |
| } |
| return false; |
| } |
| } |
| ?> |