protected function _getLine(Horde_Imap_Client_Interaction_Pipeline $pipeline)
{
$server = Horde_Imap_Client_Interaction_Server::create($this->_connection->read());
switch (get_class($server)) {
case 'Horde_Imap_Client_Interaction_Server_Continuation':
$this->_responseCode($pipeline, $server);
break;
case 'Horde_Imap_Client_Interaction_Server_Tagged':
$cmd = $pipeline->complete($server);
if (is_null($cmd)) {
/* This indicates a "dangling" tagged response - it was either
* generated by an aborted previous pipeline object or is the
* result of spurious output by the server. Ignore. */
return $this->_getLine($pipeline);
}
if ($timer = $cmd->getTimer()) {
$this->_debug->info(sprintf('Command %s took %s seconds.', $cmd->tag, $timer));
}
$this->_responseCode($pipeline, $server);
if (is_callable($cmd->on_success)) {
call_user_func($cmd->on_success);
}
break;
case 'Horde_Imap_Client_Interaction_Server_Untagged':
if (is_null($server->status)) {
$this->_serverResponse($pipeline, $server);
} else {
$this->_responseCode($pipeline, $server);
}
break;
}
switch ($server->status) {
case $server::BAD:
case $server::NO:
/* A tagged BAD response indicates that the tagged command caused
* the error. This information is unknown if untagged (RFC 3501
* [7.1.3]) - ignore these untagged responses.
* An untagged NO response indicates a warning; ignore and assume
* that it also included response text code that is handled
* elsewhere. Throw exception if tagged; command handlers can
* catch this if able to workaround this issue (RFC 3501
* [7.1.2]). */
if ($server instanceof Horde_Imap_Client_Interaction_Server_Tagged) {
/* Check for a on_error callback. If function returns true,
* ignore the error. */
if (($cmd = $pipeline->getCmd($server->tag)) && is_callable($cmd->on_error) && call_user_func($cmd->on_error)) {
break;
}
throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::r("IMAP error reported by server."), 0, $server, $pipeline);
}
break;
case $server::BYE:
/* A BYE response received as part of a logout command should be
* be treated like a regular command: a client MUST process the
* entire command until logging out (RFC 3501 [3.4; 7.1.5]). */
if (empty($this->_temp['logout'])) {
$e = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("IMAP Server closed the connection."), Horde_Imap_Client_Exception::DISCONNECT);
$e->details = strval($server);
throw $e;
}
break;
case $server::PREAUTH:
/* The user was pre-authenticated. (RFC 3501 [7.1.4]) */
$this->_temp['preauth'] = true;
break;
}
return $server;
}