BxDolInstallerUtils.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. define('BX_FORCE_AUTOUPDATE_MAX_CHANGED_FILES_PERCENT', 0.05);
  10. define('BX_FORCE_USE_FTP_FILE_TRANSFER', false);
  11. class BxDolInstallerUtils extends BxDolIO
  12. {
  13. protected $_aNonHashableFiles = array();
  14. public function __construct()
  15. {
  16. parent::__construct();
  17. }
  18. static public function isAllowUrlInclude()
  19. {
  20. if (version_compare(phpversion(), "5.2", ">") == 1 && version_compare(phpversion(), "8.0", "<") == 1) {
  21. $sAllowUrlInclude = ini_get('allow_url_include');
  22. return !($sAllowUrlInclude == 0);
  23. };
  24. return false;
  25. }
  26. static public function getModuleConfig($mixed)
  27. {
  28. $sConfig = '';
  29. if(is_array($mixed) && !empty($mixed['path']))
  30. $sConfig = BX_DIRECTORY_PATH_MODULES . $mixed['path'] . 'install/config.php';
  31. else if(is_string($mixed))
  32. $sConfig = $mixed;
  33. else
  34. return array();
  35. if(!file_exists($sConfig))
  36. return array();
  37. ob_start();
  38. include($sConfig);
  39. ob_end_clean();
  40. return isset($aConfig) ? $aConfig : array();
  41. }
  42. static public function isModuleInstalled($sUri)
  43. {
  44. return BxDolModuleQuery::getInstance()->isModule($sUri);
  45. }
  46. /**
  47. * Set module for delayed uninstall
  48. */
  49. static public function setModulePendingUninstall($sUri, $bPendingUninstall = true)
  50. {
  51. return BxDolModuleQuery::getInstance()->setModulePendingUninstall($sUri, $bPendingUninstall);
  52. }
  53. /**
  54. * Check if module is pending for uninstall
  55. */
  56. static public function isModulePendingUninstall($sUri)
  57. {
  58. $a = BxDolModuleQuery::getInstance()->getModuleByUri($sUri);
  59. return $a['pending_uninstall'];
  60. }
  61. /**
  62. * Check all pending for uninstallation modules and uninstall them if no pending for deletion files are found
  63. */
  64. static public function checkModulesPendingUninstall()
  65. {
  66. $a = BxDolModuleQuery::getInstance()->getModules();
  67. foreach ($a as $aModule) {
  68. // after we make sure that all pending for deletion files are deleted
  69. if (!$aModule['pending_uninstall'] || BxDolStorage::isQueuedFilesForDeletion($aModule['name']))
  70. continue;
  71. // remove pending uninstall flag
  72. self::setModulePendingUninstall($aModule['uri'], false);
  73. // perform uninstallation
  74. $aResult = BxDolStudioInstallerUtils::getInstance()->perform($aModule['path'], 'uninstall');
  75. // send email nofitication
  76. $aTemplateKeys = array(
  77. 'Module' => $aModule['title'],
  78. 'Result' => _t('_Success'),
  79. 'Message' => '',
  80. );
  81. if ($aResult['code'] > 0) {
  82. $aTemplateKeys['Result'] = _t('_Failed');
  83. $aTemplateKeys['Message'] = $aResult['message'];
  84. }
  85. $aMessage = BxDolEmailTemplates::getInstance()->parseTemplate('t_DelayedModuleUninstall', $aTemplateKeys);
  86. sendMail (getParam('site_email'), $aMessage['Subject'], $aMessage['Body'], 0, array(), BX_EMAIL_SYSTEM);
  87. }
  88. }
  89. /**
  90. * Generate hash for module files.
  91. * @param $sPath module's root folder
  92. * @param $aFiles array to fill with files hashes
  93. */
  94. public function hashFiles($sPath, &$aFiles)
  95. {
  96. $aExcludes = array('.', '..', 'error_log', 'php.ini', '.DS_Store', 'Thumbs.db');
  97. if (file_exists($sPath) && is_dir($sPath) && ($rSource = opendir($sPath))) {
  98. while (($sFile = readdir($rSource)) !== false) {
  99. if ('.' == $sFile[0] || in_array($sFile, $aExcludes))
  100. continue;
  101. if (in_array($this->filePathWithoutBase($sPath . $sFile), $this->_aNonHashableFiles))
  102. continue;
  103. if (is_dir($sPath . $sFile))
  104. $this->hashFiles($sPath . $sFile . '/', $aFiles);
  105. else
  106. $aFiles[] = $this->hashInfo($sPath . $sFile);
  107. }
  108. closedir($rSource);
  109. } elseif (file_exists($sPath) && is_file($sPath)) {
  110. $aFiles[] = $this->hashInfo($sPath);
  111. }
  112. }
  113. /**
  114. * Check module's files hashes. For system files use @see BxDolInstallerHasher class.
  115. * @param $aFiles current files checksums
  116. * @param $iModuleId module id
  117. * @return empty array on success, or array of files which checksum was changed
  118. */
  119. public function hashCheck($aFiles, $iModuleId)
  120. {
  121. $oDb = bx_instance('BxDolStudioInstallerQuery');
  122. $aFilesOrig = $oDb->getModuleTrackFiles($iModuleId);
  123. $aFailesChanged = array();
  124. foreach ($aFiles as $aFile)
  125. if(!isset($aFilesOrig[$aFile['file']]) || $aFilesOrig[$aFile['file']]['hash'] != $aFile['hash'])
  126. $aFailesChanged[] = $aFile['file'];
  127. $fChangedPercent = 0;
  128. if(count($aFilesOrig) != 0)
  129. $fChangedPercent = count($aFailesChanged) / count($aFilesOrig);
  130. return array($aFailesChanged, $fChangedPercent);
  131. }
  132. protected function hashInfo($sPath)
  133. {
  134. return array(
  135. 'file' => $this->filePathWithoutBase($sPath),
  136. 'hash' => md5_file($sPath)
  137. );
  138. }
  139. protected function filePathWithoutBase($sPath)
  140. {
  141. return bx_ltrim_str($sPath, BX_DIRECTORY_PATH_ROOT);
  142. }
  143. }
  144. /** @} */