Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
restservice.php
1<?
3
4use \Bitrix\Main\Loader;
6use \Bitrix\Rest\AppTable;
8use \Bitrix\Rest\RestException;
9use \Bitrix\Rest\AccessException;
10use CRestServer;
11
12Loader::includeModule('rest');
13
14class RestService extends \IRestService
15{
16 const SCOPE = 'messageservice';
17 protected static $app;
18
19 const ERROR_UNSUPPORTED_PROTOCOL = 'ERROR_UNSUPPORTED_PROTOCOL';
20 const ERROR_WRONG_HANDLER_URL = 'ERROR_WRONG_HANDLER_URL';
21 const ERROR_HANDLER_URL_MATCH = 'ERROR_HANDLER_URL_MATCH';
22
23 const ERROR_SENDER_ALREADY_INSTALLED = 'ERROR_SENDER_ALREADY_INSTALLED';
24 const ERROR_SENDER_ADD_FAILURE = 'ERROR_SENDER_ADD_FAILURE';
25 const ERROR_SENDER_VALIDATION_FAILURE = 'ERROR_SENDER_VALIDATION_FAILURE';
26 const ERROR_SENDER_NOT_FOUND = 'ERROR_SENDER_NOT_FOUND';
27
28 const ERROR_MESSAGE_NOT_FOUND = 'ERROR_MESSAGE_NOT_FOUND';
29 const ERROR_MESSAGE_STATUS_INCORRECT = 'ERROR_MESSAGE_STATUS_INCORRECT';
30
31 public static function onRestServiceBuildDescription()
32 {
33 return [
34 static::SCOPE => [
35 'messageservice.sender.add' => [__CLASS__, 'addSender'],
36 'messageservice.sender.delete' => [__CLASS__, 'deleteSender'],
37 'messageservice.sender.list' => [__CLASS__, 'getSenderList'],
38
39 'messageservice.message.status.update' => [__CLASS__, 'updateMessageStatus'],
40 'messageservice.message.status.get' => [__CLASS__, 'getMessageStatus'],
41 ]
42 ];
43 }
44
49 public static function onRestAppDelete(array $fields)
50 {
51 $fields = array_change_key_case($fields, CASE_UPPER);
52 if (empty($fields['APP_ID']))
53 {
54 return;
55 }
56
57 if (!Loader::includeModule('rest'))
58 {
59 return;
60 }
61
62 $dbRes = AppTable::getById($fields['APP_ID']);
63 $app = $dbRes->fetch();
64
65 if (!$app)
66 {
67 return;
68 }
69
70 $iterator = Internal\Entity\RestAppTable::getList([
71 'select' => ['ID'],
72 'filter' => ['=APP_ID' => $app['CLIENT_ID']]
73 ]);
74
75 while ($row = $iterator->fetch())
76 {
77 Internal\Entity\RestAppTable::delete($row['ID']);
78 }
79 }
80
85 public static function onRestAppUpdate(array $fields)
86 {
87 static::onRestAppDelete($fields);
88 }
89
97 public static function addSender($params, $n, $server)
98 {
99 global $USER;
100
101 if(!$server->getClientId())
102 {
103 throw new AccessException("Application context required");
104 }
105
106 self::checkAdminPermissions();
107 $params = array_change_key_case($params, CASE_UPPER);
108
109 self::validateSender($params, $server);
110
111 $params['APP_ID'] = $server->getClientId();
112
113 $iterator = Internal\Entity\RestAppTable::getList([
114 'select' => ['ID'],
115 'filter' => [
116 '=APP_ID' => $params['APP_ID'],
117 '=CODE' => $params['CODE']
118 ]
119 ]);
120 $result = $iterator->fetch();
121 if ($result)
122 {
123 throw new RestException('Sender already installed!', self::ERROR_SENDER_ALREADY_INSTALLED);
124 }
125
126 $senderLang = [
127 'NAME' => $params['NAME'],
128 'DESCRIPTION' => isset($params['DESCRIPTION']) ? $params['DESCRIPTION'] : ''
129 ];
130 unset($params['NAME'], $params['DESCRIPTION']);
131
132 $params['AUTHOR_ID'] = $USER->getId();
133 $result = Internal\Entity\RestAppTable::add($params);
134
135 if ($result->getErrors())
136 {
137 throw new RestException('Sender save error!', self::ERROR_SENDER_ADD_FAILURE);
138 }
139
140 $senderLang['APP_ID'] = $result->getId();
141 static::addSenderLang($senderLang, $server->getClientId());
142
143 $app = \Bitrix\Rest\AppTable::getByClientId($params['APP_ID']);
144 if ($app['CODE'])
145 {
146 AddEventToStatFile(
147 'messageservice',
148 'addProvider' . $params['TYPE'],
149 uniqid($app['CODE'], true),
150 $app['CODE']
151 );
152 }
153
154 return true;
155 }
156
164 public static function deleteSender($params, $n, $server)
165 {
166 if(!$server->getClientId())
167 {
168 throw new AccessException("Application context required");
169 }
170
171 $params = array_change_key_case($params, CASE_UPPER);
172 self::checkAdminPermissions();
173 self::validateSenderCode($params['CODE']);
174 $params['APP_ID'] = $server->getClientId();
175
176 $iterator = Internal\Entity\RestAppTable::getList([
177 'select' => ['ID'],
178 'filter' => [
179 '=APP_ID' => $params['APP_ID'],
180 '=CODE' => $params['CODE']
181 ]
182 ]);
183 $result = $iterator->fetch();
184 if (!$result)
185 {
186 throw new RestException('Sender not found!', self::ERROR_SENDER_NOT_FOUND);
187 }
188 Internal\Entity\RestAppTable::delete($result['ID']);
189 Internal\Entity\RestAppLangTable::deleteByApp($result['ID']);
190
191 return true;
192 }
193
202 public static function getSenderList($params, $n, $server)
203 {
204 if(!$server->getClientId())
205 {
206 throw new AccessException("Application context required");
207 }
208
209 self::checkAdminPermissions();
210 $iterator = Internal\Entity\RestAppTable::getList([
211 'select' => ['CODE'],
212 'filter' => [
213 '=APP_ID' => $server->getClientId()
214 ]
215 ]);
216
217 $result = [];
218 while ($row = $iterator->fetch())
219 {
220 $result[] = $row['CODE'];
221 }
222 return $result;
223 }
224
233 public static function updateMessageStatus($params, $n, $server)
234 {
235 if(!$server->getClientId())
236 {
237 throw new AccessException("Application context required");
238 }
239
240 $params = array_change_key_case($params, CASE_UPPER);
241 static::validateSenderCode($params['CODE']);
242 if (empty($params['MESSAGE_ID']))
243 {
244 throw new RestException('Message not found!', self::ERROR_MESSAGE_NOT_FOUND);
245 }
246
247 $statusId = isset($params['STATUS']) ? Sender\Sms\Rest::resolveStatus($params['STATUS']) : null;
248 if ($statusId === null || $statusId === MessageStatus::UNKNOWN)
249 {
250 throw new RestException('Message status incorrect!', self::ERROR_MESSAGE_STATUS_INCORRECT);
251 }
252
253 $message = Message::loadByExternalId(
254 'rest',
255 $params['MESSAGE_ID'],
256 $server->getClientId().'|'.$params['CODE']
257 );
258 if (!$message)
259 {
260 throw new RestException('Message not found!', self::ERROR_MESSAGE_NOT_FOUND);
261 }
262
263 if ($message->getAuthorId() !== static::getUserId())
264 {
265 static::checkAdminPermissions();
266 }
267 $message->updateStatus($statusId);
268
269 return true;
270 }
271
279 public static function getMessageStatus(array $params, int $n, CRestServer $server)
280 {
281 if (Loader::includeModule('intranet') && \Bitrix\Intranet\Util::isExtranetUser(static::getUserId()))
282 {
283 throw new AccessException("Extranet user denied access");
284 }
285
286 $params = array_change_key_case($params, CASE_UPPER);
287
288 if (empty($params['MESSAGE_ID']) || !is_numeric($params['MESSAGE_ID']))
289 {
290 throw new RestException('Message not found!', self::ERROR_MESSAGE_NOT_FOUND);
291 }
292
293 $message = Message::loadById($params['MESSAGE_ID']);
294
295 if ($message === null)
296 {
297 throw new RestException('Message not found!', self::ERROR_MESSAGE_NOT_FOUND);
298 }
299
300 $statusList = MessageStatus::getDescriptions('en');
301
302 return array_key_exists($message->getStatusId(), $statusList) ? $statusList[$message->getStatusId()] : '';
303 }
304
305 private static function getUserId(): int
306 {
307 global $USER;
308 if (isset($USER) && $USER instanceof \CUser)
309 {
310 return (int)$USER->getID();
311 }
312 return 0;
313 }
314
315 private static function checkAdminPermissions()
316 {
317 global $USER;
318 if (!isset($USER)
319 || !is_object($USER)
320 || (!$USER->isAdmin() && !(Loader::includeModule('bitrix24') && \CBitrix24::isPortalAdmin($USER->getID())))
321 )
322 {
323 throw new AccessException();
324 }
325 }
326
327 private static function validateSender($data, $server)
328 {
329 if (!is_array($data) || empty($data))
330 {
331 throw new RestException('Empty data!', self::ERROR_SENDER_VALIDATION_FAILURE);
332 }
333
334 static::validateSenderCode($data['CODE']);
335 static::validateSenderHandler($data['HANDLER'], $server);
336 if (empty($data['NAME']))
337 {
338 throw new RestException('Empty sender NAME!', self::ERROR_SENDER_VALIDATION_FAILURE);
339 }
340
341 if (empty($data['TYPE']))
342 {
343 throw new RestException('Empty sender message TYPE!', self::ERROR_SENDER_VALIDATION_FAILURE);
344 }
345
346 if (!in_array($data['TYPE'], ['SMS'], true))
347 {
348 throw new RestException('Unknown sender message TYPE!', self::ERROR_SENDER_VALIDATION_FAILURE);
349 }
350 }
351
352 private static function validateSenderCode($code)
353 {
354 if (empty($code))
355 {
356 throw new RestException('Empty sender code!', self::ERROR_SENDER_VALIDATION_FAILURE);
357 }
358 if (!preg_match('#^[a-z0-9\.\-_]+$#i', $code))
359 {
360 throw new RestException('Wrong sender code!', self::ERROR_SENDER_VALIDATION_FAILURE);
361 }
362 }
363
364 private static function validateSenderHandler($handler, $server)
365 {
367 }
368
375 private static function getApp($server)
376 {
377 if(self::$app == null)
378 {
379 if (Loader::includeModule('rest'))
380 {
381 $result = AppTable::getList(
382 [
383 'filter' => [
384 '=CLIENT_ID' => $server->getClientId()
385 ]
386 ]
387 );
388 self::$app = $result->fetch();
389 }
390 }
391
392 return self::$app;
393 }
394
395 private static function addSenderLang($langFields, $clientId)
396 {
397 $langData = [];
398
399 if (!is_array($langFields['NAME']))
400 {
401 $langData['**'] = [
402 'APP_ID' => $langFields['APP_ID'],
403 'LANGUAGE_ID' => '**',
404 'NAME' => $langFields['NAME'],
405 'DESCRIPTION' => is_scalar($langFields['DESCRIPTION']) ? (string)$langFields['DESCRIPTION'] : null
406 ];
407 }
408 else
409 {
410 foreach ($langFields['NAME'] as $langId => $langName)
411 {
412 $langData[mb_strtolower($langId)] = [
413 'APP_ID' => $langFields['APP_ID'],
414 'LANGUAGE_ID' => mb_strtolower($langId),
415 'NAME' => $langFields['NAME'][$langId],
416 'DESCRIPTION' => is_array($langFields['DESCRIPTION']) && isset($langFields['DESCRIPTION'][$langId])
417 ? (string)$langFields['DESCRIPTION'][$langId] : null
418 ];
419
420 if (!isset($langData['**']))
421 {
422 $langData['**'] = [
423 'APP_ID' => $langFields['APP_ID'],
424 'LANGUAGE_ID' => '**',
425 'NAME' => $langFields['NAME'][$langId],
426 'DESCRIPTION' => is_array($langFields['DESCRIPTION']) && isset($langFields['DESCRIPTION'][$langId])
427 ? (string)$langFields['DESCRIPTION'][$langId] : null
428 ];
429 }
430 }
431 }
432
433 $appNames = static::getAppNames($clientId);
434 foreach ($appNames as $langId => $appName)
435 {
436 if (isset($langData[$langId]))
437 {
438 $langData[$langId]['APP_NAME'] = $appName;
439 }
440 }
441
442 foreach ($langData as $toAdd)
443 {
444 Internal\Entity\RestAppLangTable::add($toAdd);
445 }
446 }
447
448 private static function getAppNames($clientId)
449 {
450 $iterator = \Bitrix\Rest\AppTable::getList(
451 [
452 'filter' => [
453 '=CLIENT_ID' => $clientId
454 ],
455 'select' => ['ID', 'APP_NAME', 'CODE'],
456 ]
457 );
458 $app = $iterator->fetch();
459 $result = [
460 '**' => $app['APP_NAME'] ? $app['APP_NAME'] : $app['CODE']
461 ];
462
463 $orm = \Bitrix\Rest\AppLangTable::getList([
464 'filter' => [
465 '=APP_ID' => $app['ID']
466 ],
467 'select' => ['LANGUAGE_ID', 'MENU_NAME']
468 ]);
469
470 while ($row = $orm->fetch())
471 {
472 $result[mb_strtolower($row['LANGUAGE_ID'])] = $row['MENU_NAME'];
473 }
474
475 if (isset($result[LANGUAGE_ID]))
476 {
477 $result['**'] = $result[LANGUAGE_ID];
478 }
479
480 return $result;
481 }
482}
static onRestAppUpdate(array $fields)
static onRestAppDelete(array $fields)
static getSenderList($params, $n, $server)
static getMessageStatus(array $params, int $n, CRestServer $server)
static deleteSender($params, $n, $server)
static updateMessageStatus($params, $n, $server)
static addSender($params, $n, $server)
static checkCallback($handlerUrl, $appInfo=array(), $checkInstallUrl=true)