• Модуль: rest
  • Путь к файлу: ~/bitrix/modules/rest/lib/marketplace/application.php
  • Класс: BitrixRestMarketplaceApplication
  • Вызов: Application::install
static function install($code, $version = false, $checkHash = false, $installHash = false, $from = null) : array
{
	$result = [];

	if (!OAuthService::getEngine()->isRegistered())
	{
		try
		{
			OAuthService::register();
			OAuthService::getEngine()->getClient()->getApplicationList();
		}
		catch(SystemException $e)
		{
			$result = [
				'error' => $e->getCode(),
				'errorDescription' => $e->getMessage(),
			];
		}
	}

	if (OAuthService::getEngine()->isRegistered())
	{
		$version = !empty($version) ? $version : false;

		$result = [
			'error' => 'INSTALL_ERROR',
			'errorDescription' => Loc::getMessage('RMP_INSTALL_ERROR'),
		];

		$appDetailInfo = false;
		if ($code <> '')
		{
			if (!empty($checkHash) && !empty($installHash))
			{
				$appDetailInfo = Client::getInstall($code, $version, $checkHash, $installHash);
			}
			else
			{
				$appDetailInfo = Client::getInstall($code, $version);
			}

			if ($appDetailInfo)
			{
				$appDetailInfo = $appDetailInfo['ITEMS'];
			}
		}

		if (
			$appDetailInfo
			&& (
				!Access::isAvailable($code)
				|| !Access::isAvailableCount(Access::ENTITY_TYPE_APP, $code)
			)
		)
		{
			$result = [
				'error' => 'ACTION_ACCESS_DENIED',
				'errorDescription' => Loc::getMessage('RMP_ERROR_ACCESS_DENIED'),
				'helperCode' => Access::getHelperCode(Access::ACTION_INSTALL, Access::ENTITY_TYPE_APP, $appDetailInfo)
			];
		}
		elseif ($appDetailInfo)
		{
			if (CRestUtil::canInstallApplication($appDetailInfo, self::$contextUserId))
			{
				$queryFields = [
					'CLIENT_ID' => $appDetailInfo['APP_CODE'],
					'VERSION' => $appDetailInfo['VER'],
					'BY_SUBSCRIPTION' => $appDetailInfo['BY_SUBSCRIPTION'] ?? 'N',
				];

				if (!empty($checkHash) && !empty($installHash))
				{
					$queryFields['CHECK_HASH'] = $checkHash;
					$queryFields['INSTALL_HASH'] = $installHash;
				}

				$installResult = OAuthService::getEngine()->getClient()->installApplication($queryFields);
				if (isset($installResult['error']) && $installResult['error'] === 'verification_needed')
				{
					if (BitrixMainModuleManager::isModuleInstalled('bitrix24'))
					{
						OAuthService::getEngine()->getClient()->getApplicationList();
						$installResult = OAuthService::getEngine()->getClient()->installApplication($queryFields);
					}
					elseif (
						defined('ADMIN_SECTION')
						&& $appDetailInfo['TYPE'] === 'C'
						&& $appDetailInfo['MODE'] === 'S'
						&& mb_strpos($appDetailInfo['CODE'], 'bitrix.') === 0
					)
					{
						$installResult = [
							'result' => [
								'client_id' => $appDetailInfo['APP_CODE'],
								'version' => (int)$appDetailInfo['VER'],
								'status' => AppTable::STATUS_FREE,
								'scope' => array_keys($appDetailInfo['RIGHTS']),
							],
						];
					}
				}

				if (isset($installResult['error']) && $installResult['error'])
				{
					$result['error'] = $installResult['error'];
					$result['errorDescription'] = $installResult['error_description'];
				}
				elseif ($installResult['result'])
				{
					$appFields = [
						'CLIENT_ID' => $installResult['result']['client_id'],
						'CODE' => $appDetailInfo['CODE'],
						'ACTIVE' => AppTable::ACTIVE,
						'INSTALLED' => ($appDetailInfo['OPEN_API'] === 'Y' || empty($appDetailInfo['INSTALL_URL']))
							? AppTable::INSTALLED
							: AppTable::NOT_INSTALLED,
						'URL' => $appDetailInfo['URL'],
						'URL_DEMO' => $appDetailInfo['DEMO_URL'],
						'URL_INSTALL' => $appDetailInfo['INSTALL_URL'],
						'VERSION' => $installResult['result']['version'],
						'SCOPE' => implode(',', $installResult['result']['scope']),
						'STATUS' => $installResult['result']['status'],
						'SHARED_KEY' => $appDetailInfo['SHARED_KEY'],
						'CLIENT_SECRET' => '',
						'APP_NAME' => $appDetailInfo['NAME'],
						'MOBILE' => $appDetailInfo['BXMOBILE'] === 'Y' ? AppTable::ACTIVE : AppTable::INACTIVE,
						'USER_INSTALL' => CRestUtil::appCanBeInstalledByUser($appDetailInfo) ? AppTable::ACTIVE : AppTable::INACTIVE,
					];

					if (
						$appFields['STATUS'] === AppTable::STATUS_TRIAL
						|| $appFields['STATUS'] === AppTable::STATUS_PAID
					)
					{
						$appFields['DATE_FINISH'] = DateTime::createFromTimestamp($installResult['result']['date_finish']);
					}
					else
					{
						$appFields['DATE_FINISH'] = '';
					}

					//Configuration app
					if (
						$appDetailInfo['TYPE'] === AppTable::TYPE_CONFIGURATION
						&& $appDetailInfo['MODE'] !== AppTable::MODE_SITE
					)
					{
						$appFields['INSTALLED'] = AppTable::NOT_INSTALLED;
					}

					$existingApp = AppTable::getByClientId($appFields['CLIENT_ID']);
					if ($existingApp)
					{
						$addResult = AppTable::update($existingApp['ID'], $appFields);
					}
					else
					{
						$addResult = AppTable::add($appFields);
					}

					if ($addResult->isSuccess())
					{
						$appId = $addResult->getId();

						if ($existingApp)
						{
							AppLogTable::log($appId, AppLogTable::ACTION_TYPE_UPDATE);
						}
						else
						{
							AppLogTable::log($appId, AppLogTable::ACTION_TYPE_ADD);
						}

						if ($appFields['INSTALLED'] === AppTable::INSTALLED)
						{
							AppLogTable::log($appId, AppLogTable::ACTION_TYPE_INSTALL);
						}

						if (!CRestUtil::isAdmin(self::$contextUserId))
						{
							CRestUtil::notifyInstall($appFields);
						}

						if (isset($appDetailInfo['MENU_TITLE']) && is_array($appDetailInfo['MENU_TITLE']))
						{
							foreach ($appDetailInfo['MENU_TITLE'] as $lang => $langName)
							{
								$appLangFields = array(
									'APP_ID' => $appId,
									'LANGUAGE_ID' => $lang,
									'MENU_NAME' => $langName
								);

								$appLangUpdateFields = array(
									'MENU_NAME' => $langName
								);

								$connection = MainApplication::getConnection();
								$queries = $connection->getSqlHelper()->prepareMerge(
									AppLangTable::getTableName(),
									[
										'APP_ID',
										'LANGUAGE_ID'
									],
									$appLangFields,
									$appLangUpdateFields
								);

								foreach($queries as $query)
								{
									$connection->queryExecute($query);
								}
							}
						}

						if ($appDetailInfo['OPEN_API'] === 'Y' && !empty($appFields['URL_INSTALL']))
						{
							// checkCallback is already called inside checkFields
							$result = EventTable::add(
								[
									'APP_ID' => $appId,
									'EVENT_NAME' => 'ONAPPINSTALL',
									'EVENT_HANDLER' => $appFields['URL_INSTALL'],
								]
							);
							if ($result->isSuccess())
							{
								Sender::bind('rest', 'OnRestAppInstall');
							}
						}

						AppTable::install($appId);

						$redirect = false;
						$open = false;
						$sliderUrl = false;
						if ($appDetailInfo['TYPE'] !== AppTable::TYPE_CONFIGURATION)
						{
							$uriString = CRestUtil::getApplicationPage($appId);
							$uri = new Uri($uriString);
							$ver = (int) $version;
							$uri->addParams(
								[
									'ver' => $ver,
									'check_hash' => $checkHash,
									'install_hash' => $installHash
								]
							);
							$redirect = $uri->getUri();
							$open = $appDetailInfo['OPEN_API'] !== 'Y';
						}
						else
						{
							if ((int)$appDetailInfo['IMPORT_ZIP_ID'] > 0)
							{
								$url = Url::getConfigurationImportZipUrl((int)$appDetailInfo['IMPORT_ZIP_ID']);
							}
							else
							{
								$url = Url::getConfigurationImportAppUrl($appDetailInfo['CODE']);
							}

							$uri = new Uri($url);
							if (!empty($checkHash) && !empty($installHash))
							{
								$uri->addParams(
									[
										'check_hash' => $checkHash,
										'install_hash' => $installHash,
									]
								);
							}
							$sliderUrl = $uri->getUri();
						}

						$result = [
							'success' => 1,
							'id' => $appId,
							'open' => $open,
							'installed' => $appFields['INSTALLED'] === 'Y',
							'redirect' => $redirect,
							'openSlider' => $sliderUrl,
						];

						Analytic::logToFile(
							'finishInstall',
							$code,
							$from ?? 'index'
						);
					}
					else
					{
						$result['errorDescription'] = implode('
', $addResult->getErrorMessages()); } } } elseif ( !empty($appInfo['HOLD_INSTALL_BY_TRIAL']) && $appInfo['HOLD_INSTALL_BY_TRIAL'] === 'Y' && Client::isSubscriptionDemo() ) { $result = ['error' => Loc::getMessage('RMP_TRIAL_HOLD_INSTALL')]; } else { $result = [ 'error' => 'ACCESS_DENIED', 'errorDescription' => Loc::getMessage('RMP_ACCESS_DENIED'), ]; } } else { $result = [ 'error' => 'APPLICATION_NOT_FOUND', 'errorDescription' => Loc::getMessage('RMP_NOT_FOUND'), ]; } } elseif (!$result['error']) { $result = [ 'error' => 'OAUTH_REGISTER', 'errorDescription' => Loc::getMessage('RMP_INSTALL_ERROR'), ]; } if (isset($result['error']) && $result['error']) { if ($result['error'] === 'SUBSCRIPTION_REQUIRED') { $result['errorDescription'] = Loc::getMessage('RMP_ERROR_SUBSCRIPTION_REQUIRED'); } elseif ($result['error'] === 'verification_needed') { $result['errorDescription'] = Loc::getMessage('RMP_ERROR_VERIFICATION_NEEDED'); } } return $result; }