compiler.class.inc.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. <?php
  2. // Copyright (C) 2011 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. class DOMFormatException extends Exception
  17. {
  18. }
  19. class CompilerEchoPage
  20. {
  21. public function p($s)
  22. {
  23. echo "<p>\n$s</p>\n";
  24. }
  25. public function add($s)
  26. {
  27. //echo $s;
  28. }
  29. public function output()
  30. {
  31. }
  32. }
  33. /**
  34. * Compiler class
  35. */
  36. class MFCompiler
  37. {
  38. protected $oFactory;
  39. protected $sSourceDir;
  40. public function __construct($oModelFactory, $sSourceDir)
  41. {
  42. $this->oFactory = $oModelFactory;
  43. $this->sSourceDir = $sSourceDir;
  44. }
  45. public function Compile($sTargetDir, $oP = null)
  46. {
  47. if (is_null($oP))
  48. {
  49. $oP = new CompilerEchoPage();
  50. }
  51. $aMenuNodes = array();
  52. $aMenusByModule = array();
  53. foreach ($this->oFactory->ListActiveChildNodes('menus', 'menu') as $oMenuNode)
  54. {
  55. $sMenuId = $oMenuNode->getAttribute('id');
  56. $aMenuNodes[$sMenuId] = $oMenuNode;
  57. $sModuleMenu = $oMenuNode->getAttribute('_created_in');
  58. $aMenusByModule[$sModuleMenu][] = $sMenuId;
  59. }
  60. $aResultFiles = array();
  61. $aModules = $this->oFactory->GetLoadedModules();
  62. foreach($aModules as $foo => $oModule)
  63. {
  64. $sModuleName = $oModule->GetName();
  65. $sModuleVersion = $oModule->GetVersion();
  66. $sModuleRootDir = realpath($oModule->GetRootDir());
  67. $sRelativeDir = substr($sModuleRootDir, strlen($this->sSourceDir) + 1);
  68. // Push the other module files
  69. $this->CopyDirectory($sModuleRootDir, $sTargetDir.'/'.$sRelativeDir);
  70. $oClasses = $this->oFactory->ListClasses($sModuleName);
  71. $iClassCount = $oClasses->length;
  72. if ($iClassCount == 0)
  73. {
  74. $oP->p("Found module without classes declared: $sModuleName");
  75. }
  76. else
  77. {
  78. $sResultFile = $sTargetDir.'/'.$sRelativeDir.'/model.'.$sModuleName.'.php';
  79. if (is_file($sResultFile))
  80. {
  81. $oP->p("Updating <a href=\"#$sModuleName\">$sResultFile</a> for module $sModuleName in version $sModuleVersion ($iClassCount classes)");
  82. }
  83. else
  84. {
  85. $sResultDir = dirname($sResultFile);
  86. if (!is_dir($sResultDir))
  87. {
  88. $oP->p("Creating directory $sResultDir");
  89. mkdir($sResultDir, 0777, true);
  90. }
  91. $oP->p("Creating <a href=\"#$sModuleName\">$sResultFile</a> for module $sModuleName in version $sModuleVersion ($iClassCount classes)");
  92. }
  93. // Compile the module into a single file
  94. //
  95. $sId = $sModuleName;
  96. $aResultFiles[$sId] = $sResultFile;
  97. $sCurrDate = date(DATE_ISO8601);
  98. $sAuthor = 'Combodo compiler';
  99. $sLicence = 'http://www.opensource.org/licenses/gpl-3.0.html LGPL';
  100. $sFileHeader =
  101. <<<EOF
  102. <?php
  103. //
  104. // File generated by ... on the $sCurrDate
  105. // Please do not edit manually
  106. //
  107. //
  108. // Copyright (C) 2010 Combodo SARL
  109. //
  110. // ben on met quoi ici ?
  111. // Signé: Romain
  112. //
  113. // This program is free software; you can redistribute it and/or modify
  114. // it under the terms of the GNU General Public License as published by
  115. // the Free Software Foundation; version 3 of the License.
  116. //
  117. // This program is distributed in the hope that it will be useful,
  118. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  119. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  120. // GNU General Public License for more details.
  121. //
  122. // You should have received a copy of the GNU General Public License
  123. // along with this program; if not, write to the Free Software
  124. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  125. /**
  126. * Persistent classes for $sModuleName (version $sModuleVersion)
  127. *
  128. * @author $sAuthor
  129. * @license $sLicence
  130. */
  131. EOF;
  132. file_put_contents($sResultFile, $sFileHeader);
  133. foreach($oClasses as $oClass)
  134. {
  135. try
  136. {
  137. $this->CompileClass($oClass, $sResultFile, $sRelativeDir, $oP);
  138. }
  139. catch (ssDOMFormatException $e)
  140. {
  141. $sClass = $oClass->getAttribute("id");
  142. throw new Exception("Failed to process class '$sClass', from '$sModuleRootDir': ".$e->getMessage());
  143. }
  144. }
  145. }
  146. if (!array_key_exists($sModuleName, $aMenusByModule))
  147. {
  148. $oP->p("Found module without menus declared: $sModuleName");
  149. }
  150. else
  151. {
  152. $sMenusHeader =
  153. <<<EOF
  154. //
  155. // Menus
  156. //
  157. EOF;
  158. file_put_contents($sResultFile, $sMenusHeader, FILE_APPEND);
  159. // Preliminary: determine parent menus not defined within the current module
  160. $aMenusToLoad = array();
  161. foreach($aMenusByModule[$sModuleName] as $sMenuId)
  162. {
  163. $oMenuNode = $aMenuNodes[$sMenuId];
  164. if ($sParent = $oMenuNode->GetChildText('parent', null))
  165. {
  166. $aMenusToLoad[] = $sParent;
  167. }
  168. // Note: the order matters: the parents must be defined BEFORE
  169. $aMenusToLoad[] = $sMenuId;
  170. }
  171. $aMenusToLoad = array_unique($aMenusToLoad);
  172. foreach($aMenusToLoad as $sMenuId)
  173. {
  174. $oMenuNode = $aMenuNodes[$sMenuId];
  175. try
  176. {
  177. $this->CompileMenu($oMenuNode, $sResultFile, $sRelativeDir, $oP);
  178. }
  179. catch (ssDOMFormatException $e)
  180. {
  181. throw new Exception("Failed to process menu '$sMenuId', from '$sModuleRootDir': ".$e->getMessage());
  182. }
  183. }
  184. }
  185. }
  186. if (count($aResultFiles))
  187. {
  188. $oP->add('<h2>Files</h2>');
  189. foreach ($aResultFiles as $sModuleName => $sFile)
  190. {
  191. $oP->add('<h3>'.$sFile.'</h3>');
  192. $oP->add('<a name="'.$sModuleName.'"/><div style="border:1;">');
  193. $oP->add(highlight_file($sFile, true));
  194. $oP->add('</div style="">');
  195. }
  196. }
  197. $oP->output();
  198. //$this->oFactory->Dump();
  199. }
  200. /**
  201. * Helper to copy the module files to the exploitation environment
  202. * Returns true if successfull
  203. */
  204. protected function CopyDirectory($sSource, $sDest)
  205. {
  206. if (is_dir($sSource))
  207. {
  208. if (!is_dir($sDest))
  209. {
  210. mkdir($sDest);
  211. }
  212. $aFiles = scandir($sSource);
  213. if(sizeof($aFiles) > 0 )
  214. {
  215. foreach($aFiles as $sFile)
  216. {
  217. if ($sFile == '.' || $sFile == '..' || $sFile == '.svn')
  218. {
  219. // Skip
  220. continue;
  221. }
  222. if (is_dir($sSource.'/'.$sFile))
  223. {
  224. $this->CopyDirectory($sSource.'/'.$sFile, $sDest.'/'.$sFile);
  225. }
  226. else
  227. {
  228. copy($sSource.'/'.$sFile, $sDest.'/'.$sFile);
  229. }
  230. }
  231. }
  232. return true;
  233. }
  234. elseif (is_file($sSource))
  235. {
  236. return copy($sSource, $sDest);
  237. }
  238. else
  239. {
  240. return false;
  241. }
  242. }
  243. /**
  244. * Helper to format the flags for an attribute, in a given state
  245. * @param object $oAttNode DOM node containing the information to build the flags
  246. * Returns string PHP flags, based on the OPT_ATT_ constants, or empty (meaning 0, can be omitted)
  247. */
  248. protected function FlagsToPHP($oAttNode)
  249. {
  250. static $aNodeAttributeToFlag = array(
  251. 'mandatory' => 'OPT_ATT_MANDATORY',
  252. 'read_only' => 'OPT_ATT_READONLY',
  253. 'must_prompt' => 'OPT_ATT_MUSTPROMPT',
  254. 'must_change' => 'OPT_ATT_MUSTCHANGE',
  255. 'hidden' => 'OPT_ATT_HIDDEN',
  256. );
  257. $aFlags = array();
  258. foreach ($aNodeAttributeToFlag as $sNodeAttribute => $sFlag)
  259. {
  260. $bFlag = ($oAttNode->GetOptionalElement($sNodeAttribute) != null);
  261. if ($bFlag)
  262. {
  263. $aFlags[] = $sFlag;
  264. }
  265. }
  266. $sRes = implode(' | ', $aFlags);
  267. return $sRes;
  268. }
  269. /**
  270. * Format a path (file or url) as an absolute path or relative to the module or the app
  271. */
  272. protected function PathToPHP($sPath, $sModuleRelativeDir, $bIsUrl = false)
  273. {
  274. if ($sPath == '')
  275. {
  276. $sPHP = "''";
  277. }
  278. elseif (substr($sPath, 0, 2) == '$$')
  279. {
  280. // Absolute
  281. $sPHP = "'".addslashes(substr($sPath, 2))."'";
  282. }
  283. elseif (substr($sPath, 0, 1) == '$')
  284. {
  285. // Relative to the application
  286. if ($bIsUrl)
  287. {
  288. $sPHP = "utils::GetAbsoluteUrlAppRoot().'".addslashes(substr($sPath, 1))."'";
  289. }
  290. else
  291. {
  292. $sPHP = "APPROOT.'".addslashes(substr($sPath, 1))."'";
  293. }
  294. }
  295. else
  296. {
  297. // Relative to the module
  298. if ($bIsUrl)
  299. {
  300. $sPHP = "utils::GetAbsoluteUrlAppRoot().'".addslashes($sModuleRelativeDir.''.$sPath)."'";
  301. }
  302. else
  303. {
  304. $sPHP = "dirname(__FILE__).'/$sPath'";
  305. }
  306. }
  307. return $sPHP;
  308. }
  309. protected function CompileClass($oClass, $sResFile, $sModuleRelativeDir, $oP)
  310. {
  311. $sClass = $oClass->getAttribute('id');
  312. $oProperties = $oClass->GetUniqueElement('properties');
  313. // Class caracteristics
  314. //
  315. $aClassParams = array();
  316. $aClassParams['category'] = "'".$oProperties->GetChildText('category')."'";
  317. $aClassParams['key_type'] = "'autoincrement'";
  318. $oNaming = $oProperties->GetUniqueElement('naming');
  319. $oNameAttributes = $oNaming->GetUniqueElement('attributes');
  320. $oAttributes = $oNameAttributes->getElementsByTagName('attribute');
  321. $aNameAttCodes = array();
  322. foreach($oAttributes as $oAttribute)
  323. {
  324. $aNameAttCodes[] = $oAttribute->getAttribute('id');
  325. }
  326. if (count($aNameAttCodes) > 1)
  327. {
  328. // New style...
  329. $sNameAttCode = "array('".implode("', '", $aNameAttCodes)."')";
  330. }
  331. elseif (count($aNameAttCodes) == 1)
  332. {
  333. // New style...
  334. $sNameAttCode = "'$aNameAttCodes[0]'";
  335. }
  336. else
  337. {
  338. $sNameAttCode = "''";
  339. }
  340. $aClassParams['name_attcode'] = $sNameAttCode;
  341. $oLifecycle = $oClass->GetOptionalElement('lifecycle');
  342. if ($oLifecycle)
  343. {
  344. $sStateAttCode = $oLifecycle->GetChildText('attribute');
  345. }
  346. else
  347. {
  348. $sStateAttCode = "";
  349. }
  350. $aClassParams['state_attcode'] = "'$sStateAttCode'";
  351. $oReconciliation = $oProperties->GetUniqueElement('reconciliation');
  352. $oReconcAttributes = $oReconciliation->getElementsByTagName('attribute');
  353. $aReconcAttCodes = array();
  354. foreach($oReconcAttributes as $oAttribute)
  355. {
  356. $aReconcAttCodes[] = $oAttribute->getAttribute('id');
  357. }
  358. $sReconcKeys = "array('".implode("', '", $aReconcAttCodes)."')";
  359. $aClassParams['reconc_keys'] = $sReconcKeys;
  360. $aClassParams['db_table'] = "'".$oProperties->GetChildText('db_table')."'";
  361. $aClassParams['db_key_field'] = "'".$oProperties->GetChildText('db_key_field')."'";
  362. $aClassParams['db_finalclass_field'] = "'".$oProperties->GetChildText('db_final_class_field')."'";
  363. if (($sDisplayTemplate = $oProperties->GetChildText('display_template')) && (strlen($sDisplayTemplate) > 0))
  364. {
  365. $sDisplayTemplate = $sModuleRelativeDir.'/'.$sDisplayTemplate;
  366. $aClassParams['display_template'] = "utils::GetAbsoluteUrlModulesRoot().'$sDisplayTemplate'";
  367. }
  368. if (($sIcon = $oProperties->GetChildText('icon')) && (strlen($sIcon) > 0))
  369. {
  370. $sIcon = $sModuleRelativeDir.'/'.$sIcon;
  371. $aClassParams['icon'] = "utils::GetAbsoluteUrlModulesRoot().'$sIcon'";
  372. }
  373. $oOrder = $oProperties->GetOptionalElement('order');
  374. if ($oOrder)
  375. {
  376. $oColumnsNode = $oOrder->GetUniqueElement('columns');
  377. $oColumns = $oColumnsNode->getElementsByTagName('column');
  378. $aSortColumns = array();
  379. foreach($oColumns as $oColumn)
  380. {
  381. $aSortColumns[] = "'".$oColumn->getAttribute('id')."' => ".(($oColumn->getAttribute('ascending') == 'true') ? 'true' : 'false');
  382. }
  383. if (count($aSortColumns) > 0)
  384. {
  385. $aClassParams['order_by_default'] = "array(".implode(", ", $aSortColumns).")";
  386. }
  387. }
  388. // Finalize class params declaration
  389. //
  390. $aClassParamsPHP = array();
  391. foreach($aClassParams as $sKey => $sPHPValue)
  392. {
  393. $aClassParamsPHP[] = " '$sKey' => $sPHPValue,";
  394. }
  395. $sClassParams = implode("\n", $aClassParamsPHP);
  396. // Comment on top of the class declaration
  397. //
  398. $sCodeComment = $oProperties->GetChildText('comment');
  399. // Fields
  400. //
  401. $sAttributes = '';
  402. foreach($this->oFactory->ListFields($oClass) as $oField)
  403. {
  404. // $oField
  405. $sAttCode = $oField->getAttribute('id');
  406. $sAttType = $oField->getAttribute('xsi:type');
  407. $aDependencies = array();
  408. $oDependencies = $oField->GetOptionalElement('dependencies');
  409. if (!is_null($oDependencies))
  410. {
  411. $oDepNodes = $oDependencies->getElementsByTagName('attribute');
  412. foreach($oDepNodes as $oDepAttribute)
  413. {
  414. $aDependencies[] = "'".$oDepAttribute->getAttribute('id')."'";
  415. }
  416. }
  417. $sDependencies = 'array('.implode(', ', $aDependencies).')';
  418. $aParameters = array();
  419. if ($sAttType == 'AttributeLinkedSetIndirect')
  420. {
  421. $aParameters['linked_class'] = "'".$oField->GetChildText('linked_class')."'";
  422. $aParameters['ext_key_to_me'] = "'".$oField->GetChildText('ext_key_to_me')."'";
  423. $aParameters['ext_key_to_remote'] = "'".$oField->GetChildText('ext_key_to_remote')."'";
  424. // todo - utile ?
  425. $aParameters['allowed_values'] = 'null';
  426. $aParameters['count_min'] = $oField->GetChildText('count_min');
  427. $aParameters['count_max'] = $oField->GetChildText('count_max');
  428. $aParameters['depends_on'] = $sDependencies;
  429. }
  430. elseif ($sAttType == 'AttributeLinkedSet')
  431. {
  432. $aParameters['linked_class'] = "'".$oField->GetChildText('linked_class')."'";
  433. $aParameters['ext_key_to_me'] = "'".$oField->GetChildText('ext_key_to_me')."'";
  434. // todo - utile ?
  435. $aParameters['allowed_values'] = 'null';
  436. $aParameters['count_min'] = $oField->GetChildText('count_min');
  437. $aParameters['count_max'] = $oField->GetChildText('count_max');
  438. $aParameters['depends_on'] = $sDependencies;
  439. }
  440. elseif ($sAttType == 'AttributeExternalKey')
  441. {
  442. $aParameters['targetclass'] = "'".$oField->GetChildText('target_class')."'";
  443. $aParameters['jointype'] = 'null';
  444. if ($sOql = $oField->GetChildText('filter'))
  445. {
  446. $sEscapedOql = addslashes($sOql);
  447. $aParameters['allowed_values'] = "new ValueSetObjects('$sEscapedOql')"; // or "new ValueSetObjects('SELECT xxxx')"
  448. }
  449. else
  450. {
  451. $aParameters['allowed_values'] = 'null'; // or "new ValueSetObjects('SELECT xxxx')"
  452. }
  453. $aParameters['sql'] = "'".$oField->GetChildText('sql')."'";
  454. $aParameters['is_null_allowed'] = $oField->GetChildText('is_null_allowed') == 'true' ? 'true' : 'false';
  455. $aParameters['on_target_delete'] = $oField->GetChildText('on_target_delete');
  456. $aParameters['depends_on'] = $sDependencies;
  457. }
  458. elseif ($sAttType == 'AttributeHierarchicalKey')
  459. {
  460. if ($sOql = $oField->GetChildText('filter'))
  461. {
  462. $sEscapedOql = addslashes($sOql);
  463. $aParameters['allowed_values'] = "new ValueSetObjects('$sEscapedOql')"; // or "new ValueSetObjects('SELECT xxxx')"
  464. }
  465. else
  466. {
  467. $aParameters['allowed_values'] = 'null'; // or "new ValueSetObjects('SELECT xxxx')"
  468. }
  469. $aParameters['sql'] = "'".$oField->GetChildText('sql')."'";
  470. $aParameters['is_null_allowed'] = $oField->GetChildText('is_null_allowed') == 'true' ? 'true' : 'false';
  471. $aParameters['on_target_delete'] = $oField->GetChildText('on_target_delete');
  472. $aParameters['depends_on'] = $sDependencies;
  473. }
  474. elseif ($sAttType == 'AttributeExternalField')
  475. {
  476. $aParameters['allowed_values'] = 'null';
  477. $aParameters['extkey_attcode'] = "'".$oField->GetChildText('extkey_attcode')."'";
  478. $aParameters['target_attcode'] = "'".$oField->GetChildText('target_attcode')."'";
  479. }
  480. elseif ($sAttType == 'AttributeURL')
  481. {
  482. $aParameters['target'] = "'".$oField->GetChildText('target')."'";
  483. $aParameters['allowed_values'] = 'null';
  484. $aParameters['sql'] = "'".$oField->GetChildText('sql')."'";
  485. $aParameters['default_value'] = "'".$oField->GetChildText('default_value')."'";
  486. $aParameters['is_null_allowed'] = $oField->GetChildText('is_null_allowed') == 'true' ? 'true' : 'false';
  487. $aParameters['depends_on'] = $sDependencies;
  488. }
  489. elseif ($sAttType == 'AttributeEnum')
  490. {
  491. $oValues = $oField->GetUniqueElement('values');
  492. $oValueNodes = $oValues->getElementsByTagName('value');
  493. $aValues = array();
  494. foreach($oValueNodes as $oValue)
  495. {
  496. // new style... $aValues[] = "'".addslashes($oValue->textContent)."'";
  497. $aValues[] = $oValue->textContent;
  498. }
  499. // new style... $sValues = 'array('.implode(', ', $aValues).')';
  500. $sValues = '"'.implode(',', $aValues).'"';
  501. $aParameters['allowed_values'] = "new ValueSetEnum($sValues)";
  502. $aParameters['sql'] = "'".$oField->GetChildText('sql')."'";
  503. $aParameters['default_value'] = "'".$oField->GetChildText('default_value')."'";
  504. $aParameters['is_null_allowed'] = $oField->GetChildText('is_null_allowed') == 'true' ? 'true' : 'false';
  505. $aParameters['depends_on'] = $sDependencies;
  506. }
  507. elseif ($sAttType == 'AttributeBlob')
  508. {
  509. $aParameters['depends_on'] = $sDependencies;
  510. }
  511. else
  512. {
  513. $aParameters['allowed_values'] = 'null'; // or "new ValueSetEnum('SELECT xxxx')"
  514. $aParameters['sql'] = "'".$oField->GetChildText('sql')."'";
  515. $aParameters['default_value'] = "'".$oField->GetChildText('default_value')."'";
  516. $aParameters['is_null_allowed'] = $oField->GetChildText('is_null_allowed') == 'true' ? 'true' : 'false';
  517. $aParameters['depends_on'] = $sDependencies;
  518. if ($sValidationPattern = $oField->GetChildText('validation_pattern'))
  519. {
  520. $aParameters['validation_pattern'] = '"'.addslashes($sValidationPattern).'"';
  521. }
  522. }
  523. $aParams = array();
  524. foreach($aParameters as $sKey => $sValue)
  525. {
  526. $aParams[] = '"'.$sKey.'"=>'.$sValue;
  527. }
  528. $sParams = implode(', ', $aParams);
  529. $sAttributes .= " MetaModel::Init_AddAttribute(new $sAttType(\"$sAttCode\", array($sParams)));\n";
  530. }
  531. // Lifecycle
  532. //
  533. $sLifecycle = '';
  534. if ($oLifecycle)
  535. {
  536. $sLifecycle .= "\t\t// Lifecycle (status attribute: $sStateAttCode)\n";
  537. $sLifecycle .= "\t\t//\n";
  538. $oStimuli = $oLifecycle->GetUniqueElement('stimuli');
  539. foreach ($oStimuli->getElementsByTagName('stimulus') as $oStimulus)
  540. {
  541. $sStimulus = $oStimulus->getAttribute('id');
  542. $sStimulusClass = $oStimulus->getAttribute('xsi:type');
  543. $sLifecycle .= " MetaModel::Init_DefineStimulus(new ".$sStimulusClass."(\"".$sStimulus."\", array()));\n";
  544. }
  545. $oStates = $oLifecycle->GetUniqueElement('states');
  546. foreach ($oStates->getElementsByTagName('state') as $oState)
  547. {
  548. $sState = $oState->getAttribute('id');
  549. $sLifecycle .= " MetaModel::Init_DefineState(\n";
  550. $sLifecycle .= " \"".$sState."\",\n";
  551. $sLifecycle .= " array(\n";
  552. $sLifecycle .= " \"attribute_inherit\" => '',\n";
  553. $sLifecycle .= " \"attribute_list\" => array(\n";
  554. $oFlags = $oState->GetUniqueElement('flags');
  555. foreach ($oFlags->getElementsByTagName('attribute') as $oAttributeNode)
  556. {
  557. $sFlags = $this->FlagsToPHP($oAttributeNode);
  558. if (strlen($sFlags) > 0)
  559. {
  560. $sAttCode = $oAttributeNode->GetAttribute('id');
  561. $sLifecycle .= " '$sAttCode' => $sFlags,\n";
  562. }
  563. }
  564. $sLifecycle .= " ),\n";
  565. $sLifecycle .= " )\n";
  566. $sLifecycle .= " );\n";
  567. $oTransitions = $oState->GetUniqueElement('transitions');
  568. foreach ($oTransitions->getElementsByTagName('transition') as $oTransition)
  569. {
  570. $sStimulus = $oTransition->GetChildText('stimulus');
  571. $sTargetState = $oTransition->GetChildText('target');
  572. $oActions = $oTransition->GetUniqueElement('actions');
  573. $aVerbs = array();
  574. foreach ($oActions->getElementsByTagName('action') as $oAction)
  575. {
  576. $sVerb = $oAction->GetChildText('verb');
  577. $aVerbs[] = "'$sVerb'";
  578. }
  579. $sActions = implode(', ', $aVerbs);
  580. $sLifecycle .= " MetaModel::Init_DefineTransition(\"$sState\", \"$sStimulus\", array(\"target_state\"=>\"$sTargetState\", \"actions\"=>array($sActions), \"user_restriction\"=>null));\n";
  581. }
  582. }
  583. }
  584. // ZLists
  585. //
  586. $aListRef = array(
  587. 'details' => 'details',
  588. 'standard_search' => 'search',
  589. 'list' => 'list'
  590. );
  591. $oPresentation = $oClass->GetUniqueElement('presentation');
  592. $sZlists = '';
  593. foreach ($aListRef as $sListCode => $sListTag)
  594. {
  595. $oListNode = $oPresentation->GetOptionalElement($sListTag);
  596. if ($oListNode)
  597. {
  598. $aAttributes = $oListNode->GetNodeAsArrayOfItems();
  599. $sZAttributes = var_export($aAttributes, true);
  600. $sZlists .= " MetaModel::Init_SetZListItems('$sListCode', $sZAttributes);\n";
  601. }
  602. }
  603. // Methods
  604. $sMethods = "";
  605. $oMethods = $oClass->GetUniqueElement('methods');
  606. foreach($oMethods->getElementsByTagName('method') as $oMethod)
  607. {
  608. $sMethodCode = $oMethod->GetChildText('code');
  609. if ($sMethodComment = $oMethod->GetChildText('comment', null))
  610. {
  611. $sMethods .= "\n\t$sMethodComment\n".$sMethodCode."\n";
  612. }
  613. else
  614. {
  615. $sMethods .= "\n\n".$sMethodCode."\n";
  616. }
  617. }
  618. // Let's make the whole class declaration
  619. //
  620. $sPHP = "\n\n$sCodeComment\n";
  621. if ($oProperties->GetChildText('abstract') == 'true')
  622. {
  623. $sPHP .= 'abstract class '.$oClass->getAttribute('id');
  624. }
  625. else
  626. {
  627. $sPHP .= 'class '.$oClass->getAttribute('id');
  628. }
  629. $sPHP .= " extends ".$oClass->GetChildText('parent', 'DBObject')."\n";
  630. $sPHP .=
  631. <<<EOF
  632. {
  633. public static function Init()
  634. {
  635. \$aParams = array
  636. (
  637. $sClassParams
  638. );
  639. MetaModel::Init_Params(\$aParams);
  640. MetaModel::Init_InheritAttributes();
  641. $sAttributes
  642. $sLifecycle
  643. $sZlists
  644. }
  645. $sMethods
  646. }
  647. EOF;
  648. file_put_contents($sResFile, $sPHP, FILE_APPEND);
  649. }// function CompileClass()
  650. protected function CompileMenu($oMenu, $sResFile, $sModuleRelativeDir, $oP)
  651. {
  652. $sMenuId = $oMenu->getAttribute("id");
  653. $sMenuClass = $oMenu->getAttribute("xsi:type");
  654. $sParent = $oMenu->GetChildText('parent', null);
  655. if ($sParent)
  656. {
  657. $sParentSpec = "\$__comp_menus__['$sParent']->GetIndex()";
  658. }
  659. else
  660. {
  661. $sParentSpec = '-1';
  662. }
  663. $fRank = $oMenu->GetChildText('rank');
  664. switch($sMenuClass)
  665. {
  666. case 'WebPageMenuNode':
  667. $sUrl = $oMenu->GetChildText('url');
  668. $sUrlSpec = $this->PathToPHP($sUrl, $sModuleRelativeDir, true /* Url */);
  669. $sNewMenu = "new WebPageMenuNode('$sMenuId', $sUrlSpec, $sParentSpec, $fRank);";
  670. break;
  671. case 'TemplateMenuNode':
  672. $sTemplateFile = $oMenu->GetChildText('template_file');
  673. $sTemplateSpec = $this->PathToPHP($sTemplateFile, $sModuleRelativeDir);
  674. $sNewMenu = "new TemplateMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank);";
  675. break;
  676. case 'OQLMenuNode':
  677. $sOQL = $oMenu->GetChildText('oql');
  678. $bSearch = ($oMenu->GetChildText('do_search') == '1') ? 'true' : 'false';
  679. $sNewMenu = "new OQLMenuNode('$sMenuId', '$sOQL', $sParentSpec, $fRank, $bSearch);";
  680. break;
  681. case 'NewObjectMenuNode':
  682. $sClass = $oMenu->GetChildText('class');
  683. $sNewMenu = "new NewObjectMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank);";
  684. break;
  685. case 'SearchMenuNode':
  686. $sClass = $oMenu->GetChildText('class');
  687. $sNewMenu = "new SearchMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank);";
  688. break;
  689. case 'MenuGroup':
  690. default:
  691. if ($sEnableClass = $oMenu->GetChildText('enable_class'))
  692. {
  693. $sEnableAction = $oMenu->GetChildText('enable_action');
  694. $sEnablePermission = $oMenu->GetChildText('enable_permission');
  695. $sEnableStimulus = $oMenu->GetChildText('enable_stimulus');
  696. if (strlen($sEnableStimulus) > 0)
  697. {
  698. $sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission, '$sEnableStimulus');";
  699. }
  700. else
  701. {
  702. $sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission);";
  703. }
  704. //$sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', UR_ACTION_MODIFY, UR_ALLOWED_YES|UR_ALLOWED_DEPENDS);";
  705. }
  706. else
  707. {
  708. $sNewMenu = "new MenuGroup('$sMenuId', $fRank);";
  709. }
  710. }
  711. $sIndent = '';
  712. $aPHPMenu = array("\$__comp_menus__['$sMenuId'] = $sNewMenu");
  713. if ($sAutoReload = $oMenu->GetChildText('auto_reload'))
  714. {
  715. $sAutoReload = addslashes($sAutoReload);
  716. $aPHPMenu[] = "\$__comp_menus__['$sMenuId']->SetParameters(array('auto_reload' => '$sAutoReload'));";
  717. }
  718. $sAdminOnly = $oMenu->GetChildText('enable_admin_only');
  719. if ($sAdminOnly && ($sAdminOnly == '1'))
  720. {
  721. $sPHP = $sIndent."if (UserRights::IsAdministrator())\n";
  722. $sPHP .= $sIndent."{\n";
  723. foreach($aPHPMenu as $sPHPLine)
  724. {
  725. $sPHP .= $sIndent." $sPHPLine\n";
  726. }
  727. $sPHP .= $sIndent."}\n";
  728. }
  729. else
  730. {
  731. $sPHP = '';
  732. foreach($aPHPMenu as $sPHPLine)
  733. {
  734. $sPHP .= $sIndent.$sPHPLine."\n";
  735. }
  736. }
  737. file_put_contents($sResFile, $sPHP, FILE_APPEND);
  738. }
  739. }
  740. ?>