public function CompileFrom($sSourceEnv, $bUseSymLinks = false)
 {
     $oSourceConfig = new Config(utils::GetConfigFilePath($sSourceEnv));
     $sSourceDir = $oSourceConfig->Get('source_dir');
     $sSourceDirFull = APPROOT . $sSourceDir;
     // Do load the required modules
     //
     $oFactory = new ModelFactory($sSourceDirFull);
     foreach ($this->GetMFModulesToCompile($sSourceEnv, $sSourceDir) as $oModule) {
         $sModule = $oModule->GetName();
         $oFactory->LoadModule($oModule);
         if ($oFactory->HasLoadErrors()) {
             break;
         }
     }
     if ($oFactory->HasLoadErrors()) {
         foreach ($oFactory->GetLoadErrors() as $sModuleId => $aErrors) {
             echo "<h3>Module: " . $sModuleId . "</h3>\n";
             foreach ($aErrors as $oXmlError) {
                 echo "<p>File: " . $oXmlError->file . " Line:" . $oXmlError->line . " Message:" . $oXmlError->message . "</p>\n";
             }
         }
     } else {
         $oFactory->ApplyChanges();
         //$oFactory->Dump();
         $sTargetDir = APPROOT . 'env-' . $this->sTargetEnv;
         self::MakeDirSafe($sTargetDir);
         $oMFCompiler = new MFCompiler($oFactory);
         $oMFCompiler->Compile($sTargetDir, null, $bUseSymLinks);
         require_once APPROOT . '/core/dict.class.inc.php';
         MetaModel::ResetCache(md5(APPROOT) . '-' . $this->sTargetEnv);
     }
 }
 protected static function DoCompile($aSelectedModules, $sSourceDir, $sExtensionDir, $sTargetDir, $sEnvironment, $bUseSymbolicLinks = false)
 {
     SetupPage::log_info("Compiling data model.");
     require_once APPROOT . 'setup/modulediscovery.class.inc.php';
     require_once APPROOT . 'setup/modelfactory.class.inc.php';
     require_once APPROOT . 'setup/compiler.class.inc.php';
     if (empty($sSourceDir) || empty($sTargetDir)) {
         throw new Exception("missing parameter source_dir and/or target_dir");
     }
     $sSourcePath = APPROOT . $sSourceDir;
     $aDirsToScan = array($sSourcePath);
     $sExtensionsPath = APPROOT . $sExtensionDir;
     if (is_dir($sExtensionsPath)) {
         // if the extensions dir exists, scan it for additional modules as well
         $aDirsToScan[] = $sExtensionsPath;
     }
     $sExtraPath = APPROOT . '/data/' . $sEnvironment . '-modules/';
     if (is_dir($sExtraPath)) {
         // if the extra dir exists, scan it for additional modules as well
         $aDirsToScan[] = $sExtraPath;
     }
     $sTargetPath = APPROOT . $sTargetDir;
     if (!is_dir($sSourcePath)) {
         throw new Exception("Failed to find the source directory '{$sSourcePath}', please check the rights of the web server");
     }
     if (!is_dir($sTargetPath)) {
         if (!mkdir($sTargetPath)) {
             throw new Exception("Failed to create directory '{$sTargetPath}', please check the rights of the web server");
         } else {
             // adjust the rights if and only if the directory was just created
             // owner:rwx user/group:rx
             chmod($sTargetPath, 0755);
         }
     } else {
         if (substr($sTargetPath, 0, strlen(APPROOT)) == APPROOT) {
             // If the directory is under the root folder - as expected - let's clean-it before compiling
             SetupUtils::tidydir($sTargetPath);
         }
     }
     $oFactory = new ModelFactory($aDirsToScan);
     $sDeltaFile = APPROOT . 'core/datamodel.core.xml';
     if (file_exists($sDeltaFile)) {
         $oCoreModule = new MFCoreModule('core', 'Core Module', $sDeltaFile);
         $oFactory->LoadModule($oCoreModule);
     }
     $sDeltaFile = APPROOT . 'application/datamodel.application.xml';
     if (file_exists($sDeltaFile)) {
         $oApplicationModule = new MFCoreModule('application', 'Application Module', $sDeltaFile);
         $oFactory->LoadModule($oApplicationModule);
     }
     $aModules = $oFactory->FindModules();
     foreach ($aModules as $foo => $oModule) {
         $sModule = $oModule->GetName();
         if (in_array($sModule, $aSelectedModules)) {
             $oFactory->LoadModule($oModule);
         }
     }
     $sDeltaFile = APPROOT . 'data/' . $sEnvironment . '.delta.xml';
     if (file_exists($sDeltaFile)) {
         $oDelta = new MFDeltaModule($sDeltaFile);
         $oFactory->LoadModule($oDelta);
     }
     //$oFactory->Dump();
     if ($oFactory->HasLoadErrors()) {
         foreach ($oFactory->GetLoadErrors() as $sModuleId => $aErrors) {
             SetupPage::log_error("Data model source file (xml) could not be loaded - found errors in module: {$sModuleId}");
             foreach ($aErrors as $oXmlError) {
                 SetupPage::log_error("Load error: File: " . $oXmlError->file . " Line:" . $oXmlError->line . " Message:" . $oXmlError->message);
             }
         }
         throw new Exception("The data model could not be compiled. Please check the setup error log");
     } else {
         $oMFCompiler = new MFCompiler($oFactory);
         $oMFCompiler->Compile($sTargetPath, null, $bUseSymbolicLinks);
         //$aCompilerLog = $oMFCompiler->GetLog();
         //SetupPage::log_info(implode("\n", $aCompilerLog));
         SetupPage::log_info("Data model successfully compiled to '{$sTargetPath}'.");
     }
     // Special case to patch a ugly patch in itop-config-mgmt
     $sFileToPatch = $sTargetPath . '/itop-config-mgmt-1.0.0/model.itop-config-mgmt.php';
     if (file_exists($sFileToPatch)) {
         $sContent = file_get_contents($sFileToPatch);
         $sContent = str_replace("require_once(APPROOT.'modules/itop-welcome-itil/model.itop-welcome-itil.php');", "//\n// The line below is no longer needed in iTop 2.0 -- patched by the setup program\n// require_once(APPROOT.'modules/itop-welcome-itil/model.itop-welcome-itil.php');", $sContent);
         file_put_contents($sFileToPatch, $sContent);
     }
 }