Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
application.php
1<?php
2
4
19use CRestUtil;
20
21Loc::loadMessages(__FILE__);
22
24{
29 protected static ?int $contextUserId = null;
30
31 public static function setContextUserId(int $id): void
32 {
33 self::$contextUserId = $id;
34 }
35
36 public static function install($code, $version = false, $checkHash = false, $installHash = false, $from = null) : array
37 {
38 $result = [];
39
40 if (!OAuthService::getEngine()->isRegistered())
41 {
42 try
43 {
44 OAuthService::register();
45 OAuthService::getEngine()->getClient()->getApplicationList();
46 }
47 catch(SystemException $e)
48 {
49 $result = [
50 'error' => $e->getCode(),
51 'errorDescription' => $e->getMessage(),
52 ];
53 }
54 }
55
56 if (OAuthService::getEngine()->isRegistered())
57 {
58 $version = !empty($version) ? $version : false;
59
60 $result = [
61 'error' => 'INSTALL_ERROR',
62 'errorDescription' => Loc::getMessage('RMP_INSTALL_ERROR'),
63 ];
64
65 $appDetailInfo = false;
66 if ($code <> '')
67 {
68 if (!empty($checkHash) && !empty($installHash))
69 {
70 $appDetailInfo = Client::getInstall($code, $version, $checkHash, $installHash);
71 }
72 else
73 {
74 $appDetailInfo = Client::getInstall($code, $version);
75 }
76
77 if ($appDetailInfo)
78 {
79 $appDetailInfo = $appDetailInfo['ITEMS'];
80 }
81 }
82
83 if (
84 $appDetailInfo
85 && (
86 !Access::isAvailable($code)
87 || !Access::isAvailableCount(Access::ENTITY_TYPE_APP, $code)
88 )
89 )
90 {
91 $result = [
92 'error' => 'ACTION_ACCESS_DENIED',
93 'errorDescription' => Loc::getMessage('RMP_ERROR_ACCESS_DENIED'),
94 'helperCode' => Access::getHelperCode(Access::ACTION_INSTALL, Access::ENTITY_TYPE_APP, $appDetailInfo)
95 ];
96 }
97 elseif ($appDetailInfo)
98 {
99 if (CRestUtil::canInstallApplication($appDetailInfo, self::$contextUserId))
100 {
101 $queryFields = [
102 'CLIENT_ID' => $appDetailInfo['APP_CODE'],
103 'VERSION' => $appDetailInfo['VER'],
104 'BY_SUBSCRIPTION' => $appDetailInfo['BY_SUBSCRIPTION'] ?? 'N',
105 ];
106
107 if (!empty($checkHash) && !empty($installHash))
108 {
109 $queryFields['CHECK_HASH'] = $checkHash;
110 $queryFields['INSTALL_HASH'] = $installHash;
111 }
112
113 $installResult = OAuthService::getEngine()->getClient()->installApplication($queryFields);
114 if (isset($installResult['error']) && $installResult['error'] === 'verification_needed')
115 {
116 if (\Bitrix\Main\ModuleManager::isModuleInstalled('bitrix24'))
117 {
118 OAuthService::getEngine()->getClient()->getApplicationList();
119 $installResult = OAuthService::getEngine()->getClient()->installApplication($queryFields);
120 }
121 elseif (
122 defined('ADMIN_SECTION')
123 && $appDetailInfo['TYPE'] === 'C'
124 && $appDetailInfo['MODE'] === 'S'
125 && mb_strpos($appDetailInfo['CODE'], 'bitrix.') === 0
126 )
127 {
128 $installResult = [
129 'result' => [
130 'client_id' => $appDetailInfo['APP_CODE'],
131 'version' => (int)$appDetailInfo['VER'],
132 'status' => AppTable::STATUS_FREE,
133 'scope' => array_keys($appDetailInfo['RIGHTS']),
134 ],
135 ];
136 }
137 }
138
139 if (isset($installResult['error']) && $installResult['error'])
140 {
141 $result['error'] = $installResult['error'];
142 $result['errorDescription'] = $installResult['error_description'];
143 }
144 elseif ($installResult['result'])
145 {
146 $appFields = [
147 'CLIENT_ID' => $installResult['result']['client_id'],
148 'CODE' => $appDetailInfo['CODE'],
149 'ACTIVE' => AppTable::ACTIVE,
150 'INSTALLED' => ($appDetailInfo['OPEN_API'] === 'Y' || empty($appDetailInfo['INSTALL_URL']))
151 ? AppTable::INSTALLED
152 : AppTable::NOT_INSTALLED,
153 'URL' => $appDetailInfo['URL'],
154 'URL_DEMO' => $appDetailInfo['DEMO_URL'],
155 'URL_INSTALL' => $appDetailInfo['INSTALL_URL'],
156 'VERSION' => $installResult['result']['version'],
157 'SCOPE' => implode(',', $installResult['result']['scope']),
158 'STATUS' => $installResult['result']['status'],
159 'SHARED_KEY' => $appDetailInfo['SHARED_KEY'],
160 'CLIENT_SECRET' => '',
161 'APP_NAME' => $appDetailInfo['NAME'],
162 'MOBILE' => $appDetailInfo['BXMOBILE'] === 'Y' ? AppTable::ACTIVE : AppTable::INACTIVE,
163 'USER_INSTALL' => CRestUtil::appCanBeInstalledByUser($appDetailInfo) ? AppTable::ACTIVE : AppTable::INACTIVE,
164 ];
165
166 if (
167 $appFields['STATUS'] === AppTable::STATUS_TRIAL
168 || $appFields['STATUS'] === AppTable::STATUS_PAID
169 )
170 {
171 $appFields['DATE_FINISH'] = DateTime::createFromTimestamp($installResult['result']['date_finish']);
172 }
173 else
174 {
175 $appFields['DATE_FINISH'] = '';
176 }
177
178 //Configuration app
179 if (
180 $appDetailInfo['TYPE'] === AppTable::TYPE_CONFIGURATION
181 && $appDetailInfo['MODE'] !== AppTable::MODE_SITE
182 )
183 {
184 $appFields['INSTALLED'] = AppTable::NOT_INSTALLED;
185 }
186
187 $existingApp = AppTable::getByClientId($appFields['CLIENT_ID']);
188 if ($existingApp)
189 {
190 $addResult = AppTable::update($existingApp['ID'], $appFields);
191 }
192 else
193 {
194 $addResult = AppTable::add($appFields);
195 }
196
197 if ($addResult->isSuccess())
198 {
199 $appId = $addResult->getId();
200
201 if ($existingApp)
202 {
203 AppLogTable::log($appId, AppLogTable::ACTION_TYPE_UPDATE);
204 }
205 else
206 {
207 AppLogTable::log($appId, AppLogTable::ACTION_TYPE_ADD);
208 }
209
210 if ($appFields['INSTALLED'] === AppTable::INSTALLED)
211 {
212 AppLogTable::log($appId, AppLogTable::ACTION_TYPE_INSTALL);
213 }
214
215 if (!CRestUtil::isAdmin(self::$contextUserId))
216 {
217 CRestUtil::notifyInstall($appFields);
218 }
219
220 if (isset($appDetailInfo['MENU_TITLE']) && is_array($appDetailInfo['MENU_TITLE']))
221 {
222 foreach ($appDetailInfo['MENU_TITLE'] as $lang => $langName)
223 {
224 $appLangFields = array(
225 'APP_ID' => $appId,
226 'LANGUAGE_ID' => $lang,
227 'MENU_NAME' => $langName
228 );
229
230 $appLangUpdateFields = array(
231 'MENU_NAME' => $langName
232 );
233
234 $connection = Main\Application::getConnection();
235 $queries = $connection->getSqlHelper()->prepareMerge(
236 AppLangTable::getTableName(),
237 [
238 'APP_ID',
239 'LANGUAGE_ID'
240 ],
241 $appLangFields,
242 $appLangUpdateFields
243 );
244
245 foreach($queries as $query)
246 {
247 $connection->queryExecute($query);
248 }
249 }
250 }
251
252 if ($appDetailInfo['OPEN_API'] === 'Y' && !empty($appFields['URL_INSTALL']))
253 {
254 // checkCallback is already called inside checkFields
255 $result = EventTable::add(
256 [
257 'APP_ID' => $appId,
258 'EVENT_NAME' => 'ONAPPINSTALL',
259 'EVENT_HANDLER' => $appFields['URL_INSTALL'],
260 ]
261 );
262 if ($result->isSuccess())
263 {
264 Sender::bind('rest', 'OnRestAppInstall');
265 }
266 }
267
268 AppTable::install($appId);
269
270 $redirect = false;
271 $open = false;
272 $sliderUrl = false;
273 if ($appDetailInfo['TYPE'] !== AppTable::TYPE_CONFIGURATION)
274 {
275 $uriString = CRestUtil::getApplicationPage($appId);
276 $uri = new Uri($uriString);
277 $ver = (int) $version;
278 $uri->addParams(
279 [
280 'ver' => $ver,
281 'check_hash' => $checkHash,
282 'install_hash' => $installHash
283 ]
284 );
285 $redirect = $uri->getUri();
286 $open = $appDetailInfo['OPEN_API'] !== 'Y';
287 }
288 else
289 {
290 if ((int)$appDetailInfo['IMPORT_ZIP_ID'] > 0)
291 {
292 $url = Url::getConfigurationImportZipUrl((int)$appDetailInfo['IMPORT_ZIP_ID']);
293 }
294 else
295 {
296 $url = Url::getConfigurationImportAppUrl($appDetailInfo['CODE']);
297 }
298
299 $uri = new Uri($url);
300 if (!empty($checkHash) && !empty($installHash))
301 {
302 $uri->addParams(
303 [
304 'check_hash' => $checkHash,
305 'install_hash' => $installHash,
306 ]
307 );
308 }
309 $sliderUrl = $uri->getUri();
310 }
311
312 $result = [
313 'success' => 1,
314 'id' => $appId,
315 'open' => $open,
316 'installed' => $appFields['INSTALLED'] === 'Y',
317 'redirect' => $redirect,
318 'openSlider' => $sliderUrl,
319 ];
320
321 Analytic::logToFile(
322 'finishInstall',
323 $code,
324 $from ?? 'index'
325 );
326 }
327 else
328 {
329 $result['errorDescription'] = implode('<br />', $addResult->getErrorMessages());
330 }
331 }
332 }
333 elseif (
334 !empty($appInfo['HOLD_INSTALL_BY_TRIAL'])
335 && $appInfo['HOLD_INSTALL_BY_TRIAL'] === 'Y'
336 && Client::isSubscriptionDemo()
337 )
338 {
339 $result = ['error' => Loc::getMessage('RMP_TRIAL_HOLD_INSTALL')];
340 }
341 else
342 {
343 $result = [
344 'error' => 'ACCESS_DENIED',
345 'errorDescription' => Loc::getMessage('RMP_ACCESS_DENIED'),
346 ];
347 }
348 }
349 else
350 {
351 $result = [
352 'error' => 'APPLICATION_NOT_FOUND',
353 'errorDescription' => Loc::getMessage('RMP_NOT_FOUND'),
354 ];
355 }
356 }
357 elseif (!$result['error'])
358 {
359 $result = [
360 'error' => 'OAUTH_REGISTER',
361 'errorDescription' => Loc::getMessage('RMP_INSTALL_ERROR'),
362 ];
363 }
364
365 if (isset($result['error']) && $result['error'])
366 {
367 if ($result['error'] === 'SUBSCRIPTION_REQUIRED')
368 {
369 $result['errorDescription'] = Loc::getMessage('RMP_ERROR_SUBSCRIPTION_REQUIRED');
370 }
371 elseif ($result['error'] === 'verification_needed')
372 {
373 $result['errorDescription'] = Loc::getMessage('RMP_ERROR_VERIFICATION_NEEDED');
374 }
375 }
376
377 return $result;
378 }
379
380 public static function uninstall($code, bool $clean = false, $from = null) : array
381 {
382 if (CRestUtil::isAdmin(self::$contextUserId))
383 {
384 $res = AppTable::getList(
385 [
386 'filter' => [
387 '=CODE' => $code,
388 '!=STATUS' => AppTable::STATUS_LOCAL,
389 ],
390 ]
391 );
392
393 $appInfo = $res->fetch();
394 if ($appInfo)
395 {
396 $checkResult = AppTable::checkUninstallAvailability($appInfo['ID'], $clean);
397 if (
398 $checkResult->isEmpty()
399 && AppTable::canUninstallByType($appInfo['CODE'], $appInfo['VERSION'])
400 )
401 {
402 AppTable::uninstall($appInfo['ID'], $clean);
403
404 $appFields = [
405 'ACTIVE' => 'N',
406 'INSTALLED' => 'N',
407 ];
408
409 AppTable::update($appInfo['ID'], $appFields);
410
411 AppLogTable::log($appInfo['ID'], AppLogTable::ACTION_TYPE_UNINSTALL);
412
413 Analytic::logToFile(
414 'finishUninstall',
415 $appInfo['CODE'],
416 $from ?? 'index'
417 );
418
419 $result = ['success' => 1];
420 }
421 else
422 {
423 $errorMessage = '';
424 foreach ($checkResult as $error)
425 {
426 $errorMessage .= $error->getMessage() . "\n";
427 }
428
429 $result = ['error' => $errorMessage];
430 if (
431 $checkResult->isEmpty()
432 && AppTable::getAppType($appInfo['CODE']) == AppTable::TYPE_CONFIGURATION
433 )
434 {
435 $result = [
436 'sliderUrl' => \Bitrix\Rest\Marketplace\Url::getConfigurationImportRollbackUrl(
437 $appInfo['CODE']
438 ),
439 ];
440 }
441 }
442 }
443 else
444 {
445 $result = ['error' => Loc::getMessage('RMP_NOT_FOUND')];
446 }
447 }
448 else
449 {
450 $result = ['error' => Loc::getMessage('RMP_ACCESS_DENIED')];
451 }
452
453 return $result;
454 }
455
456 public static function reinstall($id) : array
457 {
458 $result = [];
459 if (CRestUtil::isAdmin(self::$contextUserId))
460 {
461 $appInfo = AppTable::getByClientId($id);
462 if (
463 !Access::isAvailable($id)
464 || !Access::isAvailableCount(Access::ENTITY_TYPE_APP, $id)
465 )
466 {
467 $result = [
468 'error' => Loc::getMessage('RMP_ERROR_ACCESS_DENIED'),
469 'helperCode' => Access::getHelperCode(Access::ACTION_INSTALL, Access::ENTITY_TYPE_APP, $appInfo)
470 ];
471 }
472 elseif ($appInfo && $appInfo['STATUS'] === AppTable::STATUS_LOCAL)
473 {
474 if (empty($appInfo['MENU_NAME']) && empty($appInfo['MENU_NAME_DEFAULT']))
475 {
476 AppTable::install($appInfo['ID']);
477 $result = ['success' => 1];
478 }
479 elseif (!empty($appInfo['URL_INSTALL']))
480 {
481 $appFields = [
482 'INSTALLED' => 'N',
483 ];
484
485 AppTable::update($appInfo['ID'], $appFields);
486
487 $result = [
488 'success' => 1,
489 'redirect' => CRestUtil::getApplicationPage($appInfo['ID']),
490 ];
491 }
492 }
493 else
494 {
495 $result = ['error' => Loc::getMessage('RMP_NOT_FOUND')];
496 }
497 }
498 else
499 {
500 $result = ['error' => Loc::getMessage('RMP_ACCESS_DENIED')];
501 }
502
503 return $result;
504 }
505
506 public static function setRights($appId, $rights) : array
507 {
508 $result = [];
509 // todo: maybe can add self::$contextUser to isAdmin check
510 if (CRestUtil::isAdmin())
511 {
512 if ($appId > 0)
513 {
514 $appInfo = AppTable::getByClientId($appId);
515 if ($appInfo['CODE'])
516 {
517 Analytic::logToFile(
518 'setAppRight',
519 $appInfo['CODE'],
520 $appInfo['CODE']
521 );
522 }
523 AppTable::setAccess($appId, $rights);
524 PlacementTable::clearHandlerCache();
525 $result = ['success' => 1];
526 }
527 }
528 else
529 {
530 $result = ['error' => Loc::getMessage('RMP_ACCESS_DENIED')];
531 }
532
533 return $result;
534 }
535
536 public static function getRights($appId)
537 {
538 // todo: maybe can add self::$contextUser to isAdmin check
539 if (CRestUtil::isAdmin())
540 {
541 if ($appId > 0)
542 {
543 $result = AppTable::getAccess($appId);
544 }
545 else
546 {
547 $result = 0;
548 }
549 }
550 else
551 {
552 $result = ['error' => Loc::getMessage('RMP_ACCESS_DENIED')];
553 }
554
555 return $result;
556 }
557}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static isModuleInstalled($moduleName)
static createFromTimestamp($timestamp)
Definition datetime.php:246
static install($code, $version=false, $checkHash=false, $installHash=false, $from=null)
static setRights($appId, $rights)
static uninstall($code, bool $clean=false, $from=null)