Example #1
0
 /**
  * Sends the command to the server and reads the response to it. 
  * 
  * @param string|NULL|array $command The command to send (can use printf 
  *                                   style). If NULL, no command is sent 
  *                                   and this just reads a server response.
  *                                   If it is an array, all items will be 
  *                                   treated like lines of commands and
  *                                   will be sent to the server while the
  *                                   response will be read only after all
  *                                   of them are sent.
  * @param mixed $args,... Optional printf-like arguments
  *
  * @return Response The server response
  *
  * @throws InvalidStateException If the communicator is not connected
  * @throws InvalidArgumentException If printf-like arguments are used for
  *                                  non-textual command (ie. array command)
  * @throws IOException If writing or reading over network failed
  */
 public function getResponse($command)
 {
     if ($this->connection === NULL) {
         throw new InvalidStateException('Cannot communicate with SMTP ' . 'server when not connected.');
     }
     if ($command !== NULL) {
         if (func_num_args() > 1) {
             if (!is_string($command)) {
                 throw new InvalidArgumentException('Cannot use printf-like arguments to a command which' . ' is not a string!');
             }
             $args = func_get_args();
             array_shift($args);
             $command = vsprintf($command, $args);
         }
         if (!is_array($command)) {
             $command = array($command);
         }
         foreach ($command as $line) {
             //send the command to the server
             SMTPClient::debug("\n\nCOMMAND: %s\n=======", $line);
             if (@fwrite($this->connection, $line . self::EOL) === FALSE) {
                 if (@fwrite($this->connection, $line . self::EOL) === FALSE) {
                     throw new IOException('Could not send the command to the ' . 'server: ' . $command);
                 }
             }
         }
     }
     /*
      * The reply text may be longer than a single line; in these cases the
      * complete text must be marked so the SMTP client knows when it can
      * stop reading the reply.  This requires a special format to indicate a
      * multiple line reply.
      *
      * The format for multiline replies requires that every line, except the
      * last, begin with the reply code, followed immediately by a hyphen,
      * "-" (also known as minus), followed by text.  The last line will
      * begin with the reply code, followed immediately by <SP>, optionally
      * some text, and <CRLF>.  As noted above, servers SHOULD send the <SP>
      * if subsequent text is not sent, but clients MUST be prepared for it
      * to be omitted.
      *
      * For example:
      *
      *    123-First line
      *    123-Second line
      *    123-234 text beginning with numbers
      *    123 The last line
      *
      * In many cases the SMTP client then simply needs to search for a line
      * beginning with the reply code followed by <SP> or <CRLF> and ignore
      * all preceding lines.  In a few cases, there is important data for the
      * client in the reply "text".  The client will be able to identify
      * these cases from the current context.
      */
     $response['code'] = '';
     $response['text'] = array();
     $responsePart = '';
     $i = 0;
     //we fetch lines of the response
     while ($line = fgets($this->connection, self::MAX_RESPONSE_LENGTH)) {
         //fgets leaves the CRLF at the end of the string
         $line = rtrim($line);
         //blank line shouldn't appear, it indicates nothing more is to
         //be read
         if (strlen($line) < 3) {
             break;
         }
         //if we loop a lot of times, something went wrong, so
         //give up the reading
         if ($i > self::MAX_RESPONSE_LINES) {
             throw new InvalidStateException('There was a problem reading server response. The client' . 'could not detect its end.');
         }
         SMTPClient::debug('RESPONSE LINE #%u: %s', ++$i, $line);
         //first 3 charachters denote the response code
         $response['code'] = substr($line, 0, 3);
         //and everything after the 4th character is the response text
         //note that the response text can be empty, in that case the
         //response text will be false ( @see substr() )
         $response['text'][] = substr($line, 4);
         //If we encountered a response, where space follows response code,
         //it is the last line. Other lines have a hyphen (-) instead
         if (substr($line, 3, 1) == ' ') {
             break;
         }
     }
     $this->lastResponse = new Response((int) $response['code'], $response['text']);
     return $this->lastResponse;
 }