1<?php
2/**
3 * Copyright 2012-2017 Horde LLC (http://www.horde.org/)
4 *
5 * See the enclosed file COPYING for license information (LGPL). If you
6 * did not receive this file, see http://www.horde.org/licenses/lgpl21.
7 *
8 * @category  Horde
9 * @copyright 2012-2017 Horde LLC
10 * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
11 * @package   Imap_Client
12 */
13
14/**
15 * An object representing an IMAP server command interaction (RFC 3501
16 * [2.2.2]).
17 *
18 * @author    Michael Slusarz <slusarz@horde.org>
19 * @category  Horde
20 * @copyright 2012-2017 Horde LLC
21 * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
22 * @package   Imap_Client
23 */
24class Horde_Imap_Client_Interaction_Server
25{
26    /**
27     * Response codes (RFC 3501 [7.1]).
28     */
29    const BAD = 1;
30    const BYE = 2;
31    const NO = 3;
32    const OK = 4;
33    const PREAUTH = 5;
34
35    /**
36     * Check for status response?
37     *
38     * @var boolean
39     */
40    protected $_checkStatus = true;
41
42    /**
43     * Response code (RFC 3501 [7.1]). Properties:
44     *   - code: (string) Response code.
45     *   - data: (array) Data associated with response.
46     *
47     * @var object
48     */
49    public $responseCode = null;
50
51    /**
52     * Status response from the server.
53     *
54     * @var string
55     */
56    public $status = null;
57
58    /**
59     * IMAP server data.
60     *
61     * @var Horde_Imap_Client_Tokenize
62     */
63    public $token;
64
65    /**
66     * Auto-scan an incoming line to determine the response type.
67     *
68     * @param Horde_Imap_Client_Tokenize $t  Tokenized data returned from the
69     *                                       server.
70     *
71     * @return Horde_Imap_Client_Interaction_Server  A server response object.
72     */
73    public static function create(Horde_Imap_Client_Tokenize $t)
74    {
75        $t->rewind();
76        $tag = $t->next();
77        $t->next();
78
79        switch ($tag) {
80        case '+':
81            return new Horde_Imap_Client_Interaction_Server_Continuation($t);
82
83        case '*':
84            return new Horde_Imap_Client_Interaction_Server_Untagged($t);
85
86        default:
87            return new Horde_Imap_Client_Interaction_Server_Tagged($t, $tag);
88        }
89    }
90
91    /**
92     * Constructor.
93     *
94     * @param Horde_Imap_Client_Tokenize $token  Tokenized data returned from
95     *                                           the server.
96     */
97    public function __construct(Horde_Imap_Client_Tokenize $token)
98    {
99        $this->token = $token;
100
101        /* Check for response status. */
102        $status = $token->current();
103        $valid = array('BAD', 'BYE', 'NO', 'OK', 'PREAUTH');
104
105        if (in_array($status, $valid)) {
106            $this->status = constant(__CLASS__ . '::' . $status);
107            $resp_text = $token->next();
108
109            /* Check for response code. Only occurs if there is a response
110             * status. */
111            if (is_string($resp_text) && ($resp_text[0] === '[')) {
112                $resp = new stdClass;
113                $resp->data = array();
114
115                if ($resp_text[strlen($resp_text) - 1] === ']') {
116                    $resp->code = substr($resp_text, 1, -1);
117                } else {
118                    $resp->code = substr($resp_text, 1);
119
120                    while (($elt = $token->next()) !== false) {
121                        if (is_string($elt) && $elt[strlen($elt) - 1] === ']') {
122                            $resp->data[] = substr($elt, 0, -1);
123                            break;
124                        }
125                        $resp->data[] = is_string($elt)
126                            ? $elt
127                            : $token->flushIterator();
128                    }
129                }
130
131                $token->next();
132                $this->responseCode = $resp;
133            }
134        }
135    }
136
137    /**
138     */
139    public function __toString()
140    {
141        return strval($this->token);
142    }
143
144}
145