Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
restclient.php
1<?php
2
4
16
17Loc::loadMessages(__FILE__);
18
20{
21 const REST_URI = '/rest/';
22 const REGISTER_URI = '/oauth/register/';
23 const SCOPE = 'sale';
24 const SERVICE_ACCESS_OPTION = 'saleservices_access';
25
30
31 const UNSUCCESSFUL_CALL_OPTION = 'sale_hda_last_unsuccessful_call';
32 const UNSUCCESSFUL_CALL_TRYINGS = 3; //times
34
35 protected $httpTimeout = 5;
36 protected $streamTimeout = 10;
37 protected $accessSettings = null;
38 protected $serviceHost = 'https://saleservices.bitrix.info';
39
40 protected $version = 5;
41
51 protected function call($methodName, $additionalParams = null, $licenseCheck = false, $clearAccessSettings = false)
52 {
53 $result = new ResultSerializable();
54
55 if(!self::isServerAlive() && !defined('SALE_SRVS_RESTCLIENT_DISABLE_SRV_ALIVE_CHECK'))
56 {
57 $result->addError(
58 new Error(
59 Loc::getMessage('SALE_SRV_BASE_REST_CONNECT_ERROR').' '.$this->getServiceHost(),
60 self::ERROR_SERVICE_UNAVAILABLE
61 )
62 );
63 return $result;
64 }
65
66 if ($clearAccessSettings)
67 {
68 $this->clearAccessSettings();
69 $this->accessSettings = null;
70 }
71
72 if (is_null($this->accessSettings))
73 {
74 $this->accessSettings = $this->getAccessSettings();
75 }
76
77 if (!$this->accessSettings)
78 {
79 $result->addError(new Error(Loc::getMessage('SALE_SRV_BASE_REST_ACCESS_SETTINGS_ERROR')));
80 return $result;
81 }
82
83 if (!is_array($additionalParams))
84 $additionalParams = array();
85 else
86 $additionalParams = Encoding::convertEncodingArray($additionalParams, LANG_CHARSET, "utf-8");
87
88 $additionalParams['version'] = $this->version;
89 $additionalParams['client_id'] = $this->accessSettings['client_id'];
90 $additionalParams['client_secret'] = $this->accessSettings['client_secret'];
91 $additionalParams['lang'] = LANGUAGE_ID;
92
93 if ($licenseCheck)
94 {
95 $additionalParams = static::signLicenseRequest($additionalParams, static::getLicense());
96 }
97
98 $host = $this->getServiceHost();
99 $http = new HttpClient([
100 'socketTimeout' => $this->httpTimeout,
101 'streamTimeout' => $this->streamTimeout,
102 ]);
103 $postResult = @$http->post(
104 $host.static::REST_URI.$methodName,
105 $additionalParams
106 );
107
108 try
109 {
110 $answer = $this->prepareAnswer($postResult);
111 }
112 catch(\Exception $e)
113 {
114 $answer = false;
115 }
116
117 if (!is_array($answer))
118 {
119 $result->addError(new Error(Loc::getMessage('SALE_SRV_BASE_REST_ANSWER_ERROR').' '.$this->getServiceHost().'. (Status: "'.$http->getStatus().'", Result: "'.$postResult.'")', static::ERROR_SERVICE_UNAVAILABLE));
121 return $result;
122 }
123
124 if(self::getLastUnSuccessCount() > 0)
125 $this->setLastUnSuccessCallInfo(true);
126
127 if (array_key_exists('error', $answer))
128 {
129 if ($answer['error'] === 'verification_needed')
130 {
131 if($licenseCheck)
132 {
133 $result->addError(new Error($answer['error'].". ".$answer['error_description'], self::ERROR_WRONG_LICENSE));
134 return $result;
135 }
136 else
137 {
138 return $this->call($methodName, $additionalParams, true);
139 }
140 }
141 else if (($answer['error'] === 'ACCESS_DENIED' || $answer['error'] === 'Invalid client' || $answer['error'] === 'NO_AUTH_FOUND')
142 && !$clearAccessSettings)
143 {
144 return $this->call($methodName, $additionalParams, true, true);
145 }
146
147 $result->addError(new Error($answer['error'].". ".$answer['error_description']));
148 return $result;
149 }
150
151 if ($answer['result'] == false)
152 $result->addError(new Error('Nothing found', static::ERROR_NOTHING_FOUND));
153
154 if (is_array($answer['result']))
155 $result->addData($answer['result']);
156
157 return $result;
158 }
159
164 public function getServiceHost()
165 {
166 if(!defined('SALE_SRVS_RESTCLIENT_SRV_HOST'))
167 $result = $this->serviceHost;
168 else
169 $result = SALE_SRVS_RESTCLIENT_SRV_HOST;
170
171 return $result;
172 }
173
179 protected function prepareAnswer($result)
180 {
181 return Json::decode($result);
182 }
183
188 protected function register()
189 {
190 $result = new Result();
191 $httpClient = new HttpClient();
192
193 $queryParams = array(
194 "scope" => static::SCOPE,
195 "redirect_uri" => static::getRedirectUri(),
196 );
197
198 $queryParams = static::signLicenseRequest($queryParams, static::getLicense());
199 $host = $this->getServiceHost();
200 $postResult = $httpClient->post($host.static::REGISTER_URI, $queryParams);
201
202 if ($postResult === false)
203 {
204 $result->addError(new Error(implode("\n", $httpClient->getError()), static::ERROR_SERVICE_UNAVAILABLE));
205 return $result;
206 }
207
208 try
209 {
210 $jsonResult = Json::decode($postResult);
211 }
212 catch(\Exception $e)
213 {
214 $result->addError(new Error($e->getMessage()));
215 return $result;
216 }
217
218 if (!empty($jsonResult["error"]))
219 {
220 $result->addError(new Error($jsonResult["error"], static::ERROR_WRONG_LICENSE));
221 }
222 else
223 {
224 $result->addData($jsonResult);
225 }
226
227 return $result;
228 }
229
230 public static function signLicenseRequest(array $request, $licenseKey)
231 {
232 if(Loader::includeModule('bitrix24'))
233 {
234 $request['BX_TYPE'] = 'B24';
235 $request['BX_LICENCE'] = BX24_HOST_NAME;
236 $request['BX_HASH'] = \CBitrix24::RequestSign(md5(implode("|", $request)));
237 }
238 else
239 {
240 $request['BX_TYPE'] = ModuleManager::isModuleInstalled('intranet') ? 'CP' : 'BSM';
241 $request['BX_LICENCE'] = md5("BITRIX".$licenseKey."LICENCE");
242 $request['BX_HASH'] = md5(md5(implode("|", $request)).md5($licenseKey));
243 }
244
245 return $request;
246 }
247
253 protected static function setAccessSettings(array $params)
254 {
255 Option::set('sale', static::SERVICE_ACCESS_OPTION, serialize($params));
256 }
257
262 protected function getAccessSettings()
263 {
264 $accessSettings = Option::get('sale', static::SERVICE_ACCESS_OPTION);
265
266 if($accessSettings != '')
267 {
268 $accessSettings = unserialize($accessSettings, ['allowed_classes' => false]);
269
271 return $accessSettings;
272 else
273 $this->clearAccessSettings();
274 }
275
277 $result = $this->register();
278
279 if($result->isSuccess())
280 {
281 $accessSettings = $result->getData();
283 return $accessSettings;
284 }
285 else
286 {
287 return array();
288 }
289 }
290
295 public function clearAccessSettings()
296 {
297 Option::set('sale', static::SERVICE_ACCESS_OPTION, null);
298 }
299
304 protected static function getRedirectUri()
305 {
306 $request = Context::getCurrent()->getRequest();
307
308 $host = $request->getHttpHost();
309 $isHttps = $request->isHttps();
310
311 return ($isHttps ? 'https' : 'http').'://'.$host."/";
312 }
313
318 protected static function getLicenseHash()
319 {
320 return md5(static::getLicense());
321 }
322
323 protected static function getLicense()
324 {
325 return LICENSE_KEY;
326 }
327
328 protected static function getLastUnSuccessCallInfo()
329 {
330 $result = Option::get('sale', static::UNSUCCESSFUL_CALL_OPTION, "");
331
332 if($result <> '')
333 $result = unserialize($result, ['allowed_classes' => false]);
334
335 return is_array($result) ? $result : array();
336 }
337
341 protected static function setLastUnSuccessCallInfo($reset = false)
342 {
343 static $alreadySetted = false;
344
345 if($alreadySetted && !$reset)
346 return;
347
348 $data = "";
349
350 if (!$reset)
351 {
352 $alreadySetted = true;
353 $last = static::getLastUnSuccessCallInfo();
354
355 $lastCount = (int)($last['COUNT'] ?? 0);
356
357 $data = serialize([
358 'COUNT' => $lastCount > 0 ? $lastCount + 1 : 1,
359 'TIMESTAMP' => time()
360 ]);
361 }
362
363 Option::set('sale', static::UNSUCCESSFUL_CALL_OPTION, $data);
364 }
365
366
371 public static function isServerAlive()
372 {
373 $last = static::getLastUnSuccessCallInfo();
374
375 if(empty($last))
376 return true;
377
378 if(time() - intval($last['TIMESTAMP']) >= self::UNSUCCESSFUL_CALL_WAIT_INTERVAL)
379 return true;
380
381 if(intval($last['COUNT']) <= self::UNSUCCESSFUL_CALL_TRYINGS)
382 return true;
383
384 return false;
385 }
386
390 protected function getLastUnSuccessCount()
391 {
392 $last = static::getLastUnSuccessCallInfo();
393 $count = (int)($last['COUNT'] ?? 0);
394
395 return max(0, $count);
396 }
397}
static getCurrent()
Definition context.php:241
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static signLicenseRequest(array $request, $licenseKey)
static setLastUnSuccessCallInfo($reset=false)
static setAccessSettings(array $params)
call($methodName, $additionalParams=null, $licenseCheck=false, $clearAccessSettings=false)