1<?php
2/**
3 * Copyright 2012-2017 Horde LLC (http://www.horde.org/)
4 *
5 * See the enclosed file LICENSE 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 command (RFC 3501 [2.2.1]).
16 *
17 * @author    Michael Slusarz <slusarz@horde.org>
18 * @category  Horde
19 * @copyright 2012-2017 Horde LLC
20 * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
21 * @package   Imap_Client
22 * @since     2.10.0
23 *
24 * @property-read boolean $continuation  True if the command requires a server
25 *                                       continuation response.
26 */
27class Horde_Imap_Client_Interaction_Command
28extends Horde_Imap_Client_Data_Format_List
29{
30    /**
31     * Debug string(s) to use instead of command text.
32     *
33     * Multiple entries refer to the various steps in a continuation command.
34     *
35     * @var array
36     */
37    public $debug = array();
38
39    /**
40     * Use LITERAL+ if available
41     *
42     * @var boolean
43     */
44    public $literalplus = true;
45
46    /**
47     * Are literal8's available?
48     *
49     * @var boolean
50     */
51    public $literal8 = false;
52
53    /**
54     * A callback to run on error.
55     *
56     * If callback returns true, the command will be treated as successful.
57     *
58     * @since 2.24.0
59     *
60     * @var callback
61     */
62    public $on_error = null;
63
64    /**
65     * A callback to run on success.
66     *
67     * @since 2.28.0
68     *
69     * @var callback
70     */
71    public $on_success = null;
72
73    /**
74     * Pipeline object associated with this command.
75     *
76     * @since 2.28.0
77     *
78     * @var Horde_Imap_Client_Interaction_Pipeline
79     */
80    public $pipeline;
81
82    /**
83     * Server response.
84     *
85     * @var Horde_Imap_Client_Interaction_Server
86     */
87    public $response;
88
89    /**
90     * The command tag.
91     *
92     * @var string
93     */
94    public $tag;
95
96    /**
97     * Command timer.
98     *
99     * @var Horde_Support_Timer
100     */
101    protected $_timer;
102
103    /**
104     * Constructor.
105     *
106     * @param string $cmd  The IMAP command.
107     * @param string $tag  The tag to use. If not set, will be automatically
108     *                     generated.
109     */
110    public function __construct($cmd, $tag = null)
111    {
112        $this->tag = is_null($tag)
113            ? substr(new Horde_Support_Randomid(), 0, 10)
114            : strval($tag);
115
116        parent::__construct($this->tag);
117
118        $this->add($cmd);
119    }
120
121    /**
122     */
123    public function __get($name)
124    {
125        switch ($name) {
126        case 'continuation':
127            return $this->_continuationCheck($this);
128        }
129    }
130
131    /**
132     * Get the command.
133     *
134     * @return string  The command.
135     */
136    public function getCommand()
137    {
138        return $this->_data[1];
139    }
140
141    /**
142     * Start the command timer.
143     */
144    public function startTimer()
145    {
146        $this->_timer = new Horde_Support_Timer();
147        $this->_timer->push();
148    }
149
150    /**
151     * Return the timer data.
152     *
153     * @return mixed  Null if timer wasn't started, or a float containing
154     *                elapsed command time.
155     */
156    public function getTimer()
157    {
158        return $this->_timer
159            ? round($this->_timer->pop(), 4)
160            : null;
161    }
162
163    /**
164     * Recursive check for continuation functions.
165     */
166    protected function _continuationCheck($list)
167    {
168        foreach ($list as $val) {
169            if (($val instanceof Horde_Imap_Client_Interaction_Command_Continuation) ||
170                (($val instanceof Horde_Imap_Client_Data_Format_String) &&
171                 $val->literal())) {
172                return true;
173            }
174
175            if (($val instanceof Horde_Imap_Client_Data_Format_List) &&
176                $this->_continuationCheck($val)) {
177                return true;
178            }
179        }
180
181        return false;
182    }
183
184}
185