123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630 |
- <?php
- // Copyright (C) 2010 Combodo SARL
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; version 3 of the License.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- /**
- * Web page used for displaying the login form
- *
- * @author Erwan Taloc <erwan.taloc@combodo.com>
- * @author Romain Quetiez <romain.quetiez@combodo.com>
- * @author Denis Flaven <denis.flaven@combodo.com>
- * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
- */
- require_once(APPROOT."/application/nicewebpage.class.inc.php");
- require_once(APPROOT."setup/modulediscovery.class.inc.php");
- define('INSTALL_LOG_FILE', APPROOT.'/setup.log');
- define ('MODULE_ACTION_OPTIONAL', 1);
- define ('MODULE_ACTION_MANDATORY', 2);
- define ('MODULE_ACTION_IMPOSSIBLE', 3);
- define ('ROOT_MODULE', '_Root_'); // Convention to store IN MEMORY the name/version of the root module i.e. application
- date_default_timezone_set('Europe/Paris');
- class SetupPage extends NiceWebPage
- {
- public function __construct($sTitle)
- {
- parent::__construct($sTitle);
- $this->add_linked_script("../js/jquery.blockUI.js");
- $this->add_linked_script("../setup/setup.js");
- $this->add_linked_script("../setup/setup_environment.js");
- $this->add_style("
- body {
- background-color: #eee;
- margin: 0;
- padding: 0;
- font-size: 10pt;
- overflow-y: auto;
- }
- #header {
- width: 600px;
- margin-left: auto;
- margin-right: auto;
- margin-top: 50px;
- padding: 20px;
- background: #f6f6f1;
- height: 54px;
- border-top: 1px solid #000;
- border-left: 1px solid #000;
- border-right: 1px solid #000;
- }
- #header img {
- border: 0;
- vertical-align: middle;
- margin-right: 20px;
- }
- #header h1 {
- vertical-align: middle;
- height: 54px;
- noline-height: 54px;
- margin: 0;
- }
- #setup {
- width: 600px;
- margin-left: auto;
- margin-right: auto;
- padding: 20px;
- background-color: #fff;
- border-left: 1px solid #000;
- border-right: 1px solid #000;
- border-bottom: 1px solid #000;
- }
- .center {
- text-align: center;
- }
- h1 {
- color: #1C94C4;
- font-size: 16pt;
- }
- h2 {
- color: #000;
- font-size: 14pt;
- }
- h3 {
- color: #1C94C4;
- font-size: 12pt;
- font-weight: bold;
- }
- .next {
- width: 100%;
- text-align: right;
- }
- .v-spacer {
- padding-top: 1em;
- }
- button {
- margin-top: 1em;
- padding-left: 1em;
- padding-right: 1em;
- }
- p.info {
- padding-left: 50px;
- background: url(../images/info-mid.png) no-repeat left -5px;
- min-height: 48px;
- }
- p.ok {
- padding-left: 50px;
- background: url(../images/clean-mid.png) no-repeat left -8px;
- min-height: 48px;
- }
- p.warning {
- padding-left: 50px;
- background: url(../images/messagebox_warning-mid.png) no-repeat left -5px;
- min-height: 48px;
- }
- p.error {
- padding-left: 50px;
- background: url(../images/stop-mid.png) no-repeat left -5px;
- min-height: 48px;
- }
- td.label {
- text-align: left;
- }
- label.read-only {
- color: #666;
- cursor: text;
- }
- td.input {
- text-align: left;
- }
- table.formTable {
- border: 0;
- cellpadding: 2px;
- cellspacing: 0;
- }
- .wizlabel, .wizinput {
- color: #000;
- font-size: 10pt;
- }
- .wizhelp {
- color: #333;
- font-size: 8pt;
- }
- #progress {
- border:1px solid #000000;
- width: 180px;
- height: 20px;
- line-height: 20px;
- text-align: center;
- margin: 5px;
- }
- h3.clickable {
- background: url(../images/plus.gif) no-repeat left;
- padding-left:16px;
- cursor: hand;
- }
- h3.clickable.open {
- background: url(../images/minus.gif) no-repeat left;
- padding-left:16px;
- cursor: hand;
- }
- ");
- }
- /**
- * Overriden because the application is not fully loaded when the setup is being run
- */
- public function GetAbsoluteUrlAppRoot()
- {
- return '../';
- }
- /**
- * Overriden because the application is not fully loaded when the setup is being run
- */
- public function GetAbsoluteUrlModulesRoot()
- {
- return $this->GetAbsoluteUrlAppRoot().utils::GetCurrentEnvironment();
- }
- /**
- * Overriden because the application is not fully loaded when the setup is being run
- */
- function GetApplicationContext()
- {
- return '';
- }
- public function info($sText)
- {
- $this->add("<p class=\"info\">$sText</p>\n");
- $this->log_info($sText);
- }
-
- public function ok($sText)
- {
- $this->add("<p class=\"ok\">$sText</p>\n");
- $this->log_ok($sText);
- }
-
- public function warning($sText)
- {
- $this->add("<p class=\"warning\">$sText</p>\n");
- $this->log_warning($sText);
- }
-
- public function error($sText)
- {
- $this->add("<p class=\"error\">$sText</p>\n");
- $this->log_error($sText);
- }
-
- public function form($aData)
- {
- $this->add("<table class=\"formTable\">\n");
- foreach($aData as $aRow)
- {
- $this->add("<tr>\n");
- if (isset($aRow['label']) && isset($aRow['input']) && isset($aRow['help']))
- {
- $this->add("<td class=\"wizlabel\">{$aRow['label']}</td>\n");
- $this->add("<td class=\"wizinput\">{$aRow['input']}</td>\n");
- $this->add("<td class=\"wizhelp\">{$aRow['help']}</td>\n");
- }
- else if (isset($aRow['label']) && isset($aRow['help']))
- {
- $this->add("<td colspan=\"2\" class=\"wizlabel\">{$aRow['label']}</td>\n");
- $this->add("<td class=\"wizhelp\">{$aRow['help']}</td>\n");
- }
- else if (isset($aRow['label']) && isset($aRow['input']))
- {
- $this->add("<td class=\"wizlabel\">{$aRow['label']}</td>\n");
- $this->add("<td colspan=\"2\" class=\"wizinput\">{$aRow['input']}</td>\n");
- }
- else if (isset($aRow['label']))
- {
- $this->add("<td colspan=\"3\" class=\"wizlabel\">{$aRow['label']}</td>\n");
- }
- $this->add("</tr>\n");
- }
- $this->add("</table>\n");
- }
-
- public function collapsible($sId, $sTitle, $aItems, $bOpen = true)
- {
- $this->add("<h3 class=\"clickable open\" id=\"{$sId}\">$sTitle</h3>");
- $this->p('<ul id="'.$sId.'_list">');
- foreach($aItems as $sItem)
- {
- $this->p("<li>$sItem</li>\n");
- }
- $this->p('</ul>');
- $this->add_ready_script("$('#{$sId}').click( function() { $(this).toggleClass('open'); $('#{$sId}_list').toggle();} );\n");
- if (!$bOpen)
- {
- $this->add_ready_script("$('#{$sId}').toggleClass('open'); $('#{$sId}_list').toggle();\n");
- }
- }
-
- public function output()
- {
- $this->s_content = "<div id=\"header\"><h1><a href=\"http://www.combodo.com/itop\" target=\"_blank\"><img title=\"iTop by Combodo\" src=\"../images/itop-logo.png\"></a> ".htmlentities($this->s_title, ENT_QUOTES, 'UTF-8')."</h1>\n</div><div id=\"setup\">{$this->s_content}\n</div>\n";
- return parent::output();
- }
-
- public static function log_error($sText)
- {
- self::log("Error - ".$sText);
- }
- public static function log_warning($sText)
- {
- self::log("Warning - ".$sText);
- }
- public static function log_info($sText)
- {
- self::log("Info - ".$sText);
- }
- public static function log_ok($sText)
- {
- self::log("Ok - ".$sText);
- }
- public static function log($sText)
- {
- $hLogFile = @fopen(INSTALL_LOG_FILE, 'a');
- if ($hLogFile !== false)
- {
- $sDate = date('Y-m-d H:i:s');
- fwrite($hLogFile, "$sDate - $sText\n");
- fclose($hLogFile);
- }
- }
- } // End of class
- /**
- * Helper function to initialize the ORM and load the data model
- * from the given file
- * @param $oConfig object The configuration (volatile, not necessarily already on disk)
- * @param $bModelOnly boolean Whether or not to allow loading a data model with no corresponding DB
- * @return none
- */
- function InitDataModel($oConfig, $bModelOnly = true, $bUseCache = false)
- {
- require_once(APPROOT.'/core/log.class.inc.php');
- require_once(APPROOT.'/core/kpi.class.inc.php');
- require_once(APPROOT.'/core/coreexception.class.inc.php');
- require_once(APPROOT.'/core/dict.class.inc.php');
- require_once(APPROOT.'/core/attributedef.class.inc.php');
- require_once(APPROOT.'/core/filterdef.class.inc.php');
- require_once(APPROOT.'/core/stimulus.class.inc.php');
- require_once(APPROOT.'/core/MyHelpers.class.inc.php');
- require_once(APPROOT.'/core/expression.class.inc.php');
- require_once(APPROOT.'/core/cmdbsource.class.inc.php');
- require_once(APPROOT.'/core/sqlquery.class.inc.php');
- require_once(APPROOT.'/core/dbobject.class.php');
- require_once(APPROOT.'/core/dbobjectsearch.class.php');
- require_once(APPROOT.'/core/dbobjectset.class.php');
- require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
- require_once(APPROOT.'/core/userrights.class.inc.php');
- require_once(APPROOT.'/setup/moduleinstallation.class.inc.php');
- $sConfigFile = $oConfig->GetLoadedFile();
- if (strlen($sConfigFile) > 0)
- {
- SetupPage::log_info("MetaModel::Startup from $sConfigFile (ModelOnly = $bModelOnly)");
- }
- else
- {
- SetupPage::log_info("MetaModel::Startup (ModelOnly = $bModelOnly)");
- }
- if (!$bUseCache)
- {
- // Reset the cache for the first use !
- MetaModel::ResetCache($oConfig);
- }
- MetaModel::Startup($oConfig, $bModelOnly, $bUseCache);
- }
- /**
- * Analyzes the current installation and the possibilities
- *
- * @param $oConfig Config Defines the target environment (DB)
- * @return hash Array with the following format:
- * array =>
- * 'iTop' => array(
- * 'version_db' => ... (could be empty in case of a fresh install)
- * 'version_code => ...
- * )
- * <module_name> => array(
- * 'version_db' => ...
- * 'version_code' => ...
- * 'install' => array(
- * 'flag' => SETUP_NEVER | SETUP_OPTIONAL | SETUP_MANDATORY
- * 'message' => ...
- * )
- * 'uninstall' => array(
- * 'flag' => SETUP_NEVER | SETUP_OPTIONAL | SETUP_MANDATORY
- * 'message' => ...
- * )
- * 'label' => ...
- * 'dependencies' => array(<module1>, <module2>, ...)
- * 'visible' => true | false
- * )
- * )
- */
- function AnalyzeInstallation($oConfig, $sModulesRelativePath)
- {
- $aRes = array(
- ROOT_MODULE => array(
- 'version_db' => '',
- 'name_db' => '',
- 'version_code' => ITOP_VERSION.'.'.ITOP_REVISION,
- 'name_code' => ITOP_APPLICATION,
- )
- );
- $aModules = ModuleDiscovery::GetAvailableModules(APPROOT, $sModulesRelativePath);
- foreach($aModules as $sModuleId => $aModuleInfo)
- {
- list($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
- $sModuleAppVersion = $aModuleInfo['itop_version'];
- $aModuleInfo['version_db'] = '';
- $aModuleInfo['version_code'] = $sModuleVersion;
- if (!in_array($sModuleAppVersion, array('1.0.0', '1.0.1', '1.0.2')))
- {
- // This module is NOT compatible with the current version
- $aModuleInfo['install'] = array(
- 'flag' => MODULE_ACTION_IMPOSSIBLE,
- 'message' => 'the module is not compatible with the current version of the application'
- );
- }
- elseif ($aModuleInfo['mandatory'])
- {
- $aModuleInfo['install'] = array(
- 'flag' => MODULE_ACTION_MANDATORY,
- 'message' => 'the module is part of the application'
- );
- }
- else
- {
- $aModuleInfo['install'] = array(
- 'flag' => MODULE_ACTION_OPTIONAL,
- 'message' => ''
- );
- }
- $aRes[$sModuleName] = $aModuleInfo;
- }
- try
- {
- CMDBSource::Init($oConfig->GetDBHost(), $oConfig->GetDBUser(), $oConfig->GetDBPwd(), $oConfig->GetDBName());
- $aSelectInstall = CMDBSource::QueryToArray("SELECT * FROM ".$oConfig->GetDBSubname()."priv_module_install");
- }
- catch (MySQLException $e)
- {
- // No database or eroneous information
- $aSelectInstall = array();
- }
- // Build the list of installed module (get the latest installation)
- //
- $aInstallByModule = array(); // array of <module> => array ('installed' => timestamp, 'version' => <version>)
- foreach ($aSelectInstall as $aInstall)
- {
- //$aInstall['comment']; // unsused
- $iInstalled = strtotime($aInstall['installed']);
- $sModuleName = $aInstall['name'];
- $sModuleVersion = $aInstall['version'];
- if ($aInstall['parent_id'] == 0)
- {
- $sModuleName = ROOT_MODULE;
- }
- if (array_key_exists($sModuleName, $aInstallByModule))
- {
- if ($iInstalled < $aInstallByModule[$sModuleName]['installed'])
- {
- continue;
- }
- }
- if ($aInstall['parent_id'] == 0)
- {
- $aRes[$sModuleName]['version_db'] = $sModuleVersion;
- $aRes[$sModuleName]['name_db'] = $aInstall['name'];
- }
- $aInstallByModule[$sModuleName]['installed'] = $iInstalled;
- $aInstallByModule[$sModuleName]['version'] = $sModuleVersion;
- }
- // Adjust the list of proposed modules
- //
- foreach ($aInstallByModule as $sModuleName => $aModuleDB)
- {
- if ($sModuleName == ROOT_MODULE) continue; // Skip the main module
-
- if (!array_key_exists($sModuleName, $aRes))
- {
- // A module was installed, it is not proposed in the new build... skip
- continue;
- }
- $aRes[$sModuleName]['version_db'] = $aModuleDB['version'];
- if ($aRes[$sModuleName]['install']['flag'] == MODULE_ACTION_MANDATORY)
- {
- $aRes[$sModuleName]['uninstall'] = array(
- 'flag' => MODULE_ACTION_IMPOSSIBLE,
- 'message' => 'the module is part of the application'
- );
- }
- else
- {
- $aRes[$sModuleName]['uninstall'] = array(
- 'flag' => MODULE_ACTION_OPTIONAL,
- 'message' => ''
- );
- }
- }
- return $aRes;
- }
- /**
- * Helper function to create the database structure
- * @return boolean true on success, false otherwise
- */
- function CreateDatabaseStructure(Config $oConfig, $sMode)
- {
- if (strlen($oConfig->GetDBSubname()) > 0)
- {
- SetupPage::log_info("Creating the structure in '".$oConfig->GetDBName()."' (table names prefixed by '".$oConfig->GetDBSubname()."').");
- }
- else
- {
- SetupPage::log_info("Creating the structure in '".$oConfig->GetDBSubname()."'.");
- }
- //MetaModel::CheckDefinitions();
- if ($sMode == 'install')
- {
- if (!MetaModel::DBExists(/* bMustBeComplete */ false))
- {
- MetaModel::DBCreate();
- SetupPage::log_ok("Database structure successfully created.");
- }
- else
- {
- if (strlen($oConfig->GetDBSubname()) > 0)
- {
- throw new Exception("Error: found iTop tables into the database '".$oConfig->GetDBName()."' (prefix: '".$oConfig->GetDBSubname()."'). Please, try selecting another database instance or specify another prefix to prevent conflicting table names.");
- }
- else
- {
- throw new Exception("Error: found iTop tables into the database '".$oConfig->GetDBName()."'. Please, try selecting another database instance or specify a prefix to prevent conflicting table names.");
- }
- }
- }
- else
- {
- if (MetaModel::DBExists(/* bMustBeComplete */ false))
- {
- MetaModel::DBCreate();
- SetupPage::log_ok("Database structure successfully updated.");
- // Check (and update only if it seems needed) the hierarchical keys
- ob_start();
- MetaModel::CheckHKeys(false /* bDiagnosticsOnly */, true /* bVerbose*/, true /* bForceUpdate */); // Since in 1.2-beta the detection was buggy, let's force the rebuilding of HKeys
- $sFeedback = ob_get_clean();
- SetupPage::log_ok("Hierchical keys rebuilt: $sFeedback");
- // Check (and fix) data sync configuration
- ob_start();
- MetaModel::CheckDataSources(false /*$bDiagnostics*/, true/*$bVerbose*/);
- $sFeedback = ob_get_clean();
- SetupPage::log_ok("Data sources checked: $sFeedback");
- }
- else
- {
- if (strlen($oConfig->GetDBSubname()) > 0)
- {
- throw new Exception("Error: No previous instance of iTop found into the database '".$oConfig->GetDBName()."' (prefix: '".$oConfig->GetDBSubname()."'). Please, try selecting another database instance.");
- }
- else
- {
- throw new Exception("Error: No previous instance of iTop found into the database '".$oConfig->GetDBName()."'. Please, try selecting another database instance.");
- }
- }
- }
- return true;
- }
- function RecordInstallation(Config $oConfig, $aSelectedModules, $sModulesRelativePath)
- {
- // Record main installation
- $oInstallRec = new ModuleInstallation();
- $oInstallRec->Set('name', ITOP_APPLICATION);
- $oInstallRec->Set('version', ITOP_VERSION.'.'.ITOP_REVISION);
- $oInstallRec->Set('comment', "Done by the setup program\nBuilt on ".ITOP_BUILD_DATE);
- $oInstallRec->Set('parent_id', 0); // root module
- $iMainItopRecord = $oInstallRec->DBInsertNoReload();
- // Record installed modules
- //
- $aAvailableModules = AnalyzeInstallation($oConfig, $sModulesRelativePath);
- foreach($aSelectedModules as $sModuleId)
- {
- $aModuleData = $aAvailableModules[$sModuleId];
- $sName = $sModuleId;
- $sVersion = $aModuleData['version_code'];
- $aComments = array();
- $aComments[] = 'Done by the setup program';
- if ($aModuleData['mandatory'])
- {
- $aComments[] = 'Mandatory';
- }
- else
- {
- $aComments[] = 'Optional';
- }
- if ($aModuleData['visible'])
- {
- $aComments[] = 'Visible (during the setup)';
- }
- else
- {
- $aComments[] = 'Hidden (selected automatically)';
- }
- foreach ($aModuleData['dependencies'] as $sDependOn)
- {
- $aComments[] = "Depends on module: $sDependOn";
- }
- $sComment = implode("\n", $aComments);
- $oInstallRec = new ModuleInstallation();
- $oInstallRec->Set('name', $sName);
- $oInstallRec->Set('version', $sVersion);
- $oInstallRec->Set('comment', $sComment);
- $oInstallRec->Set('parent_id', $iMainItopRecord);
- $oInstallRec->DBInsertNoReload();
- }
- // Database is created, installation has been tracked into it
- return true;
- }
- ?>
|