Completed
Push — master ( 4b2edc...52afdb )
by Armando
03:26 queued 01:23
created

Conversation::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.2098

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 5
cts 7
cp 0.7143
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 2
nop 3
crap 3.2098
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
25
     */
26
    protected $conversation = null;
27
28
    /**
29
     * Notes stored inside the conversation
30
     *
31
     * @var array
32
     */
33
    protected $protected_notes = null;
34
35
    /**
36
     * Notes to be stored
37
     *
38
     * @var array
39
     */
40
    public $notes = null;
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 9
    public function __construct($user_id, $chat_id, $command = null)
71
    {
72 9
        $this->user_id = $user_id;
73 9
        $this->chat_id = $chat_id;
74 9
        $this->command = $command;
75
76
        //Try to load an existing conversation if possible
77 9
        if (!$this->load() && $command !== null) {
78
            //A new conversation start
79
            $this->start();
80
        }
81
    }
82
83
    /**
84
     * Clear all conversation variables.
85
     *
86
     * @return bool Always return true, to allow this method in an if statement.
87
     */
88
    protected function clear()
89
    {
90
        $this->conversation    = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $conversation.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
91
        $this->protected_notes = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $protected_notes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
92
        $this->notes           = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $notes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
93
94
        return true;
95
    }
96
97
    /**
98
     * Load the conversation from the database
99
     *
100
     * @return bool
101
     */
102 9
    protected function load()
103
    {
104
105
        //Select an active conversation
106 9
        $conversation = ConversationDB::selectConversation($this->user_id, $this->chat_id, 1);
0 ignored issues
show
Documentation introduced by
1 is of type integer, but the function expects a boolean|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
107
        if (isset($conversation[0])) {
108
            //Pick only the first element
109
            $this->conversation = $conversation[0];
110
111
            //Load the command from the conversation if it hasn't been passed
112
            $this->command = $this->command ?: $this->conversation['command'];
113
114
            if ($this->command !== $this->conversation['command']) {
115
                $this->cancel();
116
                return false;
117
            }
118
119
            //Load the conversation notes
120
            $this->protected_notes = json_decode($this->conversation['notes'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like json_decode($this->conversation['notes'], true) of type * is incompatible with the declared type array of property $protected_notes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
121
            $this->notes           = $this->protected_notes;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->protected_notes of type * is incompatible with the declared type array of property $notes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
122
        }
123
124
        return $this->exists();
125
    }
126
127
    /**
128
     * Check if the conversation already exists
129
     *
130
     * @return bool
131
     */
132
    public function exists()
133
    {
134
        return ($this->conversation !== null);
135
    }
136
137
    /**
138
     * Start a new conversation if the current command doesn't have one yet
139
     *
140
     * @return bool
141
     */
142
    protected function start()
143
    {
144
        if (!$this->exists() && $this->command) {
145
            if (ConversationDB::insertConversation(
146
                $this->user_id,
147
                $this->chat_id,
148
                $this->command
149
            )
150
            ) {
151
                return $this->load();
152
            }
153
        }
154
155
        return false;
156
    }
157
158
    /**
159
     * Delete the current conversation
160
     *
161
     * Currently the Conversation is not deleted but just set to 'stopped'
162
     *
163
     * @return bool
164
     */
165
    public function stop()
166
    {
167
        return ($this->updateStatus('stopped') && $this->clear());
168
    }
169
170
    /**
171
     * Cancel the current conversation
172
     *
173
     * @return bool
174
     */
175
    public function cancel()
176
    {
177
        return ($this->updateStatus('cancelled') && $this->clear());
178
    }
179
180
    /**
181
     * Update the status of the current conversation
182
     *
183
     * @param string $status
184
     *
185
     * @return bool
186
     */
187
    protected function updateStatus($status)
188
    {
189
        if ($this->exists()) {
190
            $fields = ['status' => $status];
191
            $where  = [
192
                'id'      => $this->conversation['id'],
193
                'status'  => 'active',
194
                'user_id' => $this->user_id,
195
                'chat_id' => $this->chat_id,
196
            ];
197
            if (ConversationDB::updateConversation($fields, $where)) {
198
                return true;
199
            }
200
        }
201
202
        return false;
203
    }
204
205
    /**
206
     * Store the array/variable in the database with json_encode() function
207
     *
208
     * @return bool
209
     */
210
    public function update()
211
    {
212
        if ($this->exists()) {
213
            $fields = ['notes' => json_encode($this->notes)];
214
            //I can update a conversation whatever the state is
215
            $where = ['id' => $this->conversation['id']];
216
            if (ConversationDB::updateConversation($fields, $where)) {
217
                return true;
218
            }
219
        }
220
221
        return false;
222
    }
223
224
    /**
225
     * Retrieve the command to execute from the conversation
226
     *
227
     * @return string|null
228
     */
229
    public function getCommand()
230
    {
231
        return $this->command;
232
    }
233
}
234