BotsManager::getBotConfig()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 6
cp 0
rs 9.8333
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 20
1
<?php
2
3
namespace Telegram\Bot;
4
5
use Illuminate\Contracts\Container\Container;
6
use InvalidArgumentException;
7
use Illuminate\Support\Arr;
8
9
/**
10
 * Class BotsManager
11
 *
12
 * @TODO Add methods in docblock for autocompletion from Api file.
13
 */
14
class BotsManager
15
{
16
    /**
17
     * The config instance.
18
     *
19
     * @var array
20
     */
21
    protected $config;
22
23
    /**
24
     * The container instance.
25
     *
26
     * @var \Illuminate\Contracts\Container\Container
27
     */
28
    protected $container;
29
30
    /**
31
     * The active bot instances.
32
     *
33
     * @var Api[]
34
     */
35
    protected $bots = [];
36
37
    /**
38
     * TelegramManager constructor.
39
     *
40
     * @param array $config
41
     */
42
    public function __construct(array $config)
43
    {
44
        $this->config = $config;
45
    }
46
47
    /**
48
     * Set the IoC Container.
49
     *
50
     * @param $container Container instance
51
     *
52
     * @return $this
53
     */
54
    public function setContainer(Container $container)
55
    {
56
        $this->container = $container;
57
58
        return $this;
59
    }
60
61
    /**
62
     * Get the configuration for a bot.
63
     *
64
     * @param string|null $name
65
     *
66
     * @throws \InvalidArgumentException
67
     *
68
     * @return array
69
     */
70
    public function getBotConfig($name = null)
71
    {
72
        $name = $name ?: $this->getDefaultBot();
73
74
        $bots = $this->getConfig('bots');
75
        if (!is_array($config = Arr::get($bots, $name)) && !$config) {
76
            throw new InvalidArgumentException("Bot [$name] not configured.");
77
        }
78
79
        $config['bot'] = $name;
80
81
        return $config;
82
    }
83
84
    /**
85
     * Get a bot instance.
86
     *
87
     * @param string $name
88
     *
89
     * @return Api
90
     */
91
    public function bot($name = null)
92
    {
93
        $name = $name ?: $this->getDefaultBot();
94
95
        if (!isset($this->bots[$name])) {
96
            $this->bots[$name] = $this->makeBot($name);
97
        }
98
99
        return $this->bots[$name];
100
    }
101
102
    /**
103
     * Reconnect to the given bot.
104
     *
105
     * @param string $name
106
     *
107
     * @return Api
108
     */
109
    public function reconnect($name = null)
110
    {
111
        $name = $name ?: $this->getDefaultBot();
112
        $this->disconnect($name);
113
114
        return $this->bot($name);
115
    }
116
117
    /**
118
     * Disconnect from the given bot.
119
     *
120
     * @param string $name
121
     *
122
     * @return void
123
     */
124
    public function disconnect($name = null)
125
    {
126
        $name = $name ?: $this->getDefaultBot();
127
        unset($this->bots[$name]);
128
    }
129
130
    /**
131
     * Get the specified configuration value for Telegram.
132
     *
133
     * @param  string $key
134
     * @param  mixed  $default
135
     *
136
     * @return mixed
137
     */
138
    public function getConfig($key, $default = null)
139
    {
140
        return Arr::get($this->config, $key, $default);
141
    }
142
143
    /**
144
     * Get the default bot name.
145
     *
146
     * @return string
147
     */
148
    public function getDefaultBot()
149
    {
150
        return $this->getConfig('default');
151
    }
152
153
    /**
154
     * Set the default bot name.
155
     *
156
     * @param string $name
157
     *
158
     * @return $this
159
     */
160
    public function setDefaultBot($name)
161
    {
162
        Arr::set($this->config, 'default', $name);
163
164
        return $this;
165
    }
166
167
    /**
168
     * Return all of the created bots.
169
     *
170
     * @return Api[]
171
     */
172
    public function getBots()
173
    {
174
        return $this->bots;
175
    }
176
177
    /**
178
     * De-duplicate an array.
179
     *
180
     * @param array $array
181
     *
182
     * @return array
183
     */
184
    protected function deduplicateArray(array $array)
185
    {
186
        return array_values(array_unique($array));
187
    }
188
189
    /**
190
     * Make the bot instance.
191
     *
192
     * @param string $name
193
     *
194
     * @return Api
195
     */
196
    protected function makeBot($name)
197
    {
198
        $config = $this->getBotConfig($name);
199
200
        $token = Arr::get($config, 'token');
201
        $commands = Arr::get($config, 'commands', []);
202
203
        $telegram = new Api(
204
            $token,
205
            $this->getConfig('async_requests', false),
206
            $this->getConfig('http_client_handler', null)
207
        );
208
209
        // Check if DI needs to be enabled for Commands
210
        if ($this->getConfig('resolve_command_dependencies', false) && isset($this->container)) {
211
            $telegram->setContainer($this->container);
212
        }
213
214
        $commands = $this->parseBotCommands($commands);
215
216
        // Register Commands
217
        $telegram->addCommands($commands);
0 ignored issues
show
Documentation Bug introduced by
The method addCommands does not exist on object<Telegram\Bot\Api>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
218
219
        return $telegram;
220
    }
221
222
    /**
223
     * Builds the list of commands for the given commands array.
224
     *
225
     * @param array $commands
226
     *
227
     * @return array An array of commands which includes global and bot specific commands.
228
     */
229
    protected function parseBotCommands(array $commands)
230
    {
231
        $globalCommands = $this->getConfig('commands', []);
232
        $parsedCommands = $this->parseCommands($commands);
233
234
        return $this->deduplicateArray(array_merge($globalCommands, $parsedCommands));
235
    }
236
237
    /**
238
     * Parse an array of commands and build a list.
239
     *
240
     * @param array $commands
241
     *
242
     * @return array
243
     */
244
    protected function parseCommands(array $commands)
245
    {
246
        if (!is_array($commands)) {
247
            return $commands;
248
        }
249
250
        $commandGroups = $this->getConfig('command_groups');
251
        $sharedCommands = $this->getConfig('shared_commands');
252
253
        $results = [];
254
        foreach ($commands as $command) {
255
            // If the command is a group, we'll parse through the group of commands
256
            // and resolve the full class name.
257
            if (isset($commandGroups[$command])) {
258
                $results = array_merge(
259
                    $results, $this->parseCommands($commandGroups[$command])
260
                );
261
262
                continue;
263
264
            }
265
266
            // If this command is actually a shared command, we'll extract the full
267
            // class name out of the command list now.
268
            if (isset($sharedCommands[$command])) {
269
                $command = $sharedCommands[$command];
270
            }
271
272
            if (!in_array($command, $results)) {
273
                $results[] = $command;
274
            }
275
        }
276
277
        return $results;
278
    }
279
280
    /**
281
     * Magically pass methods to the default bot.
282
     *
283
     * @param string $method
284
     * @param array  $parameters
285
     *
286
     * @return mixed
287
     */
288
    public function __call($method, $parameters)
289
    {
290
        return call_user_func_array([$this->bot(), $method], $parameters);
291
    }
292
}
293