Passed
Pull Request — master (#56)
by Marco
02:22
created

Params::validateAndSetScriptParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the TelegramBotManager package.
4
 *
5
 * (c) Armando Lüscher <[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 PhpTelegramBot\PhpTelegramBotManager;
12
13
use PhpTelegramBot\PhpTelegramBotManager\Exception\InvalidParamsException;
14
15
class Params
16
{
17
    /**
18
     * @var array List of valid script parameters.
19
     */
20
    private static $valid_script_params = [
21
        's', // secret
22
        'a', // action
23
        'l', // loop
24
        'i', // interval
25
        'g', // group (for cron)
26
    ];
27
28
    /**
29
     * @var array List of vital parameters that must be passed.
30
     */
31
    private static $valid_vital_bot_params = [
32
        'api_key',
33
    ];
34
35
    /**
36
     * @var array List of valid extra parameters that can be passed.
37
     */
38
    private static $valid_extra_bot_params = [
39
        'bot_username',
40
        'secret',
41
        'validate_request',
42
        'valid_ips',
43
        'webhook',
44
        'logging',
45
        'limiter',
46
        'admins',
47
        'mysql',
48
        'paths',
49
        'commands',
50
        'cron',
51
        'custom_input',
52
    ];
53
54
    /**
55
     * @var array List of all params passed to the script.
56
     */
57
    private $script_params = [];
58
59
    /**
60
     * @var array List of all params passed at construction, predefined with defaults.
61
     */
62
    private $bot_params = [
63
        'validate_request' => true,
64
    ];
65
66
    /**
67
     * Params constructor.
68
     *
69
     * api_key (string) Telegram Bot API key
70
     * bot_username (string) Telegram Bot username
71
     * secret (string) Secret string to validate calls
72
     * validate_request (bool) Only allow webhook access from valid Telegram API IPs and defined valid_ips
73
     * valid_ips (array) Any IPs, besides Telegram API IPs, that are allowed to access the webhook
74
     * webhook (array)
75
     * - url (string) URI of the webhook
76
     * - certificate (string) Path to the self-signed certificate
77
     * - max_connections (int) Maximum allowed simultaneous HTTPS connections to the webhook
78
     * - allowed_updates (array) List the types of updates you want your bot to receive
79
     * logging (array) Array of logger files to set.
80
     * limiter (array)
81
     * - enabled (bool) Set limiter.
82
     * - options (array) Limiter options.
83
     * admins (array) List of admins to enable.
84
     * mysql (array) MySQL credentials to use.
85
     * paths (array)
86
     * - download (string) Custom download path to set.
87
     * - upload (string) Custom upload path to set.
88
     * commands (array)
89
     * - paths (array) Custom commands paths to set.
90
     * - configs (array) List of custom command configs.
91
     * custom_input (string) Custom raw JSON string to use as input.
92
     * cron (array)
93
     * - groups (array) Groups of cron commands to run.
94
     *   - default (array) Default group of cron commands.
95
     *
96
     * @param array $params All params to set the bot up with.
97
     *
98
     * @throws InvalidParamsException
99
     */
100
    public function __construct(array $params)
101
    {
102
        $this->validateAndSetBotParams($params);
103
        $this->validateAndSetScriptParams();
104
    }
105
106
    /**
107
     * Validate and set up the vital and extra params.
108
     *
109
     * @param array $params
110
     *
111
     * @return Params
112
     * @throws InvalidParamsException
113
     */
114
    private function validateAndSetBotParams(array $params): self
115
    {
116
        $this->validateAndSetBotParamsVital($params);
117
        $this->validateAndSetBotParamsSpecial($params);
118
        $this->validateAndSetBotParamsExtra($params);
119
120
        return $this;
121
    }
122
123
    /**
124
     * Set all vital params.
125
     *
126
     * @param array $params
127
     *
128
     * @throws InvalidParamsException
129
     */
130
    private function validateAndSetBotParamsVital(array $params): void
131
    {
132
        foreach (self::$valid_vital_bot_params as $vital_key) {
133
            if (!array_key_exists($vital_key, $params)) {
134
                throw new InvalidParamsException('Some vital info is missing: ' . $vital_key);
135
            }
136
137
            $this->bot_params[$vital_key] = $params[$vital_key];
138
        }
139
    }
140
141
    /**
142
     * Special case parameters.
143
     *
144
     * @param array $params
145
     *
146
     * @throws InvalidParamsException
147
     */
148
    private function validateAndSetBotParamsSpecial(array $params): void
149
    {
150
        // Special case, where secret MUST be defined if we have a webhook.
151
        if (($params['webhook']['url'] ?? null) && !($params['secret'] ?? null)) {
152
            // This does not apply when using CLI, but make sure it gets tested for!
153
            if ('cli' !== PHP_SAPI || BotManager::inTest()) {
154
                throw new InvalidParamsException('Some vital info is missing: secret');
155
            }
156
        }
157
    }
158
159
    /**
160
     * Set all extra params.
161
     *
162
     * @param array $params
163
     */
164
    private function validateAndSetBotParamsExtra(array $params): void
165
    {
166
        foreach (self::$valid_extra_bot_params as $extra_key) {
167
            if (!array_key_exists($extra_key, $params)) {
168
                continue;
169
            }
170
171
            $this->bot_params[$extra_key] = $params[$extra_key];
172
        }
173
    }
174
175
    /**
176
     * Handle all script params, via web server handler or CLI.
177
     *
178
     * https://url/entry.php?s=<secret>&a=<action>&l=<loop>
179
     * $ php entry.php s=<secret> a=<action> l=<loop>
180
     *
181
     * @return Params
182
     */
183
    private function validateAndSetScriptParams(): self
184
    {
185
        $this->setScriptParams();
186
        $this->validateScriptParams();
187
188
        return $this;
189
    }
190
191
    /**
192
     * Set script parameters from query string or CLI.
193
     */
194
    private function setScriptParams(): void
195
    {
196
        $this->script_params = $_GET;
197
198
        // If we're not running from CLI, script parameters are already set from $_GET.
199
        if ('cli' !== PHP_SAPI) {
200
            return;
201
        }
202
203
        // We don't need the first arg (the file name).
204
        $args = array_slice($_SERVER['argv'], 1);
205
206
        /** @var array $args */
207
        foreach ($args as $arg) {
208
            @list($key, $val) = explode('=', $arg);
209
            isset($key, $val) && $this->script_params[$key] = $val;
210
        }
211
    }
212
213
    /**
214
     * Keep only valid script parameters.
215
     */
216
    private function validateScriptParams(): void
217
    {
218
        $this->script_params = array_intersect_key(
219
            $this->script_params,
220
            array_fill_keys(self::$valid_script_params, null)
221
        );
222
    }
223
224
    /**
225
     * Get a specific bot param, allowing array-dot notation.
226
     *
227
     * @param string $param
228
     * @param mixed  $default
229
     *
230
     * @return mixed
231
     */
232
    public function getBotParam(string $param, $default = null)
233
    {
234
        $param_path = explode('.', $param);
235
236
        $value = $this->bot_params[array_shift($param_path)] ?? null;
237
        foreach ($param_path as $sub_param_key) {
238
            $value = $value[$sub_param_key] ?? null;
239
            if (null === $value) {
240
                break;
241
            }
242
        }
243
244
        return $value ?? $default;
245
    }
246
247
    /**
248
     * Get an array of all bot params.
249
     *
250
     * @return array
251
     */
252
    public function getBotParams(): array
253
    {
254
        return $this->bot_params;
255
    }
256
257
    /**
258
     * Get a specific script param.
259
     *
260
     * @param string $param
261
     * @param mixed  $default
262
     *
263
     * @return mixed
264
     */
265
    public function getScriptParam(string $param, $default = null)
266
    {
267
        return $this->script_params[$param] ?? $default;
268
    }
269
270
    /**
271
     * Get an array of all script params.
272
     *
273
     * @return array
274
     */
275
    public function getScriptParams(): array
276
    {
277
        return $this->script_params;
278
    }
279
}
280