setuppage.class.inc.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <?php
  2. // Copyright (C) 2010 Combodo SARL
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; version 3 of the License.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. /**
  17. * Web page used for displaying the login form
  18. *
  19. * @author Erwan Taloc <erwan.taloc@combodo.com>
  20. * @author Romain Quetiez <romain.quetiez@combodo.com>
  21. * @author Denis Flaven <denis.flaven@combodo.com>
  22. * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
  23. */
  24. require_once(APPROOT."/application/nicewebpage.class.inc.php");
  25. define('INSTALL_LOG_FILE', APPROOT.'/setup.log');
  26. date_default_timezone_set('Europe/Paris');
  27. class SetupWebPage extends NiceWebPage
  28. {
  29. public function __construct($sTitle)
  30. {
  31. parent::__construct($sTitle);
  32. $this->add_linked_script("../js/jquery.blockUI.js");
  33. $this->add_linked_script("./setup.js");
  34. $this->add_style("
  35. body {
  36. background-color: #eee;
  37. margin: 0;
  38. padding: 0;
  39. font-size: 10pt;
  40. overflow-y: auto;
  41. }
  42. #header {
  43. width: 600px;
  44. margin-left: auto;
  45. margin-right: auto;
  46. margin-top: 50px;
  47. padding: 20px;
  48. background: #f6f6f1;
  49. height: 54px;
  50. border-top: 1px solid #000;
  51. border-left: 1px solid #000;
  52. border-right: 1px solid #000;
  53. }
  54. #header img {
  55. border: 0;
  56. vertical-align: middle;
  57. margin-right: 20px;
  58. }
  59. #header h1 {
  60. vertical-align: middle;
  61. height: 54px;
  62. noline-height: 54px;
  63. margin: 0;
  64. }
  65. #setup {
  66. width: 600px;
  67. margin-left: auto;
  68. margin-right: auto;
  69. padding: 20px;
  70. background-color: #fff;
  71. border-left: 1px solid #000;
  72. border-right: 1px solid #000;
  73. border-bottom: 1px solid #000;
  74. }
  75. .center {
  76. text-align: center;
  77. }
  78. h1 {
  79. color: #1C94C4;
  80. font-size: 16pt;
  81. }
  82. h2 {
  83. color: #000;
  84. font-size: 14pt;
  85. }
  86. .next {
  87. width: 100%;
  88. text-align: right;
  89. }
  90. .v-spacer {
  91. padding-top: 1em;
  92. }
  93. button {
  94. margin-top: 1em;
  95. padding-left: 1em;
  96. padding-right: 1em;
  97. }
  98. p.info {
  99. padding-left: 50px;
  100. background: url(../images/info-mid.png) no-repeat left -5px;
  101. min-height: 48px;
  102. }
  103. p.ok {
  104. padding-left: 50px;
  105. background: url(../images/clean-mid.png) no-repeat left -8px;
  106. min-height: 48px;
  107. }
  108. p.warning {
  109. padding-left: 50px;
  110. background: url(../images/messagebox_warning-mid.png) no-repeat left -5px;
  111. min-height: 48px;
  112. }
  113. p.error {
  114. padding-left: 50px;
  115. background: url(../images/stop-mid.png) no-repeat left -5px;
  116. min-height: 48px;
  117. }
  118. td.label {
  119. text-align: left;
  120. }
  121. label.read-only {
  122. color: #666;
  123. cursor: text;
  124. }
  125. td.input {
  126. text-align: left;
  127. }
  128. table.formTable {
  129. border: 0;
  130. cellpadding: 2px;
  131. cellspacing: 0;
  132. }
  133. .wizlabel, .wizinput {
  134. color: #000;
  135. font-size: 10pt;
  136. }
  137. .wizhelp {
  138. color: #333;
  139. font-size: 8pt;
  140. }
  141. #progress {
  142. border:1px solid #000000;
  143. width: 180px;
  144. height: 20px;
  145. line-height: 20px;
  146. text-align: center;
  147. margin: 5px;
  148. }
  149. ");
  150. }
  151. public function info($sText)
  152. {
  153. $this->add("<p class=\"info\">$sText</p>\n");
  154. $this->log_info($sText);
  155. }
  156. public function ok($sText)
  157. {
  158. $this->add("<p class=\"ok\">$sText</p>\n");
  159. $this->log_ok($sText);
  160. }
  161. public function warning($sText)
  162. {
  163. $this->add("<p class=\"warning\">$sText</p>\n");
  164. $this->log_warning($sText);
  165. }
  166. public function error($sText)
  167. {
  168. $this->add("<p class=\"error\">$sText</p>\n");
  169. $this->log_error($sText);
  170. }
  171. public function form($aData)
  172. {
  173. $this->add("<table class=\"formTable\">\n");
  174. foreach($aData as $aRow)
  175. {
  176. $this->add("<tr>\n");
  177. if (isset($aRow['label']) && isset($aRow['input']) && isset($aRow['help']))
  178. {
  179. $this->add("<td class=\"wizlabel\">{$aRow['label']}</td>\n");
  180. $this->add("<td class=\"wizinput\">{$aRow['input']}</td>\n");
  181. $this->add("<td class=\"wizhelp\">{$aRow['help']}</td>\n");
  182. }
  183. else if (isset($aRow['label']) && isset($aRow['help']))
  184. {
  185. $this->add("<td colspan=\"2\" class=\"wizlabel\">{$aRow['label']}</td>\n");
  186. $this->add("<td class=\"wizhelp\">{$aRow['help']}</td>\n");
  187. }
  188. else if (isset($aRow['label']) && isset($aRow['input']))
  189. {
  190. $this->add("<td class=\"wizlabel\">{$aRow['label']}</td>\n");
  191. $this->add("<td colspan=\"2\" class=\"wizinput\">{$aRow['input']}</td>\n");
  192. }
  193. else if (isset($aRow['label']))
  194. {
  195. $this->add("<td colspan=\"3\" class=\"wizlabel\">{$aRow['label']}</td>\n");
  196. }
  197. $this->add("</tr>\n");
  198. }
  199. $this->add("</table>\n");
  200. }
  201. public function output()
  202. {
  203. $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>&nbsp;{$this->s_title}</h1>\n</div><div id=\"setup\">{$this->s_content}\n</div>\n";
  204. return parent::output();
  205. }
  206. public static function log_error($sText)
  207. {
  208. self::log("Error - ".$sText);
  209. }
  210. public static function log_warning($sText)
  211. {
  212. self::log("Warning - ".$sText);
  213. }
  214. public static function log_info($sText)
  215. {
  216. self::log("Info - ".$sText);
  217. }
  218. public static function log_ok($sText)
  219. {
  220. self::log("Ok - ".$sText);
  221. }
  222. public static function log($sText)
  223. {
  224. $hLogFile = @fopen(INSTALL_LOG_FILE, 'a');
  225. if ($hLogFile !== false)
  226. {
  227. $sDate = date('Y-m-d H:i:s');
  228. fwrite($hLogFile, "$sDate - $sText\n");
  229. fclose($hLogFile);
  230. }
  231. }
  232. static $m_aModuleArgs = array(
  233. 'label' => 'One line description shown during the interactive setup',
  234. 'dependencies' => 'array of module ids',
  235. 'mandatory' => 'boolean',
  236. 'visible' => 'boolean',
  237. 'datamodel' => 'array of data model files',
  238. 'dictionary' => 'array of dictionary files',
  239. 'data.struct' => 'array of structural data files',
  240. 'data.sample' => 'array of sample data files',
  241. 'doc.manual_setup' => 'url',
  242. 'doc.more_information' => 'url',
  243. );
  244. static $m_aModules = array();
  245. // All the entries below are list of file paths relative to the module directory
  246. static $m_aFilesList = array('datamodel', 'webservice', 'dictionary', 'data.struct', 'data.sample');
  247. static $m_sModulePath = null;
  248. public function SetModulePath($sModulePath)
  249. {
  250. self::$m_sModulePath = $sModulePath;
  251. }
  252. public static function AddModule($sFilePath, $sId, $aArgs)
  253. {
  254. foreach (self::$m_aModuleArgs as $sArgName => $sArgDesc)
  255. {
  256. if (!array_key_exists($sArgName, $aArgs))
  257. {
  258. throw new Exception("Module '$sId': missing argument '$sArgName'");
  259. }
  260. }
  261. self::$m_aModules[$sId] = $aArgs;
  262. foreach(self::$m_aFilesList as $sAttribute)
  263. {
  264. if (isset(self::$m_aModules[$sId][$sAttribute]))
  265. {
  266. // All the items below are list of files, that are relative to the current file
  267. // being loaded, let's update their path to store path relative to the application directory
  268. foreach(self::$m_aModules[$sId][$sAttribute] as $idx => $sRelativePath)
  269. {
  270. self::$m_aModules[$sId][$sAttribute][$idx] = self::$m_sModulePath.'/'.$sRelativePath;
  271. }
  272. }
  273. }
  274. }
  275. public function GetModules()
  276. {
  277. // Order the modules to take into account their inter-dependencies
  278. $aDependencies = array();
  279. foreach(self::$m_aModules as $sId => $aModule)
  280. {
  281. $aDependencies[$sId] = $aModule['dependencies'];
  282. }
  283. $aOrderedModules = array();
  284. $iLoopCount = 1;
  285. while(($iLoopCount < count(self::$m_aModules)) && (count($aDependencies) > 0) )
  286. {
  287. foreach($aDependencies as $sId => $aRemainingDeps)
  288. {
  289. $bDependenciesSolved = true;
  290. foreach($aRemainingDeps as $sDepId)
  291. {
  292. if (!in_array($sDepId, $aOrderedModules))
  293. {
  294. $bDependenciesSolved = false;
  295. }
  296. }
  297. if ($bDependenciesSolved)
  298. {
  299. $aOrderedModules[] = $sId;
  300. unset($aDependencies[$sId]);
  301. }
  302. }
  303. $iLoopCount++;
  304. }
  305. if (count($aDependencies) >0)
  306. {
  307. $sHtml = "<ul><b>Warning: the following modules have unmet dependencies, and have been ignored:</b>\n";
  308. foreach($aDependencies as $sId => $aDeps)
  309. {
  310. $aModule = self::$m_aModules[$sId];
  311. $sHtml.= "<li>{$aModule['label']} (id: $sId), depends on: ".implode(', ', $aDeps)."</li>";
  312. }
  313. $sHtml .= "</ul>\n";
  314. $this->warning($sHtml);
  315. }
  316. // Return the ordered list, so that the dependencies are met...
  317. $aResult = array();
  318. foreach($aOrderedModules as $sId)
  319. {
  320. $aResult[$sId] = self::$m_aModules[$sId];
  321. }
  322. return $aResult;
  323. }
  324. } // End of class
  325. ?>