1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
apiclient.php
См. документацию.
1<?php
2
3namespace Bitrix\Calendar\Sync\Office365;
4
5use Bitrix\Calendar\Sync\Exceptions\PreconditionFailedException;
6use Bitrix\Calendar\Sync\Office365\Util\ObjectStatusTrait;
7use Bitrix\Calendar\Sync\Exceptions\ApiException;
8use Bitrix\Calendar\Sync\Exceptions\AuthException;
9use Bitrix\Calendar\Sync\Exceptions\GoneException;
10use Bitrix\Calendar\Sync\Internals\ContextInterface;
11use Bitrix\Calendar\Sync\Internals\HasContextTrait;
12use Bitrix\Calendar\Sync\Exceptions\ConflictException;
13use Bitrix\Calendar\Sync\Exceptions\NotFoundException;
14use Bitrix\Calendar\Sync\Util\RequestLogger;
15use Bitrix\Main\ArgumentException;
16use Bitrix\Main\Web\HttpClient;
17use Bitrix\Main\Web\Json;
18use Exception;
19
24{
25 use ObjectStatusTrait, HasContextTrait;
26
31
38 {
39 $this->httpClient = $httpClient;
40 $this->context = $context;
41 }
42
57 public function request(string $method, string $uri, array $params): array
58 {
59 $getLogContext = static function (int $statusCode, $response, string $error = '' )
60 use ($method, $uri, $params): array
61 {
62 return [
63 'serviceName' => Helper::ACCOUNT_TYPE,
64 'host' => Helper::SERVER_PATH,
65 'method' => $method,
66 'url' => $uri,
67 'requestParams' => $params,
68 'statusCode' => $statusCode,
69 'error' => $error,
70 'response' => $response,
71 ];
72 };
73 $this->getStatus()->resetErrors();
74 try
75 {
76 $response = [];
77 $paramString = $this->prepareParams($params);
78
79 $uri = Helper::SERVER_PATH . $uri;
80
81 $this->httpClient->waitResponse(true);
82 $this->httpClient->query($method, $uri, $paramString);
83
84 if ($this->httpClient->getStatus() < 300)
85 {
86 $response = $this->prepareResponse();
87 $this->context->getLogger()
88 ->debug("API office365 success" . $this->httpClient->getStatus()
89 , $getLogContext(
90 $this->httpClient->getStatus(),
91 $this->httpClient->getResult(),
92 )
93 );
94 }
95 else
96 {
97 try
98 {
99 $error = Json::decode($this->httpClient->getResult());
100 $this->getStatus()->addError(
101 "CONNECTION",
102 "[" . $error['error']['code'] . "] " . $error['error']['message'],
103 );
104 $this->context->getLogger()
105 ->warning("API office365 returned error code "
106 . $this->httpClient->getStatus()
107 . ": " . $error['error']['message'],
108 $getLogContext(
109 $this->httpClient->getStatus(),
110 $this->httpClient->getResult(),
111 $error['error']['message']
112 )
113 );
114 switch ($this->httpClient->getStatus())
115 {
116 case 401:
117 throw new AuthException(
118 $error['error']['code'],
119 401,
120 __FILE__,
121 __LINE__
122 );
123 case 404:
124 throw new NotFoundException(
125 $error['error']['code'],
126 404,
127 __FILE__,
128 __LINE__
129 );
130 case 409:
131 throw new ConflictException(
132 $error['error']['code'],
133 409,
134 __FILE__,
135 __LINE__
136 );
137 case 410:
138 throw new GoneException(
139 $error['error']['code'],
140 410,
141 __FILE__,
142 __LINE__
143 );
144 case 412:
146 $error['error']['code'],
147 412,
148 __FILE__,
149 __LINE__
150 );
151 default:
152 throw new ApiException(
153 $error['error']['code'],
154 $this->httpClient->getStatus(),
155 __FILE__,
156 __LINE__
157 );
158 }
159 }
160 catch (ArgumentException $exception)
161 {
162 $this->context->getLogger()
163 ->error("ArgumentException from office365", $getLogContext(
164 $this->httpClient->getStatus(),
165 $this->httpClient->getResult(),
166 $exception->getMessage()
167 ));
168 foreach($this->httpClient->getError() as $code => $error)
169 {
170 $this->getStatus()->addError($code, $error);
171 }
172 }
173 }
174 }
175 catch (ApiException $e)
176 {
177 $this->context->getLogger()
178 ->error("ApiException from office365", $getLogContext(
179 $e->getCode(),
180 '',
181 $e->getMessage()
182 )
183 );
184 throw $e;
185 }
186 catch (Exception $e)
187 {
188 $this->context->getLogger()
189 ->error("Exception from office365: " . $e->getMessage(), $getLogContext(
190 $e->getCode(),
191 '',
192 $e->getMessage()
193 )
194 );
195 throw $e;
196 }
197
198 return $response;
199 }
200
207 protected function multipartDecode(string $response, string $boundary): array
208 {
209 $events = [];
210
211 $response = str_replace("--$boundary--", "--$boundary", $response);
212 $parts = explode("--$boundary\r\n", $response);
213
214 foreach ($parts as $part)
215 {
216 $part = trim($part);
217 if (!empty($part))
218 {
219 $partEvent = explode("\r\n\r\n", $part);
220 $data = $this->getMetaInfo($partEvent[1]);
221 $id = $this->getId($partEvent[0]);
222
223 if ($data['status'] === 200)
224 {
225 if ($id === null)
226 {
227 continue;
228 }
229
230 try
231 {
232 $event = Json::decode($partEvent[2]);
233 }
234 catch (Exception $exception)
235 {
236 continue;
237 }
238
239 $event['etag'] = $data['etag'];
240 $events[$id] = $event;
241 }
242 }
243 }
244
245 return $events;
246 }
247
248 private function getMetaInfo($headers): array
249 {
250 $data = [];
251 foreach (explode("\n", $headers) as $k => $header)
252 {
253 if($k === 0)
254 {
255 if(preg_match('#HTTP\S+ (\d+)#', $header, $find))
256 {
257 $data['status'] = (int)$find[1];
258 }
259 }
260 elseif(mb_strpos($header, ':') !== false)
261 {
262 [$headerName, $headerValue] = explode(':', $header, 2);
263 if(mb_strtolower($headerName) === 'etag')
264 {
265 $data['etag'] = trim($headerValue);
266 }
267 }
268 }
269
270 return $data;
271 }
272
278 private function getId(string $headers): ?int
279 {
280 $id = null;
281 foreach (explode("\n", $headers) as $header)
282 {
283 if(mb_strpos($header, ':') !== false)
284 {
285 [$headerName, $headerValue] = explode(':', $header, 2);
286 if(mb_strtolower($headerName) === 'content-id')
287 {
288 $part = explode(':', $headerValue);
289 $id = (int) rtrim($part[1], ">");
290 break;
291 }
292 }
293 }
294
295 return $id;
296 }
297
298
306 protected function prepareParams(array $params): ?string
307 {
308 return $this->formatParams($params);
309 }
310
318 protected function formatParams(array $params): ?string
319 {
320 return $params ? Json::encode($params, JSON_UNESCAPED_SLASHES) : null;
321 }
322
336 public function get(string $uri, array $params = []): array
337 {
338 if ($params)
339 {
340 $uri .= (strpos($uri, '?') ? '&' : '?')
341 . http_build_query($params)
342 ;
343 }
344 return $this->request(HttpClient::HTTP_GET, $uri, $params);
345 }
346
360 public function post(string $uri, array $params = []): array
361 {
362 return $this->request(HttpClient::HTTP_POST, $uri, $params);
363 }
364
378 public function delete(string $uri, array $params = []): array
379 {
380 return $this->request(HttpClient::HTTP_DELETE, $uri, $params);
381 }
382
396 public function put(string $uri, array $params = []): array
397 {
398 return $this->request(HttpClient::HTTP_PUT, $uri, $params);
399 }
400
414 public function patch(string $uri, array $params = []): array
415 {
416 return $this->request(HttpClient::HTTP_PATCH, $uri, $params);
417 }
418
424 protected function prepareResponse()
425 {
426 $contentType = $this->httpClient->getHeaders()->getContentType();
427
428 if ($contentType === 'multipart/mixed')
429 {
430 $response = $this->multipartDecode(
431 $this->httpClient->getResult(),
432 $this->httpClient->getHeaders()->getBoundary()
433 );
434 }
435 else
436 {
437 $response = $this->httpClient->getResult()
438 ? Json::decode($this->httpClient->getResult())
439 : [];
440 }
441
442 return $response;
443 }
444}
formatParams(array $params)
Определения apiclient.php:318
multipartDecode(string $response, string $boundary)
Определения apiclient.php:207
post(string $uri, array $params=[])
Определения apiclient.php:360
put(string $uri, array $params=[])
Определения apiclient.php:396
request(string $method, string $uri, array $params)
Определения apiclient.php:57
__construct(HttpClient $httpClient, ContextInterface $context)
Определения apiclient.php:37
prepareParams(array $params)
Определения apiclient.php:306
patch(string $uri, array $params=[])
Определения apiclient.php:414
RequestLogger $logger
Определения apiclient.php:30
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$context
Определения csv_new_setup.php:223
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
if(file_exists($_SERVER['DOCUMENT_ROOT'] . "/urlrewrite.php")) $uri
Определения urlrewrite.php:61
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$contentType
Определения quickway.php:301
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$response
Определения result.php:21
$method
Определения index.php:27
$error
Определения subscription_card_product.php:20
$k
Определения template_pdf.php:567