public function __construct($sId, $sRootDir, $sLabel)
 {
     $this->sId = $sId;
     list($this->sName, $this->sVersion) = ModuleDiscovery::GetModuleName($sId);
     if (strlen($this->sVersion) == 0) {
         $this->sVersion = '1.0.0';
     }
     $this->sRootDir = $sRootDir;
     $this->sLabel = $sLabel;
     $this->aDataModels = array();
     // Scan the module's root directory to find the datamodel(*).xml files
     if ($hDir = opendir($sRootDir)) {
         // This is the correct way to loop over the directory. (according to the documentation)
         while (($sFile = readdir($hDir)) !== false) {
             if (preg_match('/^datamodel(.*)\\.xml$/i', $sFile, $aMatches)) {
                 $this->aDataModels[] = $this->sRootDir . '/' . $aMatches[0];
             }
         }
         closedir($hDir);
     }
 }
Exemple #2
0
 /**
  * Helper function to rebuild the default configuration and the list of includes from a directory and a list of selected modules
  * @param string $sModulesDir The relative path to the directory to scan for modules (typically the 'env-xxx' directory resulting from the compilation)
  * @param array $aSelectedModules An array of selected modules' identifiers. If null all modules found will be considered as installed
  * @throws Exception
  */
 public function UpdateIncludes($sModulesDir, $aSelectedModules = null)
 {
     if (!is_null($sModulesDir)) {
         // Initialize the arrays below with default values for the application...
         $oEmptyConfig = new Config('dummy_file', false);
         // Do NOT load any config file, just set the default values
         $aAddOns = $oEmptyConfig->GetAddOns();
         $aAppModules = $oEmptyConfig->GetAppModules();
         if (file_exists(APPROOT . $sModulesDir . '/core/main.php')) {
             $aAppModules[] = $sModulesDir . '/core/main.php';
         }
         $aDataModels = $oEmptyConfig->GetDataModels();
         $aWebServiceCategories = $oEmptyConfig->GetWebServiceCategories();
         $aDictionaries = $oEmptyConfig->GetDictionaries();
         // Merge the values with the ones provided by the modules
         // Make sure when don't load the same file twice...
         $aModules = ModuleDiscovery::GetAvailableModules(array(APPROOT . $sModulesDir));
         foreach ($aModules as $sModuleId => $aModuleInfo) {
             list($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
             if (is_null($aSelectedModules) || in_array($sModuleName, $aSelectedModules)) {
                 if (isset($aModuleInfo['datamodel'])) {
                     $aDataModels = array_unique(array_merge($aDataModels, $aModuleInfo['datamodel']));
                 }
                 if (isset($aModuleInfo['webservice'])) {
                     $aWebServiceCategories = array_unique(array_merge($aWebServiceCategories, $aModuleInfo['webservice']));
                 }
                 if (isset($aModuleInfo['settings'])) {
                     list($sName, $sVersion) = ModuleDiscovery::GetModuleName($sModuleId);
                     foreach ($aModuleInfo['settings'] as $sProperty => $value) {
                         if (isset($this->m_aModuleSettings[$sName][$sProperty])) {
                             // Do nothing keep the original value
                         } else {
                             $this->SetModuleSetting($sName, $sProperty, $value);
                         }
                     }
                 }
                 if (isset($aModuleInfo['installer'])) {
                     $sModuleInstallerClass = $aModuleInfo['installer'];
                     if (!class_exists($sModuleInstallerClass)) {
                         throw new Exception("Wrong installer class: '{$sModuleInstallerClass}' is not a PHP class - Module: " . $aModuleInfo['label']);
                     }
                     if (!is_subclass_of($sModuleInstallerClass, 'ModuleInstallerAPI')) {
                         throw new Exception("Wrong installer class: '{$sModuleInstallerClass}' is not derived from 'ModuleInstallerAPI' - Module: " . $aModuleInfo['label']);
                     }
                     $aCallSpec = array($sModuleInstallerClass, 'BeforeWritingConfig');
                     call_user_func_array($aCallSpec, array($this));
                 }
             }
         }
         $this->SetAddOns($aAddOns);
         $this->SetAppModules($aAppModules);
         $this->SetDataModels($aDataModels);
         $this->SetWebServiceCategories($aWebServiceCategories);
         // Scan dictionaries
         //
         foreach (glob(APPROOT . $sModulesDir . '/dictionaries/*.dict.php') as $sFilePath) {
             $sFile = basename($sFilePath);
             $aDictionaries[] = $sModulesDir . '/dictionaries/' . $sFile;
         }
         $this->SetDictionaries($aDictionaries);
     }
 }
 /**
  * Helper function to initialize a configuration from the page arguments
  */
 public function UpdateFromParams($aParamValues, $sModulesDir = null, $bPreserveModuleSettings = false)
 {
     if (isset($aParamValues['application_path'])) {
         $this->Set('app_root_url', $aParamValues['application_path']);
     }
     if (isset($aParamValues['mode']) && isset($aParamValues['language'])) {
         if ($aParamValues['mode'] == 'install' || $this->GetDefaultLanguage() == '') {
             $this->SetDefaultLanguage($aParamValues['language']);
         }
     }
     if (isset($aParamValues['db_server'])) {
         $this->SetDBHost($aParamValues['db_server']);
         $this->SetDBUser($aParamValues['db_user']);
         $this->SetDBPwd($aParamValues['db_pwd']);
         $sDBName = $aParamValues['db_name'];
         if ($sDBName == '') {
             // Todo - obsolete after the transition to the new setup (2.0) is complete (WARNING: used by the designer)
             $sDBName = $aParamValues['new_db_name'];
         }
         $this->SetDBName($sDBName);
         $this->SetDBSubname($aParamValues['db_prefix']);
     }
     if (!is_null($sModulesDir)) {
         if (isset($aParamValues['selected_modules'])) {
             $aSelectedModules = explode(',', $aParamValues['selected_modules']);
         } else {
             $aSelectedModules = null;
         }
         // Initialize the arrays below with default values for the application...
         $oEmptyConfig = new Config('dummy_file', false);
         // Do NOT load any config file, just set the default values
         $aAddOns = $oEmptyConfig->GetAddOns();
         $aAppModules = $oEmptyConfig->GetAppModules();
         $aDataModels = $oEmptyConfig->GetDataModels();
         $aWebServiceCategories = $oEmptyConfig->GetWebServiceCategories();
         $aDictionaries = $oEmptyConfig->GetDictionaries();
         // Merge the values with the ones provided by the modules
         // Make sure when don't load the same file twice...
         $aModules = ModuleDiscovery::GetAvailableModules(array(APPROOT . $sModulesDir));
         foreach ($aModules as $sModuleId => $aModuleInfo) {
             list($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
             if (is_null($aSelectedModules) || in_array($sModuleName, $aSelectedModules)) {
                 if (isset($aModuleInfo['datamodel'])) {
                     $aDataModels = array_unique(array_merge($aDataModels, $aModuleInfo['datamodel']));
                 }
                 if (isset($aModuleInfo['webservice'])) {
                     $aWebServiceCategories = array_unique(array_merge($aWebServiceCategories, $aModuleInfo['webservice']));
                 }
                 if (isset($aModuleInfo['settings'])) {
                     list($sName, $sVersion) = ModuleDiscovery::GetModuleName($sModuleId);
                     foreach ($aModuleInfo['settings'] as $sProperty => $value) {
                         if ($bPreserveModuleSettings && isset($this->m_aModuleSettings[$sName][$sProperty])) {
                             // Do nothing keep the original value
                         } else {
                             $this->SetModuleSetting($sName, $sProperty, $value);
                         }
                     }
                 }
                 if (isset($aModuleInfo['installer'])) {
                     $sModuleInstallerClass = $aModuleInfo['installer'];
                     if (!class_exists($sModuleInstallerClass)) {
                         throw new Exception("Wrong installer class: '{$sModuleInstallerClass}' is not a PHP class - Module: " . $aModuleInfo['label']);
                     }
                     if (!is_subclass_of($sModuleInstallerClass, 'ModuleInstallerAPI')) {
                         throw new Exception("Wrong installer class: '{$sModuleInstallerClass}' is not derived from 'ModuleInstallerAPI' - Module: " . $aModuleInfo['label']);
                     }
                     $aCallSpec = array($sModuleInstallerClass, 'BeforeWritingConfig');
                     call_user_func_array($aCallSpec, array($this));
                 }
             }
         }
         $this->SetAddOns($aAddOns);
         $this->SetAppModules($aAppModules);
         $this->SetDataModels($aDataModels);
         $this->SetWebServiceCategories($aWebServiceCategories);
         // Scan dictionaries
         //
         if (!is_null($sModulesDir)) {
             foreach (glob(APPROOT . $sModulesDir . '/dictionaries/*.dict.php') as $sFilePath) {
                 $sFile = basename($sFilePath);
                 $aDictionaries[] = $sModulesDir . '/dictionaries/' . $sFile;
             }
         }
         $this->SetDictionaries($aDictionaries);
     }
 }
 /**
  * Analyzes the current installation and the possibilities
  * 
  * @param Config $oConfig Defines the target environment (DB)
  * @param mixed $modulesPath Either a single string or an array of absolute paths
  * @param bool  $bAbortOnMissingDependency ...
  * @param hash $aModulesToLoad List of modules to search for, defaults to all if ommitted
  * @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
  *     )
  * )
  */
 public function AnalyzeInstallation($oConfig, $modulesPath, $bAbortOnMissingDependency = false, $aModulesToLoad = null)
 {
     $aRes = array(ROOT_MODULE => array('version_db' => '', 'name_db' => '', 'version_code' => ITOP_VERSION . '.' . ITOP_REVISION, 'name_code' => ITOP_APPLICATION));
     $aDirs = is_array($modulesPath) ? $modulesPath : array($modulesPath);
     $aModules = ModuleDiscovery::GetAvailableModules($aDirs, $bAbortOnMissingDependency, $aModulesToLoad);
     foreach ($aModules as $sModuleId => $aModuleInfo) {
         list($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
         if ($sModuleName == '') {
             throw new Exception("Missing name for the module: '{$sModuleId}'");
         }
         if ($sModuleVersion == '') {
             // The version must not be empty (it will be used as a criteria to determine wether a module has been installed or not)
             //throw new Exception("Missing version for the module: '$sModuleId'");
             $sModuleVersion = '1.0.0';
         }
         $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 {
         require_once APPROOT . '/core/cmdbsource.class.inc.php';
         CMDBSource::Init($oConfig->GetDBHost(), $oConfig->GetDBUser(), $oConfig->GetDBPwd(), $oConfig->GetDBName());
         CMDBSource::SetCharacterSet($oConfig->GetDBCharacterSet(), $oConfig->GetDBCollation());
         $aSelectInstall = CMDBSource::QueryToArray("SELECT * FROM " . $oConfig->GetDBSubname() . "priv_module_install");
     } catch (MySQLException $e) {
         // No database or erroneous information
         $aSelectInstall = array();
     }
     // Build the list of installed module (get the latest installation)
     //
     $aInstallByModule = array();
     // array of <module> => array ('installed' => timestamp, 'version' => <version>)
     $iRootId = 0;
     foreach ($aSelectInstall as $aInstall) {
         if ($aInstall['parent_id'] == 0 && $aInstall['name'] != 'datamodel') {
             // Root module, what is its ID ?
             $iId = (int) $aInstall['id'];
             if ($iId > $iRootId) {
                 $iRootId = $iId;
             }
         }
     }
     foreach ($aSelectInstall as $aInstall) {
         //$aInstall['comment']; // unsused
         $iInstalled = strtotime($aInstall['installed']);
         $sModuleName = $aInstall['name'];
         $sModuleVersion = $aInstall['version'];
         if ($sModuleVersion == '') {
             // Though the version cannot be empty in iTop 2.0, it used to be possible
             // therefore we have to put something here or the module will not be considered
             // as being installed
             $sModuleVersion = '0.0.0';
         }
         if ($aInstall['parent_id'] == 0) {
             $sModuleName = ROOT_MODULE;
         } else {
             if ($aInstall['parent_id'] != $iRootId) {
                 // Skip all modules belonging to previous installations
                 continue;
             }
         }
         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;
 }