123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769 |
- <?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");
- 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 SetupWebPage extends NiceWebPage
- {
- public function __construct($sTitle)
- {
- parent::__construct($sTitle);
- $this->add_linked_script("../js/jquery.blockUI.js");
- $this->add_linked_script("./setup.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;
- }
- ");
- }
- 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> {$this->s_title}</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);
- }
- }
-
- static $m_aModuleArgs = array(
- 'label' => 'One line description shown during the interactive setup',
- 'dependencies' => 'array of module ids',
- 'mandatory' => 'boolean',
- 'visible' => 'boolean',
- 'datamodel' => 'array of data model files',
- 'dictionary' => 'array of dictionary files',
- 'data.struct' => 'array of structural data files',
- 'data.sample' => 'array of sample data files',
- 'doc.manual_setup' => 'url',
- 'doc.more_information' => 'url',
- );
-
- static $m_aModules = array();
-
- // All the entries below are list of file paths relative to the module directory
- static $m_aFilesList = array('datamodel', 'webservice', 'dictionary', 'data.struct', 'data.sample');
- static $m_sModulePath = null;
- public static function SetModulePath($sModulePath)
- {
- self::$m_sModulePath = $sModulePath;
- }
- public static function AddModule($sFilePath, $sId, $aArgs)
- {
- if (!array_key_exists('itop_version', $aArgs))
- {
- // Assume 1.0.2
- $aArgs['itop_version'] = '1.0.2';
- }
- foreach (self::$m_aModuleArgs as $sArgName => $sArgDesc)
- {
- if (!array_key_exists($sArgName, $aArgs))
- {
- throw new Exception("Module '$sId': missing argument '$sArgName'");
- }
- }
- self::$m_aModules[$sId] = $aArgs;
- foreach(self::$m_aFilesList as $sAttribute)
- {
- if (isset(self::$m_aModules[$sId][$sAttribute]))
- {
- // All the items below are list of files, that are relative to the current file
- // being loaded, let's update their path to store path relative to the application directory
- foreach(self::$m_aModules[$sId][$sAttribute] as $idx => $sRelativePath)
- {
- self::$m_aModules[$sId][$sAttribute][$idx] = self::$m_sModulePath.'/'.$sRelativePath;
- }
- }
- }
- }
- public static function GetModules($oP = null)
- {
- // Order the modules to take into account their inter-dependencies
- $aDependencies = array();
- foreach(self::$m_aModules as $sId => $aModule)
- {
- $aDependencies[$sId] = $aModule['dependencies'];
- }
- $aOrderedModules = array();
- $iLoopCount = 1;
- while(($iLoopCount < count(self::$m_aModules)) && (count($aDependencies) > 0) )
- {
- foreach($aDependencies as $sId => $aRemainingDeps)
- {
- $bDependenciesSolved = true;
- foreach($aRemainingDeps as $sDepId)
- {
- if (!in_array($sDepId, $aOrderedModules))
- {
- $bDependenciesSolved = false;
- }
- }
- if ($bDependenciesSolved)
- {
- $aOrderedModules[] = $sId;
- unset($aDependencies[$sId]);
- }
- }
- $iLoopCount++;
- }
- if (count($aDependencies) >0)
- {
- $sHtml = "<ul><b>Warning: the following modules have unmet dependencies, and have been ignored:</b>\n";
- foreach($aDependencies as $sId => $aDeps)
- {
- $aModule = self::$m_aModules[$sId];
- $sHtml.= "<li>{$aModule['label']} (id: $sId), depends on: ".implode(', ', $aDeps)."</li>";
- }
- $sHtml .= "</ul>\n";
- if (is_object($oP))
- {
- $oP->warning($sHtml);
- }
- else
- {
- self::log_warning($sHtml);
- }
- }
- // Return the ordered list, so that the dependencies are met...
- $aResult = array();
- foreach($aOrderedModules as $sId)
- {
- $aResult[$sId] = self::$m_aModules[$sId];
- }
- return $aResult;
- }
- } // End of class
- /**
- * Helper function to initialize the ORM and load the data model
- * from the given file
- * @param $sConfigFileName string The name of the configuration file to load
- * @param $bModelOnly boolean Whether or not to allow loading a data model with no corresponding DB
- * @return none
- */
- function InitDataModel($sConfigFileName, $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');
- SetupWebPage::log_info("MetaModel::Startup from file '$sConfigFileName' (ModelOnly = $bModelOnly)");
- if ($bUseCache)
- {
- // Reset the cache for the first use !
- $oConfig = new Config($sConfigFileName, true /* Load Config */);
- MetaModel::ResetCache($oConfig);
- }
- MetaModel::Startup($sConfigFileName, $bModelOnly, $bUseCache);
- }
- /**
- * Search (on the disk) for all defined iTop modules, load them and returns the list (as an array)
- * of the possible iTop modules to install
- * @param none
- * @return Hash A big array moduleID => ModuleData
- */
- function GetAvailableModules($oP = null)
- {
- clearstatcache();
- ListModuleFiles('modules');
- return SetupWebPage::GetModules($oP);
- }
- /**
- * Analyzes the current installation and the possibilities
- *
- * @param $oP SetupWebPage For accessing the list of loaded modules
- * @param $sDBServer string Name/IP of the DB server
- * @param $sDBUser username for the DB server connection
- * @param $sDBPwd password for the DB server connection
- * @param $sDBName Name of the database instance
- * @param $sDBPrefix Prefix for the iTop tables in the DB instance
- * @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)
- {
- $aRes = array(
- ROOT_MODULE => array(
- 'version_db' => '',
- 'name_db' => '',
- 'version_code' => ITOP_VERSION.'.'.ITOP_REVISION,
- 'name_code' => ITOP_APPLICATION,
- )
- );
- $aModules = GetAvailableModules();
- foreach($aModules as $sModuleId => $aModuleInfo)
- {
- list($sModuleName, $sModuleVersion) = 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 interpret the name of a module
- * @param $sModuleId string Identifier of the module, in the form 'name/version'
- * @return array(name, version)
- */
- function GetModuleName($sModuleId)
- {
- if (preg_match('!^(.*)/(.*)$!', $sModuleId, $aMatches))
- {
- $sName = $aMatches[1];
- $sVersion = $aMatches[2];
- }
- else
- {
- $sName = $sModuleId;
- $sVersion = "";
- }
- return array($sName, $sVersion);
- }
- /**
- * Helper function to create the database structure
- * @return boolean true on success, false otherwise
- */
- function CreateDatabaseStructure(Config $oConfig, $aSelectedModules, $sMode)
- {
- if (strlen($oConfig->GetDBSubname()) > 0)
- {
- SetupWebPage::log_info("Creating the structure in '".$oConfig->GetDBName()."' (table names prefixed by '".$oConfig->GetDBSubname()."').");
- }
- else
- {
- SetupWebPage::log_info("Creating the structure in '".$oConfig->GetDBSubname()."'.");
- }
- //MetaModel::CheckDefinitions();
- if ($sMode == 'install')
- {
- if (!MetaModel::DBExists(/* bMustBeComplete */ false))
- {
- MetaModel::DBCreate();
- SetupWebPage::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();
- SetupWebPage::log_ok("Database structure successfully created.");
- }
- 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)
- {
- // 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);
- 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;
- }
- function ListModuleFiles($sRelDir)
- {
- $sDirectory = APPROOT.'/'.$sRelDir;
- //echo "<p>$sDirectory</p>\n";
- if ($hDir = opendir($sDirectory))
- {
- // This is the correct way to loop over the directory. (according to the documentation)
- while (($sFile = readdir($hDir)) !== false)
- {
- $aMatches = array();
- if (is_dir($sDirectory.'/'.$sFile))
- {
- if (($sFile != '.') && ($sFile != '..') && ($sFile != '.svn'))
- {
- ListModuleFiles($sRelDir.'/'.$sFile);
- }
- }
- else if (preg_match('/^module\.(.*).php$/i', $sFile, $aMatches))
- {
- SetupWebPage::SetModulePath($sRelDir);
- try
- {
- //echo "<p>Loading: $sDirectory/$sFile...</p>\n";
- require_once($sDirectory.'/'.$sFile);
- //echo "<p>Done.</p>\n";
- }
- catch(Exception $e)
- {
- // Continue...
- }
- }
- }
- closedir($hDir);
- }
- else
- {
- throw new Exception("Data directory (".$sDirectory.") not found or not readable.");
- }
- }
- ?>
|