Completed
Pull Request — master (#644)
by Iman
04:56
created

Conversation::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.4285
cc 3
eloc 6
nc 2
nop 3
crap 3
1
<?php
2
/**
3
 * This file is part of the TelegramBot package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Longman\TelegramBot;
12
13
/**
14
 * Class Conversation
15
 *
16
 * Only one conversation can be active at any one time.
17
 * A conversation is directly linked to a user, chat and the command that is managing the conversation.
18
 */
19
class Conversation
20
{
21
    /**
22
     * All information fetched from the database
23
     *
24
     * @var array|null
25
     */
26
    protected $conversation;
27
28
    /**
29
     * Notes stored inside the conversation
30
     *
31
     * @var mixed
32
     */
33
    protected $protected_notes;
34
35
    /**
36
     * Notes to be stored
37
     *
38
     * @var mixed
39
     */
40
    public $notes;
41
42
    /**
43
     * Telegram user id
44
     *
45
     * @var int
46
     */
47
    protected $user_id;
48
49
    /**
50
     * Telegram chat id
51
     *
52
     * @var int
53
     */
54
    protected $chat_id;
55
56
    /**
57
     * Command to be executed if the conversation is active
58
     *
59
     * @var string
60
     */
61
    protected $command;
62
63
    /**
64
     * Conversation contructor to initialize a new conversation
65
     *
66
     * @param int    $user_id
67
     * @param int    $chat_id
68
     * @param string $command
69
     *
70
     * @throws \Longman\TelegramBot\Exception\TelegramException
71
     */
72 9
    public function __construct($user_id, $chat_id, $command = null)
73
    {
74 9
        $this->user_id = $user_id;
75 9
        $this->chat_id = $chat_id;
76 9
        $this->command = $command;
77
78
        //Try to load an existing conversation if possible
79 9
        if (!$this->load() && $command !== null) {
80
            //A new conversation start
81 6
            $this->start();
82
        }
83 8
    }
84
85
    /**
86
     * Clear all conversation variables.
87
     *
88
     * @return bool Always return true, to allow this method in an if statement.
89
     */
90 2
    protected function clear()
91
    {
92 2
        $this->conversation    = null;
93 2
        $this->protected_notes = null;
94 2
        $this->notes           = null;
95
96 2
        return true;
97
    }
98
99
    /**
100
     * Load the conversation from the database
101
     *
102
     * @return bool
103
     * @throws \Longman\TelegramBot\Exception\TelegramException
104
     */
105 9
    protected function load()
106
    {
107
        //Select an active conversation
108 9
        $conversation = ConversationDB::selectConversation($this->user_id, $this->chat_id, 1);
109 9
        if (!isset($conversation[0])) {
110 9
            return $this->exists();
111
        }
112
        //Pick only the first element
113 5
        $this->conversation = $conversation[0];
114
115
        //Load the command from the conversation if it hasn't been passed
116 5
        $this->command = $this->command ?: $this->conversation['command'];
117
118 5
        if ($this->command !== $this->conversation['command']) {
119
            $this->cancel();
120
            return false;
121
        }
122
123
        //Load the conversation notes
124 5
        $this->protected_notes = json_decode($this->conversation['notes'], true);
125 5
        $this->notes           = $this->protected_notes;
126
127 5
        return $this->exists();
128
    }
129
130
    /**
131
     * Check if the conversation already exists
132
     *
133
     * @return bool
134
     */
135 9
    public function exists()
136
    {
137 9
        return ($this->conversation !== null);
138
    }
139
140
    /**
141
     * Start a new conversation if the current command doesn't have one yet
142
     *
143
     * @return bool
144
     * @throws \Longman\TelegramBot\Exception\TelegramException
145
     */
146 6
    protected function start()
147
    {
148 6
        if ($this->command
149 6
            && !$this->exists()
150 6
            && ConversationDB::insertConversation(
151 6
                $this->user_id,
152 6
                $this->chat_id,
153 6
                $this->command
154
            )
155
        ) {
156 5
            return $this->load();
157
        }
158
159
        return false;
160
    }
161
162
    /**
163
     * Delete the current conversation
164
     *
165
     * Currently the Conversation is not deleted but just set to 'stopped'
166
     *
167
     * @return bool
168
     */
169 1
    public function stop()
170
    {
171 1
        return ($this->updateStatus('stopped') && $this->clear());
172
    }
173
174
    /**
175
     * Cancel the current conversation
176
     *
177
     * @return bool
178
     */
179 1
    public function cancel()
180
    {
181 1
        return ($this->updateStatus('cancelled') && $this->clear());
182
    }
183
184
    /**
185
     * Update the status of the current conversation
186
     *
187
     * @param string $status
188
     *
189
     * @return bool
190
     */
191 2
    protected function updateStatus($status)
192
    {
193 2
        if (!$this->exists()) {
194
            return false;
195
        }
196 2
        $fields = ['status' => $status];
197
        $where  = [
198 2
            'id'      => $this->conversation['id'],
199 2
            'status'  => 'active',
200 2
            'user_id' => $this->user_id,
201 2
            'chat_id' => $this->chat_id,
202
        ];
203 2
        if (ConversationDB::updateConversation($fields, $where)) {
204 2
            return true;
205
        }
206
207
        return false;
208
    }
209
210
    /**
211
     * Store the array/variable in the database with json_encode() function
212
     *
213
     * @return bool
214
     */
215 1
    public function update()
216
    {
217 1
        if (!$this->exists()) {
218
            return false;
219
        }
220 1
        $fields = ['notes' => json_encode($this->notes)];
221
        //I can update a conversation whatever the state is
222 1
        $where = ['id' => $this->conversation['id']];
223 1
        if (ConversationDB::updateConversation($fields, $where)) {
224 1
            return true;
225
        }
226
227
        return false;
228
    }
229
230
    /**
231
     * Retrieve the command to execute from the conversation
232
     *
233
     * @return string|null
234
     */
235 3
    public function getCommand()
236
    {
237 3
        return $this->command;
238
    }
239
}
240