diff --git a/composer.json b/composer.json index bcaa784c9..eab8d0a0a 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,8 @@ "autoload": { "classmap": [ "core", - "application" + "application", + "sources/application" ], "exclude-from-classmap": [ "core/dbobjectsearch.class.php", diff --git a/datamodels/2.x/installation.xml b/datamodels/2.x/installation.xml index e15ab2b39..6f7fc2760 100755 --- a/datamodels/2.x/installation.xml +++ b/datamodels/2.x/installation.xml @@ -17,7 +17,6 @@ itop-welcome-itil itop-tickets itop-files-information - itop-twig-base combodo-db-tools itop-core-update itop-hub-connector diff --git a/datamodels/2.x/itop-core-update/ajax.php b/datamodels/2.x/itop-core-update/ajax.php index 97f03b61e..78f513701 100644 --- a/datamodels/2.x/itop-core-update/ajax.php +++ b/datamodels/2.x/itop-core-update/ajax.php @@ -8,8 +8,20 @@ namespace Combodo\iTop\CoreUpdate; use Combodo\iTop\CoreUpdate\Controller\AjaxController; use ContextTag; +use MetaModel; +use utils; + +if (!defined('MODULESROOT')) +{ + define('MODULESROOT', APPROOT.'env-production/'); +} + +require_once(MODULESROOT.'itop-core-update/src/Service/RunTimeEnvironmentCoreUpdater.php'); +require_once(MODULESROOT.'itop-core-update/src/Service/CoreUpdater.php'); +require_once(MODULESROOT.'itop-core-update/src/Controller/AjaxController.php'); + +MetaModel::LoadConfig(utils::GetConfig()); -require_once(APPROOT.'application/startup.inc.php'); new ContextTag('Setup'); $oUpdateController = new AjaxController(); diff --git a/datamodels/2.x/itop-core-update/module.itop-core-update.php b/datamodels/2.x/itop-core-update/module.itop-core-update.php index 1d28e74a4..24e8bda89 100644 --- a/datamodels/2.x/itop-core-update/module.itop-core-update.php +++ b/datamodels/2.x/itop-core-update/module.itop-core-update.php @@ -20,7 +20,6 @@ SetupWebPage::AddModule( // Setup // 'dependencies' => array( - 'itop-twig-base/1.0.0', 'itop-files-information/1.0.0', 'combodo-db-tools/1.0.8', ), diff --git a/datamodels/2.x/itop-core-update/src/Controller/AjaxController.php b/datamodels/2.x/itop-core-update/src/Controller/AjaxController.php index 38670804c..b0176829c 100644 --- a/datamodels/2.x/itop-core-update/src/Controller/AjaxController.php +++ b/datamodels/2.x/itop-core-update/src/Controller/AjaxController.php @@ -8,11 +8,11 @@ namespace Combodo\iTop\CoreUpdate\Controller; +use Combodo\iTop\Application\TwigBase\Controller\Controller; use Combodo\iTop\CoreUpdate\Service\CoreUpdater; use Combodo\iTop\DBTools\Service\DBToolsUtils; use Combodo\iTop\FilesInformation\Service\FileNotExistException; use Combodo\iTop\FilesInformation\Service\FilesInformation; -use Combodo\iTop\TwigBase\Controller\Controller; use Dict; use Exception; use IssueLog; @@ -22,61 +22,63 @@ use utils; class AjaxController extends Controller { - const LOCAL_DIR = __DIR__; + public function __construct() + { + parent::__construct(); + $this->InitFromModule(); + } - public function OperationCanUpdateCore() - { - $aParams = array(); + public function OperationCanUpdateCore() + { + $aParams = array(); - try - { - $bCanUpdateCore = FilesInformation::CanUpdateCore($sMessage); - $aParams['bStatus'] = $bCanUpdateCore; - if ($bCanUpdateCore) - { - $aParams['sMessage'] = Dict::S('iTopUpdate:UI:CanCoreUpdate:Yes'); - } - else - { - $aParams['sMessage'] = Dict::Format('iTopUpdate:UI:CanCoreUpdate:No', $sMessage); - } - } - catch (FileNotExistException $e) - { - $aParams['bStatus'] = false; - $aParams['sMessage'] = Dict::Format('iTopUpdate:UI:CanCoreUpdate:ErrorFileNotExist', $e->getMessage()); - } - catch(Exception $e) - { - $aParams['bStatus'] = false; - $aParams['sMessage'] = Dict::Format('iTopUpdate:UI:CanCoreUpdate:Error', $e->getMessage()); - } + try + { + $bCanUpdateCore = FilesInformation::CanUpdateCore($sMessage); + $aParams['bStatus'] = $bCanUpdateCore; + if ($bCanUpdateCore) + { + $aParams['sMessage'] = Dict::S('iTopUpdate:UI:CanCoreUpdate:Yes'); + } + else + { + $aParams['sMessage'] = Dict::Format('iTopUpdate:UI:CanCoreUpdate:No', $sMessage); + } + } catch (FileNotExistException $e) + { + $aParams['bStatus'] = false; + $aParams['sMessage'] = Dict::Format('iTopUpdate:UI:CanCoreUpdate:ErrorFileNotExist', $e->getMessage()); + } catch (Exception $e) + { + $aParams['bStatus'] = false; + $aParams['sMessage'] = Dict::Format('iTopUpdate:UI:CanCoreUpdate:Error', $e->getMessage()); + } - $this->DisplayJSONPage($aParams); - } + $this->DisplayJSONPage($aParams); + } - public function OperationGetItopDiskSpace() - { - $aParams = array(); - $aParams['iItopDiskSpace'] = FilesInformation::GetItopDiskSpace(); - $aParams['sItopDiskSpace'] = utils::BytesToFriendlyFormat($aParams['iItopDiskSpace']); - $this->DisplayJSONPage($aParams); - } + public function OperationGetItopDiskSpace() + { + $aParams = array(); + $aParams['iItopDiskSpace'] = FilesInformation::GetItopDiskSpace(); + $aParams['sItopDiskSpace'] = utils::BytesToFriendlyFormat($aParams['iItopDiskSpace']); + $this->DisplayJSONPage($aParams); + } - public function OperationGetDBDiskSpace() - { - $aParams = array(); - $aParams['iDBDiskSpace'] = DBToolsUtils::GetDatabaseSize(); - $aParams['sDBDiskSpace'] = utils::BytesToFriendlyFormat($aParams['iDBDiskSpace']); - $this->DisplayJSONPage($aParams); - } + public function OperationGetDBDiskSpace() + { + $aParams = array(); + $aParams['iDBDiskSpace'] = DBToolsUtils::GetDatabaseSize(); + $aParams['sDBDiskSpace'] = utils::BytesToFriendlyFormat($aParams['iDBDiskSpace']); + $this->DisplayJSONPage($aParams); + } - public function OperationGetCurrentVersion() - { - $aParams = array(); - $aParams['sVersion'] = Dict::Format('UI:iTopVersion:Long', ITOP_APPLICATION, ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE); - $this->DisplayJSONPage($aParams); - } + public function OperationGetCurrentVersion() + { + $aParams = array(); + $aParams['sVersion'] = Dict::Format('UI:iTopVersion:Long', ITOP_APPLICATION, ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE); + $this->DisplayJSONPage($aParams); + } public function OperationEnterMaintenance() { @@ -85,8 +87,7 @@ class AjaxController extends Controller { SetupUtils::EnterReadOnlyMode(MetaModel::GetConfig()); $iResponseCode = 200; - } - catch (Exception $e) + } catch (Exception $e) { IssueLog::Error("EnterMaintenance: ".$e->getMessage()); $aParams['sError'] = $e->getMessage(); @@ -102,8 +103,7 @@ class AjaxController extends Controller { SetupUtils::ExitReadOnlyMode(); $iResponseCode = 200; - } - catch (Exception $e) + } catch (Exception $e) { IssueLog::Error("ExitMaintenance: ".$e->getMessage()); $aParams['sError'] = $e->getMessage(); @@ -112,22 +112,21 @@ class AjaxController extends Controller $this->DisplayJSONPage($aParams, $iResponseCode); } - public function OperationBackup() - { - $aParams = array(); - try - { - CoreUpdater::Backup(); - $iResponseCode = 200; - } - catch (Exception $e) - { - IssueLog::Error("Backup: ".$e->getMessage()); - $aParams['sError'] = $e->getMessage(); - $iResponseCode = 500; - } - $this->DisplayJSONPage($aParams, $iResponseCode); - } + public function OperationBackup() + { + $aParams = array(); + try + { + CoreUpdater::Backup(); + $iResponseCode = 200; + } catch (Exception $e) + { + IssueLog::Error("Backup: ".$e->getMessage()); + $aParams['sError'] = $e->getMessage(); + $iResponseCode = 500; + } + $this->DisplayJSONPage($aParams, $iResponseCode); + } public function OperationFilesArchive() { @@ -136,8 +135,7 @@ class AjaxController extends Controller { CoreUpdater::CreateItopArchive(); $iResponseCode = 200; - } - catch (Exception $e) + } catch (Exception $e) { IssueLog::Error("FilesArchive: ".$e->getMessage()); $aParams['sError'] = $e->getMessage(); @@ -146,39 +144,71 @@ class AjaxController extends Controller $this->DisplayJSONPage($aParams, $iResponseCode); } - public function OperationCopyFiles() - { - $aParams = array(); - try - { - CoreUpdater::CopyCoreFiles(); - $iResponseCode = 200; - } - catch (Exception $e) - { - IssueLog::Error("CopyFiles: ".$e->getMessage()); - $aParams['sError'] = $e->getMessage(); - $iResponseCode = 500; - } + public function OperationCopyFiles() + { + $aParams = array(); + try + { + CoreUpdater::CopyCoreFiles(); + $iResponseCode = 200; + } catch (Exception $e) + { + IssueLog::Error("CopyFiles: ".$e->getMessage()); + $aParams['sError'] = $e->getMessage(); + $iResponseCode = 500; + } - $this->DisplayJSONPage($aParams, $iResponseCode); - } + $this->DisplayJSONPage($aParams, $iResponseCode); + } - public function OperationCompile() - { - $aParams = array(); - try - { - CoreUpdater::Compile(); - $iResponseCode = 200; - } - catch (Exception $e) - { - IssueLog::Error("Compile: ".$e->getMessage()); - $aParams['sError'] = $e->getMessage(); - $iResponseCode = 500; - } + public function OperationCheckCompile() + { + $aParams = array(); + try + { + CoreUpdater::CheckCompile(); + $iResponseCode = 200; + } catch (Exception $e) + { + IssueLog::Error("Compile: ".$e->getMessage()); + $aParams['sError'] = $e->getMessage(); + $iResponseCode = 500; + } - $this->DisplayJSONPage($aParams, $iResponseCode); - } + $this->DisplayJSONPage($aParams, $iResponseCode); + } + + public function OperationCompile() + { + $aParams = array(); + try + { + CoreUpdater::Compile(); + $iResponseCode = 200; + } catch (Exception $e) + { + IssueLog::Error("Compile: ".$e->getMessage()); + $aParams['sError'] = $e->getMessage(); + $iResponseCode = 500; + } + + $this->DisplayJSONPage($aParams, $iResponseCode); + } + + public function OperationUpdateDatabase() + { + $aParams = array(); + try + { + CoreUpdater::UpdateDatabase(); + $iResponseCode = 200; + } catch (Exception $e) + { + IssueLog::Error("Compile: ".$e->getMessage()); + $aParams['sError'] = $e->getMessage(); + $iResponseCode = 500; + } + + $this->DisplayJSONPage($aParams, $iResponseCode); + } } diff --git a/datamodels/2.x/itop-core-update/src/Controller/UpdateController.php b/datamodels/2.x/itop-core-update/src/Controller/UpdateController.php index 3b4174a29..7f686ff0e 100644 --- a/datamodels/2.x/itop-core-update/src/Controller/UpdateController.php +++ b/datamodels/2.x/itop-core-update/src/Controller/UpdateController.php @@ -6,9 +6,9 @@ namespace Combodo\iTop\CoreUpdate\Controller; +use Combodo\iTop\Application\TwigBase\Controller\Controller; use Combodo\iTop\CoreUpdate\Service\CoreUpdater; use Combodo\iTop\DBTools\Service\DBToolsUtils; -use Combodo\iTop\TwigBase\Controller\Controller; use Dict; use Exception; use SetupUtils; @@ -16,7 +16,11 @@ use utils; class UpdateController extends Controller { - const LOCAL_DIR = __DIR__; + public function __construct() + { + parent::__construct(); + $this->InitFromModule(); + } public function OperationSelectUpdateFile() { diff --git a/datamodels/2.x/itop-core-update/src/Service/CoreUpdater.php b/datamodels/2.x/itop-core-update/src/Service/CoreUpdater.php index fa1f7aa5a..739ef3fb6 100644 --- a/datamodels/2.x/itop-core-update/src/Service/CoreUpdater.php +++ b/datamodels/2.x/itop-core-update/src/Service/CoreUpdater.php @@ -1,6 +1,7 @@ getMessage()); IssueLog::Info('itop-core-update: ended'); throw $e; - } - finally + } finally { self::RRmdir(self::UPDATE_DIR); } } + /** + * @throws \Exception + */ + public static function CheckCompile() + { + try + { + // Compile code in env-production-build + IssueLog::Info('itop-core-update: Check compilation'); + + $sTargetEnv = 'production'; + $oRuntimeEnv = new RunTimeEnvironmentCoreUpdater($sTargetEnv, false); + $oRuntimeEnv->CheckDirectories($sTargetEnv); + $oRuntimeEnv->CompileFrom('production'); + SetupUtils::tidydir(APPROOT."env-{$sTargetEnv}-build"); + } catch (Exception $e) + { + IssueLog::error($e->getMessage()); + throw $e; + } + } + /** * @throws \Exception */ @@ -91,18 +112,44 @@ final class CoreUpdater { // Compile code IssueLog::Info('itop-core-update: Start compilation'); - IssueLog::Info('itop-core-update: Version Dev'); $sTargetEnv = 'production'; $oRuntimeEnv = new RunTimeEnvironmentCoreUpdater($sTargetEnv); $oRuntimeEnv->CheckDirectories($sTargetEnv); $oRuntimeEnv->CompileFrom('production'); + + IssueLog::Info('itop-core-update: Compilation done'); + } catch (Exception $e) + { + IssueLog::error($e->getMessage()); + throw $e; + } + } + + /** + * @throws \Exception + */ + public static function UpdateDatabase() + { + try + { + // Compile code + IssueLog::Info('itop-core-update: Update database'); + + $sTargetEnv = 'production'; + $oRuntimeEnv = new RunTimeEnvironmentCoreUpdater($sTargetEnv); + $oRuntimeEnv->CheckDirectories($sTargetEnv); $oConfig = $oRuntimeEnv->MakeConfigFile($sTargetEnv.' (built on '.date('Y-m-d').')'); $oConfig->Set('access_mode', ACCESS_FULL); $oRuntimeEnv->WriteConfigFileSafe($oConfig); $oRuntimeEnv->InitDataModel($oConfig, true); - $aAvailableModules = $oRuntimeEnv->AnalyzeInstallation($oConfig, $oRuntimeEnv->GetBuildDir()); + $sModulesDirToKeep = $oRuntimeEnv->GetBuildDir(); + $aDirsToScanForModules = array( + $sModulesDirToKeep, + APPROOT.'extensions' + ); + $aAvailableModules = $oRuntimeEnv->AnalyzeInstallation($oConfig, $aDirsToScanForModules); $aSelectedModules = array(); foreach ($aAvailableModules as $sModuleId => $aModule) { @@ -142,9 +189,10 @@ final class CoreUpdater $oRuntimeEnv->RecordInstallation($oConfig, $sDataModelVersion, $aSelectedModules, $aSelectedExtensionCodes, 'Done by the iTop Core Updater'); - IssueLog::Info('itop-core-update: Compilation done'); - } - catch (Exception $e) + $oRuntimeEnv->Commit(); + + IssueLog::Info('itop-core-update: Update database done'); + } catch (Exception $e) { IssueLog::error($e->getMessage()); throw $e; @@ -186,87 +234,87 @@ final class CoreUpdater */ public static function Backup() { - $sBackupName = self::GetBackupName(); - $sBackupFile = self::GetBackupFile(); - if (file_exists($sBackupFile)) - { - @unlink($sBackupFile); - } + $sBackupName = self::GetBackupName(); + $sBackupFile = self::GetBackupFile(); + if (file_exists($sBackupFile)) + { + @unlink($sBackupFile); + } - self::DoBackup($sBackupName); + self::DoBackup($sBackupName); } /** * @throws \Exception */ public static function CreateItopArchive() - { - set_time_limit(0); - $sItopArchiveFile = self::GetItopArchiveFile(); - if (file_exists($sItopArchiveFile)) - { - @unlink($sItopArchiveFile); - } + { + set_time_limit(0); + $sItopArchiveFile = self::GetItopArchiveFile(); + if (file_exists($sItopArchiveFile)) + { + @unlink($sItopArchiveFile); + } - $sTempFile = sys_get_temp_dir().'/'.basename($sItopArchiveFile); - if (file_exists($sTempFile)) - { - @unlink($sTempFile); - } + $sTempFile = sys_get_temp_dir().'/'.basename($sItopArchiveFile); + if (file_exists($sTempFile)) + { + @unlink($sTempFile); + } - $aPathInfo = pathInfo(realpath(APPROOT)); - $sParentPath = $aPathInfo['dirname']; - $sDirName = $aPathInfo['basename']; + $aPathInfo = pathInfo(realpath(APPROOT)); + $sParentPath = $aPathInfo['dirname']; + $sDirName = $aPathInfo['basename']; - $oZipArchive = new ZipArchive(); - $oZipArchive->open($sTempFile, ZIPARCHIVE::CREATE); - $oZipArchive->addEmptyDir($sDirName); - self::ZipFolder(realpath(APPROOT), $oZipArchive, strlen("$sParentPath/")); - $oZipArchive->close(); - - if (!file_exists($sTempFile)) - { - IssueLog::Error("Failed to create itop archive $sTempFile"); - } + $oZipArchive = new ZipArchive(); + $oZipArchive->open($sTempFile, ZIPARCHIVE::CREATE); + $oZipArchive->addEmptyDir($sDirName); + self::ZipFolder(realpath(APPROOT), $oZipArchive, strlen("$sParentPath/")); + $oZipArchive->close(); - if (@rename($sTempFile, $sItopArchiveFile)) - { - IssueLog::Info("Archive $sItopArchiveFile Created"); - } - else - { - IssueLog::Error("Failed to create archive $sItopArchiveFile"); - } - } + if (!file_exists($sTempFile)) + { + IssueLog::Error("Failed to create itop archive $sTempFile"); + } - /** - * - * @param string $sTargetFile - * @throws Exception - */ - private static function DoBackup($sTargetFile) - { - // Make sure the target directory exists - $sBackupDir = dirname($sTargetFile); - SetupUtils::builddir($sBackupDir); + if (@rename($sTempFile, $sItopArchiveFile)) + { + IssueLog::Info("Archive $sItopArchiveFile Created"); + } + else + { + IssueLog::Error("Failed to create archive $sItopArchiveFile"); + } + } - $oBackup = new DBBackup(); - $oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', '')); + /** + * + * @param string $sTargetFile + * + * @throws Exception + */ + private static function DoBackup($sTargetFile) + { + // Make sure the target directory exists + $sBackupDir = dirname($sTargetFile); + SetupUtils::builddir($sBackupDir); - $oMutex = new iTopMutex('backup.'.utils::GetCurrentEnvironment()); - $oMutex->Lock(); - try - { - $oBackup->CreateCompressedBackup($sTargetFile); - IssueLog::Info('itop-core-update: Backup done: '.$sTargetFile); - } - catch (Exception $e) - { - $oMutex->Unlock(); - throw $e; - } - $oMutex->Unlock(); - } + $oBackup = new DBBackup(); + $oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', '')); + + $oMutex = new iTopMutex('backup.'.utils::GetCurrentEnvironment()); + $oMutex->Lock(); + try + { + $oBackup->CreateCompressedBackup($sTargetFile); + IssueLog::Info('itop-core-update: Backup done: '.$sTargetFile); + } catch (Exception $e) + { + $oMutex->Unlock(); + throw $e; + } + $oMutex->Unlock(); + } /** * @param $sSource @@ -283,9 +331,9 @@ final class CoreUpdater @mkdir($sDest, 0755); } $aFiles = scandir($sSource); - if(sizeof($aFiles) > 0 ) + if (sizeof($aFiles) > 0) { - foreach($aFiles as $sFile) + foreach ($aFiles as $sFile) { if ($sFile == '.' || $sFile == '..' || $sFile == '.svn' || $sFile == '.git') { @@ -315,7 +363,8 @@ final class CoreUpdater } } - public static function RRmdir($sDir) { + public static function RRmdir($sDir) + { if (is_dir($sDir)) { $oDir = @opendir($sDir); @@ -368,9 +417,11 @@ final class CoreUpdater * @param ZipArchive $oZipArchive * @param int $iStrippedLength Number of text to be removed from the file path. */ - private static function ZipFolder($sFolder, &$oZipArchive, $iStrippedLength) { + private static function ZipFolder($sFolder, &$oZipArchive, $iStrippedLength) + { $oFolder = opendir($sFolder); - while (false !== ($sFile = readdir($oFolder))) { + while (false !== ($sFile = readdir($oFolder))) + { if (($sFile == '.') || ($sFile == '..')) { continue; @@ -385,9 +436,12 @@ final class CoreUpdater // Remove prefix from file path before add to zip. $sLocalPath = substr($sFilePath, $iStrippedLength); - if (is_file($sFilePath)) { + if (is_file($sFilePath)) + { $oZipArchive->addFile($sFilePath, $sLocalPath); - } elseif (is_dir($sFilePath)) { + } + elseif (is_dir($sFilePath)) + { // Add sub-directory. $oZipArchive->addEmptyDir($sLocalPath); self::ZipFolder($sFilePath, $oZipArchive, $iStrippedLength); @@ -414,109 +468,106 @@ final class CoreUpdater return $sItopArchiveFile; } - /** - * @return string - */ - private static function GetBackupName() - { - $sBackupName = APPROOT.'data/backups/manual/backup-core-update'; - return $sBackupName; - } + /** + * @return string + */ + private static function GetBackupName() + { + $sBackupName = APPROOT.'data/backups/manual/backup-core-update'; + return $sBackupName; + } - /** - * @return string - */ - public static function GetBackupFile() - { - $sBackupFile = self::GetBackupName().'.tar.gz'; - return $sBackupFile; - } + /** + * @return string + */ + public static function GetBackupFile() + { + $sBackupFile = self::GetBackupName().'.tar.gz'; + return $sBackupFile; + } - /** - * @param $sArchiveFile - * - * @throws \Exception - */ - public static function ExtractDownloadedFile($sArchiveFile) - { - try - { - // Extract archive file - self::ExtractUpdateFile($sArchiveFile); + /** + * @param $sArchiveFile + * + * @throws \Exception + */ + public static function ExtractDownloadedFile($sArchiveFile) + { + try + { + // Extract archive file + self::ExtractUpdateFile($sArchiveFile); - IssueLog::Info('itop-core-update: Archive extracted, check files integrity'); + IssueLog::Info('itop-core-update: Archive extracted, check files integrity'); - // Check files integrity - FilesIntegrity::CheckInstallationIntegrity(self::UPDATE_DIR.'web/'); + // Check files integrity + FilesIntegrity::CheckInstallationIntegrity(self::UPDATE_DIR.'web/'); - IssueLog::Info('itop-core-update: Files integrity OK'); - } - catch (Exception $e) - { - self::RRmdir(self::UPDATE_DIR); - throw $e; - } - finally - { - self::RRmdir(self::DOWNLOAD_DIR); - } - } + IssueLog::Info('itop-core-update: Files integrity OK'); + } catch (Exception $e) + { + self::RRmdir(self::UPDATE_DIR); + throw $e; + } finally + { + self::RRmdir(self::DOWNLOAD_DIR); + } + } - /** - * @return string - * @throws \Exception - */ - public static function GetVersionToInstall() - { - try - { - $sConfigFile = self::UPDATE_DIR.'web/core/config.class.inc.php'; - if (!is_file($sConfigFile)) - { - throw new Exception(Dict::S(Dict::S('iTopUpdate:Error:BadFileContent'))); - } + /** + * @return string + * @throws \Exception + */ + public static function GetVersionToInstall() + { + try + { + $sConfigFile = self::UPDATE_DIR.'web/core/config.class.inc.php'; + if (!is_file($sConfigFile)) + { + throw new Exception(Dict::S(Dict::S('iTopUpdate:Error:BadFileContent'))); + } - $sContents = file_get_contents($sConfigFile); - preg_match_all("@define\('(?ITOP_[^']*)', '(?[^']*)'\);@", $sContents, $aMatches); - if (empty($aMatches)) - { - throw new Exception(Dict::S(Dict::S('iTopUpdate:Error:BadFileContent'))); - } - $aValues = array(); - foreach ($aMatches['name'] as $index => $sName) - { - $aValues[$sName] = $aMatches['value'][$index]; - } + $sContents = file_get_contents($sConfigFile); + preg_match_all("@define\('(?ITOP_[^']*)', '(?[^']*)'\);@", $sContents, $aMatches); + if (empty($aMatches)) + { + throw new Exception(Dict::S(Dict::S('iTopUpdate:Error:BadFileContent'))); + } + $aValues = array(); + foreach ($aMatches['name'] as $index => $sName) + { + $aValues[$sName] = $aMatches['value'][$index]; + } - if ($aValues['ITOP_APPLICATION'] != ITOP_APPLICATION) - { - throw new Exception(Dict::S('iTopUpdate:Error:BadItopProduct')); - } + if ($aValues['ITOP_APPLICATION'] != ITOP_APPLICATION) + { + throw new Exception(Dict::S('iTopUpdate:Error:BadItopProduct')); + } - // Extract updater file from the new version if available - if (is_file(APPROOT.'setup/appupgradecheck.php')) - { - // Remove previous specific updater - @unlink(APPROOT.'setup/appupgradecheck.php'); - } - if (is_file(self::UPDATE_DIR.'web/setup/appupgradecheck.php')) - { - IssueLog::Info('itop-core-update: Use updater provided in the archive'); - self::CopyFile(self::UPDATE_DIR.'web/setup/appupgradecheck.php', APPROOT.'setup/appupgradecheck.php'); - @include_once(APPROOT.'setup/appupgradecheck.php'); - } - if (function_exists('AppUpgradeCheckInstall')) - { - AppUpgradeCheckInstall(); - } + // Extract updater file from the new version if available + if (is_file(APPROOT.'setup/appupgradecheck.php')) + { + // Remove previous specific updater + @unlink(APPROOT.'setup/appupgradecheck.php'); + } + if (is_file(self::UPDATE_DIR.'web/setup/appupgradecheck.php')) + { + IssueLog::Info('itop-core-update: Use updater provided in the archive'); + self::CopyFile(self::UPDATE_DIR.'web/setup/appupgradecheck.php', APPROOT.'setup/appupgradecheck.php'); + @include_once(APPROOT.'setup/appupgradecheck.php'); + } + if (function_exists('AppUpgradeCheckInstall')) + { + AppUpgradeCheckInstall(); + } - return Dict::Format('UI:iTopVersion:Long', $aValues['ITOP_APPLICATION'], $aValues['ITOP_VERSION'], $aValues['ITOP_REVISION'], $aValues['ITOP_BUILD_DATE']); - } - catch (Exception $e) - { - self::RRmdir(self::UPDATE_DIR); - self::RRmdir(self::DOWNLOAD_DIR); - throw $e; - } - } + return Dict::Format('UI:iTopVersion:Long', $aValues['ITOP_APPLICATION'], $aValues['ITOP_VERSION'], $aValues['ITOP_REVISION'], $aValues['ITOP_BUILD_DATE']); + } catch (Exception $e) + { + self::RRmdir(self::UPDATE_DIR); + self::RRmdir(self::DOWNLOAD_DIR); + throw $e; + } + } } diff --git a/datamodels/2.x/itop-core-update/src/Service/RunTimeEnvironmentCoreUpdater.php b/datamodels/2.x/itop-core-update/src/Service/RunTimeEnvironmentCoreUpdater.php index e5a9f1e92..9a6943ab4 100644 --- a/datamodels/2.x/itop-core-update/src/Service/RunTimeEnvironmentCoreUpdater.php +++ b/datamodels/2.x/itop-core-update/src/Service/RunTimeEnvironmentCoreUpdater.php @@ -12,9 +12,36 @@ require_once(APPROOT."setup/runtimeenv.class.inc.php"); use Config; use Exception; use RunTimeEnvironment; +use SetupUtils; class RunTimeEnvironmentCoreUpdater extends RunTimeEnvironment { + /** + * Constructor + * + * @param string $sEnvironment + * @param bool $bAutoCommit + * + * @throws \Exception + */ + public function __construct($sEnvironment = 'production', $bAutoCommit = true) + { + parent::__construct($sEnvironment, $bAutoCommit); + + if ($sEnvironment != $this->sTargetEnv) + { + if (is_dir(APPROOT.'/env-'.$this->sTargetEnv)) + { + SetupUtils::rrmdir(APPROOT.'/env-'.$this->sTargetEnv); + } + if (is_dir(APPROOT.'/data/'.$this->sTargetEnv.'-modules')) + { + SetupUtils::rrmdir(APPROOT.'/data/'.$this->sTargetEnv.'-modules'); + } + SetupUtils::copydir(APPROOT.'/data/'.$sEnvironment.'-modules', APPROOT.'/data/'.$this->sTargetEnv.'-modules'); + } + } + public function CheckDirectories($sTargetEnv) { $sTargetDir = APPROOT.'env-'.$sTargetEnv; diff --git a/datamodels/2.x/itop-core-update/view/UpdateCoreFiles.ready.js.twig b/datamodels/2.x/itop-core-update/view/UpdateCoreFiles.ready.js.twig index 41e008d3c..42b278ce4 100644 --- a/datamodels/2.x/itop-core-update/view/UpdateCoreFiles.ready.js.twig +++ b/datamodels/2.x/itop-core-update/view/UpdateCoreFiles.ready.js.twig @@ -57,7 +57,7 @@ function GetAjaxRequest(sOperation) return oAjaxRequest; } -{% set aSteps = ['EnterMaintenance', 'Backup', 'FilesArchive', 'CopyFiles', 'Compile', 'ExitMaintenance', 'UpdateDone'] %} +{% set aSteps = ['EnterMaintenance', 'Backup', 'FilesArchive', 'CopyFiles', 'CheckCompile', 'Compile', 'UpdateDatabase', 'ExitMaintenance', 'UpdateDone'] %} aStepsName = []; @@ -75,7 +75,7 @@ var sFilesArchiveStep; sFilesArchiveStep = "FilesArchive"; {% endif %} -var aStepsAjaxOperation = ["EnterMaintenance", sBackupStep, sFilesArchiveStep, "CopyFiles", "Compile", "ExitMaintenance", null]; +var aStepsAjaxOperation = ["EnterMaintenance", sBackupStep, sFilesArchiveStep, "CopyFiles", "CheckCompile", "Compile", "UpdateDatabase", "ExitMaintenance", null]; var iNextStep = 0; function ExecNextStep() { diff --git a/datamodels/2.x/itop-twig-base/README.md b/datamodels/2.x/itop-twig-base/README.md deleted file mode 100644 index d93037a34..000000000 --- a/datamodels/2.x/itop-twig-base/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# itop-twig-base - -Provide Twig service to other modules. - -BEWARE: This feature is subject to change! The API if not guaranteed future versions may break the compatibility. - -namespace Combodo\iTop\TwigBase; diff --git a/datamodels/2.x/itop-twig-base/index.php b/datamodels/2.x/itop-twig-base/index.php deleted file mode 100644 index a81436628..000000000 --- a/datamodels/2.x/itop-twig-base/index.php +++ /dev/null @@ -1 +0,0 @@ - 'iTop Twig Base', - 'category' => 'business', - - // Setup - // - 'dependencies' => array(), - 'mandatory' => false, - 'visible' => false, - - // Components - // - 'datamodel' => array( - 'model.itop-twig-base.php', - 'src/Controller/Controller.php', - 'src/Twig/Extension.php', - 'src/Twig/TwigHelper.php', - ), - 'webservice' => array(), - 'data.struct' => array(), - 'data.sample' => array(), - - // Documentation - // - 'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any - 'doc.more_information' => '', // hyperlink to more information, if any - - // Default settings - // - 'settings' => array(), - ) -); diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index ffe03bccb..2eec1e455 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -132,6 +132,15 @@ return array( 'CharConcatWSExpression' => $baseDir . '/core/oql/expression.class.inc.php', 'CheckStopWatchThresholds' => $baseDir . '/core/ormstopwatch.class.inc.php', 'CheckableExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\AjaxSearchException' => $baseDir . '/sources/application/search/ajaxsearchexception.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionConversionAbstract' => $baseDir . '/sources/application/search/criterionconversionabstract.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionConversion\\CriterionToOQL' => $baseDir . '/sources/application/search/criterionconversion/criteriontooql.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionConversion\\CriterionToSearchForm' => $baseDir . '/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionParser' => $baseDir . '/sources/application/search/criterionparser.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\SearchForm' => $baseDir . '/sources/application/search/searchform.class.inc.php', + 'Combodo\\iTop\\Application\\TwigBase\\Controller\\Controller' => $baseDir . '/sources/application/TwigBase/Controller/Controller.php', + 'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => $baseDir . '/sources/application/TwigBase/Twig/Extension.php', + 'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => $baseDir . '/sources/application/TwigBase/Twig/TwigHelper.php', 'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\TwigExtension' => $baseDir . '/application/twigextension.class.inc.php', diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 7bdfa7d6c..2b23344b9 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -362,6 +362,15 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'CharConcatWSExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php', 'CheckStopWatchThresholds' => __DIR__ . '/../..' . '/core/ormstopwatch.class.inc.php', 'CheckableExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\AjaxSearchException' => __DIR__ . '/../..' . '/sources/application/search/ajaxsearchexception.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionConversionAbstract' => __DIR__ . '/../..' . '/sources/application/search/criterionconversionabstract.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionConversion\\CriterionToOQL' => __DIR__ . '/../..' . '/sources/application/search/criterionconversion/criteriontooql.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionConversion\\CriterionToSearchForm' => __DIR__ . '/../..' . '/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\CriterionParser' => __DIR__ . '/../..' . '/sources/application/search/criterionparser.class.inc.php', + 'Combodo\\iTop\\Application\\Search\\SearchForm' => __DIR__ . '/../..' . '/sources/application/search/searchform.class.inc.php', + 'Combodo\\iTop\\Application\\TwigBase\\Controller\\Controller' => __DIR__ . '/../..' . '/sources/application/TwigBase/Controller/Controller.php', + 'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/Extension.php', + 'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/TwigHelper.php', 'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\TwigExtension' => __DIR__ . '/../..' . '/application/twigextension.class.inc.php', diff --git a/datamodels/2.x/itop-twig-base/src/Controller/Controller.php b/sources/application/TwigBase/Controller/Controller.php similarity index 89% rename from datamodels/2.x/itop-twig-base/src/Controller/Controller.php rename to sources/application/TwigBase/Controller/Controller.php index b082035a8..402e74608 100644 --- a/datamodels/2.x/itop-twig-base/src/Controller/Controller.php +++ b/sources/application/TwigBase/Controller/Controller.php @@ -4,11 +4,11 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ -namespace Combodo\iTop\TwigBase\Controller; +namespace Combodo\iTop\Application\TwigBase\Controller; use ajax_page; use ApplicationMenu; -use Combodo\iTop\TwigBase\Twig\TwigHelper; +use Combodo\iTop\Application\TwigBase\Twig\TwigHelper; use Dict; use Exception; use IssueLog; @@ -40,6 +40,7 @@ abstract class Controller private $m_sMenuId = null; /** @var string */ private $m_sDefaultOperation = 'Default'; + private $m_aDefaultParams; private $m_aLinkedScripts; private $m_aLinkedStylesheets; private $m_aAjaxTabs; @@ -47,13 +48,50 @@ abstract class Controller public function __construct() { - $sModulePath = dirname(dirname($this->getDir())); - $this->m_sModule = basename($sModulePath); - $oTwig = TwigHelper::GetTwigEnvironment($sModulePath.'/view'); - $this->m_oTwig = $oTwig; $this->m_aLinkedScripts = array(); $this->m_aLinkedStylesheets = array(); $this->m_aAjaxTabs = array(); + $this->m_aDefaultParams = array(); + } + + /** + * Initialize the Controller from a module + */ + public function InitFromModule() + { + $sModulePath = dirname(dirname($this->getDir())); + $this->SetModuleName(basename($sModulePath)); + $this->SetViewPath($sModulePath.'/view'); + try + { + $this->m_aDefaultParams = array('sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')); + } + catch (Exception $e) + { + IssueLog::Error($e->getMessage()); + } + } + + /** + * Indicates the path of the view directory (containing the twig templates) + * + * @param string $sViewPath + */ + public function SetViewPath($sViewPath) + { + $oTwig = TwigHelper::GetTwigEnvironment($sViewPath); + $this->m_oTwig = $oTwig; + } + + /** + * Set the name of the current module + * Used to name operations see Controller::GetOperationTitle() + * + * @param string $sModule Name of the module + */ + public function SetModuleName($sModule) + { + $this->m_sModule = $sModule; } private function getDir() @@ -129,10 +167,7 @@ abstract class Controller */ private function GetDefaultParameters() { - $aParams = array(); - $aParams['sIndexURL'] = utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'); - - return $aParams; + return $this->m_aDefaultParams; } /** @@ -380,6 +415,10 @@ abstract class Controller private function RenderTemplate($aParams, $sName, $sTemplateFileExtension) { + if (empty($this->m_oTwig)) + { + return 'Not initialized. Call Controller::InitFromModule() or Controller::SetViewPath() before any display'; + } try { return $this->m_oTwig->render($sName.'.'.$sTemplateFileExtension.'.twig', $aParams); @@ -422,7 +461,7 @@ abstract class Controller */ public function GetOperationTitle() { - return Dict::S($this->m_sModule.':UI:'.$this->m_sOperation); + return Dict::S($this->m_sModule.'/Operation:'.$this->m_sOperation.'/Title'); } /** diff --git a/datamodels/2.x/itop-twig-base/src/Twig/Extension.php b/sources/application/TwigBase/Twig/Extension.php similarity index 98% rename from datamodels/2.x/itop-twig-base/src/Twig/Extension.php rename to sources/application/TwigBase/Twig/Extension.php index 88de79adc..8a57714c5 100644 --- a/datamodels/2.x/itop-twig-base/src/Twig/Extension.php +++ b/sources/application/TwigBase/Twig/Extension.php @@ -4,7 +4,7 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ -namespace Combodo\iTop\TwigBase\Twig; +namespace Combodo\iTop\Application\TwigBase\Twig; use AttributeDateTime; @@ -129,4 +129,4 @@ class Extension })); } -} \ No newline at end of file +} diff --git a/datamodels/2.x/itop-twig-base/src/Twig/TwigHelper.php b/sources/application/TwigBase/Twig/TwigHelper.php similarity index 81% rename from datamodels/2.x/itop-twig-base/src/Twig/TwigHelper.php rename to sources/application/TwigBase/Twig/TwigHelper.php index 215b70dd9..ee6d8ac97 100644 --- a/datamodels/2.x/itop-twig-base/src/Twig/TwigHelper.php +++ b/sources/application/TwigBase/Twig/TwigHelper.php @@ -4,13 +4,11 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ -namespace Combodo\iTop\TwigBase\Twig; +namespace Combodo\iTop\Application\TwigBase\Twig; use Twig_Environment; use Twig_Loader_Filesystem; -@include_once(APPROOT.'/lib/silex/vendor/autoload.php'); - class TwigHelper {