Passed
Push — master ( f78b46...593eca )
by Shahrad
02:40
created
src/lib/Entity.php 2 patches
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -12,157 +12,157 @@
 block discarded – undo
12 12
 abstract class Entity
13 13
 {
14 14
 
15
-	/**
16
-	 * @var array The raw data passed to this entity
17
-	 */
18
-	protected array $raw_data;
19
-
20
-	/**
21
-	 * Entity constructor.
22
-	 *
23
-	 * @param ?array $data The raw data passed to this entity
24
-	 */
25
-	public function __construct(?array $data)
26
-	{
27
-		if (array_key_exists('raw_data', $data)) {
28
-			$this->raw_data = $data['raw_data'];
29
-		}
30
-
31
-		$this->assignMemberVariables(($this->raw_data = $data));
32
-		$this->validate();
33
-	}
34
-
35
-	/**
36
-	 * Get the raw data passed to this entity
37
-	 *
38
-	 * @param bool $associated
39
-	 * @return array|string
40
-	 */
41
-	public function getRawData(bool $associated = true): array|string
42
-	{
43
-		return $associated ? $this->raw_data : json_encode($this->raw_data);
44
-	}
45
-
46
-	/**
47
-	 * Helper to set member variables
48
-	 *
49
-	 * @param array $data
50
-	 * @return void
51
-	 */
52
-	protected function assignMemberVariables(array $data): void
53
-	{
54
-		foreach ($data as $key => $value) {
55
-			$this->$key = $value;
56
-		}
57
-	}
58
-
59
-	/**
60
-	 * Get a property from the current Entity
61
-	 *
62
-	 * @param string $property
63
-	 * @param mixed $default
64
-	 *
65
-	 * @return mixed
66
-	 */
67
-	public function getProperty(string $property, mixed $default = null): mixed
68
-	{
69
-		return $this->raw_data[$property] ?? $default;
70
-	}
71
-
72
-	/**
73
-	 * Get the list of the properties that are themselves Entities
74
-	 *
75
-	 * @return array
76
-	 */
77
-	protected function subEntities(): array
78
-	{
79
-		return [];
80
-	}
81
-
82
-	/**
83
-	 * Perform any special entity validation
84
-	 *
85
-	 * @return void
86
-	 */
87
-	protected function validate(): void
88
-	{
89
-		// Do nothing by default
90
-	}
91
-
92
-	/**
93
-	 * @param string $name The name of the property
94
-	 * @param array $arguments The arguments passed to the method
95
-	 * @return mixed
96
-	 */
97
-	public function __call(string $name, array $arguments): mixed
98
-	{
99
-		if (method_exists($this, $name)) {
100
-			return $this->{$name}(...$arguments);
101
-		}
102
-
103
-		if (str_starts_with($name, 'get')) {
104
-			$property_name = strtolower(ltrim(preg_replace('/[A-Z]/', '_$0', substr($name, 3)), '_'));
105
-
106
-			$property = $this->getProperty($property_name);
107
-			$sub_entities = $this->subEntities() ?? [];
108
-
109
-			if (isset($sub_entities[$property_name])) {
110
-				$class_name = $sub_entities[$property_name];
111
-				return Factory::resolveEntityClass($class_name, $property);
112
-			}
113
-
114
-			return $property ?? null;
115
-		}
116
-
117
-		if (str_starts_with($name, 'set')) {
118
-			$property_name = strtolower(ltrim(preg_replace('/[A-Z]/', '_$0', substr($name, 3)), '_'));
119
-
120
-			if (property_exists($this, $property_name)) {
121
-				$this->{$property_name} = $arguments[0];
122
-				$this->raw_data[$property_name] = $arguments[0];
123
-
124
-				return $this;
125
-			}
126
-
127
-		}
128
-
129
-		throw new \BadMethodCallException("Method '$name' does not exist");
130
-	}
131
-
132
-	/**
133
-	 * Escape markdown (v1) special characters
134
-	 *
135
-	 * @see https://core.telegram.org/bots/api#markdown-style
136
-	 *
137
-	 * @param string $string
138
-	 *
139
-	 * @return string
140
-	 */
141
-	public static function escapeMarkdown(string $string): string
142
-	{
143
-		return str_replace(
144
-			['[', '`', '*', '_',],
145
-			['\[', '\`', '\*', '\_',],
146
-			$string
147
-		);
148
-	}
149
-
150
-	/**
151
-	 * Escape markdown (v2) special characters
152
-	 *
153
-	 * @see https://core.telegram.org/bots/api#markdownv2-style
154
-	 *
155
-	 * @param string $string
156
-	 *
157
-	 * @return string
158
-	 */
159
-	public static function escapeMarkdownV2(string $string): string
160
-	{
161
-		return str_replace(
162
-			['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'],
163
-			['\_', '\*', '\[', '\]', '\(', '\)', '\~', '\`', '\>', '\#', '\+', '\-', '\=', '\|', '\{', '\}', '\.', '\!'],
164
-			$string
165
-		);
166
-	}
15
+    /**
16
+     * @var array The raw data passed to this entity
17
+     */
18
+    protected array $raw_data;
19
+
20
+    /**
21
+     * Entity constructor.
22
+     *
23
+     * @param ?array $data The raw data passed to this entity
24
+     */
25
+    public function __construct(?array $data)
26
+    {
27
+        if (array_key_exists('raw_data', $data)) {
28
+            $this->raw_data = $data['raw_data'];
29
+        }
30
+
31
+        $this->assignMemberVariables(($this->raw_data = $data));
32
+        $this->validate();
33
+    }
34
+
35
+    /**
36
+     * Get the raw data passed to this entity
37
+     *
38
+     * @param bool $associated
39
+     * @return array|string
40
+     */
41
+    public function getRawData(bool $associated = true): array|string
42
+    {
43
+        return $associated ? $this->raw_data : json_encode($this->raw_data);
44
+    }
45
+
46
+    /**
47
+     * Helper to set member variables
48
+     *
49
+     * @param array $data
50
+     * @return void
51
+     */
52
+    protected function assignMemberVariables(array $data): void
53
+    {
54
+        foreach ($data as $key => $value) {
55
+            $this->$key = $value;
56
+        }
57
+    }
58
+
59
+    /**
60
+     * Get a property from the current Entity
61
+     *
62
+     * @param string $property
63
+     * @param mixed $default
64
+     *
65
+     * @return mixed
66
+     */
67
+    public function getProperty(string $property, mixed $default = null): mixed
68
+    {
69
+        return $this->raw_data[$property] ?? $default;
70
+    }
71
+
72
+    /**
73
+     * Get the list of the properties that are themselves Entities
74
+     *
75
+     * @return array
76
+     */
77
+    protected function subEntities(): array
78
+    {
79
+        return [];
80
+    }
81
+
82
+    /**
83
+     * Perform any special entity validation
84
+     *
85
+     * @return void
86
+     */
87
+    protected function validate(): void
88
+    {
89
+        // Do nothing by default
90
+    }
91
+
92
+    /**
93
+     * @param string $name The name of the property
94
+     * @param array $arguments The arguments passed to the method
95
+     * @return mixed
96
+     */
97
+    public function __call(string $name, array $arguments): mixed
98
+    {
99
+        if (method_exists($this, $name)) {
100
+            return $this->{$name}(...$arguments);
101
+        }
102
+
103
+        if (str_starts_with($name, 'get')) {
104
+            $property_name = strtolower(ltrim(preg_replace('/[A-Z]/', '_$0', substr($name, 3)), '_'));
105
+
106
+            $property = $this->getProperty($property_name);
107
+            $sub_entities = $this->subEntities() ?? [];
108
+
109
+            if (isset($sub_entities[$property_name])) {
110
+                $class_name = $sub_entities[$property_name];
111
+                return Factory::resolveEntityClass($class_name, $property);
112
+            }
113
+
114
+            return $property ?? null;
115
+        }
116
+
117
+        if (str_starts_with($name, 'set')) {
118
+            $property_name = strtolower(ltrim(preg_replace('/[A-Z]/', '_$0', substr($name, 3)), '_'));
119
+
120
+            if (property_exists($this, $property_name)) {
121
+                $this->{$property_name} = $arguments[0];
122
+                $this->raw_data[$property_name] = $arguments[0];
123
+
124
+                return $this;
125
+            }
126
+
127
+        }
128
+
129
+        throw new \BadMethodCallException("Method '$name' does not exist");
130
+    }
131
+
132
+    /**
133
+     * Escape markdown (v1) special characters
134
+     *
135
+     * @see https://core.telegram.org/bots/api#markdown-style
136
+     *
137
+     * @param string $string
138
+     *
139
+     * @return string
140
+     */
141
+    public static function escapeMarkdown(string $string): string
142
+    {
143
+        return str_replace(
144
+            ['[', '`', '*', '_',],
145
+            ['\[', '\`', '\*', '\_',],
146
+            $string
147
+        );
148
+    }
149
+
150
+    /**
151
+     * Escape markdown (v2) special characters
152
+     *
153
+     * @see https://core.telegram.org/bots/api#markdownv2-style
154
+     *
155
+     * @param string $string
156
+     *
157
+     * @return string
158
+     */
159
+    public static function escapeMarkdownV2(string $string): string
160
+    {
161
+        return str_replace(
162
+            ['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'],
163
+            ['\_', '\*', '\[', '\]', '\(', '\)', '\~', '\`', '\>', '\#', '\+', '\-', '\=', '\|', '\{', '\}', '\.', '\!'],
164
+            $string
165
+        );
166
+    }
167 167
 
168 168
 }
169 169
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -141,8 +141,8 @@
 block discarded – undo
141 141
 	public static function escapeMarkdown(string $string): string
142 142
 	{
143 143
 		return str_replace(
144
-			['[', '`', '*', '_',],
145
-			['\[', '\`', '\*', '\_',],
144
+			['[', '`', '*', '_', ],
145
+			['\[', '\`', '\*', '\_', ],
146 146
 			$string
147 147
 		);
148 148
 	}
Please login to merge, or discard this patch.
src/lib/WebhookHandler.php 2 patches
Indentation   +208 added lines, -208 removed lines patch added patch discarded remove patch
@@ -17,213 +17,213 @@
 block discarded – undo
17 17
 abstract class WebhookHandler extends Telegram
18 18
 {
19 19
 
20
-	/**
21
-	 * @var ?Update
22
-	 */
23
-	protected ?Update $update;
24
-
25
-	/**
26
-	 * @var array<Plugin>
27
-	 */
28
-	private array $plugins = [];
29
-
30
-	/**
31
-	 * @var bool
32
-	 */
33
-	private bool $isActive = false;
34
-
35
-	/**
36
-	 * The default configuration of the webhook.
37
-	 *
38
-	 * @var array
39
-	 */
40
-	private array $config = [
41
-		'autoload_env_file' => false,
42
-		'env_file_path' => null,
43
-	];
44
-
45
-	/**
46
-	 * Webhook constructor.
47
-	 *
48
-	 * @param string $api_key The API key of the bot. Leave it blank for autoload from .env file.
49
-	 */
50
-	public function __construct(string $api_key = '')
51
-	{
52
-		parent::__construct($api_key);
53
-
54
-		if (!Telegram::validateToken(self::getApiKey())) {
55
-			throw new InvalidBotTokenException();
56
-		}
57
-	}
58
-
59
-	/**
60
-	 * Initialize the receiver.
61
-	 *
62
-	 * @return void
63
-	 */
64
-	public function init(): void
65
-	{
66
-		$this->config['env_file_path'] = $_SERVER['DOCUMENT_ROOT'] . '/.env';
67
-	}
68
-
69
-	/**
70
-	 * Add a plugin to the receiver
71
-	 *
72
-	 * @param array<Plugin> $plugins
73
-	 */
74
-	public function addPlugin(array $plugins): void
75
-	{
76
-		foreach ($plugins as $plugin) {
77
-			if (!is_subclass_of($plugin, Plugin::class)) {
78
-				throw new \RuntimeException(
79
-					sprintf('The plugin %s must be an instance of %s', get_class($plugin), Plugin::class)
80
-				);
81
-			}
82
-			$this->plugins[] = $plugin;
83
-		}
84
-	}
85
-
86
-	/**
87
-	 * Match the update with the given plugins
88
-	 *
89
-	 * @param array<Plugin> $plugins
90
-	 * @param ?Update $update The update to match
91
-	 * @return void
92
-	 */
93
-	public function loadPluginsWith(array $plugins, Update $update = null): void
94
-	{
95
-		$update = $update ?? Telegram::getUpdate();
96
-		foreach ($plugins as $plugin) {
97
-			if (!is_subclass_of($plugin, Plugin::class)) {
98
-				throw new \InvalidArgumentException(
99
-					sprintf('The plugin %s must be an instance of %s', get_class($plugin), Plugin::class)
100
-				);
101
-			}
102
-		}
103
-		if ($update instanceof Update) {
104
-			$this->spreadUpdateWith($update, $plugins);
105
-		}
106
-	}
107
-
108
-	/**
109
-	 * Match the message to the plugins
110
-	 *
111
-	 * @param ?Update $update The update to match
112
-	 * @return void
113
-	 */
114
-	public function loadPlugins(Update $update = null): void
115
-	{
116
-		$update = $update ?? ($this->update ?? Telegram::getUpdate());
117
-		$this->loadPluginsWith($this->plugins, $update);
118
-	}
119
-
120
-	/**
121
-	 * Load the environment's
122
-	 *
123
-	 * @param string $path
124
-	 * @retrun void
125
-	 */
126
-	public function loadFileOfEnv(string $path): void
127
-	{
128
-		DotEnv::load($path);
129
-	}
130
-
131
-	/**
132
-	 * Update the configuration
133
-	 *
134
-	 * @param array $configuration
135
-	 * @return void
136
-	 */
137
-	public function updateConfiguration(array $configuration): void
138
-	{
139
-		$this->config = array_merge($this->config, $configuration);
140
-	}
141
-
142
-	/**
143
-	 * Resolve the request.
144
-	 *
145
-	 * @param ?Update $update The custom to work with
146
-	 * @param array $config The configuration of the receiver
147
-	 *
148
-	 * @retrun void
149
-	 */
150
-	public function resolve(Update $update = null, array $config = []): void
151
-	{
152
-		$method = '__process';
153
-		if (!method_exists($this, $method)) {
154
-			throw new \RuntimeException(sprintf('The method %s does not exist', $method));
155
-		}
156
-
157
-		if (is_array($config)) $this->updateConfiguration($config);
158
-
159
-		if (!empty($update)) $this->update = $update;
160
-		else $this->update = Telegram::getUpdate() !== false ? Telegram::getUpdate() : null;
161
-
162
-		if (empty($this->update)) {
163
-			TelegramLog::error('The update is empty');
164
-			return;
165
-		}
166
-
167
-		try {
168
-
169
-			Common::arrest($this, $method, $this->update);
170
-
171
-		} catch (\RuntimeException $e) {
172
-			TelegramLog::error(($message = sprintf('%s: %s', $e->getMessage(), $e->getTraceAsString())));
173
-			if (defined('TG_ADMIN_ID') && TG_ADMIN_ID && defined('DEBUG_MODE') && DEBUG_MODE) {
174
-				file_put_contents(
175
-					($file = getcwd() . '/' . uniqid('error_') . '.log'),
176
-					$message . PHP_EOL . PHP_EOL . $update->getRawData(false)
177
-				);
178
-				Request::sendMessage([
179
-					'chat_id' => TG_ADMIN_ID,
180
-					'text' => $message,
181
-				]);
182
-				Request::sendDocument([
183
-					'chat_id' => TG_ADMIN_ID,
184
-					'document' => $file,
185
-				]);
186
-				unlink($file);
187
-			}
188
-		}
189
-	}
190
-
191
-	/**
192
-	 * This function will get update and spread it to the plugins
193
-	 *
194
-	 * @param Update $update
195
-	 * @param array<Plugin> $plugins
196
-	 * @return void
197
-	 */
198
-	private function spreadUpdateWith(Update $update, array $plugins): void
199
-	{
200
-		$this->isActive = true;
201
-
202
-		foreach ($plugins as $plugin) {
203
-			/** @var Plugin $plugin */
204
-			(new $plugin())->__execute($this, $update);
205
-			if ($this->isActive === false) break;
206
-		}
207
-
208
-		$this->isActive = false;
209
-	}
210
-
211
-	/**
212
-	 * Kill the speeding process
213
-	 *
214
-	 * @return void
215
-	 */
216
-	public function kill(): void
217
-	{
218
-		$this->isActive = false;
219
-	}
220
-
221
-	/**
222
-	 * Use this method on the webhook class to get the updates
223
-	 *
224
-	 * @param Update $update
225
-	 * @return void
226
-	 */
227
-	abstract public function __process(Update $update): void;
20
+    /**
21
+     * @var ?Update
22
+     */
23
+    protected ?Update $update;
24
+
25
+    /**
26
+     * @var array<Plugin>
27
+     */
28
+    private array $plugins = [];
29
+
30
+    /**
31
+     * @var bool
32
+     */
33
+    private bool $isActive = false;
34
+
35
+    /**
36
+     * The default configuration of the webhook.
37
+     *
38
+     * @var array
39
+     */
40
+    private array $config = [
41
+        'autoload_env_file' => false,
42
+        'env_file_path' => null,
43
+    ];
44
+
45
+    /**
46
+     * Webhook constructor.
47
+     *
48
+     * @param string $api_key The API key of the bot. Leave it blank for autoload from .env file.
49
+     */
50
+    public function __construct(string $api_key = '')
51
+    {
52
+        parent::__construct($api_key);
53
+
54
+        if (!Telegram::validateToken(self::getApiKey())) {
55
+            throw new InvalidBotTokenException();
56
+        }
57
+    }
58
+
59
+    /**
60
+     * Initialize the receiver.
61
+     *
62
+     * @return void
63
+     */
64
+    public function init(): void
65
+    {
66
+        $this->config['env_file_path'] = $_SERVER['DOCUMENT_ROOT'] . '/.env';
67
+    }
68
+
69
+    /**
70
+     * Add a plugin to the receiver
71
+     *
72
+     * @param array<Plugin> $plugins
73
+     */
74
+    public function addPlugin(array $plugins): void
75
+    {
76
+        foreach ($plugins as $plugin) {
77
+            if (!is_subclass_of($plugin, Plugin::class)) {
78
+                throw new \RuntimeException(
79
+                    sprintf('The plugin %s must be an instance of %s', get_class($plugin), Plugin::class)
80
+                );
81
+            }
82
+            $this->plugins[] = $plugin;
83
+        }
84
+    }
85
+
86
+    /**
87
+     * Match the update with the given plugins
88
+     *
89
+     * @param array<Plugin> $plugins
90
+     * @param ?Update $update The update to match
91
+     * @return void
92
+     */
93
+    public function loadPluginsWith(array $plugins, Update $update = null): void
94
+    {
95
+        $update = $update ?? Telegram::getUpdate();
96
+        foreach ($plugins as $plugin) {
97
+            if (!is_subclass_of($plugin, Plugin::class)) {
98
+                throw new \InvalidArgumentException(
99
+                    sprintf('The plugin %s must be an instance of %s', get_class($plugin), Plugin::class)
100
+                );
101
+            }
102
+        }
103
+        if ($update instanceof Update) {
104
+            $this->spreadUpdateWith($update, $plugins);
105
+        }
106
+    }
107
+
108
+    /**
109
+     * Match the message to the plugins
110
+     *
111
+     * @param ?Update $update The update to match
112
+     * @return void
113
+     */
114
+    public function loadPlugins(Update $update = null): void
115
+    {
116
+        $update = $update ?? ($this->update ?? Telegram::getUpdate());
117
+        $this->loadPluginsWith($this->plugins, $update);
118
+    }
119
+
120
+    /**
121
+     * Load the environment's
122
+     *
123
+     * @param string $path
124
+     * @retrun void
125
+     */
126
+    public function loadFileOfEnv(string $path): void
127
+    {
128
+        DotEnv::load($path);
129
+    }
130
+
131
+    /**
132
+     * Update the configuration
133
+     *
134
+     * @param array $configuration
135
+     * @return void
136
+     */
137
+    public function updateConfiguration(array $configuration): void
138
+    {
139
+        $this->config = array_merge($this->config, $configuration);
140
+    }
141
+
142
+    /**
143
+     * Resolve the request.
144
+     *
145
+     * @param ?Update $update The custom to work with
146
+     * @param array $config The configuration of the receiver
147
+     *
148
+     * @retrun void
149
+     */
150
+    public function resolve(Update $update = null, array $config = []): void
151
+    {
152
+        $method = '__process';
153
+        if (!method_exists($this, $method)) {
154
+            throw new \RuntimeException(sprintf('The method %s does not exist', $method));
155
+        }
156
+
157
+        if (is_array($config)) $this->updateConfiguration($config);
158
+
159
+        if (!empty($update)) $this->update = $update;
160
+        else $this->update = Telegram::getUpdate() !== false ? Telegram::getUpdate() : null;
161
+
162
+        if (empty($this->update)) {
163
+            TelegramLog::error('The update is empty');
164
+            return;
165
+        }
166
+
167
+        try {
168
+
169
+            Common::arrest($this, $method, $this->update);
170
+
171
+        } catch (\RuntimeException $e) {
172
+            TelegramLog::error(($message = sprintf('%s: %s', $e->getMessage(), $e->getTraceAsString())));
173
+            if (defined('TG_ADMIN_ID') && TG_ADMIN_ID && defined('DEBUG_MODE') && DEBUG_MODE) {
174
+                file_put_contents(
175
+                    ($file = getcwd() . '/' . uniqid('error_') . '.log'),
176
+                    $message . PHP_EOL . PHP_EOL . $update->getRawData(false)
177
+                );
178
+                Request::sendMessage([
179
+                    'chat_id' => TG_ADMIN_ID,
180
+                    'text' => $message,
181
+                ]);
182
+                Request::sendDocument([
183
+                    'chat_id' => TG_ADMIN_ID,
184
+                    'document' => $file,
185
+                ]);
186
+                unlink($file);
187
+            }
188
+        }
189
+    }
190
+
191
+    /**
192
+     * This function will get update and spread it to the plugins
193
+     *
194
+     * @param Update $update
195
+     * @param array<Plugin> $plugins
196
+     * @return void
197
+     */
198
+    private function spreadUpdateWith(Update $update, array $plugins): void
199
+    {
200
+        $this->isActive = true;
201
+
202
+        foreach ($plugins as $plugin) {
203
+            /** @var Plugin $plugin */
204
+            (new $plugin())->__execute($this, $update);
205
+            if ($this->isActive === false) break;
206
+        }
207
+
208
+        $this->isActive = false;
209
+    }
210
+
211
+    /**
212
+     * Kill the speeding process
213
+     *
214
+     * @return void
215
+     */
216
+    public function kill(): void
217
+    {
218
+        $this->isActive = false;
219
+    }
220
+
221
+    /**
222
+     * Use this method on the webhook class to get the updates
223
+     *
224
+     * @param Update $update
225
+     * @return void
226
+     */
227
+    abstract public function __process(Update $update): void;
228 228
 
229 229
 }
230 230
\ No newline at end of file
Please login to merge, or discard this patch.
Braces   +11 added lines, -4 removed lines patch added patch discarded remove patch
@@ -154,10 +154,15 @@  discard block
 block discarded – undo
154 154
 			throw new \RuntimeException(sprintf('The method %s does not exist', $method));
155 155
 		}
156 156
 
157
-		if (is_array($config)) $this->updateConfiguration($config);
157
+		if (is_array($config)) {
158
+		    $this->updateConfiguration($config);
159
+		}
158 160
 
159
-		if (!empty($update)) $this->update = $update;
160
-		else $this->update = Telegram::getUpdate() !== false ? Telegram::getUpdate() : null;
161
+		if (!empty($update)) {
162
+		    $this->update = $update;
163
+		} else {
164
+		    $this->update = Telegram::getUpdate() !== false ? Telegram::getUpdate() : null;
165
+		}
161 166
 
162 167
 		if (empty($this->update)) {
163 168
 			TelegramLog::error('The update is empty');
@@ -202,7 +207,9 @@  discard block
 block discarded – undo
202 207
 		foreach ($plugins as $plugin) {
203 208
 			/** @var Plugin $plugin */
204 209
 			(new $plugin())->__execute($this, $update);
205
-			if ($this->isActive === false) break;
210
+			if ($this->isActive === false) {
211
+			    break;
212
+			}
206 213
 		}
207 214
 
208 215
 		$this->isActive = false;
Please login to merge, or discard this patch.
src/lib/Telegram.php 2 patches
Indentation   +309 added lines, -309 removed lines patch added patch discarded remove patch
@@ -18,314 +18,314 @@
 block discarded – undo
18 18
 class Telegram
19 19
 {
20 20
 
21
-	/**
22
-	 * @var string
23
-	 */
24
-	private string $api_key;
25
-
26
-	/**
27
-	 * @var string
28
-	 */
29
-	public static string $VERSION = 'v1.0.0';
30
-
31
-	/**
32
-	 * Telegram constructor.
33
-	 *
34
-	 * @param string $api_key
35
-	 */
36
-	public function __construct(string $api_key = '')
37
-	{
38
-		if ($api_key === '') {
39
-			$env_file = $this->getEnvFilePath();
40
-			$api_key = DotEnv::load($env_file)->get('TELEGRAM_API_KEY');
41
-		}
42
-
43
-		if (empty($api_key) || !is_string($api_key)) {
44
-			throw new TelegramException('API Key is required');
45
-		}
46
-
47
-		DotEnv::put('TG_CURRENT_KEY', ($this->api_key = $api_key));
48
-		DotEnv::put('TELEGRAM_API_KEY', ($this->api_key = $api_key));
49
-	}
50
-
51
-	/**
52
-	 * Get env file path and return it
53
-	 *
54
-	 * @return string
55
-	 */
56
-	private function getEnvFilePath(): string
57
-	{
58
-		$defaultEnvPaths = [
59
-			$_SERVER['DOCUMENT_ROOT'] . '/.env',
60
-			getcwd() . '/../.env',
61
-			getcwd() . '/.env',
62
-		];
63
-
64
-		foreach ($defaultEnvPaths as $path) {
65
-			if (file_exists($path)) {
66
-				return $path;
67
-			}
68
-		}
69
-
70
-		return '';
71
-	}
72
-
73
-	/**
74
-	 * Get API key from temporary ENV variable
75
-	 *
76
-	 * @return ?string
77
-	 */
78
-	public static function getApiKey(): ?string
79
-	{
80
-		return DotEnv::get('TG_CURRENT_KEY');
81
-	}
82
-
83
-	/**
84
-	 * Get bot info from given API key
85
-	 *
86
-	 * @return Response
87
-	 * @throws TelegramException
88
-	 */
89
-	public function getInfo(): Response
90
-	{
91
-		$result = Request::getMe();
92
-
93
-		if (!$result->isOk()) {
94
-			throw new TelegramException($result->getErrorCode() . ': ' . $result->getDescription());
95
-		}
96
-
97
-		return $result;
98
-	}
99
-
100
-	/**
101
-	 * Set Webhook for bot
102
-	 *
103
-	 * @param string $url
104
-	 * @param array $data Optional parameters.
105
-	 * @return Response
106
-	 * @throws TelegramException
107
-	 */
108
-	public function setWebhook(string $url, array $data = []): Response
109
-	{
110
-		if ($url === '') {
111
-			throw new TelegramException('Hook url is empty!');
112
-		}
113
-
114
-		if (!str_starts_with($url, 'https://')) {
115
-			throw new TelegramException('Hook url must start with https://');
116
-		}
117
-
118
-		$data = array_intersect_key($data, array_flip([
119
-			'certificate',
120
-			'ip_address',
121
-			'max_connections',
122
-			'allowed_updates',
123
-			'drop_pending_updates',
124
-		]));
125
-		$data['url'] = $url;
126
-
127
-		$result = Request::setWebhook($data);
128
-
129
-		if (!$result->isOk()) {
130
-			throw new TelegramException(
131
-				'Webhook was not set! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
132
-			);
133
-		}
134
-
135
-		return $result;
136
-	}
137
-
138
-	/**
139
-	 * Delete any assigned webhook
140
-	 *
141
-	 * @param array $data
142
-	 * @return Response
143
-	 * @throws TelegramException
144
-	 */
145
-	public function deleteWebhook(array $data = []): Response
146
-	{
147
-		$result = Request::deleteWebhook($data);
148
-
149
-		if (!$result->isOk()) {
150
-			throw new TelegramException(
151
-				'Webhook was not deleted! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
152
-			);
153
-		}
154
-
155
-		return $result;
156
-	}
157
-
158
-	/**
159
-	 * This method sets the admin username. and will be used to send you a message if the bot is not working.
160
-	 *
161
-	 * @param int $chat_id
162
-	 * @return void
163
-	 */
164
-	public function setAdmin(int $chat_id): void
165
-	{
166
-		defined('TG_ADMIN_ID') or define('TG_ADMIN_ID', $chat_id);
167
-	}
168
-
169
-	/**
170
-	 * Get input from stdin and return it
171
-	 *
172
-	 * @return ?string
173
-	 */
174
-	public static function getInput(): ?string
175
-	{
176
-		return file_get_contents('php://input') ?? null;
177
-	}
178
-
179
-	/**
180
-	 * This method will convert a string to an update object
181
-	 *
182
-	 * @param string $input The input string
183
-	 * @param string $apiKey The API key
184
-	 * @return Update|false
185
-	 */
186
-	public static function processUpdate(string $input, string $apiKey): Update|false
187
-	{
188
-		if (empty($input)) {
189
-			throw new TelegramException(
190
-				'Input is empty! Please check your code and try again.'
191
-			);
192
-		}
193
-
194
-		if (!self::validateToken($apiKey)) {
195
-			throw new TelegramException(
196
-				'Invalid token! Please check your code and try again.'
197
-			);
198
-		}
199
-
200
-		if (self::validateWebData($apiKey, $input)) {
201
-			if (Common::isUrlEncode($input)) {
202
-				$web_data = Common::urlDecode($input);
203
-			}
204
-
205
-			if (Common::isJson($input)) {
206
-				$web_data = json_decode($input, true);
207
-			}
208
-
209
-			$input = json_encode([
210
-				'web_data' => $web_data,
211
-			]);
212
-		}
213
-
214
-		if (!Common::isJson($input)) {
215
-			throw new TelegramException(
216
-				'Input is not a valid JSON string! Please check your code and try again.'
217
-			);
218
-		}
219
-
220
-		$input = json_decode($input, true);
221
-
222
-		return new Update($input);
223
-	}
224
-
225
-	/**
226
-	 * Validate webapp data from is from Telegram
227
-	 *
228
-	 * @link https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app
229
-	 *
230
-	 * @param string $token The bot token
231
-	 * @param string $body The message body from getInput()
232
-	 * @return bool
233
-	 */
234
-	public static function validateWebData(string $token, string $body): bool
235
-	{
236
-		if (!Common::isJson($body)) {
237
-			$raw_data = rawurldecode(str_replace('_auth=', '', $body));
238
-			$data = Common::urlDecode($raw_data);
239
-
240
-			$data['user'] = urldecode($data['user']);
241
-
242
-		} else {
243
-			$data = json_decode($body, true);
244
-			$data['user'] = json_encode($data['user']);
245
-		}
246
-
247
-		$data_check_string = "auth_date={$data['auth_date']}\nquery_id={$data['query_id']}\nuser={$data['user']}";
248
-		$secret_key = hash_hmac('sha256', $token, "WebAppData", true);
249
-
250
-		return hash_hmac('sha256', $data_check_string, $secret_key) == $data['hash'];
251
-	}
252
-
253
-	/**
254
-	 * Get the update from input
255
-	 *
256
-	 * @return Update|false
257
-	 */
258
-	public static function getUpdate(): Update|false
259
-	{
260
-		$input = self::getInput();
261
-		if (empty($input)) return false;
262
-		return Telegram::processUpdate($input, self::getApiKey());
263
-	}
264
-
265
-	/**
266
-	 * Validate the token
267
-	 *
268
-	 * @param string $token (e.g. 123456789:ABC-DEF1234ghIkl-zyx57W2v1u123ew11) {digit}:{alphanumeric[34]}
269
-	 * @return bool
270
-	 */
271
-	public static function validateToken(string $token): bool
272
-	{
273
-		preg_match_all('/([0-9]+:[a-zA-Z0-9-_]+)/', $token, $matches);
274
-		return count($matches[0]) == 1;
275
-	}
276
-
277
-	/**
278
-	 * Pass the update to the given webhook handler
279
-	 *
280
-	 * @param WebhookHandler $webhook_handler The webhook handler
281
-	 * @param ?Update $update By default, it will get the update from input
282
-	 * @return void
283
-	 */
284
-	public function fetchWith(WebhookHandler $webhook_handler, ?Update $update = null): void
285
-	{
286
-		if (is_subclass_of($webhook_handler, WebhookHandler::class)) {
287
-			if ($update === null) $update = self::getUpdate();
288
-			$webhook_handler->resolve($update);
289
-		}
290
-	}
291
-
292
-	/**
293
-	 * Get token from env file.
294
-	 *
295
-	 * @param string $file
296
-	 * @return ?string
297
-	 */
298
-	protected function getTokenFromEnvFile(string $file): ?string
299
-	{
300
-		if (!file_exists($file)) return null;
301
-		return DotEnv::load($file)::get('TELEGRAM_API_KEY');
302
-	}
303
-
304
-	/**
305
-	 * Debug mode
306
-	 *
307
-	 * @param ?int $admin_id Fill this or use setAdmin()
308
-	 * @return void
309
-	 */
310
-	public static function setDebugMode(?int $admin_id = null): void
311
-	{
312
-		error_reporting(E_ALL);
313
-		ini_set('display_errors', 1);
314
-		defined('DEBUG_MODE') or define('DEBUG_MODE', true);
315
-		if ($admin_id) {
316
-			defined('TG_ADMIN_ID') or define('TG_ADMIN_ID', $admin_id);
317
-		}
318
-	}
319
-
320
-	/**
321
-	 * Just another echo
322
-	 *
323
-	 * @param string $text
324
-	 * @return void
325
-	 */
326
-	public static function echo(string $text): void
327
-	{
328
-		echo $text;
329
-	}
21
+    /**
22
+     * @var string
23
+     */
24
+    private string $api_key;
25
+
26
+    /**
27
+     * @var string
28
+     */
29
+    public static string $VERSION = 'v1.0.0';
30
+
31
+    /**
32
+     * Telegram constructor.
33
+     *
34
+     * @param string $api_key
35
+     */
36
+    public function __construct(string $api_key = '')
37
+    {
38
+        if ($api_key === '') {
39
+            $env_file = $this->getEnvFilePath();
40
+            $api_key = DotEnv::load($env_file)->get('TELEGRAM_API_KEY');
41
+        }
42
+
43
+        if (empty($api_key) || !is_string($api_key)) {
44
+            throw new TelegramException('API Key is required');
45
+        }
46
+
47
+        DotEnv::put('TG_CURRENT_KEY', ($this->api_key = $api_key));
48
+        DotEnv::put('TELEGRAM_API_KEY', ($this->api_key = $api_key));
49
+    }
50
+
51
+    /**
52
+     * Get env file path and return it
53
+     *
54
+     * @return string
55
+     */
56
+    private function getEnvFilePath(): string
57
+    {
58
+        $defaultEnvPaths = [
59
+            $_SERVER['DOCUMENT_ROOT'] . '/.env',
60
+            getcwd() . '/../.env',
61
+            getcwd() . '/.env',
62
+        ];
63
+
64
+        foreach ($defaultEnvPaths as $path) {
65
+            if (file_exists($path)) {
66
+                return $path;
67
+            }
68
+        }
69
+
70
+        return '';
71
+    }
72
+
73
+    /**
74
+     * Get API key from temporary ENV variable
75
+     *
76
+     * @return ?string
77
+     */
78
+    public static function getApiKey(): ?string
79
+    {
80
+        return DotEnv::get('TG_CURRENT_KEY');
81
+    }
82
+
83
+    /**
84
+     * Get bot info from given API key
85
+     *
86
+     * @return Response
87
+     * @throws TelegramException
88
+     */
89
+    public function getInfo(): Response
90
+    {
91
+        $result = Request::getMe();
92
+
93
+        if (!$result->isOk()) {
94
+            throw new TelegramException($result->getErrorCode() . ': ' . $result->getDescription());
95
+        }
96
+
97
+        return $result;
98
+    }
99
+
100
+    /**
101
+     * Set Webhook for bot
102
+     *
103
+     * @param string $url
104
+     * @param array $data Optional parameters.
105
+     * @return Response
106
+     * @throws TelegramException
107
+     */
108
+    public function setWebhook(string $url, array $data = []): Response
109
+    {
110
+        if ($url === '') {
111
+            throw new TelegramException('Hook url is empty!');
112
+        }
113
+
114
+        if (!str_starts_with($url, 'https://')) {
115
+            throw new TelegramException('Hook url must start with https://');
116
+        }
117
+
118
+        $data = array_intersect_key($data, array_flip([
119
+            'certificate',
120
+            'ip_address',
121
+            'max_connections',
122
+            'allowed_updates',
123
+            'drop_pending_updates',
124
+        ]));
125
+        $data['url'] = $url;
126
+
127
+        $result = Request::setWebhook($data);
128
+
129
+        if (!$result->isOk()) {
130
+            throw new TelegramException(
131
+                'Webhook was not set! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
132
+            );
133
+        }
134
+
135
+        return $result;
136
+    }
137
+
138
+    /**
139
+     * Delete any assigned webhook
140
+     *
141
+     * @param array $data
142
+     * @return Response
143
+     * @throws TelegramException
144
+     */
145
+    public function deleteWebhook(array $data = []): Response
146
+    {
147
+        $result = Request::deleteWebhook($data);
148
+
149
+        if (!$result->isOk()) {
150
+            throw new TelegramException(
151
+                'Webhook was not deleted! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
152
+            );
153
+        }
154
+
155
+        return $result;
156
+    }
157
+
158
+    /**
159
+     * This method sets the admin username. and will be used to send you a message if the bot is not working.
160
+     *
161
+     * @param int $chat_id
162
+     * @return void
163
+     */
164
+    public function setAdmin(int $chat_id): void
165
+    {
166
+        defined('TG_ADMIN_ID') or define('TG_ADMIN_ID', $chat_id);
167
+    }
168
+
169
+    /**
170
+     * Get input from stdin and return it
171
+     *
172
+     * @return ?string
173
+     */
174
+    public static function getInput(): ?string
175
+    {
176
+        return file_get_contents('php://input') ?? null;
177
+    }
178
+
179
+    /**
180
+     * This method will convert a string to an update object
181
+     *
182
+     * @param string $input The input string
183
+     * @param string $apiKey The API key
184
+     * @return Update|false
185
+     */
186
+    public static function processUpdate(string $input, string $apiKey): Update|false
187
+    {
188
+        if (empty($input)) {
189
+            throw new TelegramException(
190
+                'Input is empty! Please check your code and try again.'
191
+            );
192
+        }
193
+
194
+        if (!self::validateToken($apiKey)) {
195
+            throw new TelegramException(
196
+                'Invalid token! Please check your code and try again.'
197
+            );
198
+        }
199
+
200
+        if (self::validateWebData($apiKey, $input)) {
201
+            if (Common::isUrlEncode($input)) {
202
+                $web_data = Common::urlDecode($input);
203
+            }
204
+
205
+            if (Common::isJson($input)) {
206
+                $web_data = json_decode($input, true);
207
+            }
208
+
209
+            $input = json_encode([
210
+                'web_data' => $web_data,
211
+            ]);
212
+        }
213
+
214
+        if (!Common::isJson($input)) {
215
+            throw new TelegramException(
216
+                'Input is not a valid JSON string! Please check your code and try again.'
217
+            );
218
+        }
219
+
220
+        $input = json_decode($input, true);
221
+
222
+        return new Update($input);
223
+    }
224
+
225
+    /**
226
+     * Validate webapp data from is from Telegram
227
+     *
228
+     * @link https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app
229
+     *
230
+     * @param string $token The bot token
231
+     * @param string $body The message body from getInput()
232
+     * @return bool
233
+     */
234
+    public static function validateWebData(string $token, string $body): bool
235
+    {
236
+        if (!Common::isJson($body)) {
237
+            $raw_data = rawurldecode(str_replace('_auth=', '', $body));
238
+            $data = Common::urlDecode($raw_data);
239
+
240
+            $data['user'] = urldecode($data['user']);
241
+
242
+        } else {
243
+            $data = json_decode($body, true);
244
+            $data['user'] = json_encode($data['user']);
245
+        }
246
+
247
+        $data_check_string = "auth_date={$data['auth_date']}\nquery_id={$data['query_id']}\nuser={$data['user']}";
248
+        $secret_key = hash_hmac('sha256', $token, "WebAppData", true);
249
+
250
+        return hash_hmac('sha256', $data_check_string, $secret_key) == $data['hash'];
251
+    }
252
+
253
+    /**
254
+     * Get the update from input
255
+     *
256
+     * @return Update|false
257
+     */
258
+    public static function getUpdate(): Update|false
259
+    {
260
+        $input = self::getInput();
261
+        if (empty($input)) return false;
262
+        return Telegram::processUpdate($input, self::getApiKey());
263
+    }
264
+
265
+    /**
266
+     * Validate the token
267
+     *
268
+     * @param string $token (e.g. 123456789:ABC-DEF1234ghIkl-zyx57W2v1u123ew11) {digit}:{alphanumeric[34]}
269
+     * @return bool
270
+     */
271
+    public static function validateToken(string $token): bool
272
+    {
273
+        preg_match_all('/([0-9]+:[a-zA-Z0-9-_]+)/', $token, $matches);
274
+        return count($matches[0]) == 1;
275
+    }
276
+
277
+    /**
278
+     * Pass the update to the given webhook handler
279
+     *
280
+     * @param WebhookHandler $webhook_handler The webhook handler
281
+     * @param ?Update $update By default, it will get the update from input
282
+     * @return void
283
+     */
284
+    public function fetchWith(WebhookHandler $webhook_handler, ?Update $update = null): void
285
+    {
286
+        if (is_subclass_of($webhook_handler, WebhookHandler::class)) {
287
+            if ($update === null) $update = self::getUpdate();
288
+            $webhook_handler->resolve($update);
289
+        }
290
+    }
291
+
292
+    /**
293
+     * Get token from env file.
294
+     *
295
+     * @param string $file
296
+     * @return ?string
297
+     */
298
+    protected function getTokenFromEnvFile(string $file): ?string
299
+    {
300
+        if (!file_exists($file)) return null;
301
+        return DotEnv::load($file)::get('TELEGRAM_API_KEY');
302
+    }
303
+
304
+    /**
305
+     * Debug mode
306
+     *
307
+     * @param ?int $admin_id Fill this or use setAdmin()
308
+     * @return void
309
+     */
310
+    public static function setDebugMode(?int $admin_id = null): void
311
+    {
312
+        error_reporting(E_ALL);
313
+        ini_set('display_errors', 1);
314
+        defined('DEBUG_MODE') or define('DEBUG_MODE', true);
315
+        if ($admin_id) {
316
+            defined('TG_ADMIN_ID') or define('TG_ADMIN_ID', $admin_id);
317
+        }
318
+    }
319
+
320
+    /**
321
+     * Just another echo
322
+     *
323
+     * @param string $text
324
+     * @return void
325
+     */
326
+    public static function echo(string $text): void
327
+    {
328
+        echo $text;
329
+    }
330 330
 
331 331
 }
332 332
\ No newline at end of file
Please login to merge, or discard this patch.
Braces   +9 added lines, -3 removed lines patch added patch discarded remove patch
@@ -258,7 +258,9 @@  discard block
 block discarded – undo
258 258
 	public static function getUpdate(): Update|false
259 259
 	{
260 260
 		$input = self::getInput();
261
-		if (empty($input)) return false;
261
+		if (empty($input)) {
262
+		    return false;
263
+		}
262 264
 		return Telegram::processUpdate($input, self::getApiKey());
263 265
 	}
264 266
 
@@ -284,7 +286,9 @@  discard block
 block discarded – undo
284 286
 	public function fetchWith(WebhookHandler $webhook_handler, ?Update $update = null): void
285 287
 	{
286 288
 		if (is_subclass_of($webhook_handler, WebhookHandler::class)) {
287
-			if ($update === null) $update = self::getUpdate();
289
+			if ($update === null) {
290
+			    $update = self::getUpdate();
291
+			}
288 292
 			$webhook_handler->resolve($update);
289 293
 		}
290 294
 	}
@@ -297,7 +301,9 @@  discard block
 block discarded – undo
297 301
 	 */
298 302
 	protected function getTokenFromEnvFile(string $file): ?string
299 303
 	{
300
-		if (!file_exists($file)) return null;
304
+		if (!file_exists($file)) {
305
+		    return null;
306
+		}
301 307
 		return DotEnv::load($file)::get('TELEGRAM_API_KEY');
302 308
 	}
303 309
 
Please login to merge, or discard this patch.
src/lib/TelegramLog.php 2 patches
Indentation   +137 added lines, -137 removed lines patch added patch discarded remove patch
@@ -25,142 +25,142 @@
 block discarded – undo
25 25
 class TelegramLog
26 26
 {
27 27
 
28
-	/**
29
-	 * Logger instance
30
-	 *
31
-	 * @var LoggerInterface
32
-	 */
33
-	protected static LoggerInterface $logger;
34
-
35
-	/**
36
-	 * Logger instance for update
37
-	 *
38
-	 * @var LoggerInterface
39
-	 */
40
-	protected static LoggerInterface $update_logger;
41
-
42
-	/**
43
-	 * Always log the request and response data to the debug log, also for successful requests
44
-	 *
45
-	 * @var bool
46
-	 */
47
-	public static bool $always_log_request_and_response = false;
48
-
49
-	/**
50
-	 * Temporary stream handle for debug log
51
-	 *
52
-	 * @var resource|null
53
-	 */
54
-	protected static $debug_log_temp_stream_handle;
55
-
56
-	/**
57
-	 * Remove bot token from debug stream
58
-	 *
59
-	 * @var bool
60
-	 */
61
-	public static bool $remove_bot_token = true;
62
-
63
-	/**
64
-	 * Initialise logging.
65
-	 *
66
-	 * @param LoggerInterface|null $logger
67
-	 * @param LoggerInterface|null $update_logger
68
-	 */
69
-	public static function initialize(LoggerInterface $logger = null, LoggerInterface $update_logger = null): void
70
-	{
71
-		self::$logger = $logger ?: new NullLogger();
72
-		self::$update_logger = $update_logger ?: new NullLogger();
73
-	}
74
-
75
-	/**
76
-	 * Get the stream handle of the temporary debug output
77
-	 *
78
-	 * @return mixed The stream if debug is active, else false
79
-	 */
80
-	public static function getDebugLogTempStream(): mixed
81
-	{
82
-		if ((self::$debug_log_temp_stream_handle === null) && $temp_stream_handle = fopen('php://temp', 'wb+')) {
83
-			self::$debug_log_temp_stream_handle = $temp_stream_handle;
84
-		}
85
-
86
-		return self::$debug_log_temp_stream_handle;
87
-	}
88
-
89
-	/**
90
-	 * Write the temporary debug stream to log and close the stream handle
91
-	 *
92
-	 * @param string $message Message (with placeholder) to write to the debug log
93
-	 */
94
-	public static function endDebugLogTempStream(string $message = '%s'): void
95
-	{
96
-		if (is_resource(self::$debug_log_temp_stream_handle)) {
97
-			rewind(self::$debug_log_temp_stream_handle);
98
-			$stream_contents = stream_get_contents(self::$debug_log_temp_stream_handle);
99
-
100
-			if (self::$remove_bot_token) {
101
-				$stream_contents = preg_replace('/\/bot(\d+):[\w\-]+\//', '/botBOT_TOKEN_REMOVED/', $stream_contents);
102
-			}
103
-
104
-			self::debug(sprintf($message, $stream_contents));
105
-			fclose(self::$debug_log_temp_stream_handle);
106
-			self::$debug_log_temp_stream_handle = null;
107
-		}
108
-	}
109
-
110
-	/**
111
-	 * Handle any logging method call.
112
-	 *
113
-	 * @param string $name
114
-	 * @param array $arguments
115
-	 */
116
-	public static function __callStatic(string $name, array $arguments)
117
-	{
118
-		// Get the correct logger instance.
119
-		$logger = null;
120
-		self::initialize();
121
-		if (in_array($name, ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug',], true)) {
122
-			$logger = self::$logger;
123
-		} elseif ($name === 'update') {
124
-			$logger = self::$update_logger;
125
-			$name = 'info';
126
-		}
127
-
128
-		// Clearly we have no logging enabled.
129
-		if ($logger === null) {
130
-			return;
131
-		}
132
-
133
-		// Replace any placeholders from the passed context.
134
-		if (count($arguments) >= 2) {
135
-			$arguments[0] = self::interpolate($arguments[0], $arguments[1]);
136
-		}
137
-
138
-		call_user_func_array([$logger, $name], $arguments);
139
-	}
140
-
141
-	/**
142
-	 * Interpolates context values into the message placeholders.
143
-	 *
144
-	 * @see https://www.php-fig.org/psr/psr-3/#12-message
145
-	 *
146
-	 * @param string $message
147
-	 * @param array $context
148
-	 *
149
-	 * @return string
150
-	 */
151
-	protected static function interpolate(string $message, array $context = []): string
152
-	{
153
-		// Build a replacement array with braces around the context keys.
154
-		$replace = [];
155
-		foreach ($context as $key => $val) {
156
-			// check that the value can be cast to string
157
-			if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
158
-				$replace["{{$key}}"] = $val;
159
-			}
160
-		}
161
-
162
-		// Interpolate replacement values into the message and return.
163
-		return strtr($message, $replace);
164
-	}
28
+    /**
29
+     * Logger instance
30
+     *
31
+     * @var LoggerInterface
32
+     */
33
+    protected static LoggerInterface $logger;
34
+
35
+    /**
36
+     * Logger instance for update
37
+     *
38
+     * @var LoggerInterface
39
+     */
40
+    protected static LoggerInterface $update_logger;
41
+
42
+    /**
43
+     * Always log the request and response data to the debug log, also for successful requests
44
+     *
45
+     * @var bool
46
+     */
47
+    public static bool $always_log_request_and_response = false;
48
+
49
+    /**
50
+     * Temporary stream handle for debug log
51
+     *
52
+     * @var resource|null
53
+     */
54
+    protected static $debug_log_temp_stream_handle;
55
+
56
+    /**
57
+     * Remove bot token from debug stream
58
+     *
59
+     * @var bool
60
+     */
61
+    public static bool $remove_bot_token = true;
62
+
63
+    /**
64
+     * Initialise logging.
65
+     *
66
+     * @param LoggerInterface|null $logger
67
+     * @param LoggerInterface|null $update_logger
68
+     */
69
+    public static function initialize(LoggerInterface $logger = null, LoggerInterface $update_logger = null): void
70
+    {
71
+        self::$logger = $logger ?: new NullLogger();
72
+        self::$update_logger = $update_logger ?: new NullLogger();
73
+    }
74
+
75
+    /**
76
+     * Get the stream handle of the temporary debug output
77
+     *
78
+     * @return mixed The stream if debug is active, else false
79
+     */
80
+    public static function getDebugLogTempStream(): mixed
81
+    {
82
+        if ((self::$debug_log_temp_stream_handle === null) && $temp_stream_handle = fopen('php://temp', 'wb+')) {
83
+            self::$debug_log_temp_stream_handle = $temp_stream_handle;
84
+        }
85
+
86
+        return self::$debug_log_temp_stream_handle;
87
+    }
88
+
89
+    /**
90
+     * Write the temporary debug stream to log and close the stream handle
91
+     *
92
+     * @param string $message Message (with placeholder) to write to the debug log
93
+     */
94
+    public static function endDebugLogTempStream(string $message = '%s'): void
95
+    {
96
+        if (is_resource(self::$debug_log_temp_stream_handle)) {
97
+            rewind(self::$debug_log_temp_stream_handle);
98
+            $stream_contents = stream_get_contents(self::$debug_log_temp_stream_handle);
99
+
100
+            if (self::$remove_bot_token) {
101
+                $stream_contents = preg_replace('/\/bot(\d+):[\w\-]+\//', '/botBOT_TOKEN_REMOVED/', $stream_contents);
102
+            }
103
+
104
+            self::debug(sprintf($message, $stream_contents));
105
+            fclose(self::$debug_log_temp_stream_handle);
106
+            self::$debug_log_temp_stream_handle = null;
107
+        }
108
+    }
109
+
110
+    /**
111
+     * Handle any logging method call.
112
+     *
113
+     * @param string $name
114
+     * @param array $arguments
115
+     */
116
+    public static function __callStatic(string $name, array $arguments)
117
+    {
118
+        // Get the correct logger instance.
119
+        $logger = null;
120
+        self::initialize();
121
+        if (in_array($name, ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug',], true)) {
122
+            $logger = self::$logger;
123
+        } elseif ($name === 'update') {
124
+            $logger = self::$update_logger;
125
+            $name = 'info';
126
+        }
127
+
128
+        // Clearly we have no logging enabled.
129
+        if ($logger === null) {
130
+            return;
131
+        }
132
+
133
+        // Replace any placeholders from the passed context.
134
+        if (count($arguments) >= 2) {
135
+            $arguments[0] = self::interpolate($arguments[0], $arguments[1]);
136
+        }
137
+
138
+        call_user_func_array([$logger, $name], $arguments);
139
+    }
140
+
141
+    /**
142
+     * Interpolates context values into the message placeholders.
143
+     *
144
+     * @see https://www.php-fig.org/psr/psr-3/#12-message
145
+     *
146
+     * @param string $message
147
+     * @param array $context
148
+     *
149
+     * @return string
150
+     */
151
+    protected static function interpolate(string $message, array $context = []): string
152
+    {
153
+        // Build a replacement array with braces around the context keys.
154
+        $replace = [];
155
+        foreach ($context as $key => $val) {
156
+            // check that the value can be cast to string
157
+            if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
158
+                $replace["{{$key}}"] = $val;
159
+            }
160
+        }
161
+
162
+        // Interpolate replacement values into the message and return.
163
+        return strtr($message, $replace);
164
+    }
165 165
 
166 166
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -118,7 +118,7 @@
 block discarded – undo
118 118
 		// Get the correct logger instance.
119 119
 		$logger = null;
120 120
 		self::initialize();
121
-		if (in_array($name, ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug',], true)) {
121
+		if (in_array($name, ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug', ], true)) {
122 122
 			$logger = self::$logger;
123 123
 		} elseif ($name === 'update') {
124 124
 			$logger = self::$update_logger;
Please login to merge, or discard this patch.
src/lib/Factory.php 1 patch
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -12,26 +12,26 @@
 block discarded – undo
12 12
 abstract class Factory
13 13
 {
14 14
 
15
-	/**
16
-	 * @param array $data
17
-	 * @return Entity
18
-	 */
19
-	abstract public static function make(array $data): Entity;
15
+    /**
16
+     * @param array $data
17
+     * @return Entity
18
+     */
19
+    abstract public static function make(array $data): Entity;
20 20
 
21
-	/**
22
-	 * This method is used to create a new instance of the entity.
23
-	 *
24
-	 * @param string $class
25
-	 * @param mixed $property
26
-	 * @return Entity
27
-	 */
28
-	public static function resolveEntityClass(string $class, mixed $property): Entity
29
-	{
30
-		if (is_subclass_of($class, Factory::class)) {
31
-			return $class::make($property);
32
-		}
21
+    /**
22
+     * This method is used to create a new instance of the entity.
23
+     *
24
+     * @param string $class
25
+     * @param mixed $property
26
+     * @return Entity
27
+     */
28
+    public static function resolveEntityClass(string $class, mixed $property): Entity
29
+    {
30
+        if (is_subclass_of($class, Factory::class)) {
31
+            return $class::make($property);
32
+        }
33 33
 
34
-		return new $class($property);
35
-	}
34
+        return new $class($property);
35
+    }
36 36
 
37 37
 }
Please login to merge, or discard this patch.
src/lib/Plugin.php 2 patches
Indentation   +74 added lines, -74 removed lines patch added patch discarded remove patch
@@ -15,88 +15,88 @@
 block discarded – undo
15 15
 abstract class Plugin
16 16
 {
17 17
 
18
-	/**
19
-	 * The Update types
20
-	 *
21
-	 * @var array
22
-	 */
23
-	protected array $update_types = [
24
-		'message',
25
-		'edited_message',
26
-		'channel_post',
27
-		'edited_channel_post',
28
-		'inline_query',
29
-		'chosen_inline_result',
30
-		'callback_query',
31
-		'shipping_query',
32
-		'pre_checkout_query',
33
-	];
18
+    /**
19
+     * The Update types
20
+     *
21
+     * @var array
22
+     */
23
+    protected array $update_types = [
24
+        'message',
25
+        'edited_message',
26
+        'channel_post',
27
+        'edited_channel_post',
28
+        'inline_query',
29
+        'chosen_inline_result',
30
+        'callback_query',
31
+        'shipping_query',
32
+        'pre_checkout_query',
33
+    ];
34 34
 
35
-	/**
36
-	 * @var WebhookHandler
37
-	 */
38
-	protected WebhookHandler $hook;
35
+    /**
36
+     * @var WebhookHandler
37
+     */
38
+    protected WebhookHandler $hook;
39 39
 
40
-	/**
41
-	 * @var \Generator
42
-	 */
43
-	protected \Generator $returns;
40
+    /**
41
+     * @var \Generator
42
+     */
43
+    protected \Generator $returns;
44 44
 
45
-	/**
46
-	 * @var bool
47
-	 */
48
-	protected bool $kill_on_yield = false;
45
+    /**
46
+     * @var bool
47
+     */
48
+    protected bool $kill_on_yield = false;
49 49
 
50
-	/**
51
-	 * Execute the plugin.
52
-	 *
53
-	 * @param WebhookHandler $receiver
54
-	 * @param Update $update
55
-	 * @return void
56
-	 */
57
-	public function __execute(WebhookHandler $receiver, Update $update): void
58
-	{
59
-		$this->hook = $receiver;
50
+    /**
51
+     * Execute the plugin.
52
+     *
53
+     * @param WebhookHandler $receiver
54
+     * @param Update $update
55
+     * @return void
56
+     */
57
+    public function __execute(WebhookHandler $receiver, Update $update): void
58
+    {
59
+        $this->hook = $receiver;
60 60
 
61
-		$method = 'onReceivedUpdate';
62
-		if (method_exists($this, $method)) {
63
-			/** @var \Generator $return */
64
-			$return = $this->{$method}($update);
65
-		}
61
+        $method = 'onReceivedUpdate';
62
+        if (method_exists($this, $method)) {
63
+            /** @var \Generator $return */
64
+            $return = $this->{$method}($update);
65
+        }
66 66
 
67
-		if (isset($return) && $return instanceof \Generator) {
68
-			while ($return->valid()) {
69
-				$return->next();
70
-			}
67
+        if (isset($return) && $return instanceof \Generator) {
68
+            while ($return->valid()) {
69
+                $return->next();
70
+            }
71 71
 
72
-			if ($return->valid() && $return->getReturn()) {
73
-				if ($this->kill_on_yield) $this->kill();
74
-			}
75
-		}
76
-	}
72
+            if ($return->valid() && $return->getReturn()) {
73
+                if ($this->kill_on_yield) $this->kill();
74
+            }
75
+        }
76
+    }
77 77
 
78
-	/**
79
-	 * Identify the update type and if method of the type is exists, execute it.
80
-	 *
81
-	 * @param Update $update
82
-	 * @return \Generator
83
-	 */
84
-	protected function onReceivedUpdate(Update $update): \Generator
85
-	{
86
-		$method = UpdateTypes::identify($update);
87
-		if (method_exists($this, $method)) {
88
-			yield $this->$method($update);
89
-		}
90
-	}
78
+    /**
79
+     * Identify the update type and if method of the type is exists, execute it.
80
+     *
81
+     * @param Update $update
82
+     * @return \Generator
83
+     */
84
+    protected function onReceivedUpdate(Update $update): \Generator
85
+    {
86
+        $method = UpdateTypes::identify($update);
87
+        if (method_exists($this, $method)) {
88
+            yield $this->$method($update);
89
+        }
90
+    }
91 91
 
92
-	/**
93
-	 * Kill the plugin.
94
-	 *
95
-	 * @return void
96
-	 */
97
-	public function kill(): void
98
-	{
99
-		$this->hook->kill();
100
-	}
92
+    /**
93
+     * Kill the plugin.
94
+     *
95
+     * @return void
96
+     */
97
+    public function kill(): void
98
+    {
99
+        $this->hook->kill();
100
+    }
101 101
 
102 102
 }
103 103
\ No newline at end of file
Please login to merge, or discard this patch.
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -70,7 +70,9 @@
 block discarded – undo
70 70
 			}
71 71
 
72 72
 			if ($return->valid() && $return->getReturn()) {
73
-				if ($this->kill_on_yield) $this->kill();
73
+				if ($this->kill_on_yield) {
74
+				    $this->kill();
75
+				}
74 76
 			}
75 77
 		}
76 78
 	}
Please login to merge, or discard this patch.
src/lib/Request.php 1 patch
Indentation   +222 added lines, -222 removed lines patch added patch discarded remove patch
@@ -143,227 +143,227 @@
 block discarded – undo
143 143
 class Request
144 144
 {
145 145
 
146
-	/**
147
-	 * Available fields for InputFile helper
148
-	 *
149
-	 * This is basically the list of all fields that allow InputFile objects
150
-	 * for which input can be simplified by providing local path directly  as string.
151
-	 *
152
-	 * @var array
153
-	 */
154
-	private static array $input_file_fields = [
155
-		'setWebhook' => ['certificate'],
156
-		'sendPhoto' => ['photo'],
157
-		'sendAudio' => ['audio', 'thumb'],
158
-		'sendDocument' => ['document', 'thumb'],
159
-		'sendVideo' => ['video', 'thumb'],
160
-		'sendAnimation' => ['animation', 'thumb'],
161
-		'sendVoice' => ['voice', 'thumb'],
162
-		'sendVideoNote' => ['video_note', 'thumb'],
163
-		'setChatPhoto' => ['photo'],
164
-		'sendSticker' => ['sticker'],
165
-		'uploadStickerFile' => ['png_sticker'],
166
-		'createNewStickerSet' => ['png_sticker', 'tgs_sticker', 'webm_sticker'],
167
-		'addStickerToSet' => ['png_sticker', 'tgs_sticker', 'webm_sticker'],
168
-		'setStickerSetThumb' => ['thumb'],
169
-	];
170
-
171
-	/**
172
-	 * URI of the Telegram API
173
-	 *
174
-	 * @var string
175
-	 */
176
-	private static string $api_base_uri = 'https://api.telegram.org';
177
-
178
-	/**
179
-	 * URI of the Telegram API for downloading files (relative to $api_base_url or absolute)
180
-	 *
181
-	 * @var string
182
-	 */
183
-	private static string $api_base_download_uri = '/file/bot{API_KEY}';
184
-
185
-	/**
186
-	 * The current action that is being executed
187
-	 *
188
-	 * @var string
189
-	 */
190
-	private static string $current_action = '';
191
-
192
-	/**
193
-	 * Get the Telegram API path
194
-	 *
195
-	 * @return string
196
-	 */
197
-	public static function getApiPath(): string
198
-	{
199
-		return self::$api_base_uri . '/bot' . Telegram::getApiKey() . '/';
200
-	}
201
-
202
-	/**
203
-	 * Initialize a http client
204
-	 *
205
-	 * @return Client
206
-	 */
207
-	private static function getClient(): Client
208
-	{
209
-		return new Client();
210
-	}
211
-
212
-	/**
213
-	 * Use this method to get stats of given user in a supergroup or channel.
214
-	 *
215
-	 * @param int $user_id User identifier
216
-	 * @param int $chat_id Identifier of the chat to get stats for
217
-	 *
218
-	 * @return string [left, member, administrator, creator]
219
-	 */
220
-	public static function getChatMemberStatus(int $user_id, int $chat_id): string
221
-	{
222
-		$response = self::getChatMember([
223
-			'user_id' => $user_id,
224
-			'chat_id' => $chat_id,
225
-		]);
226
-
227
-		return $response->getResult()->status ?? "left";
228
-	}
229
-
230
-	/**
231
-	 * Properly set up the request params
232
-	 *
233
-	 * If any item of the array is a resource, reformat it to a multipart request.
234
-	 * Else, just return the passed data as form params.
235
-	 *
236
-	 * @param array $data
237
-	 * @return array
238
-	 */
239
-	private static function setUpRequestParams(array $data): array
240
-	{
241
-		$multipart = [];
242
-		$has_resource = false;
243
-
244
-		$options = [
245
-			'header' => [
246
-				'Content-Type' => 'application/json',
247
-				'Accept' => 'application/json',
248
-				'User-Agent' => 'TelegramBot-PHP/' . Telegram::$VERSION
249
-			]
250
-		];
251
-
252
-		foreach ($data as $key => &$item) {
253
-			if (array_key_exists(self::$current_action, self::$input_file_fields) && in_array($key, self::$input_file_fields[self::$current_action], true)) {
254
-
255
-				if (is_string($item) && file_exists($item)) {
256
-					$has_resource = true;
257
-
258
-				} elseif (filter_var($item, FILTER_VALIDATE_URL)) {
259
-					$has_resource = false;
260
-					continue;
261
-
262
-				} else {
263
-					throw new TelegramException(
264
-						'Invalid file path or URL: ' . $item . ' for ' . self::$current_action . ' action'
265
-					);
266
-				}
267
-
268
-				$multipart[$key] = $item;
269
-				continue;
270
-			}
271
-
272
-			if ($item instanceof Entity) {
273
-				$item = $item->getRawData();
274
-			}
275
-
276
-			if (is_array($item)) {
277
-				$item = json_encode($item);
278
-			}
279
-
280
-			$options['query'][$key] = $item;
281
-		}
282
-		unset($item);
283
-
284
-		if ($has_resource) {
285
-			$options['multipart'] = FormData::create($multipart);
286
-		}
287
-
288
-		return $options;
289
-	}
290
-
291
-	/**
292
-	 * Create a Http Request
293
-	 *
294
-	 * @param string $action Action to execute
295
-	 * @param array $data Data to attach to the execution
296
-	 *
297
-	 * @return array An array of the setUpRequestParams and the url
298
-	 */
299
-	public static function create(string $action, array $data): array
300
-	{
301
-		return [
302
-			'url' => self::getApiPath() . $action,
303
-			'options' => self::setUpRequestParams($data)
304
-		];
305
-	}
306
-
307
-	/**
308
-	 * Execute HTTP Request
309
-	 *
310
-	 * @param string $action Action to execute
311
-	 * @param array $data Data to attach to the execution
312
-	 *
313
-	 * @return string Result of the HTTP Request
314
-	 */
315
-	private static function execute(string $action, array $data): string
316
-	{
317
-		$request = self::create($action, $data);
318
-
319
-		$response = self::getClient()->get($request['url'], $request['options']);
320
-
321
-		return $response->getBody();
322
-	}
323
-
324
-	/**
325
-	 * Send command
326
-	 *
327
-	 * @param string $action
328
-	 * @param array $data
329
-	 *
330
-	 * @return Response
331
-	 * @throws TelegramException
332
-	 */
333
-	public static function send(string $action, array $data = []): Response
334
-	{
335
-		self::$current_action = $action;
336
-
337
-		$raw_response = self::execute($action, $data);
338
-
339
-		if (!Common::isJson($raw_response)) {
340
-			TelegramLog::debug($raw_response);
341
-			throw new TelegramException('Invalid response from API');
342
-		}
343
-
344
-		$response = new Response(json_decode($raw_response, true));
345
-
346
-		if (!$response->isOk() && $response->getErrorCode() === 401 && $response->getDescription() === 'Unauthorized') {
347
-			throw new InvalidBotTokenException();
348
-		}
349
-
350
-		self::$current_action = '';
351
-
352
-		return $response;
353
-	}
354
-
355
-	/**
356
-	 * Any statically called method should be relayed to the `send` method.
357
-	 *
358
-	 * @param string $action
359
-	 * @param array $data
360
-	 *
361
-	 * @return Response
362
-	 * @throws TelegramException
363
-	 */
364
-	public static function __callStatic(string $action, array $data): Response
365
-	{
366
-		return static::send($action, reset($data) ?: []);
367
-	}
146
+    /**
147
+     * Available fields for InputFile helper
148
+     *
149
+     * This is basically the list of all fields that allow InputFile objects
150
+     * for which input can be simplified by providing local path directly  as string.
151
+     *
152
+     * @var array
153
+     */
154
+    private static array $input_file_fields = [
155
+        'setWebhook' => ['certificate'],
156
+        'sendPhoto' => ['photo'],
157
+        'sendAudio' => ['audio', 'thumb'],
158
+        'sendDocument' => ['document', 'thumb'],
159
+        'sendVideo' => ['video', 'thumb'],
160
+        'sendAnimation' => ['animation', 'thumb'],
161
+        'sendVoice' => ['voice', 'thumb'],
162
+        'sendVideoNote' => ['video_note', 'thumb'],
163
+        'setChatPhoto' => ['photo'],
164
+        'sendSticker' => ['sticker'],
165
+        'uploadStickerFile' => ['png_sticker'],
166
+        'createNewStickerSet' => ['png_sticker', 'tgs_sticker', 'webm_sticker'],
167
+        'addStickerToSet' => ['png_sticker', 'tgs_sticker', 'webm_sticker'],
168
+        'setStickerSetThumb' => ['thumb'],
169
+    ];
170
+
171
+    /**
172
+     * URI of the Telegram API
173
+     *
174
+     * @var string
175
+     */
176
+    private static string $api_base_uri = 'https://api.telegram.org';
177
+
178
+    /**
179
+     * URI of the Telegram API for downloading files (relative to $api_base_url or absolute)
180
+     *
181
+     * @var string
182
+     */
183
+    private static string $api_base_download_uri = '/file/bot{API_KEY}';
184
+
185
+    /**
186
+     * The current action that is being executed
187
+     *
188
+     * @var string
189
+     */
190
+    private static string $current_action = '';
191
+
192
+    /**
193
+     * Get the Telegram API path
194
+     *
195
+     * @return string
196
+     */
197
+    public static function getApiPath(): string
198
+    {
199
+        return self::$api_base_uri . '/bot' . Telegram::getApiKey() . '/';
200
+    }
201
+
202
+    /**
203
+     * Initialize a http client
204
+     *
205
+     * @return Client
206
+     */
207
+    private static function getClient(): Client
208
+    {
209
+        return new Client();
210
+    }
211
+
212
+    /**
213
+     * Use this method to get stats of given user in a supergroup or channel.
214
+     *
215
+     * @param int $user_id User identifier
216
+     * @param int $chat_id Identifier of the chat to get stats for
217
+     *
218
+     * @return string [left, member, administrator, creator]
219
+     */
220
+    public static function getChatMemberStatus(int $user_id, int $chat_id): string
221
+    {
222
+        $response = self::getChatMember([
223
+            'user_id' => $user_id,
224
+            'chat_id' => $chat_id,
225
+        ]);
226
+
227
+        return $response->getResult()->status ?? "left";
228
+    }
229
+
230
+    /**
231
+     * Properly set up the request params
232
+     *
233
+     * If any item of the array is a resource, reformat it to a multipart request.
234
+     * Else, just return the passed data as form params.
235
+     *
236
+     * @param array $data
237
+     * @return array
238
+     */
239
+    private static function setUpRequestParams(array $data): array
240
+    {
241
+        $multipart = [];
242
+        $has_resource = false;
243
+
244
+        $options = [
245
+            'header' => [
246
+                'Content-Type' => 'application/json',
247
+                'Accept' => 'application/json',
248
+                'User-Agent' => 'TelegramBot-PHP/' . Telegram::$VERSION
249
+            ]
250
+        ];
251
+
252
+        foreach ($data as $key => &$item) {
253
+            if (array_key_exists(self::$current_action, self::$input_file_fields) && in_array($key, self::$input_file_fields[self::$current_action], true)) {
254
+
255
+                if (is_string($item) && file_exists($item)) {
256
+                    $has_resource = true;
257
+
258
+                } elseif (filter_var($item, FILTER_VALIDATE_URL)) {
259
+                    $has_resource = false;
260
+                    continue;
261
+
262
+                } else {
263
+                    throw new TelegramException(
264
+                        'Invalid file path or URL: ' . $item . ' for ' . self::$current_action . ' action'
265
+                    );
266
+                }
267
+
268
+                $multipart[$key] = $item;
269
+                continue;
270
+            }
271
+
272
+            if ($item instanceof Entity) {
273
+                $item = $item->getRawData();
274
+            }
275
+
276
+            if (is_array($item)) {
277
+                $item = json_encode($item);
278
+            }
279
+
280
+            $options['query'][$key] = $item;
281
+        }
282
+        unset($item);
283
+
284
+        if ($has_resource) {
285
+            $options['multipart'] = FormData::create($multipart);
286
+        }
287
+
288
+        return $options;
289
+    }
290
+
291
+    /**
292
+     * Create a Http Request
293
+     *
294
+     * @param string $action Action to execute
295
+     * @param array $data Data to attach to the execution
296
+     *
297
+     * @return array An array of the setUpRequestParams and the url
298
+     */
299
+    public static function create(string $action, array $data): array
300
+    {
301
+        return [
302
+            'url' => self::getApiPath() . $action,
303
+            'options' => self::setUpRequestParams($data)
304
+        ];
305
+    }
306
+
307
+    /**
308
+     * Execute HTTP Request
309
+     *
310
+     * @param string $action Action to execute
311
+     * @param array $data Data to attach to the execution
312
+     *
313
+     * @return string Result of the HTTP Request
314
+     */
315
+    private static function execute(string $action, array $data): string
316
+    {
317
+        $request = self::create($action, $data);
318
+
319
+        $response = self::getClient()->get($request['url'], $request['options']);
320
+
321
+        return $response->getBody();
322
+    }
323
+
324
+    /**
325
+     * Send command
326
+     *
327
+     * @param string $action
328
+     * @param array $data
329
+     *
330
+     * @return Response
331
+     * @throws TelegramException
332
+     */
333
+    public static function send(string $action, array $data = []): Response
334
+    {
335
+        self::$current_action = $action;
336
+
337
+        $raw_response = self::execute($action, $data);
338
+
339
+        if (!Common::isJson($raw_response)) {
340
+            TelegramLog::debug($raw_response);
341
+            throw new TelegramException('Invalid response from API');
342
+        }
343
+
344
+        $response = new Response(json_decode($raw_response, true));
345
+
346
+        if (!$response->isOk() && $response->getErrorCode() === 401 && $response->getDescription() === 'Unauthorized') {
347
+            throw new InvalidBotTokenException();
348
+        }
349
+
350
+        self::$current_action = '';
351
+
352
+        return $response;
353
+    }
354
+
355
+    /**
356
+     * Any statically called method should be relayed to the `send` method.
357
+     *
358
+     * @param string $action
359
+     * @param array $data
360
+     *
361
+     * @return Response
362
+     * @throws TelegramException
363
+     */
364
+    public static function __callStatic(string $action, array $data): Response
365
+    {
366
+        return static::send($action, reset($data) ?: []);
367
+    }
368 368
 
369 369
 }
Please login to merge, or discard this patch.