PageRenderTime 25ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/bitrix/modules/sale/install/components/bitrix/sale.bsm.site.master/class.php

https://gitlab.com/neuser/bitrix-core
PHP | 658 lines | 432 code | 84 blank | 142 comment | 31 complexity | 811e351ce57bfcb2a8afb62a8f06111c MD5 | raw file
  1. <?php
  2. if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
  3. use Bitrix\Main,
  4. Bitrix\Main\Loader,
  5. Bitrix\Main\Config\Option,
  6. Bitrix\Main\Localization\Loc,
  7. Bitrix\Sale\BsmSiteMaster\Tools,
  8. Bitrix\Sale\BsmSiteMaster\Templates;
  9. Loc::loadMessages(__FILE__);
  10. require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/wizard.php"); //Wizard API
  11. require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/install/wizard/utils.php"); //Wizard utils
  12. require_once("tools/bsmpackage.php");
  13. require_once("tools/modulechecker.php");
  14. require_once("tools/bitrixvmchecker.php");
  15. require_once("tools/agentchecker.php");
  16. require_once("tools/pushchecker.php");
  17. require_once("tools/sitepatcher.php");
  18. /**
  19. * Class SaleBsmSiteMaster
  20. */
  21. class SaleBsmSiteMaster extends \CBitrixComponent
  22. {
  23. /** @var string Full path to wizard directory */
  24. const WIZARD_DIR = __DIR__."/wizard/";
  25. /** @var string */
  26. const IS_SALE_BSM_SITE_MASTER_FINISH = "~IS_SALE_BSM_SITE_MASTER_FINISH";
  27. const ERROR_TYPE_COMPONENT = "COMPONENT";
  28. const ERROR_TYPE_WIZARD = "WIZARD";
  29. const BSM_WIZARD_SITE_ID = "~BSM_WIZARD_SITE_ID";
  30. /** @var string */
  31. const IS_SALE_BSM_SITE_MASTER_STUB = "~IS_SALE_BSM_SITE_MASTER_STUB";
  32. /** @var CWizardBase wizard */
  33. private $wizard;
  34. /** @var Tools\ModuleChecker $moduleChecker */
  35. private $moduleChecker;
  36. /** @var array variable for wizard */
  37. private $wizardVar = [];
  38. /** @var array default steps */
  39. private $defaultStep = [];
  40. /** @var array required steps */
  41. private $requiredStep = [];
  42. /** @var array error for wizard's step */
  43. private $wizardStepErrors = [];
  44. /**
  45. * @param $arParams
  46. * @return array
  47. */
  48. public function onPrepareComponentParams($arParams)
  49. {
  50. $this->defaultStep = $this->getDefaultSteps();
  51. $this->requiredStep = $this->getRequiredSteps();
  52. $this->moduleChecker = new Tools\ModuleChecker();
  53. $this->moduleChecker->setRequiredModules($this->getRequiredModules());
  54. $this->arResult = [
  55. "CONTENT" => "",
  56. "WIZARD_STEPS" => [],
  57. "ERROR" => [
  58. self::ERROR_TYPE_COMPONENT => [],
  59. self::ERROR_TYPE_WIZARD => [],
  60. ],
  61. ];
  62. return $arParams;
  63. }
  64. /**
  65. * @return array
  66. */
  67. private function getDefaultSteps()
  68. {
  69. return [
  70. "Bitrix\Sale\BsmSiteMaster\Steps\WelcomeStep" => [
  71. "SORT" => 100
  72. ],
  73. "Bitrix\Sale\BsmSiteMaster\Steps\BackupStep" => [
  74. "SORT" => 200
  75. ],
  76. "Bitrix\Sale\BsmSiteMaster\Steps\SiteInstructionStep" => [
  77. "SORT" => 400
  78. ],
  79. "Bitrix\Sale\BsmSiteMaster\Steps\SiteStep" => [
  80. "SORT" => 500
  81. ],
  82. "Bitrix\Sale\BsmSiteMaster\Steps\FinishStep" => [
  83. "SORT" => 600
  84. ],
  85. ];
  86. }
  87. /**
  88. * @return array
  89. */
  90. private function getRequiredSteps()
  91. {
  92. return [
  93. "Bitrix\Sale\BsmSiteMaster\Steps\UpdateSystemStep" => [
  94. "SORT" => 350
  95. ],
  96. "Bitrix\Sale\BsmSiteMaster\Steps\ModuleStep" => [
  97. "SORT" => 360
  98. ],
  99. "Bitrix\Sale\BsmSiteMaster\Steps\ModuleInstallStep" => [
  100. "SORT" => 370
  101. ]
  102. ];
  103. }
  104. /**
  105. * @return array
  106. */
  107. private function getRequiredModules()
  108. {
  109. return [
  110. "main" => [
  111. "version" => "20.0.0",
  112. "name" => Loc::getMessage("SALE_BSM_MODULE_MAIN_NAME"),
  113. ],
  114. "intranet" => [
  115. "version" => "19.0.900",
  116. "name" => Loc::getMessage("SALE_BSM_MODULE_INTRANET_NAME"),
  117. ],
  118. ];
  119. }
  120. /**
  121. * @return mixed|void
  122. * @throws Main\ArgumentNullException
  123. * @throws Main\ArgumentOutOfRangeException
  124. * @throws Main\LoaderException
  125. */
  126. public function executeComponent()
  127. {
  128. /** @noinspection PhpVariableNamingConventionInspection */
  129. global $APPLICATION;
  130. $APPLICATION->SetTitle(Loc::getMessage('SALE_BSM_TITLE'));
  131. $this->checkPermission();
  132. $this->checkModules();
  133. $this->checkSession();
  134. if ($errors = $this->getErrors(self::ERROR_TYPE_COMPONENT))
  135. {
  136. ShowError(implode("<br>", $errors));
  137. return;
  138. }
  139. $this->initSteps();
  140. $this->addStepsToResult();
  141. $this->includeWizardTemplate();
  142. $this->includeWizardSteps();
  143. $this->createWizard();
  144. $this->controlRequiredSteps();
  145. $content = $this->wizard->Display();
  146. $this->arResult['CONTENT'] = $content;
  147. $this->includeComponentTemplate();
  148. }
  149. /**
  150. * Create wizard and add steps
  151. */
  152. private function createWizard()
  153. {
  154. $bsmPackage = new Tools\BsmPackage();
  155. $bsmPackage->setId("bitrix:eshop");
  156. $this->wizard = new CWizardBase(Loc::getMessage("SALE_BSM_TITLE"), $bsmPackage);
  157. // before AddSteps
  158. $this->setWizardVariables();
  159. $this->wizard->AddSteps($this->arResult["WIZARD_STEPS"]); //Add steps
  160. $this->wizard->DisableAdminTemplate();
  161. $this->wizard->SetTemplate(new Templates\BsmSiteMasterTemplate());
  162. $this->wizard->SetReturnOutput();
  163. $this->wizard->SetFormName("sale_bsm_site_master");
  164. }
  165. /**
  166. * Set variables for wizard
  167. */
  168. private function setWizardVariables()
  169. {
  170. if (!($wizard = $this->getWizard()))
  171. {
  172. return;
  173. }
  174. $wizard->SetVar("component", $this);
  175. $wizard->SetVar("modulesRequired", $this->moduleChecker->getRequiredModules());
  176. foreach ($this->getWizardVars() as $varName => $varValue)
  177. {
  178. $wizard->SetVar($varName, $varValue);
  179. }
  180. }
  181. /**
  182. * @return CWizardBase
  183. */
  184. public function getWizard()
  185. {
  186. return $this->wizard;
  187. }
  188. /**
  189. * @return array
  190. */
  191. private function getWizardVars()
  192. {
  193. return $this->wizardVar;
  194. }
  195. /**
  196. * @return Tools\ModuleChecker
  197. */
  198. public function getModuleChecker()
  199. {
  200. return $this->moduleChecker;
  201. }
  202. /**
  203. * @param $stepName
  204. * @param $sort
  205. * @param bool $replace
  206. */
  207. private function addWizardStep($stepName, $sort, $replace = false)
  208. {
  209. if ($replace)
  210. {
  211. $this->defaultStep = [];
  212. }
  213. $this->defaultStep[$stepName] = [
  214. "SORT" => $sort
  215. ];
  216. }
  217. /**
  218. * Include wizard's step
  219. */
  220. private function includeWizardSteps()
  221. {
  222. $steps = $this->arResult["WIZARD_STEPS"];
  223. foreach ($steps as $step)
  224. {
  225. $class = array_pop(explode("\\", $step));
  226. $stepFile = mb_strtolower($class).".php";
  227. if (Main\IO\File::isFileExists(self::WIZARD_DIR.$stepFile))
  228. {
  229. require_once(self::WIZARD_DIR.$stepFile);
  230. }
  231. else
  232. {
  233. $this->addError(Loc::getMessage("SALE_BSM_WIZARD_STEP_NOT_FOUND", [
  234. "#STEP_NAME#" => $step
  235. ]), self::ERROR_TYPE_WIZARD);
  236. }
  237. }
  238. }
  239. /**
  240. * Include wizard's template
  241. */
  242. private function includeWizardTemplate()
  243. {
  244. if (Main\IO\File::isFileExists(self::WIZARD_DIR."template/bsmsitemastertemplate.php"))
  245. {
  246. require_once(self::WIZARD_DIR."template/bsmsitemastertemplate.php");
  247. }
  248. else
  249. {
  250. $this->addError(Loc::getMessage("SALE_BSM_WIZARD_TEMPLATE_NOT_FOUND"), self::ERROR_TYPE_WIZARD);
  251. }
  252. }
  253. /**
  254. * Add wizard steps to component's params
  255. */
  256. private function addStepsToResult()
  257. {
  258. foreach ($this->defaultStep as $stepName => $step)
  259. {
  260. $this->arResult["WIZARD_STEPS"][] = $stepName;
  261. }
  262. }
  263. /**
  264. * Check additional required step
  265. *
  266. * @throws Main\ArgumentNullException
  267. * @throws Main\ArgumentOutOfRangeException
  268. */
  269. private function initSteps()
  270. {
  271. $notExistModules = $this->moduleChecker->getNotExistModules();
  272. if ($notExistModules)
  273. {
  274. $this->addWizardStep("Bitrix\Sale\BsmSiteMaster\Steps\UpdateSystemStep", 350);
  275. $this->addWizardVar("not_exist_modules", $notExistModules);
  276. }
  277. else
  278. {
  279. $installedModules = $this->moduleChecker->checkInstalledModules();
  280. if ($installedModules["MIN_VERSION"])
  281. {
  282. $this->addWizardStep("Bitrix\Sale\BsmSiteMaster\Steps\ModuleStep", 360);
  283. $this->addWizardVar("min_version_modules", $installedModules["MIN_VERSION"]);
  284. }
  285. else
  286. {
  287. if ($installedModules["NOT_INSTALL"] || $this->moduleChecker->isModuleInstall())
  288. {
  289. $this->addWizardStep("Bitrix\Sale\BsmSiteMaster\Steps\ModuleStep", 360);
  290. $this->addWizardStep("Bitrix\Sale\BsmSiteMaster\Steps\ModuleInstallStep", 370);
  291. $this->addWizardVar("not_installed_modules", $installedModules["NOT_INSTALL"]);
  292. }
  293. }
  294. }
  295. $this->checkBitrixVm();
  296. $this->checkAgents();
  297. $this->checkPushServer();
  298. $this->sortSteps();
  299. }
  300. /**
  301. * Sort wizard's step
  302. */
  303. private function sortSteps()
  304. {
  305. $arSteps = [];
  306. foreach ($this->defaultStep as $stepName => $step)
  307. {
  308. $arSteps[$stepName] = $step["SORT"];
  309. }
  310. // sort step
  311. array_multisort($arSteps, SORT_ASC, $this->defaultStep);
  312. unset($arSteps);
  313. }
  314. private function checkBitrixVm()
  315. {
  316. $bitrixVmChecker = new Tools\BitrixVmChecker();
  317. if (!$bitrixVmChecker->isVm())
  318. {
  319. $this->addWizardStep("Bitrix\Sale\BsmSiteMaster\Steps\BitrixVmStep", 300);
  320. }
  321. }
  322. /**
  323. * @throws Main\ArgumentNullException
  324. * @throws Main\ArgumentOutOfRangeException
  325. */
  326. private function checkAgents()
  327. {
  328. $agentChecker = new Tools\AgentChecker();
  329. $result = $agentChecker->checkAgents();
  330. if (!$result->isSuccess())
  331. {
  332. $this->addWizardStep("Bitrix\Sale\BsmSiteMaster\Steps\AgentStep", 310);
  333. $errors = $result->getErrors();
  334. foreach ($errors as $error)
  335. {
  336. if ($error->getCode() === Tools\AgentChecker::ERROR_CODE_FAIL)
  337. {
  338. $this->addWizardVar("error", $error->getMessage());
  339. $this->addWizardVar("errorType", Tools\AgentChecker::ERROR_CODE_FAIL);
  340. break;
  341. }
  342. elseif ($error->getCode() === Tools\AgentChecker::ERROR_CODE_WARNING)
  343. {
  344. $this->addWizardVar("warning", $error->getMessage());
  345. $this->addWizardVar("errorType", Tools\AgentChecker::ERROR_CODE_WARNING);
  346. break;
  347. }
  348. }
  349. }
  350. }
  351. private function checkPushServer()
  352. {
  353. $pushChecker = new Tools\PushChecker();
  354. if ($pushChecker->isModuleLoaded())
  355. {
  356. $version = $pushChecker->getModuleVersion();
  357. if ($version && (version_compare($version, "19.0.0") !== -1))
  358. {
  359. if (!$pushChecker->isPushActive() && !$pushChecker->isShared())
  360. {
  361. $registerResult = $pushChecker->registerSharedServer();
  362. if (!$registerResult->isSuccess())
  363. {
  364. $errorMessages = $registerResult->getErrorMessages();
  365. $this->addWizardVar("push_error", $errorMessages);
  366. }
  367. // after ModuleStep
  368. $this->addWizardStep("Bitrix\Sale\BsmSiteMaster\Steps\PushAndPullStep", 340);
  369. }
  370. }
  371. }
  372. }
  373. /**
  374. * @param string $currentStep
  375. * @return array
  376. */
  377. public function getSteps($currentStep)
  378. {
  379. $result = [];
  380. $stepsName = $this->arResult["WIZARD_STEPS"];
  381. $firstStep = $stepsName[0];
  382. $lastKey = $stepsName[count($stepsName) - 1];
  383. if ($firstStep === $currentStep)
  384. {
  385. $result["NEXT_STEP"] = $stepsName[1];
  386. }
  387. elseif ($lastKey === $currentStep)
  388. {
  389. $result["PREV_STEP"] = $stepsName[count($stepsName) - 2];
  390. }
  391. else
  392. {
  393. $key = array_search($currentStep, $stepsName);
  394. $result["NEXT_STEP"] = $stepsName[$key+1];
  395. $result["PREV_STEP"] = $stepsName[$key-1];
  396. }
  397. return $result;
  398. }
  399. /**
  400. * Control required steps
  401. */
  402. private function controlRequiredSteps()
  403. {
  404. if ($this->wizard->IsNextButtonClick())
  405. {
  406. $nextStepId = $this->wizard->GetNextStepID();
  407. $nextStepSort = $this->defaultStep[$nextStepId]["SORT"];
  408. foreach ($this->requiredStep as $stepName => $stepValues)
  409. {
  410. if (array_key_exists($nextStepId, $this->requiredStep))
  411. {
  412. continue;
  413. }
  414. if ($this->isStepExists($stepName))
  415. {
  416. if ($nextStepSort >= $stepValues["SORT"])
  417. {
  418. $this->setStepImmediately($stepName);
  419. break;
  420. }
  421. }
  422. }
  423. }
  424. }
  425. /**
  426. * @param $stepName
  427. * @return bool
  428. */
  429. private function isStepExists($stepName)
  430. {
  431. if (in_array($stepName, $this->arResult["WIZARD_STEPS"]))
  432. {
  433. return true;
  434. }
  435. return false;
  436. }
  437. /**
  438. * @param $stepName
  439. */
  440. private function setStepImmediately($stepName)
  441. {
  442. unset($_REQUEST[$this->wizard->nextButtonID]);
  443. unset($_REQUEST[$this->wizard->nextStepHiddenID]);
  444. $this->wizard->SetCurrentStep($stepName);
  445. }
  446. /**
  447. * @param $name
  448. * @param $value
  449. */
  450. private function addWizardVar($name, $value)
  451. {
  452. $this->wizardVar[$name] = $value;
  453. }
  454. /**
  455. * @param $stepName
  456. * @param $value
  457. */
  458. private function addWizardStepError($stepName, $value)
  459. {
  460. $this->wizardStepErrors[$stepName]["ERRORS"][] = $value;
  461. }
  462. /**
  463. * @param $stepName
  464. * @return array
  465. */
  466. public function getWizardStepErrors($stepName)
  467. {
  468. return $this->wizardStepErrors[$stepName]["ERRORS"];
  469. }
  470. /**
  471. * @param $errors
  472. * @param $type
  473. */
  474. private function addErrors($errors, $type)
  475. {
  476. if (!is_array($errors))
  477. {
  478. $errors = [$errors];
  479. }
  480. foreach ($errors as $error)
  481. {
  482. $this->addError($error, $type);
  483. }
  484. }
  485. /**
  486. * @param array|string $error
  487. * @param $type
  488. */
  489. private function addError($error, $type)
  490. {
  491. $this->arResult["ERROR"][$type] = array_merge($this->arResult["ERROR"][$type], [$error]);
  492. }
  493. /**
  494. * @param $type
  495. * @return array
  496. */
  497. private function getErrors($type)
  498. {
  499. return isset($this->arResult["ERROR"][$type]) ? $this->arResult["ERROR"][$type] : [];
  500. }
  501. /**
  502. * @throws Main\ArgumentOutOfRangeException
  503. */
  504. public function setSaleBsmSiteMasterFinish()
  505. {
  506. Option::set("sale", self::IS_SALE_BSM_SITE_MASTER_FINISH, "Y");
  507. }
  508. /**
  509. * @return bool
  510. * @throws Main\ArgumentNullException
  511. * @throws Main\ArgumentOutOfRangeException
  512. */
  513. public function isSaleBsmSiteMasterFinish()
  514. {
  515. return (Option::get("sale", self::IS_SALE_BSM_SITE_MASTER_FINISH, "N") === "Y");
  516. }
  517. /**
  518. * @throws Main\ArgumentOutOfRangeException
  519. */
  520. public function setSaleBsmSiteMasterStub()
  521. {
  522. Option::set("sale", self::IS_SALE_BSM_SITE_MASTER_STUB, "Y");
  523. }
  524. /**
  525. * @param $siteId
  526. * @throws Main\ArgumentOutOfRangeException
  527. */
  528. public static function setBsmSiteId($siteId)
  529. {
  530. Option::set("sale", self::BSM_WIZARD_SITE_ID, $siteId);
  531. }
  532. /**
  533. * @return string
  534. * @throws Main\ArgumentNullException
  535. * @throws Main\ArgumentOutOfRangeException
  536. */
  537. public static function getBsmSiteId()
  538. {
  539. return Option::get("sale", self::BSM_WIZARD_SITE_ID);
  540. }
  541. private function checkPermission()
  542. {
  543. /** @noinspection PhpVariableNamingConventionInspection */
  544. global $USER;
  545. if (!$USER->IsAdmin())
  546. {
  547. $this->addError(Loc::getMessage("SALE_BSM_MODULE_PERMISSION_DENIED"), self::ERROR_TYPE_COMPONENT);
  548. }
  549. }
  550. /**
  551. * @throws Main\LoaderException
  552. */
  553. private function checkModules()
  554. {
  555. if (!Loader::includeModule("sale"))
  556. {
  557. $this->addError(Loc::getMessage("SALE_BSM_MODULE_NOT_INSTALL"), self::ERROR_TYPE_COMPONENT);
  558. }
  559. }
  560. private function checkSession()
  561. {
  562. if ($this->request->isPost() && !check_bitrix_sessid())
  563. {
  564. $this->addError(Loc::getMessage("SALE_BSM_WIZARD_ERROR_SESSION_EXPIRED"), self::ERROR_TYPE_COMPONENT);
  565. }
  566. }
  567. /**
  568. * @return string
  569. */
  570. public function __toString()
  571. {
  572. return __CLASS__;
  573. }
  574. }