Completed
Pull Request — master (#51)
by Rick
02:01
created
src/RequestHandlerInterface.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -10,28 +10,28 @@
 block discarded – undo
10 10
 
11 11
 interface RequestHandlerInterface
12 12
 {
13
-	/**
14
-	 * This is the method that actually makes the call, which can be easily overwritten so that our unit tests can work
15
-	 *
16
-	 * @param string $uri
17
-	 * @param array $formData
18
-	 *
19
-	 * @return TelegramRawData
20
-	 */
21
-	public function request(string $uri, array $formData): TelegramRawData;
13
+ /**
14
+  * This is the method that actually makes the call, which can be easily overwritten so that our unit tests can work
15
+  *
16
+  * @param string $uri
17
+  * @param array $formData
18
+  *
19
+  * @return TelegramRawData
20
+  */
21
+ public function request(string $uri, array $formData): TelegramRawData;
22 22
 
23
-	/**
24
-	 * @param string $uri
25
-	 *
26
-	 * @return ResponseInterface
27
-	 */
28
-	public function get(string $uri): ResponseInterface;
23
+ /**
24
+  * @param string $uri
25
+  *
26
+  * @return ResponseInterface
27
+  */
28
+ public function get(string $uri): ResponseInterface;
29 29
 
30
-	/**
31
-	 * @param string $uri
32
-	 * @param array $formData
33
-	 * 
34
-	 * @return PromiseInterface
35
-	 */
36
-	public function requestAsync(string $uri, array $formData): PromiseInterface;
30
+ /**
31
+  * @param string $uri
32
+  * @param array $formData
33
+  * 
34
+  * @return PromiseInterface
35
+  */
36
+ public function requestAsync(string $uri, array $formData): PromiseInterface;
37 37
 }
38 38
\ No newline at end of file
Please login to merge, or discard this patch.
src/TgLog.php 3 patches
Indentation   +357 added lines, -357 removed lines patch added patch discarded remove patch
@@ -25,361 +25,361 @@
 block discarded – undo
25 25
  */
26 26
 class TgLog
27 27
 {
28
-	/**
29
-	 * @var RequestHandlerInterface
30
-	 */
31
-	protected $requestHandler;
32
-
33
-	/**
34
-	 * Stores the token
35
-	 * @var string
36
-	 */
37
-	private $botToken;
38
-
39
-	/**
40
-	 * Contains an instance to a PSR-3 compatible logger
41
-	 * @var LoggerInterface
42
-	 */
43
-	protected $logger;
44
-
45
-	/**
46
-	 * Stores the API URL from Telegram
47
-	 * @var string
48
-	 */
49
-	private $apiUrl = '';
50
-
51
-	/**
52
-	 * With this flag we'll know what type of request to send to Telegram
53
-	 *
54
-	 * 'application/x-www-form-urlencoded' is the "normal" one, which is simpler and quicker.
55
-	 * 'multipart/form-data' should be used only when you upload documents, photos, etc.
56
-	 *
57
-	 * @var string
58
-	 */
59
-	private $formType = 'application/x-www-form-urlencoded';
60
-
61
-	/**
62
-	 * Stores the last method name used
63
-	 * @var string
64
-	 */
65
-	protected $methodName = '';
66
-
67
-	/**
68
-	 * TelegramLog constructor.
69
-	 *
70
-	 * @param string $botToken
71
-	 * @param LoggerInterface $logger
72
-	 * @param RequestHandlerInterface $handler
73
-	 */
74
-	public function __construct(string $botToken, LoggerInterface $logger = null, RequestHandlerInterface $handler = null)
75
-	{
76
-		$this->botToken = $botToken;
77
-
78
-		// Initialize new dummy logger (PSR-3 compatible) if not injected
79
-		if ($logger === null) {
80
-			$logger = new DummyLogger();
81
-		}
82
-		$this->logger = $logger;
83
-
84
-		// Initialize new Guzzle client if not injected
85
-		if ($handler === null) {
86
-			$handler = new GuzzleRequestHandler(null, $logger);
87
-		}
88
-		$this->requestHandler = $handler;
89
-
90
-		$this->constructApiUrl();
91
-	}
92
-
93
-	/**
94
-	 * Prepares and sends an API request to Telegram
95
-	 *
96
-	 * @param TelegramMethods $method
97
-	 * @return TelegramTypes
98
-	 * @throws \unreal4u\TelegramAPI\Exceptions\MissingMandatoryField
99
-	 */
100
-	public function performApiRequest(TelegramMethods $method): TelegramTypes
101
-	{
102
-		$this->logger->debug('Request for API call, resetting internal values', [get_class($method)]);
103
-		$this->resetObjectValues();
104
-		$telegramRawData = $this->sendRequestToTelegram($method, $this->constructFormData($method));
105
-		if ($telegramRawData->isError()) {
106
-			$this->handleOffErrorRequest($telegramRawData);
107
-		}
108
-
109
-		return $method::bindToObject($telegramRawData, $this->logger);
110
-	}
111
-
112
-	/**
113
-	 * @param TelegramMethods $method
114
-	 *
115
-	 * @return PromiseInterface
116
-	 */
117
-	public function performAsyncApiRequest(TelegramMethods $method)
118
-	{
119
-		$this->logger->debug('Request for async API call, resetting internal values', [get_class($method)]);
120
-		$this->resetObjectValues();
121
-		return $this->sendAsyncRequestToTelegram($method, $this->constructFormData($method));
122
-	}
123
-
124
-	/**
125
-	 * Will download a file from the Telegram server. Before calling this function, you have to call the getFile method!
126
-	 *
127
-	 * @see \unreal4u\TelegramAPI\Telegram\Types\File
128
-	 * @see \unreal4u\TelegramAPI\Telegram\Methods\GetFile
129
-	 *
130
-	 * @param File $file
131
-	 * @return TelegramDocument
132
-	 */
133
-	public function downloadFile(File $file): TelegramDocument
134
-	{
135
-		$this->logger->debug('Downloading file from Telegram, creating URL');
136
-		$url = 'https://api.telegram.org/file/bot' . $this->botToken . '/' . $file->file_path;
137
-		$this->logger->debug('About to perform request to begin downloading file');
138
-		return new TelegramDocument($this->requestHandler->get($url));
139
-	}
140
-
141
-	/**
142
-	 * @param File $file
143
-	 *
144
-	 * @return PromiseInterface
145
-	 */
146
-	public function downloadFileAsync(File $file): PromiseInterface
147
-	{
148
-		$this->logger->debug('Downloading file async from Telegram, creating URL');
149
-		$url = 'https://api.telegram.org/file/bot' . $this->botToken . '/' . $file->file_path;
150
-		$this->logger->debug('About to perform request to begin downloading file');
151
-
152
-		$deferred = new Promise();
153
-
154
-		return $this->requestHandler->requestAsync($url)->then(function (ResponseInterface $response) use ($deferred)
155
-		{
156
-			$deferred->resolve(new TelegramDocument($response));
157
-		},
158
-			function (RequestException $exception) use ($deferred)
159
-			{
160
-				if (!empty($exception->getResponse()->getBody()))
161
-					$deferred->resolve(new TelegramDocument($exception->getResponse()));
162
-				else
163
-					$deferred->reject($exception);
164
-			});
165
-	}
166
-
167
-	/**
168
-	 * Builds up the Telegram API url
169
-	 * @return TgLog
170
-	 */
171
-	final private function constructApiUrl(): TgLog
172
-	{
173
-		$this->apiUrl = 'https://api.telegram.org/bot' . $this->botToken . '/';
174
-		$this->logger->debug('Built up the API URL');
175
-		return $this;
176
-	}
177
-
178
-	/**
179
-	 * This is the method that actually makes the call, which can be easily overwritten so that our unit tests can work
180
-	 *
181
-	 * @param TelegramMethods $method
182
-	 * @param array $formData
183
-	 * @return TelegramRawData
184
-	 */
185
-	protected function sendRequestToTelegram(TelegramMethods $method, array $formData): TelegramRawData
186
-	{
187
-		$e = null;
188
-		$this->logger->debug('About to perform HTTP call to Telegram\'s API');
189
-		try {
190
-			/** @noinspection PhpMethodParametersCountMismatchInspection */
191
-			$response = $this->requestHandler->request($this->composeApiMethodUrl($method), $formData);
192
-			$this->logger->debug('Got response back from Telegram, applying json_decode');
193
-		} catch (ClientException $e) {
194
-			$response = $e->getResponse();
195
-			// It can happen that we have a network problem, in such case, we can't do nothing about it, so rethrow
196
-			if (empty($response)) {
197
-				throw $e;
198
-			}
199
-		} finally {
200
-			return new TelegramRawData((string)$response->getBody(), $e);
201
-		}
202
-	}
203
-
204
-	/**
205
-	 * @param TelegramMethods $method
206
-	 * @param array $formData
207
-	 *
208
-	 * @return PromiseInterface
209
-	 */
210
-	protected function sendAsyncRequestToTelegram(TelegramMethods $method, array $formData): PromiseInterface
211
-	{
212
-		$this->logger->debug('About to perform async HTTP call to Telegram\'s API');
213
-		$deferred = new Promise();
214
-
215
-		$promise = $this->requestHandler->requestAsync($this->composeApiMethodUrl($method), $formData);
216
-		$promise->then(function (ResponseInterface $response) use ($deferred)
217
-		{
218
-			$deferred->resolve(new TelegramRawData((string) $response->getBody()));
219
-		},
220
-			function (RequestException $exception) use ($deferred)
221
-			{
222
-				if (!empty($exception->getResponse()->getBody()))
223
-					$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
224
-				else
225
-					$deferred->reject($exception);
226
-			});
227
-
228
-		return $deferred;
229
-	}
230
-
231
-	/**
232
-	 * Resets everything to the default values
233
-	 *
234
-	 * @return TgLog
235
-	 */
236
-	private function resetObjectValues(): TgLog
237
-	{
238
-		$this->formType = 'application/x-www-form-urlencoded';
239
-		$this->methodName = '';
240
-
241
-		return $this;
242
-	}
243
-
244
-	/**
245
-	 * Builds up the form elements to be sent to Telegram
246
-	 *
247
-	 * @TODO Move this to apart function
248
-	 *
249
-	 * @param TelegramMethods $method
250
-	 * @return array
251
-	 * @throws \unreal4u\TelegramAPI\Exceptions\MissingMandatoryField
252
-	 */
253
-	private function constructFormData(TelegramMethods $method): array
254
-	{
255
-		$result = $this->checkSpecialConditions($method);
256
-
257
-		switch ($this->formType) {
258
-			case 'application/x-www-form-urlencoded':
259
-				$this->logger->debug('Creating x-www-form-urlencoded form (AKA fast request)');
260
-				$formData = [
261
-					'form_params' => $method->export(),
262
-				];
263
-				break;
264
-			case 'multipart/form-data':
265
-				$formData = $this->buildMultipartFormData($method->export(), $result['id'], $result['stream']);
266
-				break;
267
-			default:
268
-				$this->logger->critical(sprintf(
269
-					'Invalid form-type detected, if you incur in such a situation, this is most likely a product to '.
270
-					'a bug. Please copy entire line and report at %s',
271
-					'https://github.com/unreal4u/telegram-api/issues'
272
-				), [
273
-					'formType' => $this->formType
274
-				]);
275
-				$formData = [];
276
-				break;
277
-		}
278
-		$this->logger->debug('About to send following data', $formData);
279
-
280
-		return $formData;
281
-	}
282
-
283
-	/**
284
-	 * Can perform any special checks needed to be performed before sending the actual request to Telegram
285
-	 *
286
-	 * This will return an array with data that will be different in each case (for now). This can be changed in the
287
-	 * future.
288
-	 *
289
-	 * @param TelegramMethods $method
290
-	 * @return array
291
-	 */
292
-	private function checkSpecialConditions(TelegramMethods $method): array
293
-	{
294
-		$this->logger->debug('Checking whether to apply special conditions to this request');
295
-		$method->performSpecialConditions();
296
-
297
-		$return = [false];
298
-
299
-		foreach ($method as $key => $value) {
300
-			if (is_object($value) && $value instanceof InputFile) {
301
-				$this->logger->debug('About to send a file, so changing request to use multi-part instead');
302
-				// If we are about to send a file, we must use the multipart/form-data way
303
-				$this->formType = 'multipart/form-data';
304
-				$return = [
305
-					'id' => $key,
306
-					'stream' => $value->getStream(),
307
-				];
308
-			}
309
-		}
310
-
311
-		return $return;
312
-	}
313
-
314
-	/**
315
-	 * Builds up the URL with which we can work with
316
-	 *
317
-	 * All methods in the Bot API are case-insensitive.
318
-	 * All queries must be made using UTF-8.
319
-	 *
320
-	 * @see https://core.telegram.org/bots/api#making-requests
321
-	 *
322
-	 * @param TelegramMethods $call
323
-	 * @return string
324
-	 */
325
-	protected function composeApiMethodUrl(TelegramMethods $call): string
326
-	{
327
-		$completeClassName = get_class($call);
328
-		$this->methodName = substr($completeClassName, strrpos($completeClassName, '\\') + 1);
329
-		$this->logger->info('About to perform API request', ['method' => $this->methodName]);
330
-
331
-		return $this->apiUrl . $this->methodName;
332
-	}
333
-
334
-	/**
335
-	 * Builds up a multipart form-like array for Guzzle
336
-	 *
337
-	 * @param array $data The original object in array form
338
-	 * @param string $fileKeyName A file handler will be sent instead of a string, state here which field it is
339
-	 * @param resource $stream The actual file handler
340
-	 * @return array Returns the actual formdata to be sent
341
-	 */
342
-	private function buildMultipartFormData(array $data, string $fileKeyName, $stream): array
343
-	{
344
-		$this->logger->debug('Creating multi-part form array data (complex and expensive)');
345
-		$formData = [
346
-			'multipart' => [],
347
-		];
348
-
349
-		foreach ($data as $id => $value) {
350
-			// Always send as a string unless it's a file
351
-			$multiPart = [
352
-				'name' => $id,
353
-				'contents' => null,
354
-			];
355
-
356
-			if ($id === $fileKeyName) {
357
-				$multiPart['contents'] = $stream;
358
-			} else {
359
-				$multiPart['contents'] = (string)$value;
360
-			}
361
-
362
-			$formData['multipart'][] = $multiPart;
363
-		}
364
-
365
-		return $formData;
366
-	}
367
-
368
-	/**
369
-	 * @param TelegramRawData $telegramRawData
370
-	 * @return TgLog
371
-	 * @throws CustomClientException
372
-	 */
373
-	private function handleOffErrorRequest(TelegramRawData $telegramRawData): TgLog
374
-	{
375
-		$errorRequest = new UnsuccessfulRequest($telegramRawData->getErrorData(), $this->logger);
376
-
377
-		$clientException = new CustomClientException(
378
-			$errorRequest->description,
379
-			$errorRequest->error_code,
380
-			$telegramRawData->getException()
381
-		);
382
-		$clientException->setParameters($errorRequest->parameters);
383
-		throw $clientException;
384
-	}
28
+ /**
29
+  * @var RequestHandlerInterface
30
+  */
31
+ protected $requestHandler;
32
+
33
+ /**
34
+  * Stores the token
35
+  * @var string
36
+  */
37
+ private $botToken;
38
+
39
+ /**
40
+  * Contains an instance to a PSR-3 compatible logger
41
+  * @var LoggerInterface
42
+  */
43
+ protected $logger;
44
+
45
+ /**
46
+  * Stores the API URL from Telegram
47
+  * @var string
48
+  */
49
+ private $apiUrl = '';
50
+
51
+ /**
52
+  * With this flag we'll know what type of request to send to Telegram
53
+  *
54
+  * 'application/x-www-form-urlencoded' is the "normal" one, which is simpler and quicker.
55
+  * 'multipart/form-data' should be used only when you upload documents, photos, etc.
56
+  *
57
+  * @var string
58
+  */
59
+ private $formType = 'application/x-www-form-urlencoded';
60
+
61
+ /**
62
+  * Stores the last method name used
63
+  * @var string
64
+  */
65
+ protected $methodName = '';
66
+
67
+ /**
68
+  * TelegramLog constructor.
69
+  *
70
+  * @param string $botToken
71
+  * @param LoggerInterface $logger
72
+  * @param RequestHandlerInterface $handler
73
+  */
74
+ public function __construct(string $botToken, LoggerInterface $logger = null, RequestHandlerInterface $handler = null)
75
+ {
76
+  $this->botToken = $botToken;
77
+
78
+  // Initialize new dummy logger (PSR-3 compatible) if not injected
79
+  if ($logger === null) {
80
+   $logger = new DummyLogger();
81
+  }
82
+  $this->logger = $logger;
83
+
84
+  // Initialize new Guzzle client if not injected
85
+  if ($handler === null) {
86
+   $handler = new GuzzleRequestHandler(null, $logger);
87
+  }
88
+  $this->requestHandler = $handler;
89
+
90
+  $this->constructApiUrl();
91
+ }
92
+
93
+ /**
94
+  * Prepares and sends an API request to Telegram
95
+  *
96
+  * @param TelegramMethods $method
97
+  * @return TelegramTypes
98
+  * @throws \unreal4u\TelegramAPI\Exceptions\MissingMandatoryField
99
+  */
100
+ public function performApiRequest(TelegramMethods $method): TelegramTypes
101
+ {
102
+  $this->logger->debug('Request for API call, resetting internal values', [get_class($method)]);
103
+  $this->resetObjectValues();
104
+  $telegramRawData = $this->sendRequestToTelegram($method, $this->constructFormData($method));
105
+  if ($telegramRawData->isError()) {
106
+   $this->handleOffErrorRequest($telegramRawData);
107
+  }
108
+
109
+  return $method::bindToObject($telegramRawData, $this->logger);
110
+ }
111
+
112
+ /**
113
+  * @param TelegramMethods $method
114
+  *
115
+  * @return PromiseInterface
116
+  */
117
+ public function performAsyncApiRequest(TelegramMethods $method)
118
+ {
119
+  $this->logger->debug('Request for async API call, resetting internal values', [get_class($method)]);
120
+  $this->resetObjectValues();
121
+  return $this->sendAsyncRequestToTelegram($method, $this->constructFormData($method));
122
+ }
123
+
124
+ /**
125
+  * Will download a file from the Telegram server. Before calling this function, you have to call the getFile method!
126
+  *
127
+  * @see \unreal4u\TelegramAPI\Telegram\Types\File
128
+  * @see \unreal4u\TelegramAPI\Telegram\Methods\GetFile
129
+  *
130
+  * @param File $file
131
+  * @return TelegramDocument
132
+  */
133
+ public function downloadFile(File $file): TelegramDocument
134
+ {
135
+  $this->logger->debug('Downloading file from Telegram, creating URL');
136
+  $url = 'https://api.telegram.org/file/bot' . $this->botToken . '/' . $file->file_path;
137
+  $this->logger->debug('About to perform request to begin downloading file');
138
+  return new TelegramDocument($this->requestHandler->get($url));
139
+ }
140
+
141
+ /**
142
+  * @param File $file
143
+  *
144
+  * @return PromiseInterface
145
+  */
146
+ public function downloadFileAsync(File $file): PromiseInterface
147
+ {
148
+  $this->logger->debug('Downloading file async from Telegram, creating URL');
149
+  $url = 'https://api.telegram.org/file/bot' . $this->botToken . '/' . $file->file_path;
150
+  $this->logger->debug('About to perform request to begin downloading file');
151
+
152
+  $deferred = new Promise();
153
+
154
+  return $this->requestHandler->requestAsync($url)->then(function (ResponseInterface $response) use ($deferred)
155
+  {
156
+   $deferred->resolve(new TelegramDocument($response));
157
+  },
158
+   function (RequestException $exception) use ($deferred)
159
+   {
160
+    if (!empty($exception->getResponse()->getBody()))
161
+     $deferred->resolve(new TelegramDocument($exception->getResponse()));
162
+    else
163
+     $deferred->reject($exception);
164
+   });
165
+ }
166
+
167
+ /**
168
+  * Builds up the Telegram API url
169
+  * @return TgLog
170
+  */
171
+ final private function constructApiUrl(): TgLog
172
+ {
173
+  $this->apiUrl = 'https://api.telegram.org/bot' . $this->botToken . '/';
174
+  $this->logger->debug('Built up the API URL');
175
+  return $this;
176
+ }
177
+
178
+ /**
179
+  * This is the method that actually makes the call, which can be easily overwritten so that our unit tests can work
180
+  *
181
+  * @param TelegramMethods $method
182
+  * @param array $formData
183
+  * @return TelegramRawData
184
+  */
185
+ protected function sendRequestToTelegram(TelegramMethods $method, array $formData): TelegramRawData
186
+ {
187
+  $e = null;
188
+  $this->logger->debug('About to perform HTTP call to Telegram\'s API');
189
+  try {
190
+   /** @noinspection PhpMethodParametersCountMismatchInspection */
191
+   $response = $this->requestHandler->request($this->composeApiMethodUrl($method), $formData);
192
+   $this->logger->debug('Got response back from Telegram, applying json_decode');
193
+  } catch (ClientException $e) {
194
+   $response = $e->getResponse();
195
+   // It can happen that we have a network problem, in such case, we can't do nothing about it, so rethrow
196
+   if (empty($response)) {
197
+    throw $e;
198
+   }
199
+  } finally {
200
+   return new TelegramRawData((string)$response->getBody(), $e);
201
+  }
202
+ }
203
+
204
+ /**
205
+  * @param TelegramMethods $method
206
+  * @param array $formData
207
+  *
208
+  * @return PromiseInterface
209
+  */
210
+ protected function sendAsyncRequestToTelegram(TelegramMethods $method, array $formData): PromiseInterface
211
+ {
212
+  $this->logger->debug('About to perform async HTTP call to Telegram\'s API');
213
+  $deferred = new Promise();
214
+
215
+  $promise = $this->requestHandler->requestAsync($this->composeApiMethodUrl($method), $formData);
216
+  $promise->then(function (ResponseInterface $response) use ($deferred)
217
+  {
218
+   $deferred->resolve(new TelegramRawData((string) $response->getBody()));
219
+  },
220
+   function (RequestException $exception) use ($deferred)
221
+   {
222
+    if (!empty($exception->getResponse()->getBody()))
223
+     $deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
224
+    else
225
+     $deferred->reject($exception);
226
+   });
227
+
228
+  return $deferred;
229
+ }
230
+
231
+ /**
232
+  * Resets everything to the default values
233
+  *
234
+  * @return TgLog
235
+  */
236
+ private function resetObjectValues(): TgLog
237
+ {
238
+  $this->formType = 'application/x-www-form-urlencoded';
239
+  $this->methodName = '';
240
+
241
+  return $this;
242
+ }
243
+
244
+ /**
245
+  * Builds up the form elements to be sent to Telegram
246
+  *
247
+  * @TODO Move this to apart function
248
+  *
249
+  * @param TelegramMethods $method
250
+  * @return array
251
+  * @throws \unreal4u\TelegramAPI\Exceptions\MissingMandatoryField
252
+  */
253
+ private function constructFormData(TelegramMethods $method): array
254
+ {
255
+  $result = $this->checkSpecialConditions($method);
256
+
257
+  switch ($this->formType) {
258
+   case 'application/x-www-form-urlencoded':
259
+    $this->logger->debug('Creating x-www-form-urlencoded form (AKA fast request)');
260
+    $formData = [
261
+     'form_params' => $method->export(),
262
+    ];
263
+    break;
264
+   case 'multipart/form-data':
265
+    $formData = $this->buildMultipartFormData($method->export(), $result['id'], $result['stream']);
266
+    break;
267
+   default:
268
+    $this->logger->critical(sprintf(
269
+     'Invalid form-type detected, if you incur in such a situation, this is most likely a product to '.
270
+     'a bug. Please copy entire line and report at %s',
271
+     'https://github.com/unreal4u/telegram-api/issues'
272
+    ), [
273
+     'formType' => $this->formType
274
+    ]);
275
+    $formData = [];
276
+    break;
277
+  }
278
+  $this->logger->debug('About to send following data', $formData);
279
+
280
+  return $formData;
281
+ }
282
+
283
+ /**
284
+  * Can perform any special checks needed to be performed before sending the actual request to Telegram
285
+  *
286
+  * This will return an array with data that will be different in each case (for now). This can be changed in the
287
+  * future.
288
+  *
289
+  * @param TelegramMethods $method
290
+  * @return array
291
+  */
292
+ private function checkSpecialConditions(TelegramMethods $method): array
293
+ {
294
+  $this->logger->debug('Checking whether to apply special conditions to this request');
295
+  $method->performSpecialConditions();
296
+
297
+  $return = [false];
298
+
299
+  foreach ($method as $key => $value) {
300
+   if (is_object($value) && $value instanceof InputFile) {
301
+    $this->logger->debug('About to send a file, so changing request to use multi-part instead');
302
+    // If we are about to send a file, we must use the multipart/form-data way
303
+    $this->formType = 'multipart/form-data';
304
+    $return = [
305
+     'id' => $key,
306
+     'stream' => $value->getStream(),
307
+    ];
308
+   }
309
+  }
310
+
311
+  return $return;
312
+ }
313
+
314
+ /**
315
+  * Builds up the URL with which we can work with
316
+  *
317
+  * All methods in the Bot API are case-insensitive.
318
+  * All queries must be made using UTF-8.
319
+  *
320
+  * @see https://core.telegram.org/bots/api#making-requests
321
+  *
322
+  * @param TelegramMethods $call
323
+  * @return string
324
+  */
325
+ protected function composeApiMethodUrl(TelegramMethods $call): string
326
+ {
327
+  $completeClassName = get_class($call);
328
+  $this->methodName = substr($completeClassName, strrpos($completeClassName, '\\') + 1);
329
+  $this->logger->info('About to perform API request', ['method' => $this->methodName]);
330
+
331
+  return $this->apiUrl . $this->methodName;
332
+ }
333
+
334
+ /**
335
+  * Builds up a multipart form-like array for Guzzle
336
+  *
337
+  * @param array $data The original object in array form
338
+  * @param string $fileKeyName A file handler will be sent instead of a string, state here which field it is
339
+  * @param resource $stream The actual file handler
340
+  * @return array Returns the actual formdata to be sent
341
+  */
342
+ private function buildMultipartFormData(array $data, string $fileKeyName, $stream): array
343
+ {
344
+  $this->logger->debug('Creating multi-part form array data (complex and expensive)');
345
+  $formData = [
346
+   'multipart' => [],
347
+  ];
348
+
349
+  foreach ($data as $id => $value) {
350
+   // Always send as a string unless it's a file
351
+   $multiPart = [
352
+    'name' => $id,
353
+    'contents' => null,
354
+   ];
355
+
356
+   if ($id === $fileKeyName) {
357
+    $multiPart['contents'] = $stream;
358
+   } else {
359
+    $multiPart['contents'] = (string)$value;
360
+   }
361
+
362
+   $formData['multipart'][] = $multiPart;
363
+  }
364
+
365
+  return $formData;
366
+ }
367
+
368
+ /**
369
+  * @param TelegramRawData $telegramRawData
370
+  * @return TgLog
371
+  * @throws CustomClientException
372
+  */
373
+ private function handleOffErrorRequest(TelegramRawData $telegramRawData): TgLog
374
+ {
375
+  $errorRequest = new UnsuccessfulRequest($telegramRawData->getErrorData(), $this->logger);
376
+
377
+  $clientException = new CustomClientException(
378
+   $errorRequest->description,
379
+   $errorRequest->error_code,
380
+   $telegramRawData->getException()
381
+  );
382
+  $clientException->setParameters($errorRequest->parameters);
383
+  throw $clientException;
384
+ }
385 385
 }
386 386
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
 	public function downloadFile(File $file): TelegramDocument
134 134
 	{
135 135
 		$this->logger->debug('Downloading file from Telegram, creating URL');
136
-		$url = 'https://api.telegram.org/file/bot' . $this->botToken . '/' . $file->file_path;
136
+		$url = 'https://api.telegram.org/file/bot'.$this->botToken.'/'.$file->file_path;
137 137
 		$this->logger->debug('About to perform request to begin downloading file');
138 138
 		return new TelegramDocument($this->requestHandler->get($url));
139 139
 	}
@@ -146,16 +146,16 @@  discard block
 block discarded – undo
146 146
 	public function downloadFileAsync(File $file): PromiseInterface
147 147
 	{
148 148
 		$this->logger->debug('Downloading file async from Telegram, creating URL');
149
-		$url = 'https://api.telegram.org/file/bot' . $this->botToken . '/' . $file->file_path;
149
+		$url = 'https://api.telegram.org/file/bot'.$this->botToken.'/'.$file->file_path;
150 150
 		$this->logger->debug('About to perform request to begin downloading file');
151 151
 
152 152
 		$deferred = new Promise();
153 153
 
154
-		return $this->requestHandler->requestAsync($url)->then(function (ResponseInterface $response) use ($deferred)
154
+		return $this->requestHandler->requestAsync($url)->then(function(ResponseInterface $response) use ($deferred)
155 155
 		{
156 156
 			$deferred->resolve(new TelegramDocument($response));
157 157
 		},
158
-			function (RequestException $exception) use ($deferred)
158
+			function(RequestException $exception) use ($deferred)
159 159
 			{
160 160
 				if (!empty($exception->getResponse()->getBody()))
161 161
 					$deferred->resolve(new TelegramDocument($exception->getResponse()));
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
 	 */
171 171
 	final private function constructApiUrl(): TgLog
172 172
 	{
173
-		$this->apiUrl = 'https://api.telegram.org/bot' . $this->botToken . '/';
173
+		$this->apiUrl = 'https://api.telegram.org/bot'.$this->botToken.'/';
174 174
 		$this->logger->debug('Built up the API URL');
175 175
 		return $this;
176 176
 	}
@@ -213,14 +213,14 @@  discard block
 block discarded – undo
213 213
 		$deferred = new Promise();
214 214
 
215 215
 		$promise = $this->requestHandler->requestAsync($this->composeApiMethodUrl($method), $formData);
216
-		$promise->then(function (ResponseInterface $response) use ($deferred)
216
+		$promise->then(function(ResponseInterface $response) use ($deferred)
217 217
 		{
218
-			$deferred->resolve(new TelegramRawData((string) $response->getBody()));
218
+			$deferred->resolve(new TelegramRawData((string)$response->getBody()));
219 219
 		},
220
-			function (RequestException $exception) use ($deferred)
220
+			function(RequestException $exception) use ($deferred)
221 221
 			{
222 222
 				if (!empty($exception->getResponse()->getBody()))
223
-					$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
223
+					$deferred->resolve(new TelegramRawData((string)$exception->getResponse()->getBody(), $exception));
224 224
 				else
225 225
 					$deferred->reject($exception);
226 226
 			});
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
 		$this->methodName = substr($completeClassName, strrpos($completeClassName, '\\') + 1);
329 329
 		$this->logger->info('About to perform API request', ['method' => $this->methodName]);
330 330
 
331
-		return $this->apiUrl . $this->methodName;
331
+		return $this->apiUrl.$this->methodName;
332 332
 	}
333 333
 
334 334
 	/**
Please login to merge, or discard this patch.
Braces   +10 added lines, -8 removed lines patch added patch discarded remove patch
@@ -157,10 +157,11 @@  discard block
 block discarded – undo
157 157
 		},
158 158
 			function (RequestException $exception) use ($deferred)
159 159
 			{
160
-				if (!empty($exception->getResponse()->getBody()))
161
-					$deferred->resolve(new TelegramDocument($exception->getResponse()));
162
-				else
163
-					$deferred->reject($exception);
160
+				if (!empty($exception->getResponse()->getBody())) {
161
+									$deferred->resolve(new TelegramDocument($exception->getResponse()));
162
+				} else {
163
+									$deferred->reject($exception);
164
+				}
164 165
 			});
165 166
 	}
166 167
 
@@ -219,10 +220,11 @@  discard block
 block discarded – undo
219 220
 		},
220 221
 			function (RequestException $exception) use ($deferred)
221 222
 			{
222
-				if (!empty($exception->getResponse()->getBody()))
223
-					$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
224
-				else
225
-					$deferred->reject($exception);
223
+				if (!empty($exception->getResponse()->getBody())) {
224
+									$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
225
+				} else {
226
+									$deferred->reject($exception);
227
+				}
226 228
 			});
227 229
 
228 230
 		return $deferred;
Please login to merge, or discard this patch.
src/GuzzleRequestHandler.php 3 patches
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -18,92 +18,92 @@
 block discarded – undo
18 18
 
19 19
 class GuzzleRequestHandler implements RequestHandlerInterface
20 20
 {
21
-	/**
22
-	 * @var LoggerInterface
23
-	 */
24
-	protected $logger;
21
+ /**
22
+  * @var LoggerInterface
23
+  */
24
+ protected $logger;
25 25
 
26
-	/**
27
-	 * @var ClientInterface
28
-	 */
29
-	protected $httpClient;
26
+ /**
27
+  * @var ClientInterface
28
+  */
29
+ protected $httpClient;
30 30
 
31
-	/**
32
-	 * GuzzleRequestHandler constructor.
33
-	 *
34
-	 * @param ClientInterface $client
35
-	 * @param LoggerInterface $logger
36
-	 */
37
-	public function __construct(?ClientInterface $client = null, LoggerInterface $logger = null)
38
-	{
39
-		if ($logger === null)
40
-		{
41
-			$logger = new DummyLogger();
42
-		}
43
-		$this->logger = $logger;
31
+ /**
32
+  * GuzzleRequestHandler constructor.
33
+  *
34
+  * @param ClientInterface $client
35
+  * @param LoggerInterface $logger
36
+  */
37
+ public function __construct(?ClientInterface $client = null, LoggerInterface $logger = null)
38
+ {
39
+  if ($logger === null)
40
+  {
41
+   $logger = new DummyLogger();
42
+  }
43
+  $this->logger = $logger;
44 44
 
45
-		if ($client === null)
46
-		{
47
-			$client = new Client();
48
-		}
49
-		$this->httpClient = $client;
50
-	}
45
+  if ($client === null)
46
+  {
47
+   $client = new Client();
48
+  }
49
+  $this->httpClient = $client;
50
+ }
51 51
 
52
-	public function get(string $uri): ResponseInterface
53
-	{
54
-		return $this->httpClient->get($uri);
55
-	}
52
+ public function get(string $uri): ResponseInterface
53
+ {
54
+  return $this->httpClient->get($uri);
55
+ }
56 56
 
57
-	/**
58
-	 * This is the method that actually makes the call, which can be easily overwritten so that our unit tests can work
59
-	 *
60
-	 * @param string $uri
61
-	 * @param array $formData
62
-	 *
63
-	 * @return TelegramRawData
64
-	 */
65
-	public function request(string $uri, array $formData = []): TelegramRawData
66
-	{
67
-		$e = null;
68
-		$this->logger->debug('About to perform HTTP call to Telegram\'s API');
69
-		try {
70
-			$response = $this->httpClient->post($uri, $formData);
71
-			$this->logger->debug('Got response back from Telegram, applying json_decode');
72
-		}
73
-		catch (ClientException $e) {
74
-			$response = $e->getResponse();
75
-			// It can happen that we have a network problem, in such case, we can't do nothing about it, so rethrow
76
-			if (empty($response)) {
77
-				throw $e;
78
-			}
79
-		}
80
-		finally {
81
-			return new TelegramRawData((string) $response->getBody(), $e);
82
-		}
83
-	}
57
+ /**
58
+  * This is the method that actually makes the call, which can be easily overwritten so that our unit tests can work
59
+  *
60
+  * @param string $uri
61
+  * @param array $formData
62
+  *
63
+  * @return TelegramRawData
64
+  */
65
+ public function request(string $uri, array $formData = []): TelegramRawData
66
+ {
67
+  $e = null;
68
+  $this->logger->debug('About to perform HTTP call to Telegram\'s API');
69
+  try {
70
+   $response = $this->httpClient->post($uri, $formData);
71
+   $this->logger->debug('Got response back from Telegram, applying json_decode');
72
+  }
73
+  catch (ClientException $e) {
74
+   $response = $e->getResponse();
75
+   // It can happen that we have a network problem, in such case, we can't do nothing about it, so rethrow
76
+   if (empty($response)) {
77
+    throw $e;
78
+   }
79
+  }
80
+  finally {
81
+   return new TelegramRawData((string) $response->getBody(), $e);
82
+  }
83
+ }
84 84
 
85
-	/**
86
-	 * @param string $uri
87
-	 * @param array $formData
88
-	 *
89
-	 * @return PromiseInterface
90
-	 */
91
-	public function requestAsync(string $uri, array $formData = []): PromiseInterface
92
-	{
93
-		$this->logger->debug('About to perform async HTTP call to Telegram\'s API');
94
-		$deferred = new Promise();
85
+ /**
86
+  * @param string $uri
87
+  * @param array $formData
88
+  *
89
+  * @return PromiseInterface
90
+  */
91
+ public function requestAsync(string $uri, array $formData = []): PromiseInterface
92
+ {
93
+  $this->logger->debug('About to perform async HTTP call to Telegram\'s API');
94
+  $deferred = new Promise();
95 95
 
96
-		$promise = $this->httpClient->postAsync($uri, $formData);
97
-		$promise->then(function (ResponseInterface $response) use ($deferred) {
98
-			$deferred->resolve(new TelegramRawData((string) $response->getBody()));
99
-		},
100
-			function (RequestException $exception) use ($deferred) {
101
-				if (!empty($exception->getResponse()->getBody()))
102
-					$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
103
-				else
104
-					$deferred->reject($exception);
105
-			});
96
+  $promise = $this->httpClient->postAsync($uri, $formData);
97
+  $promise->then(function (ResponseInterface $response) use ($deferred) {
98
+   $deferred->resolve(new TelegramRawData((string) $response->getBody()));
99
+  },
100
+   function (RequestException $exception) use ($deferred) {
101
+    if (!empty($exception->getResponse()->getBody()))
102
+     $deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
103
+    else
104
+     $deferred->reject($exception);
105
+   });
106 106
 
107
-		return $deferred;
108
-	}
107
+  return $deferred;
108
+ }
109 109
 }
110 110
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare(strict_types=1);
3
+declare(strict_types = 1);
4 4
 
5 5
 namespace unreal4u\TelegramAPI;
6 6
 
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
 	 * @param ClientInterface $client
35 35
 	 * @param LoggerInterface $logger
36 36
 	 */
37
-	public function __construct(?ClientInterface $client = null, LoggerInterface $logger = null)
37
+	public function __construct(? ClientInterface $client = null, LoggerInterface $logger = null)
38 38
 	{
39 39
 		if ($logger === null)
40 40
 		{
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
 			}
79 79
 		}
80 80
 		finally {
81
-			return new TelegramRawData((string) $response->getBody(), $e);
81
+			return new TelegramRawData((string)$response->getBody(), $e);
82 82
 		}
83 83
 	}
84 84
 
@@ -94,12 +94,12 @@  discard block
 block discarded – undo
94 94
 		$deferred = new Promise();
95 95
 
96 96
 		$promise = $this->httpClient->postAsync($uri, $formData);
97
-		$promise->then(function (ResponseInterface $response) use ($deferred) {
98
-			$deferred->resolve(new TelegramRawData((string) $response->getBody()));
97
+		$promise->then(function(ResponseInterface $response) use ($deferred) {
98
+			$deferred->resolve(new TelegramRawData((string)$response->getBody()));
99 99
 		},
100
-			function (RequestException $exception) use ($deferred) {
100
+			function(RequestException $exception) use ($deferred) {
101 101
 				if (!empty($exception->getResponse()->getBody()))
102
-					$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
102
+					$deferred->resolve(new TelegramRawData((string)$exception->getResponse()->getBody(), $exception));
103 103
 				else
104 104
 					$deferred->reject($exception);
105 105
 			});
Please login to merge, or discard this patch.
Braces   +7 added lines, -8 removed lines patch added patch discarded remove patch
@@ -69,15 +69,13 @@  discard block
 block discarded – undo
69 69
 		try {
70 70
 			$response = $this->httpClient->post($uri, $formData);
71 71
 			$this->logger->debug('Got response back from Telegram, applying json_decode');
72
-		}
73
-		catch (ClientException $e) {
72
+		} catch (ClientException $e) {
74 73
 			$response = $e->getResponse();
75 74
 			// It can happen that we have a network problem, in such case, we can't do nothing about it, so rethrow
76 75
 			if (empty($response)) {
77 76
 				throw $e;
78 77
 			}
79
-		}
80
-		finally {
78
+		} finally {
81 79
 			return new TelegramRawData((string) $response->getBody(), $e);
82 80
 		}
83 81
 	}
@@ -98,10 +96,11 @@  discard block
 block discarded – undo
98 96
 			$deferred->resolve(new TelegramRawData((string) $response->getBody()));
99 97
 		},
100 98
 			function (RequestException $exception) use ($deferred) {
101
-				if (!empty($exception->getResponse()->getBody()))
102
-					$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
103
-				else
104
-					$deferred->reject($exception);
99
+				if (!empty($exception->getResponse()->getBody())) {
100
+									$deferred->resolve(new TelegramRawData((string) $exception->getResponse()->getBody(), $exception));
101
+				} else {
102
+									$deferred->reject($exception);
103
+				}
105 104
 			});
106 105
 
107 106
 		return $deferred;
Please login to merge, or discard this patch.