compiler.class.inc.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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. $aResultFiles = array();
  52. $aModules = $this->oFactory->GetLoadedModules();
  53. foreach($aModules as $foo => $oModule)
  54. {
  55. $sModuleName = $oModule->GetName();
  56. $sModuleVersion = $oModule->GetVersion();
  57. $sModuleRootDir = realpath($oModule->GetRootDir());
  58. $sRelativeDir = substr($sModuleRootDir, strlen($this->sSourceDir));
  59. // Push the other module files
  60. $this->CopyDirectory($sModuleRootDir, $sTargetDir.$sRelativeDir);
  61. $oClasses = $this->oFactory->ListClasses($sModuleName);
  62. $iClassCount = $oClasses->length;
  63. if ($iClassCount == 0)
  64. {
  65. $oP->p("Found module without classes declared: $sModuleName");
  66. }
  67. else
  68. {
  69. $sResultFile = $sTargetDir.$sRelativeDir.'/model.'.$sModuleName.'.php';
  70. if (is_file($sResultFile))
  71. {
  72. $oP->p("Updating <a href=\"#$sModuleName\">$sResultFile</a> for module $sModuleName in version $sModuleVersion ($iClassCount classes)");
  73. }
  74. else
  75. {
  76. $sResultDir = dirname($sResultFile);
  77. if (!is_dir($sResultDir))
  78. {
  79. $oP->p("Creating directory $sResultDir");
  80. mkdir($sResultDir, 0777, true);
  81. }
  82. $oP->p("Creating <a href=\"#$sModuleName\">$sResultFile</a> for module $sModuleName in version $sModuleVersion ($iClassCount classes)");
  83. }
  84. // Compile the module into a single file
  85. //
  86. $sId = $sModuleName;
  87. $aResultFiles[$sId] = $sResultFile;
  88. $sCurrDate = date(DATE_ISO8601);
  89. $sAuthor = 'Combodo compiler';
  90. $sLicence = 'http://www.opensource.org/licenses/gpl-3.0.html LGPL';
  91. $sFileHeader =
  92. <<<EOF
  93. <?php
  94. //
  95. // File generated by ... on the $sCurrDate
  96. // Please do not edit manually
  97. //
  98. //
  99. // Copyright (C) 2010 Combodo SARL
  100. //
  101. // ben on met quoi ici ?
  102. // Signé: Romain
  103. //
  104. // This program is free software; you can redistribute it and/or modify
  105. // it under the terms of the GNU General Public License as published by
  106. // the Free Software Foundation; version 3 of the License.
  107. //
  108. // This program is distributed in the hope that it will be useful,
  109. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  110. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  111. // GNU General Public License for more details.
  112. //
  113. // You should have received a copy of the GNU General Public License
  114. // along with this program; if not, write to the Free Software
  115. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  116. /**
  117. * Persistent classes for $sModuleName (version $sModuleVersion)
  118. *
  119. * @author $sAuthor
  120. * @license $sLicence
  121. */
  122. EOF;
  123. file_put_contents($sResultFile, $sFileHeader);
  124. foreach($oClasses as $oClass)
  125. {
  126. $sClass = $oClass->getAttribute("name");
  127. try
  128. {
  129. $this->CompileClass($oClass, $sResultFile, $oP);
  130. }
  131. catch (ssDOMFormatException $e)
  132. {
  133. $sClass = $oClass->getAttribute("name");
  134. throw new Exception("Failed to process class '$sClass', from '$sModuleRootDir': ".$e->getMessage());
  135. }
  136. }
  137. }
  138. }
  139. if (count($aResultFiles))
  140. {
  141. $oP->add('<h2>Files</h2>');
  142. foreach ($aResultFiles as $sModuleName => $sFile)
  143. {
  144. $oP->add('<h3>'.$sFile.'</h3>');
  145. $oP->add('<a name="'.$sModuleName.'"/><div style="border:1;">');
  146. $oP->add(highlight_file($sFile, true));
  147. $oP->add('</div style="">');
  148. }
  149. }
  150. $oP->output();
  151. }
  152. /**
  153. * Helper to copy the module files to the exploitation environment
  154. * Returns true if successfull
  155. */
  156. protected function CopyDirectory($sSource, $sDest)
  157. {
  158. if (is_dir($sSource))
  159. {
  160. if (!is_dir($sDest))
  161. {
  162. mkdir($sDest);
  163. }
  164. $aFiles = scandir($sSource);
  165. if(sizeof($aFiles) > 0 )
  166. {
  167. foreach($aFiles as $sFile)
  168. {
  169. if ($sFile == '.' || $sFile == '..' || $sFile == '.svn')
  170. {
  171. // Skip
  172. continue;
  173. }
  174. if (is_dir($sSource.'/'.$sFile))
  175. {
  176. $this->CopyDirectory($sSource.'/'.$sFile, $sDest.'/'.$sFile);
  177. }
  178. else
  179. {
  180. copy($sSource.'/'.$sFile, $sDest.'/'.$sFile);
  181. }
  182. }
  183. }
  184. return true;
  185. }
  186. elseif (is_file($sSource))
  187. {
  188. return copy($sSource, $sDest);
  189. }
  190. else
  191. {
  192. return false;
  193. }
  194. }
  195. /**
  196. * Helper to browse the DOM -could be factorized in ModelFactory
  197. * Returns the node directly under the given node, and that is supposed to be always present and unique
  198. */
  199. protected function GetUniqueElement($oDOMNode, $sTagName, $bMustExist = true)
  200. {
  201. $oNode = null;
  202. foreach($oDOMNode->childNodes as $oChildNode)
  203. {
  204. if ($oChildNode->nodeName == $sTagName)
  205. {
  206. $oNode = $oChildNode;
  207. break;
  208. }
  209. }
  210. if ($bMustExist && is_null($oNode))
  211. {
  212. throw new DOMFormatException('Missing unique tag: '.$sTagName);
  213. }
  214. return $oNode;
  215. }
  216. /**
  217. * Helper to browse the DOM -could be factorized in ModelFactory
  218. * Returns the node directly under the given node, or null is missing
  219. */
  220. protected function GetOptionalElement($oDOMNode, $sTagName)
  221. {
  222. return $this->GetUniqueElement($oDOMNode, $sTagName, false);
  223. }
  224. /**
  225. * Helper to browse the DOM -could be factorized in ModelFactory
  226. * Returns the TEXT of the given node (possibly from several subnodes)
  227. */
  228. protected function GetNodeText($oNode)
  229. {
  230. $sText = '';
  231. foreach($oNode->childNodes as $oChildNode)
  232. {
  233. if ($oChildNode instanceof DOMCharacterData) // Base class of DOMText and DOMCdataSection
  234. {
  235. $sText .= $oChildNode->wholeText;
  236. }
  237. }
  238. return $sText;
  239. }
  240. /**
  241. * Helper to browse the DOM -could be factorized in ModelFactory
  242. * Assumes the given node to be either a text or
  243. * <items>
  244. * <item [key]="..."]>value<item>
  245. * <item [key]="..."]>value<item>
  246. * </items>
  247. * where value can be the either a text or an array of items... recursively
  248. * Returns a PHP array
  249. */
  250. protected function GetNodeAsArrayOfItems($oNode)
  251. {
  252. $oItems = $this->GetOptionalElement($oNode, 'items');
  253. if ($oItems)
  254. {
  255. $res = array();
  256. foreach($oItems->childNodes as $oItem)
  257. {
  258. // When an attribute is msising
  259. if ($oItem->hasAttribute('key'))
  260. {
  261. $key = $oItem->getAttribute('key');
  262. $res[$key] = $this->GetNodeAsArrayOfItems($oItem);
  263. }
  264. else
  265. {
  266. $res[] = $this->GetNodeAsArrayOfItems($oItem);
  267. }
  268. }
  269. }
  270. else
  271. {
  272. $res = $this->GetNodeText($oNode);
  273. }
  274. return $res;
  275. }
  276. /**
  277. * Helper to format the flags for an attribute, in a given state
  278. * @param object $oAttNode DOM node containing the information to build the flags
  279. * Returns string PHP flags, based on the OPT_ATT_ constants, or empty (meaning 0, can be omitted)
  280. */
  281. protected function FlagsToPHP($oAttNode)
  282. {
  283. static $aNodeAttributeToFlag = array(
  284. 'read_only' => 'OPT_ATT_READONLY',
  285. 'must_prompt' => 'OPT_ATT_MUSTPROMPT',
  286. 'must_change' => 'OPT_ATT_MUSTCHANGE',
  287. 'hidden' => 'OPT_ATT_HIDDEN',
  288. );
  289. $aFlags = array();
  290. foreach ($aNodeAttributeToFlag as $sNodeAttribute => $sFlag)
  291. {
  292. $bFlag = ($oAttNode->GetAttribute($sNodeAttribute) == '1');
  293. if ($bFlag)
  294. {
  295. $aFlags[] = $sFlag;
  296. }
  297. }
  298. $sRes = implode(' | ', $aFlags);
  299. return $sRes;
  300. }
  301. protected function CompileClass($oClass, $sResFile, $oP)
  302. {
  303. $sClass = $oClass->getAttribute('name');
  304. $oProperties = $this->GetUniqueElement($oClass, 'properties');
  305. // Class caracteristics
  306. //
  307. $aClassParams = array();
  308. $aClassParams['category'] = "'".$oClass->getAttribute('category')."'";
  309. $aClassParams['key_type'] = "'autoincrement'";
  310. $oNaming = $this->GetUniqueElement($oProperties, 'naming');
  311. $oNameAttributes = $this->GetUniqueElement($oNaming, 'attributes');
  312. $oAttributes = $oNameAttributes->getElementsByTagName('attribute');
  313. $aNameAttCodes = array();
  314. foreach($oAttributes as $oAttribute)
  315. {
  316. $aNameAttCodes[] = $oAttribute->getAttribute('name');
  317. }
  318. if (count($aNameAttCodes) > 1)
  319. {
  320. // New style...
  321. $sNameAttCode = "array('".implode("', '", $aNameAttCodes)."')";
  322. }
  323. elseif (count($aNameAttCodes) == 1)
  324. {
  325. // New style...
  326. $sNameAttCode = "'$aNameAttCodes[0]'";
  327. }
  328. else
  329. {
  330. $sNameAttCode = "''";
  331. }
  332. $aClassParams['name_attcode'] = $sNameAttCode;
  333. $oLifecycle = $this->GetOptionalElement($oClass, 'lifecycle');
  334. if ($oLifecycle)
  335. {
  336. $sStateAttCode = $oLifecycle->getAttribute('attribute');
  337. }
  338. else
  339. {
  340. $sStateAttCode = "";
  341. }
  342. $aClassParams['state_attcode'] = "'$sStateAttCode'";
  343. $oReconciliation = $this->GetUniqueElement($oProperties, 'reconciliation');
  344. $oReconcAttributes = $oReconciliation->getElementsByTagName('attribute');
  345. $aReconcAttCodes = array();
  346. foreach($oReconcAttributes as $oAttribute)
  347. {
  348. $aReconcAttCodes[] = $oAttribute->getAttribute('name');
  349. }
  350. $sReconcKeys = "array('".implode("', '", $aReconcAttCodes)."')";
  351. $aClassParams['reconc_keys'] = $sReconcKeys;
  352. $aClassParams['db_table'] = "'".$oClass->getAttribute('db_table')."'";
  353. $aClassParams['db_key_field'] = "'".$oClass->getAttribute('db_key_field')."'";
  354. $aClassParams['db_finalclass_field'] = "'".$oClass->getAttribute('db_final_class_field')."'";
  355. $oDisplayTemplate = $this->GetOptionalElement($oProperties, 'display_template');
  356. if ($oDisplayTemplate)
  357. {
  358. $sDisplayTemplate = $oDisplayTemplate->textContent;
  359. $aClassParams['display_template'] = "'$sDisplayTemplate'";
  360. }
  361. $oIcon = $this->GetOptionalElement($oProperties, 'icon');
  362. if ($oIcon)
  363. {
  364. $sIcon = $oIcon->textContent;
  365. $aClassParams['icon'] = "'$sIcon'";
  366. }
  367. // Finalize class params declaration
  368. //
  369. $aClassParamsPHP = array();
  370. foreach($aClassParams as $sKey => $sPHPValue)
  371. {
  372. $aClassParamsPHP[] = " '$sKey' => $sPHPValue,";
  373. }
  374. $sClassParams = implode("\n", $aClassParamsPHP);
  375. // Comment on top of the class declaration
  376. //
  377. $oComment = $this->GetOptionalElement($oProperties, 'comment');
  378. if ($oComment)
  379. {
  380. $sCodeComment = $oComment->textContent;
  381. }
  382. else
  383. {
  384. $sCodeComment = '';
  385. }
  386. // Fields
  387. //
  388. $sAttributes = '';
  389. foreach($this->oFactory->ListFields($oClass) as $oField)
  390. {
  391. // $oField
  392. $sAttCode = $oField->getAttribute('name');
  393. $sAttType = 'Attribute'.$oField->getAttribute('type');
  394. $aDependencies = array();
  395. $oDependencies = $this->GetOptionalElement($oField, 'dependencies');
  396. if (!is_null($oDependencies))
  397. {
  398. $oDepNodes = $oDependencies->getElementsByTagName('attribute');
  399. foreach($oDepNodes as $oDepAttribute)
  400. {
  401. $aDependencies[] = "'".$oDepAttribute->getAttribute('name')."'";
  402. }
  403. }
  404. $sDependencies = 'array('.implode(', ', $aDependencies).')';
  405. $aParameters = array();
  406. if ($sAttType == 'AttributeLinkedSetIndirect')
  407. {
  408. $aParameters['linked_class'] = "'".$oField->getAttribute('linked_class')."'";
  409. $aParameters['ext_key_to_me'] = "'".$oField->getAttribute('ext_key_to_me')."'";
  410. $aParameters['ext_key_to_remote'] = "'".$oField->getAttribute('ext_key_to_remote')."'";
  411. // todo - utile ?
  412. $aParameters['allowed_values'] = 'null';
  413. $aParameters['count_min'] = $oField->getAttribute('count_min');
  414. $aParameters['count_max'] = $oField->getAttribute('count_max');
  415. $aParameters['depends_on'] = $sDependencies;
  416. }
  417. elseif ($sAttType == 'AttributeLinkedSet')
  418. {
  419. $aParameters['linked_class'] = "'".$oField->getAttribute('linked_class')."'";
  420. $aParameters['ext_key_to_me'] = "'".$oField->getAttribute('ext_key_to_me')."'";
  421. // todo - utile ?
  422. $aParameters['allowed_values'] = 'null';
  423. $aParameters['count_min'] = $oField->getAttribute('count_min');
  424. $aParameters['count_max'] = $oField->getAttribute('count_max');
  425. $aParameters['depends_on'] = $sDependencies;
  426. }
  427. elseif ($sAttType == 'AttributeExternalKey')
  428. {
  429. $aParameters['targetclass'] = "'".$oField->getAttribute('target_class')."'";
  430. // todo = v�rifier l'utilit�
  431. $aParameters['jointype'] = 'null';
  432. if (($sOql = $oField->getAttribute('filter')) != '')
  433. {
  434. $sEscapedOql = addslashes($sOql);
  435. $aParameters['allowed_values'] = "new ValueSetObjects('$sEscapedOql')"; // or "new ValueSetObjects('SELECT xxxx')"
  436. }
  437. else
  438. {
  439. $aParameters['allowed_values'] = 'null'; // or "new ValueSetObjects('SELECT xxxx')"
  440. }
  441. $aParameters['sql'] = "'".$oField->getAttribute('sql')."'";
  442. $aParameters['is_null_allowed'] = $oField->getAttribute('is_null_allowed') == 'true' ? 'true' : 'false';
  443. $aParameters['on_target_delete'] = $oField->getAttribute('on_target_delete');
  444. $aParameters['depends_on'] = $sDependencies;
  445. }
  446. elseif ($sAttType == 'AttributeHierarchicalKey')
  447. {
  448. if (($sOql = $oField->getAttribute('filter')) != '')
  449. {
  450. $sEscapedOql = addslashes($sOql);
  451. $aParameters['allowed_values'] = "new ValueSetObjects('$sEscapedOql')"; // or "new ValueSetObjects('SELECT xxxx')"
  452. }
  453. else
  454. {
  455. $aParameters['allowed_values'] = 'null'; // or "new ValueSetObjects('SELECT xxxx')"
  456. }
  457. $aParameters['sql'] = "'".$oField->getAttribute('sql')."'";
  458. $aParameters['is_null_allowed'] = $oField->getAttribute('is_null_allowed') == 'true' ? 'true' : 'false';
  459. $aParameters['on_target_delete'] = $oField->getAttribute('on_target_delete');
  460. $aParameters['depends_on'] = $sDependencies;
  461. }
  462. elseif ($sAttType == 'AttributeExternalField')
  463. {
  464. $aParameters['allowed_values'] = 'null';
  465. $aParameters['extkey_attcode'] = "'".$oField->getAttribute('extkey_attcode')."'";
  466. $aParameters['target_attcode'] = "'".$oField->getAttribute('target_attcode')."'";
  467. }
  468. elseif ($sAttType == 'AttributeURL')
  469. {
  470. $aParameters['target'] = "'".$oField->getAttribute('target')."'";
  471. $aParameters['allowed_values'] = 'null';
  472. $aParameters['sql'] = "'".$oField->getAttribute('sql')."'";
  473. $aParameters['default_value'] = "'".$oField->getAttribute('default_value')."'";
  474. $aParameters['is_null_allowed'] = $oField->getAttribute('is_null_allowed') == 'true' ? 'true' : 'false';
  475. $aParameters['depends_on'] = $sDependencies;
  476. }
  477. elseif ($sAttType == 'AttributeEnum')
  478. {
  479. $oValues = $this->GetUniqueElement($oField, 'values');
  480. $oValueNodes = $oValues->getElementsByTagName('value');
  481. $aValues = array();
  482. foreach($oValueNodes as $oValue)
  483. {
  484. // new style... $aValues[] = "'".addslashes($oValue->textContent)."'";
  485. $aValues[] = $oValue->textContent;
  486. }
  487. // new style... $sValues = 'array('.implode(', ', $aValues).')';
  488. $sValues = '"'.implode(',', $aValues).'"';
  489. $aParameters['allowed_values'] = "new ValueSetEnum($sValues)";
  490. $aParameters['sql'] = "'".$oField->getAttribute('sql')."'";
  491. $aParameters['default_value'] = "'".$oField->getAttribute('default_value')."'";
  492. $aParameters['is_null_allowed'] = $oField->getAttribute('is_null_allowed') == 'true' ? 'true' : 'false';
  493. $aParameters['depends_on'] = $sDependencies;
  494. }
  495. elseif ($sAttType == 'AttributeBlob')
  496. {
  497. $aParameters['depends_on'] = $sDependencies;
  498. }
  499. else
  500. {
  501. $aParameters['allowed_values'] = 'null'; // or "new ValueSetEnum('SELECT xxxx')"
  502. $aParameters['sql'] = "'".$oField->getAttribute('sql')."'";
  503. $aParameters['default_value'] = "'".$oField->getAttribute('default_value')."'";
  504. $aParameters['is_null_allowed'] = $oField->getAttribute('is_null_allowed') == 'true' ? 'true' : 'false';
  505. $aParameters['depends_on'] = $sDependencies;
  506. if ($sValidationPattern = $oField->getAttribute('validation_pattern'))
  507. {
  508. $aParameters['validation_pattern'] = '"'.addslashes($sValidationPattern).'"';
  509. }
  510. }
  511. $aParams = array();
  512. foreach($aParameters as $sKey => $sValue)
  513. {
  514. $aParams[] = '"'.$sKey.'"=>'.$sValue;
  515. }
  516. $sParams = implode(', ', $aParams);
  517. $sAttributes .= " MetaModel::Init_AddAttribute(new $sAttType(\"$sAttCode\", array($sParams)));\n";
  518. }
  519. // Lifecycle
  520. //
  521. $sLifecycle = '';
  522. if ($oLifecycle)
  523. {
  524. $sLifecycle .= "\t\t// Lifecycle (status attribute: $sStateAttCode)\n";
  525. $sLifecycle .= "\t\t//\n";
  526. $oStimuli = $this->GetUniqueElement($oLifecycle, 'stimuli');
  527. foreach ($oStimuli->getElementsByTagName('stimulus') as $oStimulus)
  528. {
  529. $sStimulus = $oStimulus->getAttribute('name');
  530. $sStimulusClass = $oStimulus->getAttribute('type');
  531. $sLifecycle .= " MetaModel::Init_DefineStimulus(new ".$sStimulusClass."(\"".$sStimulus."\", array()));\n";
  532. }
  533. $oStates = $this->GetUniqueElement($oLifecycle, 'states');
  534. foreach ($oStates->getElementsByTagName('state') as $oState)
  535. {
  536. $sState = $oState->getAttribute('name');
  537. $sLifecycle .= " MetaModel::Init_DefineState(\n";
  538. $sLifecycle .= " \"".$sState."\",\n";
  539. $sLifecycle .= " array(\n";
  540. $sLifecycle .= " \"attribute_inherit\" => '',\n";
  541. $sLifecycle .= " \"attribute_list\" => array(\n";
  542. $oFlags = $this->GetUniqueElement($oState, 'flags');
  543. foreach ($oFlags->getElementsByTagName('attribute') as $oAttributeNode)
  544. {
  545. $sFlags = $this->FlagsToPHP($oAttributeNode);
  546. if (strlen($sFlags) > 0)
  547. {
  548. $sAttCode = $oAttributeNode->GetAttribute('name');
  549. $sLifecycle .= " '$sAttCode' => $sFlags,\n";
  550. }
  551. }
  552. $sLifecycle .= " ),\n";
  553. $sLifecycle .= " )\n";
  554. $sLifecycle .= " );\n";
  555. $oTransitions = $this->GetUniqueElement($oState, 'transitions');
  556. foreach ($oTransitions->getElementsByTagName('transition') as $oTransition)
  557. {
  558. $sStimulus = $oTransition->getAttribute('stimulus');
  559. $sTargetState = $oTransition->getAttribute('target');
  560. $oActions = $this->GetUniqueElement($oTransition, 'actions');
  561. $aVerbs = array();
  562. foreach ($oActions->getElementsByTagName('action') as $oAction)
  563. {
  564. $sVerb = $oAction->getAttribute('verb');
  565. $aVerbs[] = "'$sVerb'";
  566. }
  567. $sActions = implode(', ', $aVerbs);
  568. $sLifecycle .= " MetaModel::Init_DefineTransition(\"$sState\", \"$sStimulus\", array(\"target_state\"=>\"$sTargetState\", \"actions\"=>array($sActions), \"user_restriction\"=>null));\n";
  569. }
  570. }
  571. }
  572. // ZLists
  573. //
  574. $aListRef = array(
  575. 'details' => 'details',
  576. 'standard_search' => 'search',
  577. 'list' => 'list'
  578. );
  579. $oPresentation = $this->GetUniqueElement($oClass, 'presentation');
  580. $sZlists = '';
  581. foreach ($aListRef as $sListCode => $sListTag)
  582. {
  583. $oListNode = $this->GetUniqueElement($oPresentation, $sListTag);
  584. $aAttributes = $this->GetNodeAsArrayOfItems($oListNode);
  585. $sZAttributes = var_export($aAttributes, true);
  586. $sZlists .= " MetaModel::Init_SetZListItems('$sListCode', $sZAttributes);\n";
  587. }
  588. // Methods
  589. $sMethods = "";
  590. $oMethods = $this->GetUniqueElement($oClass, 'methods');
  591. foreach($oMethods->getElementsByTagName('method') as $oMethod)
  592. {
  593. $sMethodCode = $this->GetNodeText($oMethod);
  594. $oMethodComment = $this->GetOptionalElement($oMethod, 'comment');
  595. if ($oMethodComment)
  596. {
  597. $sMethods .= "\n\t".$oMethodComment->textContent."\n".$sMethodCode."\n";
  598. }
  599. else
  600. {
  601. $sMethods .= "\n\n".$sMethodCode."\n";
  602. }
  603. }
  604. // Let's make the whole class declaration
  605. //
  606. $sPHP = "\n\n$sCodeComment\n";
  607. if ($oClass->getAttribute('abstract') == 'true')
  608. {
  609. $sPHP .= 'abstract class '.$oClass->getAttribute('name');
  610. }
  611. else
  612. {
  613. $sPHP .= 'class '.$oClass->getAttribute('name');
  614. }
  615. $sPHP .= " extends ".$oClass->getAttribute('parent')."\n";
  616. $sPHP .=
  617. <<<EOF
  618. {
  619. public static function Init()
  620. {
  621. \$aParams = array
  622. (
  623. $sClassParams
  624. );
  625. MetaModel::Init_Params(\$aParams);
  626. MetaModel::Init_InheritAttributes();
  627. $sAttributes
  628. $sLifecycle
  629. $sZlists
  630. }
  631. $sMethods
  632. }
  633. EOF;
  634. file_put_contents($sResFile, $sPHP, FILE_APPEND);
  635. }
  636. }
  637. ?>