PageRenderTime 92ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/view/SSTemplateParser.php

http://github.com/silverstripe/sapphire
PHP | 4793 lines | 4258 code | 256 blank | 279 comment | 755 complexity | 8fc7ab4185d38da482a6c4e135d64fa7 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, CC-BY-3.0, GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /*
  3. WARNING: This file has been machine generated. Do not edit it, or your changes will be overwritten next time it is compiled.
  4. */
  5. // We want this to work when run by hand too
  6. if (defined(THIRDPARTY_PATH)) {
  7. require_once(THIRDPARTY_PATH . '/php-peg/Parser.php');
  8. }
  9. else {
  10. $base = dirname(__FILE__);
  11. require_once($base.'/../thirdparty/php-peg/Parser.php');
  12. }
  13. /**
  14. * This is the exception raised when failing to parse a template. Note that we don't currently do any static analysis,
  15. * so we can't know if the template will run, just if it's malformed. It also won't catch mistakes that still look
  16. * valid.
  17. *
  18. * @package framework
  19. * @subpackage view
  20. */
  21. class SSTemplateParseException extends Exception {
  22. function __construct($message, $parser) {
  23. $prior = substr($parser->string, 0, $parser->pos);
  24. preg_match_all('/\r\n|\r|\n/', $prior, $matches);
  25. $line = count($matches[0])+1;
  26. parent::__construct("Parse error in template on line $line. Error was: $message");
  27. }
  28. }
  29. /**
  30. * This is the parser for the SilverStripe template language. It gets called on a string and uses a php-peg parser
  31. * to match that string against the language structure, building up the PHP code to execute that structure as it
  32. * parses
  33. *
  34. * The $result array that is built up as part of the parsing (see thirdparty/php-peg/README.md for more on how
  35. * parsers build results) has one special member, 'php', which contains the php equivalent of that part of the
  36. * template tree.
  37. *
  38. * Some match rules generate alternate php, or other variations, so check the per-match documentation too.
  39. *
  40. * Terms used:
  41. *
  42. * Marked: A string or lookup in the template that has been explictly marked as such - lookups by prepending with
  43. * "$" (like $Foo.Bar), strings by wrapping with single or double quotes ('Foo' or "Foo")
  44. *
  45. * Bare: The opposite of marked. An argument that has to has it's type inferred by usage and 2.4 defaults.
  46. *
  47. * Example of using a bare argument for a loop block: <% loop Foo %>
  48. *
  49. * Block: One of two SS template structures. The special characters "<%" and "%>" are used to wrap the opening and
  50. * (required or forbidden depending on which block exactly) closing block marks.
  51. *
  52. * Open Block: An SS template block that doesn't wrap any content or have a closing end tag (in fact, a closing end
  53. * tag is forbidden)
  54. *
  55. * Closed Block: An SS template block that wraps content, and requires a counterpart <% end_blockname %> tag
  56. *
  57. * Angle Bracket: angle brackets "<" and ">" are used to eat whitespace between template elements
  58. * N: eats white space including newlines (using in legacy _t support)
  59. *
  60. * @package framework
  61. * @subpackage view
  62. */
  63. class SSTemplateParser extends Parser implements TemplateParser {
  64. /**
  65. * @var bool - Set true by SSTemplateParser::compileString if the template should include comments intended
  66. * for debugging (template source, included files, etc)
  67. */
  68. protected $includeDebuggingComments = false;
  69. /**
  70. * Stores the user-supplied closed block extension rules in the form:
  71. * array(
  72. * 'name' => function (&$res) {}
  73. * )
  74. * See SSTemplateParser::ClosedBlock_Handle_Loop for an example of what the callable should look like
  75. * @var array
  76. */
  77. protected $closedBlocks = array();
  78. /**
  79. * Stores the user-supplied open block extension rules in the form:
  80. * array(
  81. * 'name' => function (&$res) {}
  82. * )
  83. * See SSTemplateParser::OpenBlock_Handle_Base_tag for an example of what the callable should look like
  84. * @var array
  85. */
  86. protected $openBlocks = array();
  87. /**
  88. * Allow the injection of new closed & open block callables
  89. * @param array $closedBlocks
  90. * @param array $openBlocks
  91. */
  92. public function __construct($closedBlocks = array(), $openBlocks = array()) {
  93. $this->setClosedBlocks($closedBlocks);
  94. $this->setOpenBlocks($openBlocks);
  95. }
  96. /**
  97. * Override the function that constructs the result arrays to also prepare a 'php' item in the array
  98. */
  99. function construct($matchrule, $name, $arguments = null) {
  100. $res = parent::construct($matchrule, $name, $arguments);
  101. if (!isset($res['php'])) $res['php'] = '';
  102. return $res;
  103. }
  104. /**
  105. * Set the closed blocks that the template parser should use
  106. *
  107. * This method will delete any existing closed blocks, please use addClosedBlock if you don't
  108. * want to overwrite
  109. * @param array $closedBlocks
  110. * @throws InvalidArgumentException
  111. */
  112. public function setClosedBlocks($closedBlocks) {
  113. $this->closedBlocks = array();
  114. foreach ((array) $closedBlocks as $name => $callable) {
  115. $this->addClosedBlock($name, $callable);
  116. }
  117. }
  118. /**
  119. * Set the open blocks that the template parser should use
  120. *
  121. * This method will delete any existing open blocks, please use addOpenBlock if you don't
  122. * want to overwrite
  123. * @param array $openBlocks
  124. * @throws InvalidArgumentException
  125. */
  126. public function setOpenBlocks($openBlocks) {
  127. $this->openBlocks = array();
  128. foreach ((array) $openBlocks as $name => $callable) {
  129. $this->addOpenBlock($name, $callable);
  130. }
  131. }
  132. /**
  133. * Add a closed block callable to allow <% name %><% end_name %> syntax
  134. * @param string $name The name of the token to be used in the syntax <% name %><% end_name %>
  135. * @param callable $callable The function that modifies the generation of template code
  136. * @throws InvalidArgumentException
  137. */
  138. public function addClosedBlock($name, $callable) {
  139. $this->validateExtensionBlock($name, $callable, 'Closed block');
  140. $this->closedBlocks[$name] = $callable;
  141. }
  142. /**
  143. * Add a closed block callable to allow <% name %> syntax
  144. * @param string $name The name of the token to be used in the syntax <% name %>
  145. * @param callable $callable The function that modifies the generation of template code
  146. * @throws InvalidArgumentException
  147. */
  148. public function addOpenBlock($name, $callable) {
  149. $this->validateExtensionBlock($name, $callable, 'Open block');
  150. $this->openBlocks[$name] = $callable;
  151. }
  152. /**
  153. * Ensures that the arguments to addOpenBlock and addClosedBlock are valid
  154. * @param $name
  155. * @param $callable
  156. * @param $type
  157. * @throws InvalidArgumentException
  158. */
  159. protected function validateExtensionBlock($name, $callable, $type) {
  160. if (!is_string($name)) {
  161. throw new InvalidArgumentException(
  162. sprintf(
  163. "Name argument for %s must be a string",
  164. $type
  165. )
  166. );
  167. } elseif (!is_callable($callable)) {
  168. throw new InvalidArgumentException(
  169. sprintf(
  170. "Callable %s argument named '%s' is not callable",
  171. $type,
  172. $name
  173. )
  174. );
  175. }
  176. }
  177. /* Template: (Comment | Translate | If | Require | CacheBlock | UncachedBlock | OldI18NTag | Include | ClosedBlock |
  178. OpenBlock | MalformedBlock | Injection | Text)+ */
  179. protected $match_Template_typestack = array('Template');
  180. function match_Template ($stack = array()) {
  181. $matchrule = "Template"; $result = $this->construct($matchrule, $matchrule, null);
  182. $count = 0;
  183. while (true) {
  184. $res_50 = $result;
  185. $pos_50 = $this->pos;
  186. $_49 = NULL;
  187. do {
  188. $_47 = NULL;
  189. do {
  190. $res_0 = $result;
  191. $pos_0 = $this->pos;
  192. $matcher = 'match_'.'Comment'; $key = $matcher; $pos = $this->pos;
  193. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  194. if ($subres !== FALSE) {
  195. $this->store( $result, $subres );
  196. $_47 = TRUE; break;
  197. }
  198. $result = $res_0;
  199. $this->pos = $pos_0;
  200. $_45 = NULL;
  201. do {
  202. $res_2 = $result;
  203. $pos_2 = $this->pos;
  204. $matcher = 'match_'.'Translate'; $key = $matcher; $pos = $this->pos;
  205. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  206. if ($subres !== FALSE) {
  207. $this->store( $result, $subres );
  208. $_45 = TRUE; break;
  209. }
  210. $result = $res_2;
  211. $this->pos = $pos_2;
  212. $_43 = NULL;
  213. do {
  214. $res_4 = $result;
  215. $pos_4 = $this->pos;
  216. $matcher = 'match_'.'If'; $key = $matcher; $pos = $this->pos;
  217. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  218. if ($subres !== FALSE) {
  219. $this->store( $result, $subres );
  220. $_43 = TRUE; break;
  221. }
  222. $result = $res_4;
  223. $this->pos = $pos_4;
  224. $_41 = NULL;
  225. do {
  226. $res_6 = $result;
  227. $pos_6 = $this->pos;
  228. $matcher = 'match_'.'Require'; $key = $matcher; $pos = $this->pos;
  229. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  230. if ($subres !== FALSE) {
  231. $this->store( $result, $subres );
  232. $_41 = TRUE; break;
  233. }
  234. $result = $res_6;
  235. $this->pos = $pos_6;
  236. $_39 = NULL;
  237. do {
  238. $res_8 = $result;
  239. $pos_8 = $this->pos;
  240. $matcher = 'match_'.'CacheBlock'; $key = $matcher; $pos = $this->pos;
  241. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  242. if ($subres !== FALSE) {
  243. $this->store( $result, $subres );
  244. $_39 = TRUE; break;
  245. }
  246. $result = $res_8;
  247. $this->pos = $pos_8;
  248. $_37 = NULL;
  249. do {
  250. $res_10 = $result;
  251. $pos_10 = $this->pos;
  252. $matcher = 'match_'.'UncachedBlock'; $key = $matcher; $pos = $this->pos;
  253. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  254. if ($subres !== FALSE) {
  255. $this->store( $result, $subres );
  256. $_37 = TRUE; break;
  257. }
  258. $result = $res_10;
  259. $this->pos = $pos_10;
  260. $_35 = NULL;
  261. do {
  262. $res_12 = $result;
  263. $pos_12 = $this->pos;
  264. $matcher = 'match_'.'OldI18NTag'; $key = $matcher; $pos = $this->pos;
  265. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  266. if ($subres !== FALSE) {
  267. $this->store( $result, $subres );
  268. $_35 = TRUE; break;
  269. }
  270. $result = $res_12;
  271. $this->pos = $pos_12;
  272. $_33 = NULL;
  273. do {
  274. $res_14 = $result;
  275. $pos_14 = $this->pos;
  276. $matcher = 'match_'.'Include'; $key = $matcher; $pos = $this->pos;
  277. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  278. if ($subres !== FALSE) {
  279. $this->store( $result, $subres );
  280. $_33 = TRUE; break;
  281. }
  282. $result = $res_14;
  283. $this->pos = $pos_14;
  284. $_31 = NULL;
  285. do {
  286. $res_16 = $result;
  287. $pos_16 = $this->pos;
  288. $matcher = 'match_'.'ClosedBlock'; $key = $matcher; $pos = $this->pos;
  289. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  290. if ($subres !== FALSE) {
  291. $this->store( $result, $subres );
  292. $_31 = TRUE; break;
  293. }
  294. $result = $res_16;
  295. $this->pos = $pos_16;
  296. $_29 = NULL;
  297. do {
  298. $res_18 = $result;
  299. $pos_18 = $this->pos;
  300. $matcher = 'match_'.'OpenBlock'; $key = $matcher; $pos = $this->pos;
  301. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  302. if ($subres !== FALSE) {
  303. $this->store( $result, $subres );
  304. $_29 = TRUE; break;
  305. }
  306. $result = $res_18;
  307. $this->pos = $pos_18;
  308. $_27 = NULL;
  309. do {
  310. $res_20 = $result;
  311. $pos_20 = $this->pos;
  312. $matcher = 'match_'.'MalformedBlock'; $key = $matcher; $pos = $this->pos;
  313. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  314. if ($subres !== FALSE) {
  315. $this->store( $result, $subres );
  316. $_27 = TRUE; break;
  317. }
  318. $result = $res_20;
  319. $this->pos = $pos_20;
  320. $_25 = NULL;
  321. do {
  322. $res_22 = $result;
  323. $pos_22 = $this->pos;
  324. $matcher = 'match_'.'Injection'; $key = $matcher; $pos = $this->pos;
  325. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  326. if ($subres !== FALSE) {
  327. $this->store( $result, $subres );
  328. $_25 = TRUE; break;
  329. }
  330. $result = $res_22;
  331. $this->pos = $pos_22;
  332. $matcher = 'match_'.'Text'; $key = $matcher; $pos = $this->pos;
  333. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  334. if ($subres !== FALSE) {
  335. $this->store( $result, $subres );
  336. $_25 = TRUE; break;
  337. }
  338. $result = $res_22;
  339. $this->pos = $pos_22;
  340. $_25 = FALSE; break;
  341. }
  342. while(0);
  343. if( $_25 === TRUE ) { $_27 = TRUE; break; }
  344. $result = $res_20;
  345. $this->pos = $pos_20;
  346. $_27 = FALSE; break;
  347. }
  348. while(0);
  349. if( $_27 === TRUE ) { $_29 = TRUE; break; }
  350. $result = $res_18;
  351. $this->pos = $pos_18;
  352. $_29 = FALSE; break;
  353. }
  354. while(0);
  355. if( $_29 === TRUE ) { $_31 = TRUE; break; }
  356. $result = $res_16;
  357. $this->pos = $pos_16;
  358. $_31 = FALSE; break;
  359. }
  360. while(0);
  361. if( $_31 === TRUE ) { $_33 = TRUE; break; }
  362. $result = $res_14;
  363. $this->pos = $pos_14;
  364. $_33 = FALSE; break;
  365. }
  366. while(0);
  367. if( $_33 === TRUE ) { $_35 = TRUE; break; }
  368. $result = $res_12;
  369. $this->pos = $pos_12;
  370. $_35 = FALSE; break;
  371. }
  372. while(0);
  373. if( $_35 === TRUE ) { $_37 = TRUE; break; }
  374. $result = $res_10;
  375. $this->pos = $pos_10;
  376. $_37 = FALSE; break;
  377. }
  378. while(0);
  379. if( $_37 === TRUE ) { $_39 = TRUE; break; }
  380. $result = $res_8;
  381. $this->pos = $pos_8;
  382. $_39 = FALSE; break;
  383. }
  384. while(0);
  385. if( $_39 === TRUE ) { $_41 = TRUE; break; }
  386. $result = $res_6;
  387. $this->pos = $pos_6;
  388. $_41 = FALSE; break;
  389. }
  390. while(0);
  391. if( $_41 === TRUE ) { $_43 = TRUE; break; }
  392. $result = $res_4;
  393. $this->pos = $pos_4;
  394. $_43 = FALSE; break;
  395. }
  396. while(0);
  397. if( $_43 === TRUE ) { $_45 = TRUE; break; }
  398. $result = $res_2;
  399. $this->pos = $pos_2;
  400. $_45 = FALSE; break;
  401. }
  402. while(0);
  403. if( $_45 === TRUE ) { $_47 = TRUE; break; }
  404. $result = $res_0;
  405. $this->pos = $pos_0;
  406. $_47 = FALSE; break;
  407. }
  408. while(0);
  409. if( $_47 === FALSE) { $_49 = FALSE; break; }
  410. $_49 = TRUE; break;
  411. }
  412. while(0);
  413. if( $_49 === FALSE) {
  414. $result = $res_50;
  415. $this->pos = $pos_50;
  416. unset( $res_50 );
  417. unset( $pos_50 );
  418. break;
  419. }
  420. $count += 1;
  421. }
  422. if ($count > 0) { return $this->finalise($result); }
  423. else { return FALSE; }
  424. }
  425. function Template_STR(&$res, $sub) {
  426. $res['php'] .= $sub['php'] . PHP_EOL ;
  427. }
  428. /* Word: / [A-Za-z_] [A-Za-z0-9_]* / */
  429. protected $match_Word_typestack = array('Word');
  430. function match_Word ($stack = array()) {
  431. $matchrule = "Word"; $result = $this->construct($matchrule, $matchrule, null);
  432. if (( $subres = $this->rx( '/ [A-Za-z_] [A-Za-z0-9_]* /' ) ) !== FALSE) {
  433. $result["text"] .= $subres;
  434. return $this->finalise($result);
  435. }
  436. else { return FALSE; }
  437. }
  438. /* NamespacedWord: / [A-Za-z_\/\\] [A-Za-z0-9_\/\\]* / */
  439. protected $match_NamespacedWord_typestack = array('NamespacedWord');
  440. function match_NamespacedWord ($stack = array()) {
  441. $matchrule = "NamespacedWord"; $result = $this->construct($matchrule, $matchrule, null);
  442. if (( $subres = $this->rx( '/ [A-Za-z_\/\\\\] [A-Za-z0-9_\/\\\\]* /' ) ) !== FALSE) {
  443. $result["text"] .= $subres;
  444. return $this->finalise($result);
  445. }
  446. else { return FALSE; }
  447. }
  448. /* Number: / [0-9]+ / */
  449. protected $match_Number_typestack = array('Number');
  450. function match_Number ($stack = array()) {
  451. $matchrule = "Number"; $result = $this->construct($matchrule, $matchrule, null);
  452. if (( $subres = $this->rx( '/ [0-9]+ /' ) ) !== FALSE) {
  453. $result["text"] .= $subres;
  454. return $this->finalise($result);
  455. }
  456. else { return FALSE; }
  457. }
  458. /* Value: / [A-Za-z0-9_]+ / */
  459. protected $match_Value_typestack = array('Value');
  460. function match_Value ($stack = array()) {
  461. $matchrule = "Value"; $result = $this->construct($matchrule, $matchrule, null);
  462. if (( $subres = $this->rx( '/ [A-Za-z0-9_]+ /' ) ) !== FALSE) {
  463. $result["text"] .= $subres;
  464. return $this->finalise($result);
  465. }
  466. else { return FALSE; }
  467. }
  468. /* CallArguments: :Argument ( < "," < :Argument )* */
  469. protected $match_CallArguments_typestack = array('CallArguments');
  470. function match_CallArguments ($stack = array()) {
  471. $matchrule = "CallArguments"; $result = $this->construct($matchrule, $matchrule, null);
  472. $_62 = NULL;
  473. do {
  474. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  475. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  476. if ($subres !== FALSE) {
  477. $this->store( $result, $subres, "Argument" );
  478. }
  479. else { $_62 = FALSE; break; }
  480. while (true) {
  481. $res_61 = $result;
  482. $pos_61 = $this->pos;
  483. $_60 = NULL;
  484. do {
  485. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  486. if (substr($this->string,$this->pos,1) == ',') {
  487. $this->pos += 1;
  488. $result["text"] .= ',';
  489. }
  490. else { $_60 = FALSE; break; }
  491. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  492. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  493. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  494. if ($subres !== FALSE) {
  495. $this->store( $result, $subres, "Argument" );
  496. }
  497. else { $_60 = FALSE; break; }
  498. $_60 = TRUE; break;
  499. }
  500. while(0);
  501. if( $_60 === FALSE) {
  502. $result = $res_61;
  503. $this->pos = $pos_61;
  504. unset( $res_61 );
  505. unset( $pos_61 );
  506. break;
  507. }
  508. }
  509. $_62 = TRUE; break;
  510. }
  511. while(0);
  512. if( $_62 === TRUE ) { return $this->finalise($result); }
  513. if( $_62 === FALSE) { return FALSE; }
  514. }
  515. /**
  516. * Values are bare words in templates, but strings in PHP. We rely on PHP's type conversion to back-convert
  517. * strings to numbers when needed.
  518. */
  519. function CallArguments_Argument(&$res, $sub) {
  520. if (!empty($res['php'])) $res['php'] .= ', ';
  521. $res['php'] .= ($sub['ArgumentMode'] == 'default') ? $sub['string_php'] :
  522. str_replace('$$FINAL', 'XML_val', $sub['php']);
  523. }
  524. /* Call: Method:Word ( "(" < :CallArguments? > ")" )? */
  525. protected $match_Call_typestack = array('Call');
  526. function match_Call ($stack = array()) {
  527. $matchrule = "Call"; $result = $this->construct($matchrule, $matchrule, null);
  528. $_72 = NULL;
  529. do {
  530. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  531. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  532. if ($subres !== FALSE) {
  533. $this->store( $result, $subres, "Method" );
  534. }
  535. else { $_72 = FALSE; break; }
  536. $res_71 = $result;
  537. $pos_71 = $this->pos;
  538. $_70 = NULL;
  539. do {
  540. if (substr($this->string,$this->pos,1) == '(') {
  541. $this->pos += 1;
  542. $result["text"] .= '(';
  543. }
  544. else { $_70 = FALSE; break; }
  545. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  546. $res_67 = $result;
  547. $pos_67 = $this->pos;
  548. $matcher = 'match_'.'CallArguments'; $key = $matcher; $pos = $this->pos;
  549. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  550. if ($subres !== FALSE) {
  551. $this->store( $result, $subres, "CallArguments" );
  552. }
  553. else {
  554. $result = $res_67;
  555. $this->pos = $pos_67;
  556. unset( $res_67 );
  557. unset( $pos_67 );
  558. }
  559. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  560. if (substr($this->string,$this->pos,1) == ')') {
  561. $this->pos += 1;
  562. $result["text"] .= ')';
  563. }
  564. else { $_70 = FALSE; break; }
  565. $_70 = TRUE; break;
  566. }
  567. while(0);
  568. if( $_70 === FALSE) {
  569. $result = $res_71;
  570. $this->pos = $pos_71;
  571. unset( $res_71 );
  572. unset( $pos_71 );
  573. }
  574. $_72 = TRUE; break;
  575. }
  576. while(0);
  577. if( $_72 === TRUE ) { return $this->finalise($result); }
  578. if( $_72 === FALSE) { return FALSE; }
  579. }
  580. /* LookupStep: :Call &"." */
  581. protected $match_LookupStep_typestack = array('LookupStep');
  582. function match_LookupStep ($stack = array()) {
  583. $matchrule = "LookupStep"; $result = $this->construct($matchrule, $matchrule, null);
  584. $_76 = NULL;
  585. do {
  586. $matcher = 'match_'.'Call'; $key = $matcher; $pos = $this->pos;
  587. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  588. if ($subres !== FALSE) {
  589. $this->store( $result, $subres, "Call" );
  590. }
  591. else { $_76 = FALSE; break; }
  592. $res_75 = $result;
  593. $pos_75 = $this->pos;
  594. if (substr($this->string,$this->pos,1) == '.') {
  595. $this->pos += 1;
  596. $result["text"] .= '.';
  597. $result = $res_75;
  598. $this->pos = $pos_75;
  599. }
  600. else {
  601. $result = $res_75;
  602. $this->pos = $pos_75;
  603. $_76 = FALSE; break;
  604. }
  605. $_76 = TRUE; break;
  606. }
  607. while(0);
  608. if( $_76 === TRUE ) { return $this->finalise($result); }
  609. if( $_76 === FALSE) { return FALSE; }
  610. }
  611. /* LastLookupStep: :Call */
  612. protected $match_LastLookupStep_typestack = array('LastLookupStep');
  613. function match_LastLookupStep ($stack = array()) {
  614. $matchrule = "LastLookupStep"; $result = $this->construct($matchrule, $matchrule, null);
  615. $matcher = 'match_'.'Call'; $key = $matcher; $pos = $this->pos;
  616. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  617. if ($subres !== FALSE) {
  618. $this->store( $result, $subres, "Call" );
  619. return $this->finalise($result);
  620. }
  621. else { return FALSE; }
  622. }
  623. /* Lookup: LookupStep ("." LookupStep)* "." LastLookupStep | LastLookupStep */
  624. protected $match_Lookup_typestack = array('Lookup');
  625. function match_Lookup ($stack = array()) {
  626. $matchrule = "Lookup"; $result = $this->construct($matchrule, $matchrule, null);
  627. $_90 = NULL;
  628. do {
  629. $res_79 = $result;
  630. $pos_79 = $this->pos;
  631. $_87 = NULL;
  632. do {
  633. $matcher = 'match_'.'LookupStep'; $key = $matcher; $pos = $this->pos;
  634. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  635. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  636. else { $_87 = FALSE; break; }
  637. while (true) {
  638. $res_84 = $result;
  639. $pos_84 = $this->pos;
  640. $_83 = NULL;
  641. do {
  642. if (substr($this->string,$this->pos,1) == '.') {
  643. $this->pos += 1;
  644. $result["text"] .= '.';
  645. }
  646. else { $_83 = FALSE; break; }
  647. $matcher = 'match_'.'LookupStep'; $key = $matcher; $pos = $this->pos;
  648. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  649. if ($subres !== FALSE) {
  650. $this->store( $result, $subres );
  651. }
  652. else { $_83 = FALSE; break; }
  653. $_83 = TRUE; break;
  654. }
  655. while(0);
  656. if( $_83 === FALSE) {
  657. $result = $res_84;
  658. $this->pos = $pos_84;
  659. unset( $res_84 );
  660. unset( $pos_84 );
  661. break;
  662. }
  663. }
  664. if (substr($this->string,$this->pos,1) == '.') {
  665. $this->pos += 1;
  666. $result["text"] .= '.';
  667. }
  668. else { $_87 = FALSE; break; }
  669. $matcher = 'match_'.'LastLookupStep'; $key = $matcher; $pos = $this->pos;
  670. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  671. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  672. else { $_87 = FALSE; break; }
  673. $_87 = TRUE; break;
  674. }
  675. while(0);
  676. if( $_87 === TRUE ) { $_90 = TRUE; break; }
  677. $result = $res_79;
  678. $this->pos = $pos_79;
  679. $matcher = 'match_'.'LastLookupStep'; $key = $matcher; $pos = $this->pos;
  680. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  681. if ($subres !== FALSE) {
  682. $this->store( $result, $subres );
  683. $_90 = TRUE; break;
  684. }
  685. $result = $res_79;
  686. $this->pos = $pos_79;
  687. $_90 = FALSE; break;
  688. }
  689. while(0);
  690. if( $_90 === TRUE ) { return $this->finalise($result); }
  691. if( $_90 === FALSE) { return FALSE; }
  692. }
  693. function Lookup__construct(&$res) {
  694. $res['php'] = '$scope->locally()';
  695. $res['LookupSteps'] = array();
  696. }
  697. /**
  698. * The basic generated PHP of LookupStep and LastLookupStep is the same, except that LookupStep calls 'obj' to
  699. * get the next ViewableData in the sequence, and LastLookupStep calls different methods (XML_val, hasValue, obj)
  700. * depending on the context the lookup is used in.
  701. */
  702. function Lookup_AddLookupStep(&$res, $sub, $method) {
  703. $res['LookupSteps'][] = $sub;
  704. $property = $sub['Call']['Method']['text'];
  705. if (isset($sub['Call']['CallArguments']) && $arguments = $sub['Call']['CallArguments']['php']) {
  706. $res['php'] .= "->$method('$property', array($arguments), true)";
  707. }
  708. else {
  709. $res['php'] .= "->$method('$property', null, true)";
  710. }
  711. }
  712. function Lookup_LookupStep(&$res, $sub) {
  713. $this->Lookup_AddLookupStep($res, $sub, 'obj');
  714. }
  715. function Lookup_LastLookupStep(&$res, $sub) {
  716. $this->Lookup_AddLookupStep($res, $sub, '$$FINAL');
  717. }
  718. /* Translate: "<%t" < Entity < (Default:QuotedString)? < (!("is" "=") < "is" < Context:QuotedString)? <
  719. (InjectionVariables)? > "%>" */
  720. protected $match_Translate_typestack = array('Translate');
  721. function match_Translate ($stack = array()) {
  722. $matchrule = "Translate"; $result = $this->construct($matchrule, $matchrule, null);
  723. $_116 = NULL;
  724. do {
  725. if (( $subres = $this->literal( '<%t' ) ) !== FALSE) { $result["text"] .= $subres; }
  726. else { $_116 = FALSE; break; }
  727. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  728. $matcher = 'match_'.'Entity'; $key = $matcher; $pos = $this->pos;
  729. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  730. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  731. else { $_116 = FALSE; break; }
  732. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  733. $res_98 = $result;
  734. $pos_98 = $this->pos;
  735. $_97 = NULL;
  736. do {
  737. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  738. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  739. if ($subres !== FALSE) {
  740. $this->store( $result, $subres, "Default" );
  741. }
  742. else { $_97 = FALSE; break; }
  743. $_97 = TRUE; break;
  744. }
  745. while(0);
  746. if( $_97 === FALSE) {
  747. $result = $res_98;
  748. $this->pos = $pos_98;
  749. unset( $res_98 );
  750. unset( $pos_98 );
  751. }
  752. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  753. $res_109 = $result;
  754. $pos_109 = $this->pos;
  755. $_108 = NULL;
  756. do {
  757. $res_103 = $result;
  758. $pos_103 = $this->pos;
  759. $_102 = NULL;
  760. do {
  761. if (( $subres = $this->literal( 'is' ) ) !== FALSE) { $result["text"] .= $subres; }
  762. else { $_102 = FALSE; break; }
  763. if (substr($this->string,$this->pos,1) == '=') {
  764. $this->pos += 1;
  765. $result["text"] .= '=';
  766. }
  767. else { $_102 = FALSE; break; }
  768. $_102 = TRUE; break;
  769. }
  770. while(0);
  771. if( $_102 === TRUE ) {
  772. $result = $res_103;
  773. $this->pos = $pos_103;
  774. $_108 = FALSE; break;
  775. }
  776. if( $_102 === FALSE) {
  777. $result = $res_103;
  778. $this->pos = $pos_103;
  779. }
  780. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  781. if (( $subres = $this->literal( 'is' ) ) !== FALSE) { $result["text"] .= $subres; }
  782. else { $_108 = FALSE; break; }
  783. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  784. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  785. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  786. if ($subres !== FALSE) {
  787. $this->store( $result, $subres, "Context" );
  788. }
  789. else { $_108 = FALSE; break; }
  790. $_108 = TRUE; break;
  791. }
  792. while(0);
  793. if( $_108 === FALSE) {
  794. $result = $res_109;
  795. $this->pos = $pos_109;
  796. unset( $res_109 );
  797. unset( $pos_109 );
  798. }
  799. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  800. $res_113 = $result;
  801. $pos_113 = $this->pos;
  802. $_112 = NULL;
  803. do {
  804. $matcher = 'match_'.'InjectionVariables'; $key = $matcher; $pos = $this->pos;
  805. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  806. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  807. else { $_112 = FALSE; break; }
  808. $_112 = TRUE; break;
  809. }
  810. while(0);
  811. if( $_112 === FALSE) {
  812. $result = $res_113;
  813. $this->pos = $pos_113;
  814. unset( $res_113 );
  815. unset( $pos_113 );
  816. }
  817. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  818. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  819. else { $_116 = FALSE; break; }
  820. $_116 = TRUE; break;
  821. }
  822. while(0);
  823. if( $_116 === TRUE ) { return $this->finalise($result); }
  824. if( $_116 === FALSE) { return FALSE; }
  825. }
  826. /* InjectionVariables: (< InjectionName:Word "=" Argument)+ */
  827. protected $match_InjectionVariables_typestack = array('InjectionVariables');
  828. function match_InjectionVariables ($stack = array()) {
  829. $matchrule = "InjectionVariables"; $result = $this->construct($matchrule, $matchrule, null);
  830. $count = 0;
  831. while (true) {
  832. $res_123 = $result;
  833. $pos_123 = $this->pos;
  834. $_122 = NULL;
  835. do {
  836. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  837. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  838. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  839. if ($subres !== FALSE) {
  840. $this->store( $result, $subres, "InjectionName" );
  841. }
  842. else { $_122 = FALSE; break; }
  843. if (substr($this->string,$this->pos,1) == '=') {
  844. $this->pos += 1;
  845. $result["text"] .= '=';
  846. }
  847. else { $_122 = FALSE; break; }
  848. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  849. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  850. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  851. else { $_122 = FALSE; break; }
  852. $_122 = TRUE; break;
  853. }
  854. while(0);
  855. if( $_122 === FALSE) {
  856. $result = $res_123;
  857. $this->pos = $pos_123;
  858. unset( $res_123 );
  859. unset( $pos_123 );
  860. break;
  861. }
  862. $count += 1;
  863. }
  864. if ($count > 0) { return $this->finalise($result); }
  865. else { return FALSE; }
  866. }
  867. /* Entity: / [A-Za-z_] [\w\.]* / */
  868. protected $match_Entity_typestack = array('Entity');
  869. function match_Entity ($stack = array()) {
  870. $matchrule = "Entity"; $result = $this->construct($matchrule, $matchrule, null);
  871. if (( $subres = $this->rx( '/ [A-Za-z_] [\w\.]* /' ) ) !== FALSE) {
  872. $result["text"] .= $subres;
  873. return $this->finalise($result);
  874. }
  875. else { return FALSE; }
  876. }
  877. function Translate__construct(&$res) {
  878. $res['php'] = '$val .= _t(';
  879. }
  880. function Translate_Entity(&$res, $sub) {
  881. $res['php'] .= "'$sub[text]'";
  882. }
  883. function Translate_Default(&$res, $sub) {
  884. $res['php'] .= ",$sub[text]";
  885. }
  886. function Translate_Context(&$res, $sub) {
  887. $res['php'] .= ",$sub[text]";
  888. }
  889. function Translate_InjectionVariables(&$res, $sub) {
  890. $res['php'] .= ",$sub[php]";
  891. }
  892. function Translate__finalise(&$res) {
  893. $res['php'] .= ');';
  894. }
  895. function InjectionVariables__construct(&$res) {
  896. $res['php'] = "array(";
  897. }
  898. function InjectionVariables_InjectionName(&$res, $sub) {
  899. $res['php'] .= "'$sub[text]'=>";
  900. }
  901. function InjectionVariables_Argument(&$res, $sub) {
  902. $res['php'] .= str_replace('$$FINAL', 'XML_val', $sub['php']) . ',';
  903. }
  904. function InjectionVariables__finalise(&$res) {
  905. if (substr($res['php'], -1) == ',') $res['php'] = substr($res['php'], 0, -1); //remove last comma in the array
  906. $res['php'] .= ')';
  907. }
  908. /* SimpleInjection: '$' :Lookup */
  909. protected $match_SimpleInjection_typestack = array('SimpleInjection');
  910. function match_SimpleInjection ($stack = array()) {
  911. $matchrule = "SimpleInjection"; $result = $this->construct($matchrule, $matchrule, null);
  912. $_127 = NULL;
  913. do {
  914. if (substr($this->string,$this->pos,1) == '$') {
  915. $this->pos += 1;
  916. $result["text"] .= '$';
  917. }
  918. else { $_127 = FALSE; break; }
  919. $matcher = 'match_'.'Lookup'; $key = $matcher; $pos = $this->pos;
  920. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  921. if ($subres !== FALSE) {
  922. $this->store( $result, $subres, "Lookup" );
  923. }
  924. else { $_127 = FALSE; break; }
  925. $_127 = TRUE; break;
  926. }
  927. while(0);
  928. if( $_127 === TRUE ) { return $this->finalise($result); }
  929. if( $_127 === FALSE) { return FALSE; }
  930. }
  931. /* BracketInjection: '{$' :Lookup "}" */
  932. protected $match_BracketInjection_typestack = array('BracketInjection');
  933. function match_BracketInjection ($stack = array()) {
  934. $matchrule = "BracketInjection"; $result = $this->construct($matchrule, $matchrule, null);
  935. $_132 = NULL;
  936. do {
  937. if (( $subres = $this->literal( '{$' ) ) !== FALSE) { $result["text"] .= $subres; }
  938. else { $_132 = FALSE; break; }
  939. $matcher = 'match_'.'Lookup'; $key = $matcher; $pos = $this->pos;
  940. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  941. if ($subres !== FALSE) {
  942. $this->store( $result, $subres, "Lookup" );
  943. }
  944. else { $_132 = FALSE; break; }
  945. if (substr($this->string,$this->pos,1) == '}') {
  946. $this->pos += 1;
  947. $result["text"] .= '}';
  948. }
  949. else { $_132 = FALSE; break; }
  950. $_132 = TRUE; break;
  951. }
  952. while(0);
  953. if( $_132 === TRUE ) { return $this->finalise($result); }
  954. if( $_132 === FALSE) { return FALSE; }
  955. }
  956. /* Injection: BracketInjection | SimpleInjection */
  957. protected $match_Injection_typestack = array('Injection');
  958. function match_Injection ($stack = array()) {
  959. $matchrule = "Injection"; $result = $this->construct($matchrule, $matchrule, null);
  960. $_137 = NULL;
  961. do {
  962. $res_134 = $result;
  963. $pos_134 = $this->pos;
  964. $matcher = 'match_'.'BracketInjection'; $key = $matcher; $pos = $this->pos;
  965. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  966. if ($subres !== FALSE) {
  967. $this->store( $result, $subres );
  968. $_137 = TRUE; break;
  969. }
  970. $result = $res_134;
  971. $this->pos = $pos_134;
  972. $matcher = 'match_'.'SimpleInjection'; $key = $matcher; $pos = $this->pos;
  973. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  974. if ($subres !== FALSE) {
  975. $this->store( $result, $subres );
  976. $_137 = TRUE; break;
  977. }
  978. $result = $res_134;
  979. $this->pos = $pos_134;
  980. $_137 = FALSE; break;
  981. }
  982. while(0);
  983. if( $_137 === TRUE ) { return $this->finalise($result); }
  984. if( $_137 === FALSE) { return FALSE; }
  985. }
  986. function Injection_STR(&$res, $sub) {
  987. $res['php'] = '$val .= '. str_replace('$$FINAL', 'XML_val', $sub['Lookup']['php']) . ';';
  988. }
  989. /* DollarMarkedLookup: SimpleInjection */
  990. protected $match_DollarMarkedLookup_typestack = array('DollarMarkedLookup');
  991. function match_DollarMarkedLookup ($stack = array()) {
  992. $matchrule = "DollarMarkedLookup"; $result = $this->construct($matchrule, $matchrule, null);
  993. $matcher = 'match_'.'SimpleInjection'; $key = $matcher; $pos = $this->pos;
  994. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  995. if ($subres !== FALSE) {
  996. $this->store( $result, $subres );
  997. return $this->finalise($result);
  998. }
  999. else { return FALSE; }
  1000. }
  1001. function DollarMarkedLookup_STR(&$res, $sub) {
  1002. $res['Lookup'] = $sub['Lookup'];
  1003. }
  1004. /* QuotedString: q:/['"]/ String:/ (\\\\ | \\. | [^$q\\])* / '$q' */
  1005. protected $match_QuotedString_typestack = array('QuotedString');
  1006. function match_QuotedString ($stack = array()) {
  1007. $matchrule = "QuotedString"; $result = $this->construct($matchrule, $matchrule, null);
  1008. $_143 = NULL;
  1009. do {
  1010. $stack[] = $result; $result = $this->construct( $matchrule, "q" );
  1011. if (( $subres = $this->rx( '/[\'"]/' ) ) !== FALSE) {
  1012. $result["text"] .= $subres;
  1013. $subres = $result; $result = array_pop($stack);
  1014. $this->store( $result, $subres, 'q' );
  1015. }
  1016. else {
  1017. $result = array_pop($stack);
  1018. $_143 = FALSE; break;
  1019. }
  1020. $stack[] = $result; $result = $this->construct( $matchrule, "String" );
  1021. if (( $subres = $this->rx( '/ (\\\\\\\\ | \\\\. | [^'.$this->expression($result, $stack, 'q').'\\\\])* /' ) ) !== FALSE) {
  1022. $result["text"] .= $subres;
  1023. $subres = $result; $result = array_pop($stack);
  1024. $this->store( $result, $subres, 'String' );
  1025. }
  1026. else {
  1027. $result = array_pop($stack);
  1028. $_143 = FALSE; break;
  1029. }
  1030. if (( $subres = $this->literal( ''.$this->expression($result, $stack, 'q').'' ) ) !== FALSE) { $result["text"] .= $subres; }
  1031. else { $_143 = FALSE; break; }
  1032. $_143 = TRUE; break;
  1033. }
  1034. while(0);
  1035. if( $_143 === TRUE ) { return $this->finalise($result); }
  1036. if( $_143 === FALSE) { return FALSE; }
  1037. }
  1038. /* FreeString: /[^,)%!=><|&]+/ */
  1039. protected $match_FreeString_typestack = array('FreeString');
  1040. function match_FreeString ($stack = array()) {
  1041. $matchrule = "FreeString"; $result = $this->construct($matchrule, $matchrule, null);
  1042. if (( $subres = $this->rx( '/[^,)%!=><|&]+/' ) ) !== FALSE) {
  1043. $result["text"] .= $subres;
  1044. return $this->finalise($result);
  1045. }
  1046. else { return FALSE; }
  1047. }
  1048. /* Argument:
  1049. :DollarMarkedLookup |
  1050. :QuotedString |
  1051. :Lookup !(< FreeString)|
  1052. :FreeString */
  1053. protected $match_Argument_typestack = array('Argument');
  1054. function match_Argument ($stack = array()) {
  1055. $matchrule = "Argument"; $result = $this->construct($matchrule, $matchrule, null);
  1056. $_163 = NULL;
  1057. do {
  1058. $res_146 = $result;
  1059. $pos_146 = $this->pos;
  1060. $matcher = 'match_'.'DollarMarkedLookup'; $key = $matcher; $pos = $this->pos;
  1061. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1062. if ($subres !== FALSE) {
  1063. $this->store( $result, $subres, "DollarMarkedLookup" );
  1064. $_163 = TRUE; break;
  1065. }
  1066. $result = $res_146;
  1067. $this->pos = $pos_146;
  1068. $_161 = NULL;
  1069. do {
  1070. $res_148 = $result;
  1071. $pos_148 = $this->pos;
  1072. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  1073. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1074. if ($subres !== FALSE) {
  1075. $this->store( $result, $subres, "QuotedString" );
  1076. $_161 = TRUE; break;
  1077. }
  1078. $result = $res_148;
  1079. $this->pos = $pos_148;
  1080. $_159 = NULL;
  1081. do {
  1082. $res_150 = $result;
  1083. $pos_150 = $this->pos;
  1084. $_156 = NULL;
  1085. do {
  1086. $matcher = 'match_'.'Lookup'; $key = $matcher; $pos = $this->pos;
  1087. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1088. if ($subres !== FALSE) {
  1089. $this->store( $result, $subres, "Lookup" );
  1090. }
  1091. else { $_156 = FALSE; break; }
  1092. $res_155 = $result;
  1093. $pos_155 = $this->pos;
  1094. $_154 = NULL;
  1095. do {
  1096. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1097. $matcher = 'match_'.'FreeString'; $key = $matcher; $pos = $this->pos;
  1098. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1099. if ($subres !== FALSE) {
  1100. $this->store( $result, $subres );
  1101. }
  1102. else { $_154 = FALSE; break; }
  1103. $_154 = TRUE; break;
  1104. }
  1105. while(0);
  1106. if( $_154 === TRUE ) {
  1107. $result = $res_155;
  1108. $this->pos = $pos_155;
  1109. $_156 = FALSE; break;
  1110. }
  1111. if( $_154 === FALSE) {
  1112. $result = $res_155;
  1113. $this->pos = $pos_155;
  1114. }
  1115. $_156 = TRUE; break;
  1116. }
  1117. while(0);
  1118. if( $_156 === TRUE ) { $_159 = TRUE; break; }
  1119. $result = $res_150;
  1120. $this->pos = $pos_150;
  1121. $matcher = 'match_'.'FreeString'; $key = $matcher; $pos = $this->pos;
  1122. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1123. if ($subres !== FALSE) {
  1124. $this->store( $result, $subres, "FreeString" );
  1125. $_159 = TRUE; break;
  1126. }
  1127. $result = $res_150;
  1128. $this->pos = $pos_150;
  1129. $_159 = FALSE; break;
  1130. }
  1131. while(0);
  1132. if( $_159 === TRUE ) { $_161 = TRUE; break; }
  1133. $result = $res_148;
  1134. $this->pos = $pos_148;
  1135. $_161 = FALSE; break;
  1136. }
  1137. while(0);
  1138. if( $_161 === TRUE ) { $_163 = TRUE; break; }
  1139. $result = $res_146;
  1140. $this->pos = $pos_146;
  1141. $_163 = FALSE; break;
  1142. }
  1143. while(0);
  1144. if( $_163 === TRUE ) { return $this->finalise($result); }
  1145. if( $_163 === FALSE) { return FALSE; }
  1146. }
  1147. /**
  1148. * If we get a bare value, we don't know enough to determine exactly what php would be the translation, because
  1149. * we don't know if the position of use indicates a lookup or a string argument.
  1150. *
  1151. * Instead, we record 'ArgumentMode' as a member of this matches results node, which can be:
  1152. * - lookup if this argument was unambiguously a lookup (marked as such)
  1153. * - string is this argument was unambiguously a string (marked as such, or impossible to parse as lookup)
  1154. * - default if this argument needs to be handled as per 2.4
  1155. *
  1156. * In the case of 'default', there is no php member of the results node, but instead 'lookup_php', which
  1157. * should be used by the parent if the context indicates a lookup, and 'string_php' which should be used
  1158. * if the context indicates a string
  1159. */
  1160. function Argument_DollarMarkedLookup(&$res, $sub) {
  1161. $res['ArgumentMode'] = 'lookup';
  1162. $res['php'] = $sub['Lookup']['php'];
  1163. }
  1164. function Argument_QuotedString(&$res, $sub) {
  1165. $res['ArgumentMode'] = 'string';
  1166. $res['php'] = "'" . str_replace("'", "\\'", $sub['String']['text']) . "'";
  1167. }
  1168. function Argument_Lookup(&$res, $sub) {
  1169. if (count($sub['LookupSteps']) == 1 && !isset($sub['LookupSteps'][0]['Call']['Arguments'])) {
  1170. $res['ArgumentMode'] = 'default';
  1171. $res['lookup_php'] = $sub['php'];
  1172. $res['string_php'] = "'".$sub['LookupSteps'][0]['Call']['Method']['text']."'";
  1173. }
  1174. else {
  1175. $res['ArgumentMode'] = 'lookup';
  1176. $res['php'] = $sub['php'];
  1177. }
  1178. }
  1179. function Argument_FreeString(&$res, $sub) {
  1180. $res['ArgumentMode'] = 'string';
  1181. $res['php'] = "'" . str_replace("'", "\\'", trim($sub['text'])) . "'";
  1182. }
  1183. /* ComparisonOperator: "!=" | "==" | ">=" | ">" | "<=" | "<" | "=" */
  1184. protected $match_ComparisonOperator_typestack = array('ComparisonOperator');
  1185. function match_ComparisonOperator ($stack = array()) {
  1186. $matchrule = "ComparisonOperator"; $result = $this->construct($matchrule, $matchrule, null);
  1187. $_188 = NULL;
  1188. do {
  1189. $res_165 = $result;
  1190. $pos_165 = $this->pos;
  1191. if (( $subres = $this->literal( '!=' ) ) !== FALSE) {
  1192. $result["text"] .= $subres;
  1193. $_188 = TRUE; break;
  1194. }
  1195. $result = $res_165;
  1196. $this->pos = $pos_165;
  1197. $_186 = NULL;
  1198. do {
  1199. $res_167 = $result;
  1200. $pos_167 = $this->pos;
  1201. if (( $subres = $this->literal( '==' ) ) !== FALSE) {
  1202. $result["text"] .= $subres;
  1203. $_186 = TRUE; break;
  1204. }
  1205. $result = $res_167;
  1206. $this->pos = $pos_167;
  1207. $_184 = NULL;
  1208. do {
  1209. $res_169 = $result;
  1210. $pos_169 = $this->pos;
  1211. if (( $subres = $this->literal( '>=' ) ) !== FALSE) {
  1212. $result["text"] .= $subres;
  1213. $_184 = TRUE; break;
  1214. }
  1215. $result = $res_169;
  1216. $this->pos = $pos_169;
  1217. $_182 = NULL;
  1218. do {
  1219. $res_171 = $result;
  1220. $pos_171 = $this->pos;
  1221. if (substr($this->string,$this->pos,1) == '>') {
  1222. $this->pos += 1;
  1223. $result["text"] .= '>';
  1224. $_182 = TRUE; break;
  1225. }
  1226. $result = $res_171;
  1227. $this->pos = $pos_171;
  1228. $_180 = NULL;
  1229. do {
  1230. $res_173 = $result;
  1231. $pos_173 = $this->pos;
  1232. if (( $subres = $this->literal( '<=' ) ) !== FALSE) {
  1233. $result["text"] .= $subres;
  1234. $_180 = TRUE; break;
  1235. }
  1236. $result = $res_173;
  1237. $this->pos = $pos_173;
  1238. $_178 = NULL;
  1239. do {
  1240. $res_175 = $result;
  1241. $pos_175 = $this->pos;
  1242. if (substr($this->string,$this->pos,1) == '<') {
  1243. $this->pos += 1;
  1244. $result["text"] .= '<';
  1245. $_178 = TRUE; break;
  1246. }
  1247. $result = $res_175;
  1248. $this->pos = $pos_175;
  1249. if (substr($this->string,$this->pos,1) == '=') {
  1250. $this->pos += 1;
  1251. $result["text"] .= '=';
  1252. $_178 = TRUE; break;
  1253. }
  1254. $result = $res_175;
  1255. $this->pos = $pos_175;
  1256. $_178 = FALSE; break;
  1257. }
  1258. while(0);
  1259. if( $_178 === TRUE ) { $_180 = TRUE; break; }
  1260. $result = $res_173;
  1261. $this->pos = $pos_173;
  1262. $_180 = FALSE; break;
  1263. }
  1264. while(0);
  1265. if( $_180 === TRUE ) { $_182 = TRUE; break; }
  1266. $result = $res_171;
  1267. $this->pos = $pos_171;
  1268. $_182 = FALSE; break;
  1269. }
  1270. while(0);
  1271. if( $_182 === TRUE ) { $_184 = TRUE; break; }
  1272. $result = $res_169;
  1273. $this->pos = $pos_169;
  1274. $_184 = FALSE; break;
  1275. }
  1276. while(0);
  1277. if( $_184 === TRUE ) { $_186 = TRUE; break; }
  1278. $result = $res_167;
  1279. $this->pos = $pos_167;
  1280. $_186 = FALSE; break;
  1281. }
  1282. while(0);
  1283. if( $_186 === TRUE ) { $_188 = TRUE; break; }
  1284. $result = $res_165;
  1285. $this->pos = $pos_165;
  1286. $_188 = FALSE; break;
  1287. }
  1288. while(0);
  1289. if( $_188 === TRUE ) { return $this->finalise($result); }
  1290. if( $_188 === FALSE) { return FALSE; }
  1291. }
  1292. /* Comparison: Argument < ComparisonOperator > Argument */
  1293. protected $match_Comparison_typestack = array('Comparison');
  1294. function match_Comparison ($stack = array()) {
  1295. $matchrule = "Comparison"; $result = $this->construct($matchrule, $matchrule, null);
  1296. $_195 = NULL;
  1297. do {
  1298. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  1299. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1300. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1301. else { $_195 = FALSE; break; }
  1302. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1303. $matcher = 'match_'.'ComparisonOperator'; $key = $matcher; $pos = $this->pos;
  1304. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1305. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1306. else { $_195 = FALSE; break; }
  1307. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1308. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  1309. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1310. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1311. else { $_195 = FALSE; break; }
  1312. $_195 = TRUE; break;
  1313. }
  1314. while(0);
  1315. if( $_195 === TRUE ) { return $this->finalise($result); }
  1316. if( $_195 === FALSE) { return FALSE; }
  1317. }
  1318. function Comparison_Argument(&$res, $sub) {
  1319. if ($sub['ArgumentMode'] == 'default') {
  1320. if (!empty($res['php'])) $res['php'] .= $sub['string_php'];
  1321. else $res['php'] = str_replace('$$FINAL', 'XML_val', $sub['lookup_php']);
  1322. }
  1323. else {
  1324. $res['php'] .= str_replace('$$FINAL', 'XML_val', $sub['php']);
  1325. }
  1326. }
  1327. function Comparison_ComparisonOperator(&$res, $sub) {
  1328. $res['php'] .= ($sub['text'] == '=' ? '==' : $sub['text']);
  1329. }
  1330. /* PresenceCheck: (Not:'not' <)? Argument */
  1331. protected $match_PresenceCheck_typestack = array('PresenceCheck');
  1332. function match_PresenceCheck ($stack = array()) {
  1333. $matchrule = "PresenceCheck"; $result = $this->construct($matchrule, $matchrule, null);
  1334. $_202 = NULL;
  1335. do {
  1336. $res_200 = $result;
  1337. $pos_200 = $this->pos;
  1338. $_199 = NULL;
  1339. do {
  1340. $stack[] = $result; $result = $this->construct( $matchrule, "Not" );
  1341. if (( $subres = $this->literal( 'not' ) ) !== FALSE) {
  1342. $result["text"] .= $subres;
  1343. $subres = $result; $result = array_pop($stack);
  1344. $this->store( $result, $subres, 'Not' );
  1345. }
  1346. else {
  1347. $result = array_pop($stack);
  1348. $_199 = FALSE; break;
  1349. }
  1350. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1351. $_199 = TRUE; break;
  1352. }
  1353. while(0);
  1354. if( $_199 === FALSE) {
  1355. $result = $res_200;
  1356. $this->pos = $pos_200;
  1357. unset( $res_200 );
  1358. unset( $pos_200 );
  1359. }
  1360. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  1361. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1362. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1363. else { $_202 = FALSE; break; }
  1364. $_202 = TRUE; break;
  1365. }
  1366. while(0);
  1367. if( $_202 === TRUE ) { return $this->finalise($result); }
  1368. if( $_202 === FALSE) { return FALSE; }
  1369. }
  1370. function PresenceCheck_Not(&$res, $sub) {
  1371. $res['php'] = '!';
  1372. }
  1373. function PresenceCheck_Argument(&$res, $sub) {
  1374. if ($sub['ArgumentMode'] == 'string') {
  1375. $res['php'] .= '((bool)'.$sub['php'].')';
  1376. }
  1377. else {
  1378. $php = ($sub['ArgumentMode'] == 'default' ? $sub['lookup_php'] : $sub['php']);
  1379. // TODO: kinda hacky - maybe we need a way to pass state down the parse chain so
  1380. // Lookup_LastLookupStep and Argument_BareWord can produce hasValue instead of XML_val
  1381. $res['php'] .= str_replace('$$FINAL', 'hasValue', $php);
  1382. }
  1383. }
  1384. /* IfArgumentPortion: Comparison | PresenceCheck */
  1385. protected $match_IfArgumentPortion_typestack = array('IfArgumentPortion');
  1386. function match_IfArgumentPortion ($stack = array()) {
  1387. $matchrule = "IfArgumentPortion"; $result = $this->construct($matchrule, $matchrule, null);
  1388. $_207 = NULL;
  1389. do {
  1390. $res_204 = $result;
  1391. $pos_204 = $this->pos;
  1392. $matcher = 'match_'.'Comparison'; $key = $matcher; $pos = $this->pos;
  1393. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1394. if ($subres !== FALSE) {
  1395. $this->store( $result, $subres );
  1396. $_207 = TRUE; break;
  1397. }
  1398. $result = $res_204;
  1399. $this->pos = $pos_204;
  1400. $matcher = 'match_'.'PresenceCheck'; $key = $matcher; $pos = $this->pos;
  1401. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1402. if ($subres !== FALSE) {
  1403. $this->store( $result, $subres );
  1404. $_207 = TRUE; break;
  1405. }
  1406. $result = $res_204;
  1407. $this->pos = $pos_204;
  1408. $_207 = FALSE; break;
  1409. }
  1410. while(0);
  1411. if( $_207 === TRUE ) { return $this->finalise($result); }
  1412. if( $_207 === FALSE) { return FALSE; }
  1413. }
  1414. function IfArgumentPortion_STR(&$res, $sub) {
  1415. $res['php'] = $sub['php'];
  1416. }
  1417. /* BooleanOperator: "||" | "&&" */
  1418. protected $match_BooleanOperator_typestack = array('BooleanOperator');
  1419. function match_BooleanOperator ($stack = array()) {
  1420. $matchrule = "BooleanOperator"; $result = $this->construct($matchrule, $matchrule, null);
  1421. $_212 = NULL;
  1422. do {
  1423. $res_209 = $result;
  1424. $pos_209 = $this->pos;
  1425. if (( $subres = $this->literal( '||' ) ) !== FALSE) {
  1426. $result["text"] .= $subres;
  1427. $_212 = TRUE; break;
  1428. }
  1429. $result = $res_209;
  1430. $this->pos = $pos_209;
  1431. if (( $subres = $this->literal( '&&' ) ) !== FALSE) {
  1432. $result["text"] .= $subres;
  1433. $_212 = TRUE; break;
  1434. }
  1435. $result = $res_209;
  1436. $this->pos = $pos_209;
  1437. $_212 = FALSE; break;
  1438. }
  1439. while(0);
  1440. if( $_212 === TRUE ) { return $this->finalise($result); }
  1441. if( $_212 === FALSE) { return FALSE; }
  1442. }
  1443. /* IfArgument: :IfArgumentPortion ( < :BooleanOperator < :IfArgumentPortion )* */
  1444. protected $match_IfArgument_typestack = array('IfArgument');
  1445. function match_IfArgument ($stack = array()) {
  1446. $matchrule = "IfArgument"; $result = $this->construct($matchrule, $matchrule, null);
  1447. $_221 = NULL;
  1448. do {
  1449. $matcher = 'match_'.'IfArgumentPortion'; $key = $matcher; $pos = $this->pos;
  1450. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1451. if ($subres !== FALSE) {
  1452. $this->store( $result, $subres, "IfArgumentPortion" );
  1453. }
  1454. else { $_221 = FALSE; break; }
  1455. while (true) {
  1456. $res_220 = $result;
  1457. $pos_220 = $this->pos;
  1458. $_219 = NULL;
  1459. do {
  1460. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1461. $matcher = 'match_'.'BooleanOperator'; $key = $matcher; $pos = $this->pos;
  1462. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1463. if ($subres !== FALSE) {
  1464. $this->store( $result, $subres, "BooleanOperator" );
  1465. }
  1466. else { $_219 = FALSE; break; }
  1467. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1468. $matcher = 'match_'.'IfArgumentPortion'; $key = $matcher; $pos = $this->pos;
  1469. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1470. if ($subres !== FALSE) {
  1471. $this->store( $result, $subres, "IfArgumentPortion" );
  1472. }
  1473. else { $_219 = FALSE; break; }
  1474. $_219 = TRUE; break;
  1475. }
  1476. while(0);
  1477. if( $_219 === FALSE) {
  1478. $result = $res_220;
  1479. $this->pos = $pos_220;
  1480. unset( $res_220 );
  1481. unset( $pos_220 );
  1482. break;
  1483. }
  1484. }
  1485. $_221 = TRUE; break;
  1486. }
  1487. while(0);
  1488. if( $_221 === TRUE ) { return $this->finalise($result); }
  1489. if( $_221 === FALSE) { return FALSE; }
  1490. }
  1491. function IfArgument_IfArgumentPortion(&$res, $sub) {
  1492. $res['php'] .= $sub['php'];
  1493. }
  1494. function IfArgument_BooleanOperator(&$res, $sub) {
  1495. $res['php'] .= $sub['text'];
  1496. }
  1497. /* IfPart: '<%' < 'if' [ :IfArgument > '%>' Template:$TemplateMatcher? */
  1498. protected $match_IfPart_typestack = array('IfPart');
  1499. function match_IfPart ($stack = array()) {
  1500. $matchrule = "IfPart"; $result = $this->construct($matchrule, $matchrule, null);
  1501. $_231 = NULL;
  1502. do {
  1503. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  1504. else { $_231 = FALSE; break; }
  1505. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1506. if (( $subres = $this->literal( 'if' ) ) !== FALSE) { $result["text"] .= $subres; }
  1507. else { $_231 = FALSE; break; }
  1508. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1509. else { $_231 = FALSE; break; }
  1510. $matcher = 'match_'.'IfArgument'; $key = $matcher; $pos = $this->pos;
  1511. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1512. if ($subres !== FALSE) {
  1513. $this->store( $result, $subres, "IfArgument" );
  1514. }
  1515. else { $_231 = FALSE; break; }
  1516. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1517. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  1518. else { $_231 = FALSE; break; }
  1519. $res_230 = $result;
  1520. $pos_230 = $this->pos;
  1521. $matcher = 'match_'.$this->expression($result, $stack, 'TemplateMatcher'); $key = $matcher; $pos = $this->pos;
  1522. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1523. if ($subres !== FALSE) {
  1524. $this->store( $result, $subres, "Template" );
  1525. }
  1526. else {
  1527. $result = $res_230;
  1528. $this->pos = $pos_230;
  1529. unset( $res_230 );
  1530. unset( $pos_230 );
  1531. }
  1532. $_231 = TRUE; break;
  1533. }
  1534. while(0);
  1535. if( $_231 === TRUE ) { return $this->finalise($result); }
  1536. if( $_231 === FALSE) { return FALSE; }
  1537. }
  1538. /* ElseIfPart: '<%' < 'else_if' [ :IfArgument > '%>' Template:$TemplateMatcher? */
  1539. protected $match_ElseIfPart_typestack = array('ElseIfPart');
  1540. function match_ElseIfPart ($stack = array()) {
  1541. $matchrule = "ElseIfPart"; $result = $this->construct($matchrule, $matchrule, null);
  1542. $_241 = NULL;
  1543. do {
  1544. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  1545. else { $_241 = FALSE; break; }
  1546. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1547. if (( $subres = $this->literal( 'else_if' ) ) !== FALSE) { $result["text"] .= $subres; }
  1548. else { $_241 = FALSE; break; }
  1549. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1550. else { $_241 = FALSE; break; }
  1551. $matcher = 'match_'.'IfArgument'; $key = $matcher; $pos = $this->pos;
  1552. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1553. if ($subres !== FALSE) {
  1554. $this->store( $result, $subres, "IfArgument" );
  1555. }
  1556. else { $_241 = FALSE; break; }
  1557. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1558. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  1559. else { $_241 = FALSE; break; }
  1560. $res_240 = $result;
  1561. $pos_240 = $this->pos;
  1562. $matcher = 'match_'.$this->expression($result, $stack, 'TemplateMatcher'); $key = $matcher; $pos = $this->pos;
  1563. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1564. if ($subres !== FALSE) {
  1565. $this->store( $result, $subres, "Template" );
  1566. }
  1567. else {
  1568. $result = $res_240;
  1569. $this->pos = $pos_240;
  1570. unset( $res_240 );
  1571. unset( $pos_240 );
  1572. }
  1573. $_241 = TRUE; break;
  1574. }
  1575. while(0);
  1576. if( $_241 === TRUE ) { return $this->finalise($result); }
  1577. if( $_241 === FALSE) { return FALSE; }
  1578. }
  1579. /* ElsePart: '<%' < 'else' > '%>' Template:$TemplateMatcher? */
  1580. protected $match_ElsePart_typestack = array('ElsePart');
  1581. function match_ElsePart ($stack = array()) {
  1582. $matchrule = "ElsePart"; $result = $this->construct($matchrule, $matchrule, null);
  1583. $_249 = NULL;
  1584. do {
  1585. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  1586. else { $_249 = FALSE; break; }
  1587. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1588. if (( $subres = $this->literal( 'else' ) ) !== FALSE) { $result["text"] .= $subres; }
  1589. else { $_249 = FALSE; break; }
  1590. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1591. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  1592. else { $_249 = FALSE; break; }
  1593. $res_248 = $result;
  1594. $pos_248 = $this->pos;
  1595. $matcher = 'match_'.$this->expression($result, $stack, 'TemplateMatcher'); $key = $matcher; $pos = $this->pos;
  1596. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1597. if ($subres !== FALSE) {
  1598. $this->store( $result, $subres, "Template" );
  1599. }
  1600. else {
  1601. $result = $res_248;
  1602. $this->pos = $pos_248;
  1603. unset( $res_248 );
  1604. unset( $pos_248 );
  1605. }
  1606. $_249 = TRUE; break;
  1607. }
  1608. while(0);
  1609. if( $_249 === TRUE ) { return $this->finalise($result); }
  1610. if( $_249 === FALSE) { return FALSE; }
  1611. }
  1612. /* If: IfPart ElseIfPart* ElsePart? '<%' < 'end_if' > '%>' */
  1613. protected $match_If_typestack = array('If');
  1614. function match_If ($stack = array()) {
  1615. $matchrule = "If"; $result = $this->construct($matchrule, $matchrule, null);
  1616. $_259 = NULL;
  1617. do {
  1618. $matcher = 'match_'.'IfPart'; $key = $matcher; $pos = $this->pos;
  1619. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1620. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1621. else { $_259 = FALSE; break; }
  1622. while (true) {
  1623. $res_252 = $result;
  1624. $pos_252 = $this->pos;
  1625. $matcher = 'match_'.'ElseIfPart'; $key = $matcher; $pos = $this->pos;
  1626. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1627. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1628. else {
  1629. $result = $res_252;
  1630. $this->pos = $pos_252;
  1631. unset( $res_252 );
  1632. unset( $pos_252 );
  1633. break;
  1634. }
  1635. }
  1636. $res_253 = $result;
  1637. $pos_253 = $this->pos;
  1638. $matcher = 'match_'.'ElsePart'; $key = $matcher; $pos = $this->pos;
  1639. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1640. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1641. else {
  1642. $result = $res_253;
  1643. $this->pos = $pos_253;
  1644. unset( $res_253 );
  1645. unset( $pos_253 );
  1646. }
  1647. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  1648. else { $_259 = FALSE; break; }
  1649. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1650. if (( $subres = $this->literal( 'end_if' ) ) !== FALSE) { $result["text"] .= $subres; }
  1651. else { $_259 = FALSE; break; }
  1652. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1653. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  1654. else { $_259 = FALSE; break; }
  1655. $_259 = TRUE; break;
  1656. }
  1657. while(0);
  1658. if( $_259 === TRUE ) { return $this->finalise($result); }
  1659. if( $_259 === FALSE) { return FALSE; }
  1660. }
  1661. function If_IfPart(&$res, $sub) {
  1662. $res['php'] =
  1663. 'if (' . $sub['IfArgument']['php'] . ') { ' . PHP_EOL .
  1664. (isset($sub['Template']) ? $sub['Template']['php'] : '') . PHP_EOL .
  1665. '}';
  1666. }
  1667. function If_ElseIfPart(&$res, $sub) {
  1668. $res['php'] .=
  1669. 'else if (' . $sub['IfArgument']['php'] . ') { ' . PHP_EOL .
  1670. (isset($sub['Template']) ? $sub['Template']['php'] : '') . PHP_EOL .
  1671. '}';
  1672. }
  1673. function If_ElsePart(&$res, $sub) {
  1674. $res['php'] .=
  1675. 'else { ' . PHP_EOL .
  1676. (isset($sub['Template']) ? $sub['Template']['php'] : '') . PHP_EOL .
  1677. '}';
  1678. }
  1679. /* Require: '<%' < 'require' [ Call:(Method:Word "(" < :CallArguments > ")") > '%>' */
  1680. protected $match_Require_typestack = array('Require');
  1681. function match_Require ($stack = array()) {
  1682. $matchrule = "Require"; $result = $this->construct($matchrule, $matchrule, null);
  1683. $_275 = NULL;
  1684. do {
  1685. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  1686. else { $_275 = FALSE; break; }
  1687. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1688. if (( $subres = $this->literal( 'require' ) ) !== FALSE) { $result["text"] .= $subres; }
  1689. else { $_275 = FALSE; break; }
  1690. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1691. else { $_275 = FALSE; break; }
  1692. $stack[] = $result; $result = $this->construct( $matchrule, "Call" );
  1693. $_271 = NULL;
  1694. do {
  1695. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  1696. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1697. if ($subres !== FALSE) {
  1698. $this->store( $result, $subres, "Method" );
  1699. }
  1700. else { $_271 = FALSE; break; }
  1701. if (substr($this->string,$this->pos,1) == '(') {
  1702. $this->pos += 1;
  1703. $result["text"] .= '(';
  1704. }
  1705. else { $_271 = FALSE; break; }
  1706. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1707. $matcher = 'match_'.'CallArguments'; $key = $matcher; $pos = $this->pos;
  1708. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1709. if ($subres !== FALSE) {
  1710. $this->store( $result, $subres, "CallArguments" );
  1711. }
  1712. else { $_271 = FALSE; break; }
  1713. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1714. if (substr($this->string,$this->pos,1) == ')') {
  1715. $this->pos += 1;
  1716. $result["text"] .= ')';
  1717. }
  1718. else { $_271 = FALSE; break; }
  1719. $_271 = TRUE; break;
  1720. }
  1721. while(0);
  1722. if( $_271 === TRUE ) {
  1723. $subres = $result; $result = array_pop($stack);
  1724. $this->store( $result, $subres, 'Call' );
  1725. }
  1726. if( $_271 === FALSE) {
  1727. $result = array_pop($stack);
  1728. $_275 = FALSE; break;
  1729. }
  1730. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1731. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  1732. else { $_275 = FALSE; break; }
  1733. $_275 = TRUE; break;
  1734. }
  1735. while(0);
  1736. if( $_275 === TRUE ) { return $this->finalise($result); }
  1737. if( $_275 === FALSE) { return FALSE; }
  1738. }
  1739. function Require_Call(&$res, $sub) {
  1740. $res['php'] = "Requirements::".$sub['Method']['text'].'('.$sub['CallArguments']['php'].');';
  1741. }
  1742. /* CacheBlockArgument:
  1743. !( "if " | "unless " )
  1744. (
  1745. :DollarMarkedLookup |
  1746. :QuotedString |
  1747. :Lookup
  1748. ) */
  1749. protected $match_CacheBlockArgument_typestack = array('CacheBlockArgument');
  1750. function match_CacheBlockArgument ($stack = array()) {
  1751. $matchrule = "CacheBlockArgument"; $result = $this->construct($matchrule, $matchrule, null);
  1752. $_295 = NULL;
  1753. do {
  1754. $res_283 = $result;
  1755. $pos_283 = $this->pos;
  1756. $_282 = NULL;
  1757. do {
  1758. $_280 = NULL;
  1759. do {
  1760. $res_277 = $result;
  1761. $pos_277 = $this->pos;
  1762. if (( $subres = $this->literal( 'if ' ) ) !== FALSE) {
  1763. $result["text"] .= $subres;
  1764. $_280 = TRUE; break;
  1765. }
  1766. $result = $res_277;
  1767. $this->pos = $pos_277;
  1768. if (( $subres = $this->literal( 'unless ' ) ) !== FALSE) {
  1769. $result["text"] .= $subres;
  1770. $_280 = TRUE; break;
  1771. }
  1772. $result = $res_277;
  1773. $this->pos = $pos_277;
  1774. $_280 = FALSE; break;
  1775. }
  1776. while(0);
  1777. if( $_280 === FALSE) { $_282 = FALSE; break; }
  1778. $_282 = TRUE; break;
  1779. }
  1780. while(0);
  1781. if( $_282 === TRUE ) {
  1782. $result = $res_283;
  1783. $this->pos = $pos_283;
  1784. $_295 = FALSE; break;
  1785. }
  1786. if( $_282 === FALSE) {
  1787. $result = $res_283;
  1788. $this->pos = $pos_283;
  1789. }
  1790. $_293 = NULL;
  1791. do {
  1792. $_291 = NULL;
  1793. do {
  1794. $res_284 = $result;
  1795. $pos_284 = $this->pos;
  1796. $matcher = 'match_'.'DollarMarkedLookup'; $key = $matcher; $pos = $this->pos;
  1797. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1798. if ($subres !== FALSE) {
  1799. $this->store( $result, $subres, "DollarMarkedLookup" );
  1800. $_291 = TRUE; break;
  1801. }
  1802. $result = $res_284;
  1803. $this->pos = $pos_284;
  1804. $_289 = NULL;
  1805. do {
  1806. $res_286 = $result;
  1807. $pos_286 = $this->pos;
  1808. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  1809. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1810. if ($subres !== FALSE) {
  1811. $this->store( $result, $subres, "QuotedString" );
  1812. $_289 = TRUE; break;
  1813. }
  1814. $result = $res_286;
  1815. $this->pos = $pos_286;
  1816. $matcher = 'match_'.'Lookup'; $key = $matcher; $pos = $this->pos;
  1817. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1818. if ($subres !== FALSE) {
  1819. $this->store( $result, $subres, "Lookup" );
  1820. $_289 = TRUE; break;
  1821. }
  1822. $result = $res_286;
  1823. $this->pos = $pos_286;
  1824. $_289 = FALSE; break;
  1825. }
  1826. while(0);
  1827. if( $_289 === TRUE ) { $_291 = TRUE; break; }
  1828. $result = $res_284;
  1829. $this->pos = $pos_284;
  1830. $_291 = FALSE; break;
  1831. }
  1832. while(0);
  1833. if( $_291 === FALSE) { $_293 = FALSE; break; }
  1834. $_293 = TRUE; break;
  1835. }
  1836. while(0);
  1837. if( $_293 === FALSE) { $_295 = FALSE; break; }
  1838. $_295 = TRUE; break;
  1839. }
  1840. while(0);
  1841. if( $_295 === TRUE ) { return $this->finalise($result); }
  1842. if( $_295 === FALSE) { return FALSE; }
  1843. }
  1844. function CacheBlockArgument_DollarMarkedLookup(&$res, $sub) {
  1845. $res['php'] = $sub['Lookup']['php'];
  1846. }
  1847. function CacheBlockArgument_QuotedString(&$res, $sub) {
  1848. $res['php'] = "'" . str_replace("'", "\\'", $sub['String']['text']) . "'";
  1849. }
  1850. function CacheBlockArgument_Lookup(&$res, $sub) {
  1851. $res['php'] = $sub['php'];
  1852. }
  1853. /* CacheBlockArguments: CacheBlockArgument ( < "," < CacheBlockArgument )* */
  1854. protected $match_CacheBlockArguments_typestack = array('CacheBlockArguments');
  1855. function match_CacheBlockArguments ($stack = array()) {
  1856. $matchrule = "CacheBlockArguments"; $result = $this->construct($matchrule, $matchrule, null);
  1857. $_304 = NULL;
  1858. do {
  1859. $matcher = 'match_'.'CacheBlockArgument'; $key = $matcher; $pos = $this->pos;
  1860. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1861. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1862. else { $_304 = FALSE; break; }
  1863. while (true) {
  1864. $res_303 = $result;
  1865. $pos_303 = $this->pos;
  1866. $_302 = NULL;
  1867. do {
  1868. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1869. if (substr($this->string,$this->pos,1) == ',') {
  1870. $this->pos += 1;
  1871. $result["text"] .= ',';
  1872. }
  1873. else { $_302 = FALSE; break; }
  1874. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1875. $matcher = 'match_'.'CacheBlockArgument'; $key = $matcher; $pos = $this->pos;
  1876. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1877. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1878. else { $_302 = FALSE; break; }
  1879. $_302 = TRUE; break;
  1880. }
  1881. while(0);
  1882. if( $_302 === FALSE) {
  1883. $result = $res_303;
  1884. $this->pos = $pos_303;
  1885. unset( $res_303 );
  1886. unset( $pos_303 );
  1887. break;
  1888. }
  1889. }
  1890. $_304 = TRUE; break;
  1891. }
  1892. while(0);
  1893. if( $_304 === TRUE ) { return $this->finalise($result); }
  1894. if( $_304 === FALSE) { return FALSE; }
  1895. }
  1896. function CacheBlockArguments_CacheBlockArgument(&$res, $sub) {
  1897. if (!empty($res['php'])) $res['php'] .= ".'_'.";
  1898. else $res['php'] = '';
  1899. $res['php'] .= str_replace('$$FINAL', 'XML_val', $sub['php']);
  1900. }
  1901. /* CacheBlockTemplate: (Comment | Translate | If | Require | OldI18NTag | Include | ClosedBlock |
  1902. OpenBlock | MalformedBlock | Injection | Text)+ */
  1903. protected $match_CacheBlockTemplate_typestack = array('CacheBlockTemplate','Template');
  1904. function match_CacheBlockTemplate ($stack = array()) {
  1905. $matchrule = "CacheBlockTemplate"; $result = $this->construct($matchrule, $matchrule, array('TemplateMatcher' => 'CacheRestrictedTemplate'));
  1906. $count = 0;
  1907. while (true) {
  1908. $res_348 = $result;
  1909. $pos_348 = $this->pos;
  1910. $_347 = NULL;
  1911. do {
  1912. $_345 = NULL;
  1913. do {
  1914. $res_306 = $result;
  1915. $pos_306 = $this->pos;
  1916. $matcher = 'match_'.'Comment'; $key = $matcher; $pos = $this->pos;
  1917. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1918. if ($subres !== FALSE) {
  1919. $this->store( $result, $subres );
  1920. $_345 = TRUE; break;
  1921. }
  1922. $result = $res_306;
  1923. $this->pos = $pos_306;
  1924. $_343 = NULL;
  1925. do {
  1926. $res_308 = $result;
  1927. $pos_308 = $this->pos;
  1928. $matcher = 'match_'.'Translate'; $key = $matcher; $pos = $this->pos;
  1929. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1930. if ($subres !== FALSE) {
  1931. $this->store( $result, $subres );
  1932. $_343 = TRUE; break;
  1933. }
  1934. $result = $res_308;
  1935. $this->pos = $pos_308;
  1936. $_341 = NULL;
  1937. do {
  1938. $res_310 = $result;
  1939. $pos_310 = $this->pos;
  1940. $matcher = 'match_'.'If'; $key = $matcher; $pos = $this->pos;
  1941. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1942. if ($subres !== FALSE) {
  1943. $this->store( $result, $subres );
  1944. $_341 = TRUE; break;
  1945. }
  1946. $result = $res_310;
  1947. $this->pos = $pos_310;
  1948. $_339 = NULL;
  1949. do {
  1950. $res_312 = $result;
  1951. $pos_312 = $this->pos;
  1952. $matcher = 'match_'.'Require'; $key = $matcher; $pos = $this->pos;
  1953. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1954. if ($subres !== FALSE) {
  1955. $this->store( $result, $subres );
  1956. $_339 = TRUE; break;
  1957. }
  1958. $result = $res_312;
  1959. $this->pos = $pos_312;
  1960. $_337 = NULL;
  1961. do {
  1962. $res_314 = $result;
  1963. $pos_314 = $this->pos;
  1964. $matcher = 'match_'.'OldI18NTag'; $key = $matcher; $pos = $this->pos;
  1965. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1966. if ($subres !== FALSE) {
  1967. $this->store( $result, $subres );
  1968. $_337 = TRUE; break;
  1969. }
  1970. $result = $res_314;
  1971. $this->pos = $pos_314;
  1972. $_335 = NULL;
  1973. do {
  1974. $res_316 = $result;
  1975. $pos_316 = $this->pos;
  1976. $matcher = 'match_'.'Include'; $key = $matcher; $pos = $this->pos;
  1977. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1978. if ($subres !== FALSE) {
  1979. $this->store( $result, $subres );
  1980. $_335 = TRUE; break;
  1981. }
  1982. $result = $res_316;
  1983. $this->pos = $pos_316;
  1984. $_333 = NULL;
  1985. do {
  1986. $res_318 = $result;
  1987. $pos_318 = $this->pos;
  1988. $matcher = 'match_'.'ClosedBlock'; $key = $matcher; $pos = $this->pos;
  1989. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1990. if ($subres !== FALSE) {
  1991. $this->store( $result, $subres );
  1992. $_333 = TRUE; break;
  1993. }
  1994. $result = $res_318;
  1995. $this->pos = $pos_318;
  1996. $_331 = NULL;
  1997. do {
  1998. $res_320 = $result;
  1999. $pos_320 = $this->pos;
  2000. $matcher = 'match_'.'OpenBlock'; $key = $matcher; $pos = $this->pos;
  2001. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2002. if ($subres !== FALSE) {
  2003. $this->store( $result, $subres );
  2004. $_331 = TRUE; break;
  2005. }
  2006. $result = $res_320;
  2007. $this->pos = $pos_320;
  2008. $_329 = NULL;
  2009. do {
  2010. $res_322 = $result;
  2011. $pos_322 = $this->pos;
  2012. $matcher = 'match_'.'MalformedBlock'; $key = $matcher; $pos = $this->pos;
  2013. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2014. if ($subres !== FALSE) {
  2015. $this->store( $result, $subres );
  2016. $_329 = TRUE; break;
  2017. }
  2018. $result = $res_322;
  2019. $this->pos = $pos_322;
  2020. $_327 = NULL;
  2021. do {
  2022. $res_324 = $result;
  2023. $pos_324 = $this->pos;
  2024. $matcher = 'match_'.'Injection'; $key = $matcher; $pos = $this->pos;
  2025. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2026. if ($subres !== FALSE) {
  2027. $this->store( $result, $subres );
  2028. $_327 = TRUE; break;
  2029. }
  2030. $result = $res_324;
  2031. $this->pos = $pos_324;
  2032. $matcher = 'match_'.'Text'; $key = $matcher; $pos = $this->pos;
  2033. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2034. if ($subres !== FALSE) {
  2035. $this->store( $result, $subres );
  2036. $_327 = TRUE; break;
  2037. }
  2038. $result = $res_324;
  2039. $this->pos = $pos_324;
  2040. $_327 = FALSE; break;
  2041. }
  2042. while(0);
  2043. if( $_327 === TRUE ) { $_329 = TRUE; break; }
  2044. $result = $res_322;
  2045. $this->pos = $pos_322;
  2046. $_329 = FALSE; break;
  2047. }
  2048. while(0);
  2049. if( $_329 === TRUE ) { $_331 = TRUE; break; }
  2050. $result = $res_320;
  2051. $this->pos = $pos_320;
  2052. $_331 = FALSE; break;
  2053. }
  2054. while(0);
  2055. if( $_331 === TRUE ) { $_333 = TRUE; break; }
  2056. $result = $res_318;
  2057. $this->pos = $pos_318;
  2058. $_333 = FALSE; break;
  2059. }
  2060. while(0);
  2061. if( $_333 === TRUE ) { $_335 = TRUE; break; }
  2062. $result = $res_316;
  2063. $this->pos = $pos_316;
  2064. $_335 = FALSE; break;
  2065. }
  2066. while(0);
  2067. if( $_335 === TRUE ) { $_337 = TRUE; break; }
  2068. $result = $res_314;
  2069. $this->pos = $pos_314;
  2070. $_337 = FALSE; break;
  2071. }
  2072. while(0);
  2073. if( $_337 === TRUE ) { $_339 = TRUE; break; }
  2074. $result = $res_312;
  2075. $this->pos = $pos_312;
  2076. $_339 = FALSE; break;
  2077. }
  2078. while(0);
  2079. if( $_339 === TRUE ) { $_341 = TRUE; break; }
  2080. $result = $res_310;
  2081. $this->pos = $pos_310;
  2082. $_341 = FALSE; break;
  2083. }
  2084. while(0);
  2085. if( $_341 === TRUE ) { $_343 = TRUE; break; }
  2086. $result = $res_308;
  2087. $this->pos = $pos_308;
  2088. $_343 = FALSE; break;
  2089. }
  2090. while(0);
  2091. if( $_343 === TRUE ) { $_345 = TRUE; break; }
  2092. $result = $res_306;
  2093. $this->pos = $pos_306;
  2094. $_345 = FALSE; break;
  2095. }
  2096. while(0);
  2097. if( $_345 === FALSE) { $_347 = FALSE; break; }
  2098. $_347 = TRUE; break;
  2099. }
  2100. while(0);
  2101. if( $_347 === FALSE) {
  2102. $result = $res_348;
  2103. $this->pos = $pos_348;
  2104. unset( $res_348 );
  2105. unset( $pos_348 );
  2106. break;
  2107. }
  2108. $count += 1;
  2109. }
  2110. if ($count > 0) { return $this->finalise($result); }
  2111. else { return FALSE; }
  2112. }
  2113. /* UncachedBlock:
  2114. '<%' < "uncached" < CacheBlockArguments? ( < Conditional:("if"|"unless") > Condition:IfArgument )? > '%>'
  2115. Template:$TemplateMatcher?
  2116. '<%' < 'end_' ("uncached"|"cached"|"cacheblock") > '%>' */
  2117. protected $match_UncachedBlock_typestack = array('UncachedBlock');
  2118. function match_UncachedBlock ($stack = array()) {
  2119. $matchrule = "UncachedBlock"; $result = $this->construct($matchrule, $matchrule, null);
  2120. $_385 = NULL;
  2121. do {
  2122. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  2123. else { $_385 = FALSE; break; }
  2124. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2125. if (( $subres = $this->literal( 'uncached' ) ) !== FALSE) { $result["text"] .= $subres; }
  2126. else { $_385 = FALSE; break; }
  2127. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2128. $res_353 = $result;
  2129. $pos_353 = $this->pos;
  2130. $matcher = 'match_'.'CacheBlockArguments'; $key = $matcher; $pos = $this->pos;
  2131. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2132. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2133. else {
  2134. $result = $res_353;
  2135. $this->pos = $pos_353;
  2136. unset( $res_353 );
  2137. unset( $pos_353 );
  2138. }
  2139. $res_365 = $result;
  2140. $pos_365 = $this->pos;
  2141. $_364 = NULL;
  2142. do {
  2143. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2144. $stack[] = $result; $result = $this->construct( $matchrule, "Conditional" );
  2145. $_360 = NULL;
  2146. do {
  2147. $_358 = NULL;
  2148. do {
  2149. $res_355 = $result;
  2150. $pos_355 = $this->pos;
  2151. if (( $subres = $this->literal( 'if' ) ) !== FALSE) {
  2152. $result["text"] .= $subres;
  2153. $_358 = TRUE; break;
  2154. }
  2155. $result = $res_355;
  2156. $this->pos = $pos_355;
  2157. if (( $subres = $this->literal( 'unless' ) ) !== FALSE) {
  2158. $result["text"] .= $subres;
  2159. $_358 = TRUE; break;
  2160. }
  2161. $result = $res_355;
  2162. $this->pos = $pos_355;
  2163. $_358 = FALSE; break;
  2164. }
  2165. while(0);
  2166. if( $_358 === FALSE) { $_360 = FALSE; break; }
  2167. $_360 = TRUE; break;
  2168. }
  2169. while(0);
  2170. if( $_360 === TRUE ) {
  2171. $subres = $result; $result = array_pop($stack);
  2172. $this->store( $result, $subres, 'Conditional' );
  2173. }
  2174. if( $_360 === FALSE) {
  2175. $result = array_pop($stack);
  2176. $_364 = FALSE; break;
  2177. }
  2178. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2179. $matcher = 'match_'.'IfArgument'; $key = $matcher; $pos = $this->pos;
  2180. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2181. if ($subres !== FALSE) {
  2182. $this->store( $result, $subres, "Condition" );
  2183. }
  2184. else { $_364 = FALSE; break; }
  2185. $_364 = TRUE; break;
  2186. }
  2187. while(0);
  2188. if( $_364 === FALSE) {
  2189. $result = $res_365;
  2190. $this->pos = $pos_365;
  2191. unset( $res_365 );
  2192. unset( $pos_365 );
  2193. }
  2194. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2195. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  2196. else { $_385 = FALSE; break; }
  2197. $res_368 = $result;
  2198. $pos_368 = $this->pos;
  2199. $matcher = 'match_'.$this->expression($result, $stack, 'TemplateMatcher'); $key = $matcher; $pos = $this->pos;
  2200. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2201. if ($subres !== FALSE) {
  2202. $this->store( $result, $subres, "Template" );
  2203. }
  2204. else {
  2205. $result = $res_368;
  2206. $this->pos = $pos_368;
  2207. unset( $res_368 );
  2208. unset( $pos_368 );
  2209. }
  2210. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  2211. else { $_385 = FALSE; break; }
  2212. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2213. if (( $subres = $this->literal( 'end_' ) ) !== FALSE) { $result["text"] .= $subres; }
  2214. else { $_385 = FALSE; break; }
  2215. $_381 = NULL;
  2216. do {
  2217. $_379 = NULL;
  2218. do {
  2219. $res_372 = $result;
  2220. $pos_372 = $this->pos;
  2221. if (( $subres = $this->literal( 'uncached' ) ) !== FALSE) {
  2222. $result["text"] .= $subres;
  2223. $_379 = TRUE; break;
  2224. }
  2225. $result = $res_372;
  2226. $this->pos = $pos_372;
  2227. $_377 = NULL;
  2228. do {
  2229. $res_374 = $result;
  2230. $pos_374 = $this->pos;
  2231. if (( $subres = $this->literal( 'cached' ) ) !== FALSE) {
  2232. $result["text"] .= $subres;
  2233. $_377 = TRUE; break;
  2234. }
  2235. $result = $res_374;
  2236. $this->pos = $pos_374;
  2237. if (( $subres = $this->literal( 'cacheblock' ) ) !== FALSE) {
  2238. $result["text"] .= $subres;
  2239. $_377 = TRUE; break;
  2240. }
  2241. $result = $res_374;
  2242. $this->pos = $pos_374;
  2243. $_377 = FALSE; break;
  2244. }
  2245. while(0);
  2246. if( $_377 === TRUE ) { $_379 = TRUE; break; }
  2247. $result = $res_372;
  2248. $this->pos = $pos_372;
  2249. $_379 = FALSE; break;
  2250. }
  2251. while(0);
  2252. if( $_379 === FALSE) { $_381 = FALSE; break; }
  2253. $_381 = TRUE; break;
  2254. }
  2255. while(0);
  2256. if( $_381 === FALSE) { $_385 = FALSE; break; }
  2257. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2258. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  2259. else { $_385 = FALSE; break; }
  2260. $_385 = TRUE; break;
  2261. }
  2262. while(0);
  2263. if( $_385 === TRUE ) { return $this->finalise($result); }
  2264. if( $_385 === FALSE) { return FALSE; }
  2265. }
  2266. function UncachedBlock_Template(&$res, $sub){
  2267. $res['php'] = $sub['php'];
  2268. }
  2269. /* CacheRestrictedTemplate: (Comment | Translate | If | Require | CacheBlock | UncachedBlock | OldI18NTag | Include | ClosedBlock |
  2270. OpenBlock | MalformedBlock | Injection | Text)+ */
  2271. protected $match_CacheRestrictedTemplate_typestack = array('CacheRestrictedTemplate','Template');
  2272. function match_CacheRestrictedTemplate ($stack = array()) {
  2273. $matchrule = "CacheRestrictedTemplate"; $result = $this->construct($matchrule, $matchrule, null);
  2274. $count = 0;
  2275. while (true) {
  2276. $res_437 = $result;
  2277. $pos_437 = $this->pos;
  2278. $_436 = NULL;
  2279. do {
  2280. $_434 = NULL;
  2281. do {
  2282. $res_387 = $result;
  2283. $pos_387 = $this->pos;
  2284. $matcher = 'match_'.'Comment'; $key = $matcher; $pos = $this->pos;
  2285. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2286. if ($subres !== FALSE) {
  2287. $this->store( $result, $subres );
  2288. $_434 = TRUE; break;
  2289. }
  2290. $result = $res_387;
  2291. $this->pos = $pos_387;
  2292. $_432 = NULL;
  2293. do {
  2294. $res_389 = $result;
  2295. $pos_389 = $this->pos;
  2296. $matcher = 'match_'.'Translate'; $key = $matcher; $pos = $this->pos;
  2297. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2298. if ($subres !== FALSE) {
  2299. $this->store( $result, $subres );
  2300. $_432 = TRUE; break;
  2301. }
  2302. $result = $res_389;
  2303. $this->pos = $pos_389;
  2304. $_430 = NULL;
  2305. do {
  2306. $res_391 = $result;
  2307. $pos_391 = $this->pos;
  2308. $matcher = 'match_'.'If'; $key = $matcher; $pos = $this->pos;
  2309. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2310. if ($subres !== FALSE) {
  2311. $this->store( $result, $subres );
  2312. $_430 = TRUE; break;
  2313. }
  2314. $result = $res_391;
  2315. $this->pos = $pos_391;
  2316. $_428 = NULL;
  2317. do {
  2318. $res_393 = $result;
  2319. $pos_393 = $this->pos;
  2320. $matcher = 'match_'.'Require'; $key = $matcher; $pos = $this->pos;
  2321. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2322. if ($subres !== FALSE) {
  2323. $this->store( $result, $subres );
  2324. $_428 = TRUE; break;
  2325. }
  2326. $result = $res_393;
  2327. $this->pos = $pos_393;
  2328. $_426 = NULL;
  2329. do {
  2330. $res_395 = $result;
  2331. $pos_395 = $this->pos;
  2332. $matcher = 'match_'.'CacheBlock'; $key = $matcher; $pos = $this->pos;
  2333. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2334. if ($subres !== FALSE) {
  2335. $this->store( $result, $subres );
  2336. $_426 = TRUE; break;
  2337. }
  2338. $result = $res_395;
  2339. $this->pos = $pos_395;
  2340. $_424 = NULL;
  2341. do {
  2342. $res_397 = $result;
  2343. $pos_397 = $this->pos;
  2344. $matcher = 'match_'.'UncachedBlock'; $key = $matcher; $pos = $this->pos;
  2345. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2346. if ($subres !== FALSE) {
  2347. $this->store( $result, $subres );
  2348. $_424 = TRUE; break;
  2349. }
  2350. $result = $res_397;
  2351. $this->pos = $pos_397;
  2352. $_422 = NULL;
  2353. do {
  2354. $res_399 = $result;
  2355. $pos_399 = $this->pos;
  2356. $matcher = 'match_'.'OldI18NTag'; $key = $matcher; $pos = $this->pos;
  2357. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2358. if ($subres !== FALSE) {
  2359. $this->store( $result, $subres );
  2360. $_422 = TRUE; break;
  2361. }
  2362. $result = $res_399;
  2363. $this->pos = $pos_399;
  2364. $_420 = NULL;
  2365. do {
  2366. $res_401 = $result;
  2367. $pos_401 = $this->pos;
  2368. $matcher = 'match_'.'Include'; $key = $matcher; $pos = $this->pos;
  2369. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2370. if ($subres !== FALSE) {
  2371. $this->store( $result, $subres );
  2372. $_420 = TRUE; break;
  2373. }
  2374. $result = $res_401;
  2375. $this->pos = $pos_401;
  2376. $_418 = NULL;
  2377. do {
  2378. $res_403 = $result;
  2379. $pos_403 = $this->pos;
  2380. $matcher = 'match_'.'ClosedBlock'; $key = $matcher; $pos = $this->pos;
  2381. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2382. if ($subres !== FALSE) {
  2383. $this->store( $result, $subres );
  2384. $_418 = TRUE; break;
  2385. }
  2386. $result = $res_403;
  2387. $this->pos = $pos_403;
  2388. $_416 = NULL;
  2389. do {
  2390. $res_405 = $result;
  2391. $pos_405 = $this->pos;
  2392. $matcher = 'match_'.'OpenBlock'; $key = $matcher; $pos = $this->pos;
  2393. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2394. if ($subres !== FALSE) {
  2395. $this->store( $result, $subres );
  2396. $_416 = TRUE; break;
  2397. }
  2398. $result = $res_405;
  2399. $this->pos = $pos_405;
  2400. $_414 = NULL;
  2401. do {
  2402. $res_407 = $result;
  2403. $pos_407 = $this->pos;
  2404. $matcher = 'match_'.'MalformedBlock'; $key = $matcher; $pos = $this->pos;
  2405. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2406. if ($subres !== FALSE) {
  2407. $this->store( $result, $subres );
  2408. $_414 = TRUE; break;
  2409. }
  2410. $result = $res_407;
  2411. $this->pos = $pos_407;
  2412. $_412 = NULL;
  2413. do {
  2414. $res_409 = $result;
  2415. $pos_409 = $this->pos;
  2416. $matcher = 'match_'.'Injection'; $key = $matcher; $pos = $this->pos;
  2417. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2418. if ($subres !== FALSE) {
  2419. $this->store( $result, $subres );
  2420. $_412 = TRUE; break;
  2421. }
  2422. $result = $res_409;
  2423. $this->pos = $pos_409;
  2424. $matcher = 'match_'.'Text'; $key = $matcher; $pos = $this->pos;
  2425. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2426. if ($subres !== FALSE) {
  2427. $this->store( $result, $subres );
  2428. $_412 = TRUE; break;
  2429. }
  2430. $result = $res_409;
  2431. $this->pos = $pos_409;
  2432. $_412 = FALSE; break;
  2433. }
  2434. while(0);
  2435. if( $_412 === TRUE ) { $_414 = TRUE; break; }
  2436. $result = $res_407;
  2437. $this->pos = $pos_407;
  2438. $_414 = FALSE; break;
  2439. }
  2440. while(0);
  2441. if( $_414 === TRUE ) { $_416 = TRUE; break; }
  2442. $result = $res_405;
  2443. $this->pos = $pos_405;
  2444. $_416 = FALSE; break;
  2445. }
  2446. while(0);
  2447. if( $_416 === TRUE ) { $_418 = TRUE; break; }
  2448. $result = $res_403;
  2449. $this->pos = $pos_403;
  2450. $_418 = FALSE; break;
  2451. }
  2452. while(0);
  2453. if( $_418 === TRUE ) { $_420 = TRUE; break; }
  2454. $result = $res_401;
  2455. $this->pos = $pos_401;
  2456. $_420 = FALSE; break;
  2457. }
  2458. while(0);
  2459. if( $_420 === TRUE ) { $_422 = TRUE; break; }
  2460. $result = $res_399;
  2461. $this->pos = $pos_399;
  2462. $_422 = FALSE; break;
  2463. }
  2464. while(0);
  2465. if( $_422 === TRUE ) { $_424 = TRUE; break; }
  2466. $result = $res_397;
  2467. $this->pos = $pos_397;
  2468. $_424 = FALSE; break;
  2469. }
  2470. while(0);
  2471. if( $_424 === TRUE ) { $_426 = TRUE; break; }
  2472. $result = $res_395;
  2473. $this->pos = $pos_395;
  2474. $_426 = FALSE; break;
  2475. }
  2476. while(0);
  2477. if( $_426 === TRUE ) { $_428 = TRUE; break; }
  2478. $result = $res_393;
  2479. $this->pos = $pos_393;
  2480. $_428 = FALSE; break;
  2481. }
  2482. while(0);
  2483. if( $_428 === TRUE ) { $_430 = TRUE; break; }
  2484. $result = $res_391;
  2485. $this->pos = $pos_391;
  2486. $_430 = FALSE; break;
  2487. }
  2488. while(0);
  2489. if( $_430 === TRUE ) { $_432 = TRUE; break; }
  2490. $result = $res_389;
  2491. $this->pos = $pos_389;
  2492. $_432 = FALSE; break;
  2493. }
  2494. while(0);
  2495. if( $_432 === TRUE ) { $_434 = TRUE; break; }
  2496. $result = $res_387;
  2497. $this->pos = $pos_387;
  2498. $_434 = FALSE; break;
  2499. }
  2500. while(0);
  2501. if( $_434 === FALSE) { $_436 = FALSE; break; }
  2502. $_436 = TRUE; break;
  2503. }
  2504. while(0);
  2505. if( $_436 === FALSE) {
  2506. $result = $res_437;
  2507. $this->pos = $pos_437;
  2508. unset( $res_437 );
  2509. unset( $pos_437 );
  2510. break;
  2511. }
  2512. $count += 1;
  2513. }
  2514. if ($count > 0) { return $this->finalise($result); }
  2515. else { return FALSE; }
  2516. }
  2517. function CacheRestrictedTemplate_CacheBlock(&$res, $sub) {
  2518. throw new SSTemplateParseException('You cant have cache blocks nested within with, loop or control blocks ' .
  2519. 'that are within cache blocks', $this);
  2520. }
  2521. function CacheRestrictedTemplate_UncachedBlock(&$res, $sub) {
  2522. throw new SSTemplateParseException('You cant have uncache blocks nested within with, loop or control blocks ' .
  2523. 'that are within cache blocks', $this);
  2524. }
  2525. /* CacheBlock:
  2526. '<%' < CacheTag:("cached"|"cacheblock") < (CacheBlockArguments)? ( < Conditional:("if"|"unless") >
  2527. Condition:IfArgument )? > '%>'
  2528. (CacheBlock | UncachedBlock | CacheBlockTemplate)*
  2529. '<%' < 'end_' ("cached"|"uncached"|"cacheblock") > '%>' */
  2530. protected $match_CacheBlock_typestack = array('CacheBlock');
  2531. function match_CacheBlock ($stack = array()) {
  2532. $matchrule = "CacheBlock"; $result = $this->construct($matchrule, $matchrule, null);
  2533. $_492 = NULL;
  2534. do {
  2535. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  2536. else { $_492 = FALSE; break; }
  2537. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2538. $stack[] = $result; $result = $this->construct( $matchrule, "CacheTag" );
  2539. $_445 = NULL;
  2540. do {
  2541. $_443 = NULL;
  2542. do {
  2543. $res_440 = $result;
  2544. $pos_440 = $this->pos;
  2545. if (( $subres = $this->literal( 'cached' ) ) !== FALSE) {
  2546. $result["text"] .= $subres;
  2547. $_443 = TRUE; break;
  2548. }
  2549. $result = $res_440;
  2550. $this->pos = $pos_440;
  2551. if (( $subres = $this->literal( 'cacheblock' ) ) !== FALSE) {
  2552. $result["text"] .= $subres;
  2553. $_443 = TRUE; break;
  2554. }
  2555. $result = $res_440;
  2556. $this->pos = $pos_440;
  2557. $_443 = FALSE; break;
  2558. }
  2559. while(0);
  2560. if( $_443 === FALSE) { $_445 = FALSE; break; }
  2561. $_445 = TRUE; break;
  2562. }
  2563. while(0);
  2564. if( $_445 === TRUE ) {
  2565. $subres = $result; $result = array_pop($stack);
  2566. $this->store( $result, $subres, 'CacheTag' );
  2567. }
  2568. if( $_445 === FALSE) {
  2569. $result = array_pop($stack);
  2570. $_492 = FALSE; break;
  2571. }
  2572. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2573. $res_450 = $result;
  2574. $pos_450 = $this->pos;
  2575. $_449 = NULL;
  2576. do {
  2577. $matcher = 'match_'.'CacheBlockArguments'; $key = $matcher; $pos = $this->pos;
  2578. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2579. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2580. else { $_449 = FALSE; break; }
  2581. $_449 = TRUE; break;
  2582. }
  2583. while(0);
  2584. if( $_449 === FALSE) {
  2585. $result = $res_450;
  2586. $this->pos = $pos_450;
  2587. unset( $res_450 );
  2588. unset( $pos_450 );
  2589. }
  2590. $res_462 = $result;
  2591. $pos_462 = $this->pos;
  2592. $_461 = NULL;
  2593. do {
  2594. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2595. $stack[] = $result; $result = $this->construct( $matchrule, "Conditional" );
  2596. $_457 = NULL;
  2597. do {
  2598. $_455 = NULL;
  2599. do {
  2600. $res_452 = $result;
  2601. $pos_452 = $this->pos;
  2602. if (( $subres = $this->literal( 'if' ) ) !== FALSE) {
  2603. $result["text"] .= $subres;
  2604. $_455 = TRUE; break;
  2605. }
  2606. $result = $res_452;
  2607. $this->pos = $pos_452;
  2608. if (( $subres = $this->literal( 'unless' ) ) !== FALSE) {
  2609. $result["text"] .= $subres;
  2610. $_455 = TRUE; break;
  2611. }
  2612. $result = $res_452;
  2613. $this->pos = $pos_452;
  2614. $_455 = FALSE; break;
  2615. }
  2616. while(0);
  2617. if( $_455 === FALSE) { $_457 = FALSE; break; }
  2618. $_457 = TRUE; break;
  2619. }
  2620. while(0);
  2621. if( $_457 === TRUE ) {
  2622. $subres = $result; $result = array_pop($stack);
  2623. $this->store( $result, $subres, 'Conditional' );
  2624. }
  2625. if( $_457 === FALSE) {
  2626. $result = array_pop($stack);
  2627. $_461 = FALSE; break;
  2628. }
  2629. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2630. $matcher = 'match_'.'IfArgument'; $key = $matcher; $pos = $this->pos;
  2631. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2632. if ($subres !== FALSE) {
  2633. $this->store( $result, $subres, "Condition" );
  2634. }
  2635. else { $_461 = FALSE; break; }
  2636. $_461 = TRUE; break;
  2637. }
  2638. while(0);
  2639. if( $_461 === FALSE) {
  2640. $result = $res_462;
  2641. $this->pos = $pos_462;
  2642. unset( $res_462 );
  2643. unset( $pos_462 );
  2644. }
  2645. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2646. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  2647. else { $_492 = FALSE; break; }
  2648. while (true) {
  2649. $res_475 = $result;
  2650. $pos_475 = $this->pos;
  2651. $_474 = NULL;
  2652. do {
  2653. $_472 = NULL;
  2654. do {
  2655. $res_465 = $result;
  2656. $pos_465 = $this->pos;
  2657. $matcher = 'match_'.'CacheBlock'; $key = $matcher; $pos = $this->pos;
  2658. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2659. if ($subres !== FALSE) {
  2660. $this->store( $result, $subres );
  2661. $_472 = TRUE; break;
  2662. }
  2663. $result = $res_465;
  2664. $this->pos = $pos_465;
  2665. $_470 = NULL;
  2666. do {
  2667. $res_467 = $result;
  2668. $pos_467 = $this->pos;
  2669. $matcher = 'match_'.'UncachedBlock'; $key = $matcher; $pos = $this->pos;
  2670. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2671. if ($subres !== FALSE) {
  2672. $this->store( $result, $subres );
  2673. $_470 = TRUE; break;
  2674. }
  2675. $result = $res_467;
  2676. $this->pos = $pos_467;
  2677. $matcher = 'match_'.'CacheBlockTemplate'; $key = $matcher; $pos = $this->pos;
  2678. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2679. if ($subres !== FALSE) {
  2680. $this->store( $result, $subres );
  2681. $_470 = TRUE; break;
  2682. }
  2683. $result = $res_467;
  2684. $this->pos = $pos_467;
  2685. $_470 = FALSE; break;
  2686. }
  2687. while(0);
  2688. if( $_470 === TRUE ) { $_472 = TRUE; break; }
  2689. $result = $res_465;
  2690. $this->pos = $pos_465;
  2691. $_472 = FALSE; break;
  2692. }
  2693. while(0);
  2694. if( $_472 === FALSE) { $_474 = FALSE; break; }
  2695. $_474 = TRUE; break;
  2696. }
  2697. while(0);
  2698. if( $_474 === FALSE) {
  2699. $result = $res_475;
  2700. $this->pos = $pos_475;
  2701. unset( $res_475 );
  2702. unset( $pos_475 );
  2703. break;
  2704. }
  2705. }
  2706. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  2707. else { $_492 = FALSE; break; }
  2708. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2709. if (( $subres = $this->literal( 'end_' ) ) !== FALSE) { $result["text"] .= $subres; }
  2710. else { $_492 = FALSE; break; }
  2711. $_488 = NULL;
  2712. do {
  2713. $_486 = NULL;
  2714. do {
  2715. $res_479 = $result;
  2716. $pos_479 = $this->pos;
  2717. if (( $subres = $this->literal( 'cached' ) ) !== FALSE) {
  2718. $result["text"] .= $subres;
  2719. $_486 = TRUE; break;
  2720. }
  2721. $result = $res_479;
  2722. $this->pos = $pos_479;
  2723. $_484 = NULL;
  2724. do {
  2725. $res_481 = $result;
  2726. $pos_481 = $this->pos;
  2727. if (( $subres = $this->literal( 'uncached' ) ) !== FALSE) {
  2728. $result["text"] .= $subres;
  2729. $_484 = TRUE; break;
  2730. }
  2731. $result = $res_481;
  2732. $this->pos = $pos_481;
  2733. if (( $subres = $this->literal( 'cacheblock' ) ) !== FALSE) {
  2734. $result["text"] .= $subres;
  2735. $_484 = TRUE; break;
  2736. }
  2737. $result = $res_481;
  2738. $this->pos = $pos_481;
  2739. $_484 = FALSE; break;
  2740. }
  2741. while(0);
  2742. if( $_484 === TRUE ) { $_486 = TRUE; break; }
  2743. $result = $res_479;
  2744. $this->pos = $pos_479;
  2745. $_486 = FALSE; break;
  2746. }
  2747. while(0);
  2748. if( $_486 === FALSE) { $_488 = FALSE; break; }
  2749. $_488 = TRUE; break;
  2750. }
  2751. while(0);
  2752. if( $_488 === FALSE) { $_492 = FALSE; break; }
  2753. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2754. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  2755. else { $_492 = FALSE; break; }
  2756. $_492 = TRUE; break;
  2757. }
  2758. while(0);
  2759. if( $_492 === TRUE ) { return $this->finalise($result); }
  2760. if( $_492 === FALSE) { return FALSE; }
  2761. }
  2762. function CacheBlock__construct(&$res){
  2763. $res['subblocks'] = 0;
  2764. }
  2765. function CacheBlock_CacheBlockArguments(&$res, $sub){
  2766. $res['key'] = !empty($sub['php']) ? $sub['php'] : '';
  2767. }
  2768. function CacheBlock_Condition(&$res, $sub){
  2769. $res['condition'] = ($res['Conditional']['text'] == 'if' ? '(' : '!(') . $sub['php'] . ') && ';
  2770. }
  2771. function CacheBlock_CacheBlock(&$res, $sub){
  2772. $res['php'] .= $sub['php'];
  2773. }
  2774. function CacheBlock_UncachedBlock(&$res, $sub){
  2775. $res['php'] .= $sub['php'];
  2776. }
  2777. function CacheBlock_CacheBlockTemplate(&$res, $sub){
  2778. // Get the block counter
  2779. $block = ++$res['subblocks'];
  2780. // Build the key for this block from the global key (evaluated in a closure within the template),
  2781. // the passed cache key, the block index, and the sha hash of the template.
  2782. $res['php'] .= '$keyExpression = function() use ($scope, $cache) {' . PHP_EOL;
  2783. $res['php'] .= '$val = \'\';' . PHP_EOL;
  2784. if($globalKey = Config::inst()->get('SSViewer', 'global_key')) {
  2785. // Embed the code necessary to evaluate the globalKey directly into the template,
  2786. // so that SSTemplateParser only needs to be called during template regeneration.
  2787. // Warning: If the global key is changed, it's necessary to flush the template cache.
  2788. $parser = Injector::inst()->get('SSTemplateParser', false);
  2789. $result = $parser->compileString($globalKey, '', false, false);
  2790. if(!$result) throw new SSTemplateParseException('Unexpected problem parsing template', $parser);
  2791. $res['php'] .= $result . PHP_EOL;
  2792. }
  2793. $res['php'] .= 'return $val;' . PHP_EOL;
  2794. $res['php'] .= '};' . PHP_EOL;
  2795. $key = 'sha1($keyExpression())' // Global key
  2796. . '.\'_' . sha1($sub['php']) // sha of template
  2797. . (isset($res['key']) && $res['key'] ? "_'.sha1(".$res['key'].")" : "'") // Passed key
  2798. . ".'_$block'"; // block index
  2799. // Get any condition
  2800. $condition = isset($res['condition']) ? $res['condition'] : '';
  2801. $res['php'] .= 'if ('.$condition.'($partial = $cache->load('.$key.'))) $val .= $partial;' . PHP_EOL;
  2802. $res['php'] .= 'else { $oldval = $val; $val = "";' . PHP_EOL;
  2803. $res['php'] .= $sub['php'] . PHP_EOL;
  2804. $res['php'] .= $condition . ' $cache->save($val); $val = $oldval . $val;' . PHP_EOL;
  2805. $res['php'] .= '}';
  2806. }
  2807. /* OldTPart: "_t" N "(" N QuotedString (N "," N CallArguments)? N ")" N (";")? */
  2808. protected $match_OldTPart_typestack = array('OldTPart');
  2809. function match_OldTPart ($stack = array()) {
  2810. $matchrule = "OldTPart"; $result = $this->construct($matchrule, $matchrule, null);
  2811. $_511 = NULL;
  2812. do {
  2813. if (( $subres = $this->literal( '_t' ) ) !== FALSE) { $result["text"] .= $subres; }
  2814. else { $_511 = FALSE; break; }
  2815. $matcher = 'match_'.'N'; $key = $matcher; $pos = $this->pos;
  2816. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2817. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2818. else { $_511 = FALSE; break; }
  2819. if (substr($this->string,$this->pos,1) == '(') {
  2820. $this->pos += 1;
  2821. $result["text"] .= '(';
  2822. }
  2823. else { $_511 = FALSE; break; }
  2824. $matcher = 'match_'.'N'; $key = $matcher; $pos = $this->pos;
  2825. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2826. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2827. else { $_511 = FALSE; break; }
  2828. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  2829. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2830. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2831. else { $_511 = FALSE; break; }
  2832. $res_504 = $result;
  2833. $pos_504 = $this->pos;
  2834. $_503 = NULL;
  2835. do {
  2836. $matcher = 'match_'.'N'; $key = $matcher; $pos = $this->pos;
  2837. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2838. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2839. else { $_503 = FALSE; break; }
  2840. if (substr($this->string,$this->pos,1) == ',') {
  2841. $this->pos += 1;
  2842. $result["text"] .= ',';
  2843. }
  2844. else { $_503 = FALSE; break; }
  2845. $matcher = 'match_'.'N'; $key = $matcher; $pos = $this->pos;
  2846. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2847. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2848. else { $_503 = FALSE; break; }
  2849. $matcher = 'match_'.'CallArguments'; $key = $matcher; $pos = $this->pos;
  2850. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2851. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2852. else { $_503 = FALSE; break; }
  2853. $_503 = TRUE; break;
  2854. }
  2855. while(0);
  2856. if( $_503 === FALSE) {
  2857. $result = $res_504;
  2858. $this->pos = $pos_504;
  2859. unset( $res_504 );
  2860. unset( $pos_504 );
  2861. }
  2862. $matcher = 'match_'.'N'; $key = $matcher; $pos = $this->pos;
  2863. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2864. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2865. else { $_511 = FALSE; break; }
  2866. if (substr($this->string,$this->pos,1) == ')') {
  2867. $this->pos += 1;
  2868. $result["text"] .= ')';
  2869. }
  2870. else { $_511 = FALSE; break; }
  2871. $matcher = 'match_'.'N'; $key = $matcher; $pos = $this->pos;
  2872. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2873. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2874. else { $_511 = FALSE; break; }
  2875. $res_510 = $result;
  2876. $pos_510 = $this->pos;
  2877. $_509 = NULL;
  2878. do {
  2879. if (substr($this->string,$this->pos,1) == ';') {
  2880. $this->pos += 1;
  2881. $result["text"] .= ';';
  2882. }
  2883. else { $_509 = FALSE; break; }
  2884. $_509 = TRUE; break;
  2885. }
  2886. while(0);
  2887. if( $_509 === FALSE) {
  2888. $result = $res_510;
  2889. $this->pos = $pos_510;
  2890. unset( $res_510 );
  2891. unset( $pos_510 );
  2892. }
  2893. $_511 = TRUE; break;
  2894. }
  2895. while(0);
  2896. if( $_511 === TRUE ) { return $this->finalise($result); }
  2897. if( $_511 === FALSE) { return FALSE; }
  2898. }
  2899. /* N: / [\s\n]* / */
  2900. protected $match_N_typestack = array('N');
  2901. function match_N ($stack = array()) {
  2902. $matchrule = "N"; $result = $this->construct($matchrule, $matchrule, null);
  2903. if (( $subres = $this->rx( '/ [\s\n]* /' ) ) !== FALSE) {
  2904. $result["text"] .= $subres;
  2905. return $this->finalise($result);
  2906. }
  2907. else { return FALSE; }
  2908. }
  2909. function OldTPart__construct(&$res) {
  2910. $res['php'] = "_t(";
  2911. }
  2912. function OldTPart_QuotedString(&$res, $sub) {
  2913. $entity = $sub['String']['text'];
  2914. if (strpos($entity, '.') === false) {
  2915. $res['php'] .= "\$scope->XML_val('I18NNamespace').'.$entity'";
  2916. }
  2917. else {
  2918. $res['php'] .= "'$entity'";
  2919. }
  2920. }
  2921. function OldTPart_CallArguments(&$res, $sub) {
  2922. $res['php'] .= ',' . $sub['php'];
  2923. }
  2924. function OldTPart__finalise(&$res) {
  2925. $res['php'] .= ')';
  2926. }
  2927. /* OldTTag: "<%" < OldTPart > "%>" */
  2928. protected $match_OldTTag_typestack = array('OldTTag');
  2929. function match_OldTTag ($stack = array()) {
  2930. $matchrule = "OldTTag"; $result = $this->construct($matchrule, $matchrule, null);
  2931. $_519 = NULL;
  2932. do {
  2933. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  2934. else { $_519 = FALSE; break; }
  2935. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2936. $matcher = 'match_'.'OldTPart'; $key = $matcher; $pos = $this->pos;
  2937. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2938. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2939. else { $_519 = FALSE; break; }
  2940. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2941. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  2942. else { $_519 = FALSE; break; }
  2943. $_519 = TRUE; break;
  2944. }
  2945. while(0);
  2946. if( $_519 === TRUE ) { return $this->finalise($result); }
  2947. if( $_519 === FALSE) { return FALSE; }
  2948. }
  2949. function OldTTag_OldTPart(&$res, $sub) {
  2950. $res['php'] = $sub['php'];
  2951. }
  2952. /* OldSprintfTag: "<%" < "sprintf" < "(" < OldTPart < "," < CallArguments > ")" > "%>" */
  2953. protected $match_OldSprintfTag_typestack = array('OldSprintfTag');
  2954. function match_OldSprintfTag ($stack = array()) {
  2955. $matchrule = "OldSprintfTag"; $result = $this->construct($matchrule, $matchrule, null);
  2956. $_536 = NULL;
  2957. do {
  2958. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  2959. else { $_536 = FALSE; break; }
  2960. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2961. if (( $subres = $this->literal( 'sprintf' ) ) !== FALSE) { $result["text"] .= $subres; }
  2962. else { $_536 = FALSE; break; }
  2963. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2964. if (substr($this->string,$this->pos,1) == '(') {
  2965. $this->pos += 1;
  2966. $result["text"] .= '(';
  2967. }
  2968. else { $_536 = FALSE; break; }
  2969. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2970. $matcher = 'match_'.'OldTPart'; $key = $matcher; $pos = $this->pos;
  2971. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2972. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2973. else { $_536 = FALSE; break; }
  2974. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2975. if (substr($this->string,$this->pos,1) == ',') {
  2976. $this->pos += 1;
  2977. $result["text"] .= ',';
  2978. }
  2979. else { $_536 = FALSE; break; }
  2980. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2981. $matcher = 'match_'.'CallArguments'; $key = $matcher; $pos = $this->pos;
  2982. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  2983. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  2984. else { $_536 = FALSE; break; }
  2985. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2986. if (substr($this->string,$this->pos,1) == ')') {
  2987. $this->pos += 1;
  2988. $result["text"] .= ')';
  2989. }
  2990. else { $_536 = FALSE; break; }
  2991. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  2992. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  2993. else { $_536 = FALSE; break; }
  2994. $_536 = TRUE; break;
  2995. }
  2996. while(0);
  2997. if( $_536 === TRUE ) { return $this->finalise($result); }
  2998. if( $_536 === FALSE) { return FALSE; }
  2999. }
  3000. function OldSprintfTag__construct(&$res) {
  3001. $res['php'] = "sprintf(";
  3002. }
  3003. function OldSprintfTag_OldTPart(&$res, $sub) {
  3004. $res['php'] .= $sub['php'];
  3005. }
  3006. function OldSprintfTag_CallArguments(&$res, $sub) {
  3007. $res['php'] .= ',' . $sub['php'] . ')';
  3008. }
  3009. /* OldI18NTag: OldSprintfTag | OldTTag */
  3010. protected $match_OldI18NTag_typestack = array('OldI18NTag');
  3011. function match_OldI18NTag ($stack = array()) {
  3012. $matchrule = "OldI18NTag"; $result = $this->construct($matchrule, $matchrule, null);
  3013. $_541 = NULL;
  3014. do {
  3015. $res_538 = $result;
  3016. $pos_538 = $this->pos;
  3017. $matcher = 'match_'.'OldSprintfTag'; $key = $matcher; $pos = $this->pos;
  3018. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3019. if ($subres !== FALSE) {
  3020. $this->store( $result, $subres );
  3021. $_541 = TRUE; break;
  3022. }
  3023. $result = $res_538;
  3024. $this->pos = $pos_538;
  3025. $matcher = 'match_'.'OldTTag'; $key = $matcher; $pos = $this->pos;
  3026. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3027. if ($subres !== FALSE) {
  3028. $this->store( $result, $subres );
  3029. $_541 = TRUE; break;
  3030. }
  3031. $result = $res_538;
  3032. $this->pos = $pos_538;
  3033. $_541 = FALSE; break;
  3034. }
  3035. while(0);
  3036. if( $_541 === TRUE ) { return $this->finalise($result); }
  3037. if( $_541 === FALSE) { return FALSE; }
  3038. }
  3039. function OldI18NTag_STR(&$res, $sub) {
  3040. $res['php'] = '$val .= ' . $sub['php'] . ';';
  3041. }
  3042. /* NamedArgument: Name:Word "=" Value:Argument */
  3043. protected $match_NamedArgument_typestack = array('NamedArgument');
  3044. function match_NamedArgument ($stack = array()) {
  3045. $matchrule = "NamedArgument"; $result = $this->construct($matchrule, $matchrule, null);
  3046. $_546 = NULL;
  3047. do {
  3048. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  3049. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3050. if ($subres !== FALSE) {
  3051. $this->store( $result, $subres, "Name" );
  3052. }
  3053. else { $_546 = FALSE; break; }
  3054. if (substr($this->string,$this->pos,1) == '=') {
  3055. $this->pos += 1;
  3056. $result["text"] .= '=';
  3057. }
  3058. else { $_546 = FALSE; break; }
  3059. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  3060. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3061. if ($subres !== FALSE) {
  3062. $this->store( $result, $subres, "Value" );
  3063. }
  3064. else { $_546 = FALSE; break; }
  3065. $_546 = TRUE; break;
  3066. }
  3067. while(0);
  3068. if( $_546 === TRUE ) { return $this->finalise($result); }
  3069. if( $_546 === FALSE) { return FALSE; }
  3070. }
  3071. function NamedArgument_Name(&$res, $sub) {
  3072. $res['php'] = "'" . $sub['text'] . "' => ";
  3073. }
  3074. function NamedArgument_Value(&$res, $sub) {
  3075. switch($sub['ArgumentMode']) {
  3076. case 'string':
  3077. $res['php'] .= $sub['php'];
  3078. break;
  3079. case 'default':
  3080. $res['php'] .= $sub['string_php'];
  3081. break;
  3082. default:
  3083. $res['php'] .= str_replace('$$FINAL', 'obj', $sub['php']) . '->self()';
  3084. break;
  3085. }
  3086. }
  3087. /* Include: "<%" < "include" < Template:NamespacedWord < (NamedArgument ( < "," < NamedArgument )*)? > "%>" */
  3088. protected $match_Include_typestack = array('Include');
  3089. function match_Include ($stack = array()) {
  3090. $matchrule = "Include"; $result = $this->construct($matchrule, $matchrule, null);
  3091. $_565 = NULL;
  3092. do {
  3093. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  3094. else { $_565 = FALSE; break; }
  3095. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3096. if (( $subres = $this->literal( 'include' ) ) !== FALSE) { $result["text"] .= $subres; }
  3097. else { $_565 = FALSE; break; }
  3098. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3099. $matcher = 'match_'.'NamespacedWord'; $key = $matcher; $pos = $this->pos;
  3100. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3101. if ($subres !== FALSE) {
  3102. $this->store( $result, $subres, "Template" );
  3103. }
  3104. else { $_565 = FALSE; break; }
  3105. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3106. $res_562 = $result;
  3107. $pos_562 = $this->pos;
  3108. $_561 = NULL;
  3109. do {
  3110. $matcher = 'match_'.'NamedArgument'; $key = $matcher; $pos = $this->pos;
  3111. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3112. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  3113. else { $_561 = FALSE; break; }
  3114. while (true) {
  3115. $res_560 = $result;
  3116. $pos_560 = $this->pos;
  3117. $_559 = NULL;
  3118. do {
  3119. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3120. if (substr($this->string,$this->pos,1) == ',') {
  3121. $this->pos += 1;
  3122. $result["text"] .= ',';
  3123. }
  3124. else { $_559 = FALSE; break; }
  3125. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3126. $matcher = 'match_'.'NamedArgument'; $key = $matcher; $pos = $this->pos;
  3127. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3128. if ($subres !== FALSE) {
  3129. $this->store( $result, $subres );
  3130. }
  3131. else { $_559 = FALSE; break; }
  3132. $_559 = TRUE; break;
  3133. }
  3134. while(0);
  3135. if( $_559 === FALSE) {
  3136. $result = $res_560;
  3137. $this->pos = $pos_560;
  3138. unset( $res_560 );
  3139. unset( $pos_560 );
  3140. break;
  3141. }
  3142. }
  3143. $_561 = TRUE; break;
  3144. }
  3145. while(0);
  3146. if( $_561 === FALSE) {
  3147. $result = $res_562;
  3148. $this->pos = $pos_562;
  3149. unset( $res_562 );
  3150. unset( $pos_562 );
  3151. }
  3152. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3153. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  3154. else { $_565 = FALSE; break; }
  3155. $_565 = TRUE; break;
  3156. }
  3157. while(0);
  3158. if( $_565 === TRUE ) { return $this->finalise($result); }
  3159. if( $_565 === FALSE) { return FALSE; }
  3160. }
  3161. function Include__construct(&$res){
  3162. $res['arguments'] = array();
  3163. }
  3164. function Include_Template(&$res, $sub){
  3165. $res['template'] = "'" . $sub['text'] . "'";
  3166. }
  3167. function Include_NamedArgument(&$res, $sub){
  3168. $res['arguments'][] = $sub['php'];
  3169. }
  3170. function Include__finalise(&$res){
  3171. $template = $res['template'];
  3172. $arguments = $res['arguments'];
  3173. $res['php'] = '$val .= SSViewer::execute_template(["type" => "Includes", '.$template.'], $scope->getItem(), array(' .
  3174. implode(',', $arguments)."), \$scope);\n";
  3175. if($this->includeDebuggingComments) { // Add include filename comments on dev sites
  3176. $res['php'] =
  3177. '$val .= \'<!-- include '.addslashes($template).' -->\';'. "\n".
  3178. $res['php'].
  3179. '$val .= \'<!-- end include '.addslashes($template).' -->\';'. "\n";
  3180. }
  3181. }
  3182. /* BlockArguments: :Argument ( < "," < :Argument)* */
  3183. protected $match_BlockArguments_typestack = array('BlockArguments');
  3184. function match_BlockArguments ($stack = array()) {
  3185. $matchrule = "BlockArguments"; $result = $this->construct($matchrule, $matchrule, null);
  3186. $_574 = NULL;
  3187. do {
  3188. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  3189. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3190. if ($subres !== FALSE) {
  3191. $this->store( $result, $subres, "Argument" );
  3192. }
  3193. else { $_574 = FALSE; break; }
  3194. while (true) {
  3195. $res_573 = $result;
  3196. $pos_573 = $this->pos;
  3197. $_572 = NULL;
  3198. do {
  3199. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3200. if (substr($this->string,$this->pos,1) == ',') {
  3201. $this->pos += 1;
  3202. $result["text"] .= ',';
  3203. }
  3204. else { $_572 = FALSE; break; }
  3205. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3206. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  3207. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3208. if ($subres !== FALSE) {
  3209. $this->store( $result, $subres, "Argument" );
  3210. }
  3211. else { $_572 = FALSE; break; }
  3212. $_572 = TRUE; break;
  3213. }
  3214. while(0);
  3215. if( $_572 === FALSE) {
  3216. $result = $res_573;
  3217. $this->pos = $pos_573;
  3218. unset( $res_573 );
  3219. unset( $pos_573 );
  3220. break;
  3221. }
  3222. }
  3223. $_574 = TRUE; break;
  3224. }
  3225. while(0);
  3226. if( $_574 === TRUE ) { return $this->finalise($result); }
  3227. if( $_574 === FALSE) { return FALSE; }
  3228. }
  3229. /* NotBlockTag: "end_" | (("if" | "else_if" | "else" | "require" | "cached" | "uncached" | "cacheblock" | "include")]) */
  3230. protected $match_NotBlockTag_typestack = array('NotBlockTag');
  3231. function match_NotBlockTag ($stack = array()) {
  3232. $matchrule = "NotBlockTag"; $result = $this->construct($matchrule, $matchrule, null);
  3233. $_612 = NULL;
  3234. do {
  3235. $res_576 = $result;
  3236. $pos_576 = $this->pos;
  3237. if (( $subres = $this->literal( 'end_' ) ) !== FALSE) {
  3238. $result["text"] .= $subres;
  3239. $_612 = TRUE; break;
  3240. }
  3241. $result = $res_576;
  3242. $this->pos = $pos_576;
  3243. $_610 = NULL;
  3244. do {
  3245. $_607 = NULL;
  3246. do {
  3247. $_605 = NULL;
  3248. do {
  3249. $res_578 = $result;
  3250. $pos_578 = $this->pos;
  3251. if (( $subres = $this->literal( 'if' ) ) !== FALSE) {
  3252. $result["text"] .= $subres;
  3253. $_605 = TRUE; break;
  3254. }
  3255. $result = $res_578;
  3256. $this->pos = $pos_578;
  3257. $_603 = NULL;
  3258. do {
  3259. $res_580 = $result;
  3260. $pos_580 = $this->pos;
  3261. if (( $subres = $this->literal( 'else_if' ) ) !== FALSE) {
  3262. $result["text"] .= $subres;
  3263. $_603 = TRUE; break;
  3264. }
  3265. $result = $res_580;
  3266. $this->pos = $pos_580;
  3267. $_601 = NULL;
  3268. do {
  3269. $res_582 = $result;
  3270. $pos_582 = $this->pos;
  3271. if (( $subres = $this->literal( 'else' ) ) !== FALSE) {
  3272. $result["text"] .= $subres;
  3273. $_601 = TRUE; break;
  3274. }
  3275. $result = $res_582;
  3276. $this->pos = $pos_582;
  3277. $_599 = NULL;
  3278. do {
  3279. $res_584 = $result;
  3280. $pos_584 = $this->pos;
  3281. if (( $subres = $this->literal( 'require' ) ) !== FALSE) {
  3282. $result["text"] .= $subres;
  3283. $_599 = TRUE; break;
  3284. }
  3285. $result = $res_584;
  3286. $this->pos = $pos_584;
  3287. $_597 = NULL;
  3288. do {
  3289. $res_586 = $result;
  3290. $pos_586 = $this->pos;
  3291. if (( $subres = $this->literal( 'cached' ) ) !== FALSE) {
  3292. $result["text"] .= $subres;
  3293. $_597 = TRUE; break;
  3294. }
  3295. $result = $res_586;
  3296. $this->pos = $pos_586;
  3297. $_595 = NULL;
  3298. do {
  3299. $res_588 = $result;
  3300. $pos_588 = $this->pos;
  3301. if (( $subres = $this->literal( 'uncached' ) ) !== FALSE) {
  3302. $result["text"] .= $subres;
  3303. $_595 = TRUE; break;
  3304. }
  3305. $result = $res_588;
  3306. $this->pos = $pos_588;
  3307. $_593 = NULL;
  3308. do {
  3309. $res_590 = $result;
  3310. $pos_590 = $this->pos;
  3311. if (( $subres = $this->literal( 'cacheblock' ) ) !== FALSE) {
  3312. $result["text"] .= $subres;
  3313. $_593 = TRUE; break;
  3314. }
  3315. $result = $res_590;
  3316. $this->pos = $pos_590;
  3317. if (( $subres = $this->literal( 'include' ) ) !== FALSE) {
  3318. $result["text"] .= $subres;
  3319. $_593 = TRUE; break;
  3320. }
  3321. $result = $res_590;
  3322. $this->pos = $pos_590;
  3323. $_593 = FALSE; break;
  3324. }
  3325. while(0);
  3326. if( $_593 === TRUE ) { $_595 = TRUE; break; }
  3327. $result = $res_588;
  3328. $this->pos = $pos_588;
  3329. $_595 = FALSE; break;
  3330. }
  3331. while(0);
  3332. if( $_595 === TRUE ) { $_597 = TRUE; break; }
  3333. $result = $res_586;
  3334. $this->pos = $pos_586;
  3335. $_597 = FALSE; break;
  3336. }
  3337. while(0);
  3338. if( $_597 === TRUE ) { $_599 = TRUE; break; }
  3339. $result = $res_584;
  3340. $this->pos = $pos_584;
  3341. $_599 = FALSE; break;
  3342. }
  3343. while(0);
  3344. if( $_599 === TRUE ) { $_601 = TRUE; break; }
  3345. $result = $res_582;
  3346. $this->pos = $pos_582;
  3347. $_601 = FALSE; break;
  3348. }
  3349. while(0);
  3350. if( $_601 === TRUE ) { $_603 = TRUE; break; }
  3351. $result = $res_580;
  3352. $this->pos = $pos_580;
  3353. $_603 = FALSE; break;
  3354. }
  3355. while(0);
  3356. if( $_603 === TRUE ) { $_605 = TRUE; break; }
  3357. $result = $res_578;
  3358. $this->pos = $pos_578;
  3359. $_605 = FALSE; break;
  3360. }
  3361. while(0);
  3362. if( $_605 === FALSE) { $_607 = FALSE; break; }
  3363. $_607 = TRUE; break;
  3364. }
  3365. while(0);
  3366. if( $_607 === FALSE) { $_610 = FALSE; break; }
  3367. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3368. else { $_610 = FALSE; break; }
  3369. $_610 = TRUE; break;
  3370. }
  3371. while(0);
  3372. if( $_610 === TRUE ) { $_612 = TRUE; break; }
  3373. $result = $res_576;
  3374. $this->pos = $pos_576;
  3375. $_612 = FALSE; break;
  3376. }
  3377. while(0);
  3378. if( $_612 === TRUE ) { return $this->finalise($result); }
  3379. if( $_612 === FALSE) { return FALSE; }
  3380. }
  3381. /* ClosedBlock: '<%' < !NotBlockTag BlockName:Word ( [ :BlockArguments ] )? > Zap:'%>' Template:$TemplateMatcher?
  3382. '<%' < 'end_' '$BlockName' > '%>' */
  3383. protected $match_ClosedBlock_typestack = array('ClosedBlock');
  3384. function match_ClosedBlock ($stack = array()) {
  3385. $matchrule = "ClosedBlock"; $result = $this->construct($matchrule, $matchrule, null);
  3386. $_632 = NULL;
  3387. do {
  3388. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  3389. else { $_632 = FALSE; break; }
  3390. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3391. $res_616 = $result;
  3392. $pos_616 = $this->pos;
  3393. $matcher = 'match_'.'NotBlockTag'; $key = $matcher; $pos = $this->pos;
  3394. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3395. if ($subres !== FALSE) {
  3396. $this->store( $result, $subres );
  3397. $result = $res_616;
  3398. $this->pos = $pos_616;
  3399. $_632 = FALSE; break;
  3400. }
  3401. else {
  3402. $result = $res_616;
  3403. $this->pos = $pos_616;
  3404. }
  3405. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  3406. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3407. if ($subres !== FALSE) {
  3408. $this->store( $result, $subres, "BlockName" );
  3409. }
  3410. else { $_632 = FALSE; break; }
  3411. $res_622 = $result;
  3412. $pos_622 = $this->pos;
  3413. $_621 = NULL;
  3414. do {
  3415. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3416. else { $_621 = FALSE; break; }
  3417. $matcher = 'match_'.'BlockArguments'; $key = $matcher; $pos = $this->pos;
  3418. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3419. if ($subres !== FALSE) {
  3420. $this->store( $result, $subres, "BlockArguments" );
  3421. }
  3422. else { $_621 = FALSE; break; }
  3423. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3424. else { $_621 = FALSE; break; }
  3425. $_621 = TRUE; break;
  3426. }
  3427. while(0);
  3428. if( $_621 === FALSE) {
  3429. $result = $res_622;
  3430. $this->pos = $pos_622;
  3431. unset( $res_622 );
  3432. unset( $pos_622 );
  3433. }
  3434. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3435. $stack[] = $result; $result = $this->construct( $matchrule, "Zap" );
  3436. if (( $subres = $this->literal( '%>' ) ) !== FALSE) {
  3437. $result["text"] .= $subres;
  3438. $subres = $result; $result = array_pop($stack);
  3439. $this->store( $result, $subres, 'Zap' );
  3440. }
  3441. else {
  3442. $result = array_pop($stack);
  3443. $_632 = FALSE; break;
  3444. }
  3445. $res_625 = $result;
  3446. $pos_625 = $this->pos;
  3447. $matcher = 'match_'.$this->expression($result, $stack, 'TemplateMatcher'); $key = $matcher; $pos = $this->pos;
  3448. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3449. if ($subres !== FALSE) {
  3450. $this->store( $result, $subres, "Template" );
  3451. }
  3452. else {
  3453. $result = $res_625;
  3454. $this->pos = $pos_625;
  3455. unset( $res_625 );
  3456. unset( $pos_625 );
  3457. }
  3458. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  3459. else { $_632 = FALSE; break; }
  3460. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3461. if (( $subres = $this->literal( 'end_' ) ) !== FALSE) { $result["text"] .= $subres; }
  3462. else { $_632 = FALSE; break; }
  3463. if (( $subres = $this->literal( ''.$this->expression($result, $stack, 'BlockName').'' ) ) !== FALSE) { $result["text"] .= $subres; }
  3464. else { $_632 = FALSE; break; }
  3465. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3466. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  3467. else { $_632 = FALSE; break; }
  3468. $_632 = TRUE; break;
  3469. }
  3470. while(0);
  3471. if( $_632 === TRUE ) { return $this->finalise($result); }
  3472. if( $_632 === FALSE) { return FALSE; }
  3473. }
  3474. /**
  3475. * As mentioned in the parser comment, block handling is kept fairly generic for extensibility. The match rule
  3476. * builds up two important elements in the match result array:
  3477. * 'ArgumentCount' - how many arguments were passed in the opening tag
  3478. * 'Arguments' an array of the Argument match rule result arrays
  3479. *
  3480. * Once a block has successfully been matched against, it will then look for the actual handler, which should
  3481. * be on this class (either defined or extended on) as ClosedBlock_Handler_Name(&$res), where Name is the
  3482. * tag name, first letter captialized (i.e Control, Loop, With, etc).
  3483. *
  3484. * This function will be called with the match rule result array as it's first argument. It should return
  3485. * the php result of this block as it's return value, or throw an error if incorrect arguments were passed.
  3486. */
  3487. function ClosedBlock__construct(&$res) {
  3488. $res['ArgumentCount'] = 0;
  3489. }
  3490. function ClosedBlock_BlockArguments(&$res, $sub) {
  3491. if (isset($sub['Argument']['ArgumentMode'])) {
  3492. $res['Arguments'] = array($sub['Argument']);
  3493. $res['ArgumentCount'] = 1;
  3494. }
  3495. else {
  3496. $res['Arguments'] = $sub['Argument'];
  3497. $res['ArgumentCount'] = count($res['Arguments']);
  3498. }
  3499. }
  3500. function ClosedBlock__finalise(&$res) {
  3501. $blockname = $res['BlockName']['text'];
  3502. $method = 'ClosedBlock_Handle_'.$blockname;
  3503. if (method_exists($this, $method)) {
  3504. $res['php'] = $this->$method($res);
  3505. } else if (isset($this->closedBlocks[$blockname])) {
  3506. $res['php'] = call_user_func($this->closedBlocks[$blockname], $res);
  3507. } else {
  3508. throw new SSTemplateParseException('Unknown closed block "'.$blockname.'" encountered. Perhaps you are ' .
  3509. 'not supposed to close this block, or have mis-spelled it?', $this);
  3510. }
  3511. }
  3512. /**
  3513. * This is an example of a block handler function. This one handles the loop tag.
  3514. */
  3515. function ClosedBlock_Handle_Loop(&$res) {
  3516. if ($res['ArgumentCount'] > 1) {
  3517. throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one ' .
  3518. 'argument only.', $this);
  3519. }
  3520. //loop without arguments loops on the current scope
  3521. if ($res['ArgumentCount'] == 0) {
  3522. $on = '$scope->obj(\'Up\', null)->obj(\'Foo\', null)';
  3523. } else { //loop in the normal way
  3524. $arg = $res['Arguments'][0];
  3525. if ($arg['ArgumentMode'] == 'string') {
  3526. throw new SSTemplateParseException('Control block cant take string as argument.', $this);
  3527. }
  3528. $on = str_replace('$$FINAL', 'obj',
  3529. ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']);
  3530. }
  3531. return
  3532. $on . '; $scope->pushScope(); while (($key = $scope->next()) !== false) {' . PHP_EOL .
  3533. $res['Template']['php'] . PHP_EOL .
  3534. '}; $scope->popScope(); ';
  3535. }
  3536. /**
  3537. * The closed block handler for with blocks
  3538. */
  3539. function ClosedBlock_Handle_With(&$res) {
  3540. if ($res['ArgumentCount'] != 1) {
  3541. throw new SSTemplateParseException('Either no or too many arguments in with block. Must be one ' .
  3542. 'argument only.', $this);
  3543. }
  3544. $arg = $res['Arguments'][0];
  3545. if ($arg['ArgumentMode'] == 'string') {
  3546. throw new SSTemplateParseException('Control block cant take string as argument.', $this);
  3547. }
  3548. $on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']);
  3549. return
  3550. $on . '; $scope->pushScope();' . PHP_EOL .
  3551. $res['Template']['php'] . PHP_EOL .
  3552. '; $scope->popScope(); ';
  3553. }
  3554. /* OpenBlock: '<%' < !NotBlockTag BlockName:Word ( [ :BlockArguments ] )? > '%>' */
  3555. protected $match_OpenBlock_typestack = array('OpenBlock');
  3556. function match_OpenBlock ($stack = array()) {
  3557. $matchrule = "OpenBlock"; $result = $this->construct($matchrule, $matchrule, null);
  3558. $_645 = NULL;
  3559. do {
  3560. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  3561. else { $_645 = FALSE; break; }
  3562. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3563. $res_636 = $result;
  3564. $pos_636 = $this->pos;
  3565. $matcher = 'match_'.'NotBlockTag'; $key = $matcher; $pos = $this->pos;
  3566. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3567. if ($subres !== FALSE) {
  3568. $this->store( $result, $subres );
  3569. $result = $res_636;
  3570. $this->pos = $pos_636;
  3571. $_645 = FALSE; break;
  3572. }
  3573. else {
  3574. $result = $res_636;
  3575. $this->pos = $pos_636;
  3576. }
  3577. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  3578. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3579. if ($subres !== FALSE) {
  3580. $this->store( $result, $subres, "BlockName" );
  3581. }
  3582. else { $_645 = FALSE; break; }
  3583. $res_642 = $result;
  3584. $pos_642 = $this->pos;
  3585. $_641 = NULL;
  3586. do {
  3587. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3588. else { $_641 = FALSE; break; }
  3589. $matcher = 'match_'.'BlockArguments'; $key = $matcher; $pos = $this->pos;
  3590. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3591. if ($subres !== FALSE) {
  3592. $this->store( $result, $subres, "BlockArguments" );
  3593. }
  3594. else { $_641 = FALSE; break; }
  3595. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3596. else { $_641 = FALSE; break; }
  3597. $_641 = TRUE; break;
  3598. }
  3599. while(0);
  3600. if( $_641 === FALSE) {
  3601. $result = $res_642;
  3602. $this->pos = $pos_642;
  3603. unset( $res_642 );
  3604. unset( $pos_642 );
  3605. }
  3606. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3607. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  3608. else { $_645 = FALSE; break; }
  3609. $_645 = TRUE; break;
  3610. }
  3611. while(0);
  3612. if( $_645 === TRUE ) { return $this->finalise($result); }
  3613. if( $_645 === FALSE) { return FALSE; }
  3614. }
  3615. function OpenBlock__construct(&$res) {
  3616. $res['ArgumentCount'] = 0;
  3617. }
  3618. function OpenBlock_BlockArguments(&$res, $sub) {
  3619. if (isset($sub['Argument']['ArgumentMode'])) {
  3620. $res['Arguments'] = array($sub['Argument']);
  3621. $res['ArgumentCount'] = 1;
  3622. }
  3623. else {
  3624. $res['Arguments'] = $sub['Argument'];
  3625. $res['ArgumentCount'] = count($res['Arguments']);
  3626. }
  3627. }
  3628. function OpenBlock__finalise(&$res) {
  3629. $blockname = $res['BlockName']['text'];
  3630. $method = 'OpenBlock_Handle_'.$blockname;
  3631. if (method_exists($this, $method)) {
  3632. $res['php'] = $this->$method($res);
  3633. } elseif (isset($this->openBlocks[$blockname])) {
  3634. $res['php'] = call_user_func($this->openBlocks[$blockname], $res);
  3635. } else {
  3636. throw new SSTemplateParseException('Unknown open block "'.$blockname.'" encountered. Perhaps you missed ' .
  3637. ' the closing tag or have mis-spelled it?', $this);
  3638. }
  3639. }
  3640. /**
  3641. * This is an open block handler, for the <% debug %> utility tag
  3642. */
  3643. function OpenBlock_Handle_Debug(&$res) {
  3644. if ($res['ArgumentCount'] == 0) return '$scope->debug();';
  3645. else if ($res['ArgumentCount'] == 1) {
  3646. $arg = $res['Arguments'][0];
  3647. if ($arg['ArgumentMode'] == 'string') return 'Debug::show('.$arg['php'].');';
  3648. $php = ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php'];
  3649. return '$val .= Debug::show('.str_replace('FINALGET!', 'cachedCall', $php).');';
  3650. }
  3651. else {
  3652. throw new SSTemplateParseException('Debug takes 0 or 1 argument only.', $this);
  3653. }
  3654. }
  3655. /**
  3656. * This is an open block handler, for the <% base_tag %> tag
  3657. */
  3658. function OpenBlock_Handle_Base_tag(&$res) {
  3659. if ($res['ArgumentCount'] != 0) throw new SSTemplateParseException('Base_tag takes no arguments', $this);
  3660. return '$val .= SSViewer::get_base_tag($val);';
  3661. }
  3662. /**
  3663. * This is an open block handler, for the <% current_page %> tag
  3664. */
  3665. function OpenBlock_Handle_Current_page(&$res) {
  3666. if ($res['ArgumentCount'] != 0) throw new SSTemplateParseException('Current_page takes no arguments', $this);
  3667. return '$val .= $_SERVER[SCRIPT_URL];';
  3668. }
  3669. /* MismatchedEndBlock: '<%' < 'end_' :Word > '%>' */
  3670. protected $match_MismatchedEndBlock_typestack = array('MismatchedEndBlock');
  3671. function match_MismatchedEndBlock ($stack = array()) {
  3672. $matchrule = "MismatchedEndBlock"; $result = $this->construct($matchrule, $matchrule, null);
  3673. $_653 = NULL;
  3674. do {
  3675. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  3676. else { $_653 = FALSE; break; }
  3677. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3678. if (( $subres = $this->literal( 'end_' ) ) !== FALSE) { $result["text"] .= $subres; }
  3679. else { $_653 = FALSE; break; }
  3680. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  3681. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3682. if ($subres !== FALSE) {
  3683. $this->store( $result, $subres, "Word" );
  3684. }
  3685. else { $_653 = FALSE; break; }
  3686. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3687. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  3688. else { $_653 = FALSE; break; }
  3689. $_653 = TRUE; break;
  3690. }
  3691. while(0);
  3692. if( $_653 === TRUE ) { return $this->finalise($result); }
  3693. if( $_653 === FALSE) { return FALSE; }
  3694. }
  3695. function MismatchedEndBlock__finalise(&$res) {
  3696. $blockname = $res['Word']['text'];
  3697. throw new SSTemplateParseException('Unexpected close tag end_' . $blockname .
  3698. ' encountered. Perhaps you have mis-nested blocks, or have mis-spelled a tag?', $this);
  3699. }
  3700. /* MalformedOpenTag: '<%' < !NotBlockTag Tag:Word !( ( [ :BlockArguments ] )? > '%>' ) */
  3701. protected $match_MalformedOpenTag_typestack = array('MalformedOpenTag');
  3702. function match_MalformedOpenTag ($stack = array()) {
  3703. $matchrule = "MalformedOpenTag"; $result = $this->construct($matchrule, $matchrule, null);
  3704. $_668 = NULL;
  3705. do {
  3706. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  3707. else { $_668 = FALSE; break; }
  3708. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3709. $res_657 = $result;
  3710. $pos_657 = $this->pos;
  3711. $matcher = 'match_'.'NotBlockTag'; $key = $matcher; $pos = $this->pos;
  3712. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3713. if ($subres !== FALSE) {
  3714. $this->store( $result, $subres );
  3715. $result = $res_657;
  3716. $this->pos = $pos_657;
  3717. $_668 = FALSE; break;
  3718. }
  3719. else {
  3720. $result = $res_657;
  3721. $this->pos = $pos_657;
  3722. }
  3723. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  3724. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3725. if ($subres !== FALSE) {
  3726. $this->store( $result, $subres, "Tag" );
  3727. }
  3728. else { $_668 = FALSE; break; }
  3729. $res_667 = $result;
  3730. $pos_667 = $this->pos;
  3731. $_666 = NULL;
  3732. do {
  3733. $res_663 = $result;
  3734. $pos_663 = $this->pos;
  3735. $_662 = NULL;
  3736. do {
  3737. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3738. else { $_662 = FALSE; break; }
  3739. $matcher = 'match_'.'BlockArguments'; $key = $matcher; $pos = $this->pos;
  3740. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3741. if ($subres !== FALSE) {
  3742. $this->store( $result, $subres, "BlockArguments" );
  3743. }
  3744. else { $_662 = FALSE; break; }
  3745. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3746. else { $_662 = FALSE; break; }
  3747. $_662 = TRUE; break;
  3748. }
  3749. while(0);
  3750. if( $_662 === FALSE) {
  3751. $result = $res_663;
  3752. $this->pos = $pos_663;
  3753. unset( $res_663 );
  3754. unset( $pos_663 );
  3755. }
  3756. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3757. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  3758. else { $_666 = FALSE; break; }
  3759. $_666 = TRUE; break;
  3760. }
  3761. while(0);
  3762. if( $_666 === TRUE ) {
  3763. $result = $res_667;
  3764. $this->pos = $pos_667;
  3765. $_668 = FALSE; break;
  3766. }
  3767. if( $_666 === FALSE) {
  3768. $result = $res_667;
  3769. $this->pos = $pos_667;
  3770. }
  3771. $_668 = TRUE; break;
  3772. }
  3773. while(0);
  3774. if( $_668 === TRUE ) { return $this->finalise($result); }
  3775. if( $_668 === FALSE) { return FALSE; }
  3776. }
  3777. function MalformedOpenTag__finalise(&$res) {
  3778. $tag = $res['Tag']['text'];
  3779. throw new SSTemplateParseException("Malformed opening block tag $tag. Perhaps you have tried to use operators?"
  3780. , $this);
  3781. }
  3782. /* MalformedCloseTag: '<%' < Tag:('end_' :Word ) !( > '%>' ) */
  3783. protected $match_MalformedCloseTag_typestack = array('MalformedCloseTag');
  3784. function match_MalformedCloseTag ($stack = array()) {
  3785. $matchrule = "MalformedCloseTag"; $result = $this->construct($matchrule, $matchrule, null);
  3786. $_680 = NULL;
  3787. do {
  3788. if (( $subres = $this->literal( '<%' ) ) !== FALSE) { $result["text"] .= $subres; }
  3789. else { $_680 = FALSE; break; }
  3790. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3791. $stack[] = $result; $result = $this->construct( $matchrule, "Tag" );
  3792. $_674 = NULL;
  3793. do {
  3794. if (( $subres = $this->literal( 'end_' ) ) !== FALSE) { $result["text"] .= $subres; }
  3795. else { $_674 = FALSE; break; }
  3796. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  3797. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3798. if ($subres !== FALSE) {
  3799. $this->store( $result, $subres, "Word" );
  3800. }
  3801. else { $_674 = FALSE; break; }
  3802. $_674 = TRUE; break;
  3803. }
  3804. while(0);
  3805. if( $_674 === TRUE ) {
  3806. $subres = $result; $result = array_pop($stack);
  3807. $this->store( $result, $subres, 'Tag' );
  3808. }
  3809. if( $_674 === FALSE) {
  3810. $result = array_pop($stack);
  3811. $_680 = FALSE; break;
  3812. }
  3813. $res_679 = $result;
  3814. $pos_679 = $this->pos;
  3815. $_678 = NULL;
  3816. do {
  3817. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  3818. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  3819. else { $_678 = FALSE; break; }
  3820. $_678 = TRUE; break;
  3821. }
  3822. while(0);
  3823. if( $_678 === TRUE ) {
  3824. $result = $res_679;
  3825. $this->pos = $pos_679;
  3826. $_680 = FALSE; break;
  3827. }
  3828. if( $_678 === FALSE) {
  3829. $result = $res_679;
  3830. $this->pos = $pos_679;
  3831. }
  3832. $_680 = TRUE; break;
  3833. }
  3834. while(0);
  3835. if( $_680 === TRUE ) { return $this->finalise($result); }
  3836. if( $_680 === FALSE) { return FALSE; }
  3837. }
  3838. function MalformedCloseTag__finalise(&$res) {
  3839. $tag = $res['Tag']['text'];
  3840. throw new SSTemplateParseException("Malformed closing block tag $tag. Perhaps you have tried to pass an " .
  3841. "argument to one?", $this);
  3842. }
  3843. /* MalformedBlock: MalformedOpenTag | MalformedCloseTag */
  3844. protected $match_MalformedBlock_typestack = array('MalformedBlock');
  3845. function match_MalformedBlock ($stack = array()) {
  3846. $matchrule = "MalformedBlock"; $result = $this->construct($matchrule, $matchrule, null);
  3847. $_685 = NULL;
  3848. do {
  3849. $res_682 = $result;
  3850. $pos_682 = $this->pos;
  3851. $matcher = 'match_'.'MalformedOpenTag'; $key = $matcher; $pos = $this->pos;
  3852. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3853. if ($subres !== FALSE) {
  3854. $this->store( $result, $subres );
  3855. $_685 = TRUE; break;
  3856. }
  3857. $result = $res_682;
  3858. $this->pos = $pos_682;
  3859. $matcher = 'match_'.'MalformedCloseTag'; $key = $matcher; $pos = $this->pos;
  3860. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3861. if ($subres !== FALSE) {
  3862. $this->store( $result, $subres );
  3863. $_685 = TRUE; break;
  3864. }
  3865. $result = $res_682;
  3866. $this->pos = $pos_682;
  3867. $_685 = FALSE; break;
  3868. }
  3869. while(0);
  3870. if( $_685 === TRUE ) { return $this->finalise($result); }
  3871. if( $_685 === FALSE) { return FALSE; }
  3872. }
  3873. /* Comment: "<%--" (!"--%>" /(?s)./)+ "--%>" */
  3874. protected $match_Comment_typestack = array('Comment');
  3875. function match_Comment ($stack = array()) {
  3876. $matchrule = "Comment"; $result = $this->construct($matchrule, $matchrule, null);
  3877. $_693 = NULL;
  3878. do {
  3879. if (( $subres = $this->literal( '<%--' ) ) !== FALSE) { $result["text"] .= $subres; }
  3880. else { $_693 = FALSE; break; }
  3881. $count = 0;
  3882. while (true) {
  3883. $res_691 = $result;
  3884. $pos_691 = $this->pos;
  3885. $_690 = NULL;
  3886. do {
  3887. $res_688 = $result;
  3888. $pos_688 = $this->pos;
  3889. if (( $subres = $this->literal( '--%>' ) ) !== FALSE) {
  3890. $result["text"] .= $subres;
  3891. $result = $res_688;
  3892. $this->pos = $pos_688;
  3893. $_690 = FALSE; break;
  3894. }
  3895. else {
  3896. $result = $res_688;
  3897. $this->pos = $pos_688;
  3898. }
  3899. if (( $subres = $this->rx( '/(?s)./' ) ) !== FALSE) { $result["text"] .= $subres; }
  3900. else { $_690 = FALSE; break; }
  3901. $_690 = TRUE; break;
  3902. }
  3903. while(0);
  3904. if( $_690 === FALSE) {
  3905. $result = $res_691;
  3906. $this->pos = $pos_691;
  3907. unset( $res_691 );
  3908. unset( $pos_691 );
  3909. break;
  3910. }
  3911. $count += 1;
  3912. }
  3913. if ($count > 0) { }
  3914. else { $_693 = FALSE; break; }
  3915. if (( $subres = $this->literal( '--%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  3916. else { $_693 = FALSE; break; }
  3917. $_693 = TRUE; break;
  3918. }
  3919. while(0);
  3920. if( $_693 === TRUE ) { return $this->finalise($result); }
  3921. if( $_693 === FALSE) { return FALSE; }
  3922. }
  3923. function Comment__construct(&$res) {
  3924. $res['php'] = '';
  3925. }
  3926. /* TopTemplate: (Comment | Translate | If | Require | CacheBlock | UncachedBlock | OldI18NTag | Include | ClosedBlock |
  3927. OpenBlock | MalformedBlock | MismatchedEndBlock | Injection | Text)+ */
  3928. protected $match_TopTemplate_typestack = array('TopTemplate','Template');
  3929. function match_TopTemplate ($stack = array()) {
  3930. $matchrule = "TopTemplate"; $result = $this->construct($matchrule, $matchrule, array('TemplateMatcher' => 'Template'));
  3931. $count = 0;
  3932. while (true) {
  3933. $res_749 = $result;
  3934. $pos_749 = $this->pos;
  3935. $_748 = NULL;
  3936. do {
  3937. $_746 = NULL;
  3938. do {
  3939. $res_695 = $result;
  3940. $pos_695 = $this->pos;
  3941. $matcher = 'match_'.'Comment'; $key = $matcher; $pos = $this->pos;
  3942. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3943. if ($subres !== FALSE) {
  3944. $this->store( $result, $subres );
  3945. $_746 = TRUE; break;
  3946. }
  3947. $result = $res_695;
  3948. $this->pos = $pos_695;
  3949. $_744 = NULL;
  3950. do {
  3951. $res_697 = $result;
  3952. $pos_697 = $this->pos;
  3953. $matcher = 'match_'.'Translate'; $key = $matcher; $pos = $this->pos;
  3954. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3955. if ($subres !== FALSE) {
  3956. $this->store( $result, $subres );
  3957. $_744 = TRUE; break;
  3958. }
  3959. $result = $res_697;
  3960. $this->pos = $pos_697;
  3961. $_742 = NULL;
  3962. do {
  3963. $res_699 = $result;
  3964. $pos_699 = $this->pos;
  3965. $matcher = 'match_'.'If'; $key = $matcher; $pos = $this->pos;
  3966. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3967. if ($subres !== FALSE) {
  3968. $this->store( $result, $subres );
  3969. $_742 = TRUE; break;
  3970. }
  3971. $result = $res_699;
  3972. $this->pos = $pos_699;
  3973. $_740 = NULL;
  3974. do {
  3975. $res_701 = $result;
  3976. $pos_701 = $this->pos;
  3977. $matcher = 'match_'.'Require'; $key = $matcher; $pos = $this->pos;
  3978. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3979. if ($subres !== FALSE) {
  3980. $this->store( $result, $subres );
  3981. $_740 = TRUE; break;
  3982. }
  3983. $result = $res_701;
  3984. $this->pos = $pos_701;
  3985. $_738 = NULL;
  3986. do {
  3987. $res_703 = $result;
  3988. $pos_703 = $this->pos;
  3989. $matcher = 'match_'.'CacheBlock'; $key = $matcher; $pos = $this->pos;
  3990. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  3991. if ($subres !== FALSE) {
  3992. $this->store( $result, $subres );
  3993. $_738 = TRUE; break;
  3994. }
  3995. $result = $res_703;
  3996. $this->pos = $pos_703;
  3997. $_736 = NULL;
  3998. do {
  3999. $res_705 = $result;
  4000. $pos_705 = $this->pos;
  4001. $matcher = 'match_'.'UncachedBlock'; $key = $matcher; $pos = $this->pos;
  4002. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4003. if ($subres !== FALSE) {
  4004. $this->store( $result, $subres );
  4005. $_736 = TRUE; break;
  4006. }
  4007. $result = $res_705;
  4008. $this->pos = $pos_705;
  4009. $_734 = NULL;
  4010. do {
  4011. $res_707 = $result;
  4012. $pos_707 = $this->pos;
  4013. $matcher = 'match_'.'OldI18NTag'; $key = $matcher; $pos = $this->pos;
  4014. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4015. if ($subres !== FALSE) {
  4016. $this->store( $result, $subres );
  4017. $_734 = TRUE; break;
  4018. }
  4019. $result = $res_707;
  4020. $this->pos = $pos_707;
  4021. $_732 = NULL;
  4022. do {
  4023. $res_709 = $result;
  4024. $pos_709 = $this->pos;
  4025. $matcher = 'match_'.'Include'; $key = $matcher; $pos = $this->pos;
  4026. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4027. if ($subres !== FALSE) {
  4028. $this->store( $result, $subres );
  4029. $_732 = TRUE; break;
  4030. }
  4031. $result = $res_709;
  4032. $this->pos = $pos_709;
  4033. $_730 = NULL;
  4034. do {
  4035. $res_711 = $result;
  4036. $pos_711 = $this->pos;
  4037. $matcher = 'match_'.'ClosedBlock'; $key = $matcher; $pos = $this->pos;
  4038. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4039. if ($subres !== FALSE) {
  4040. $this->store( $result, $subres );
  4041. $_730 = TRUE; break;
  4042. }
  4043. $result = $res_711;
  4044. $this->pos = $pos_711;
  4045. $_728 = NULL;
  4046. do {
  4047. $res_713 = $result;
  4048. $pos_713 = $this->pos;
  4049. $matcher = 'match_'.'OpenBlock'; $key = $matcher; $pos = $this->pos;
  4050. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4051. if ($subres !== FALSE) {
  4052. $this->store( $result, $subres );
  4053. $_728 = TRUE; break;
  4054. }
  4055. $result = $res_713;
  4056. $this->pos = $pos_713;
  4057. $_726 = NULL;
  4058. do {
  4059. $res_715 = $result;
  4060. $pos_715 = $this->pos;
  4061. $matcher = 'match_'.'MalformedBlock'; $key = $matcher; $pos = $this->pos;
  4062. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4063. if ($subres !== FALSE) {
  4064. $this->store( $result, $subres );
  4065. $_726 = TRUE; break;
  4066. }
  4067. $result = $res_715;
  4068. $this->pos = $pos_715;
  4069. $_724 = NULL;
  4070. do {
  4071. $res_717 = $result;
  4072. $pos_717 = $this->pos;
  4073. $matcher = 'match_'.'MismatchedEndBlock'; $key = $matcher; $pos = $this->pos;
  4074. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4075. if ($subres !== FALSE) {
  4076. $this->store( $result, $subres );
  4077. $_724 = TRUE; break;
  4078. }
  4079. $result = $res_717;
  4080. $this->pos = $pos_717;
  4081. $_722 = NULL;
  4082. do {
  4083. $res_719 = $result;
  4084. $pos_719 = $this->pos;
  4085. $matcher = 'match_'.'Injection'; $key = $matcher; $pos = $this->pos;
  4086. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4087. if ($subres !== FALSE) {
  4088. $this->store( $result, $subres );
  4089. $_722 = TRUE; break;
  4090. }
  4091. $result = $res_719;
  4092. $this->pos = $pos_719;
  4093. $matcher = 'match_'.'Text'; $key = $matcher; $pos = $this->pos;
  4094. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  4095. if ($subres !== FALSE) {
  4096. $this->store( $result, $subres );
  4097. $_722 = TRUE; break;
  4098. }
  4099. $result = $res_719;
  4100. $this->pos = $pos_719;
  4101. $_722 = FALSE; break;
  4102. }
  4103. while(0);
  4104. if( $_722 === TRUE ) { $_724 = TRUE; break; }
  4105. $result = $res_717;
  4106. $this->pos = $pos_717;
  4107. $_724 = FALSE; break;
  4108. }
  4109. while(0);
  4110. if( $_724 === TRUE ) { $_726 = TRUE; break; }
  4111. $result = $res_715;
  4112. $this->pos = $pos_715;
  4113. $_726 = FALSE; break;
  4114. }
  4115. while(0);
  4116. if( $_726 === TRUE ) { $_728 = TRUE; break; }
  4117. $result = $res_713;
  4118. $this->pos = $pos_713;
  4119. $_728 = FALSE; break;
  4120. }
  4121. while(0);
  4122. if( $_728 === TRUE ) { $_730 = TRUE; break; }
  4123. $result = $res_711;
  4124. $this->pos = $pos_711;
  4125. $_730 = FALSE; break;
  4126. }
  4127. while(0);
  4128. if( $_730 === TRUE ) { $_732 = TRUE; break; }
  4129. $result = $res_709;
  4130. $this->pos = $pos_709;
  4131. $_732 = FALSE; break;
  4132. }
  4133. while(0);
  4134. if( $_732 === TRUE ) { $_734 = TRUE; break; }
  4135. $result = $res_707;
  4136. $this->pos = $pos_707;
  4137. $_734 = FALSE; break;
  4138. }
  4139. while(0);
  4140. if( $_734 === TRUE ) { $_736 = TRUE; break; }
  4141. $result = $res_705;
  4142. $this->pos = $pos_705;
  4143. $_736 = FALSE; break;
  4144. }
  4145. while(0);
  4146. if( $_736 === TRUE ) { $_738 = TRUE; break; }
  4147. $result = $res_703;
  4148. $this->pos = $pos_703;
  4149. $_738 = FALSE; break;
  4150. }
  4151. while(0);
  4152. if( $_738 === TRUE ) { $_740 = TRUE; break; }
  4153. $result = $res_701;
  4154. $this->pos = $pos_701;
  4155. $_740 = FALSE; break;
  4156. }
  4157. while(0);
  4158. if( $_740 === TRUE ) { $_742 = TRUE; break; }
  4159. $result = $res_699;
  4160. $this->pos = $pos_699;
  4161. $_742 = FALSE; break;
  4162. }
  4163. while(0);
  4164. if( $_742 === TRUE ) { $_744 = TRUE; break; }
  4165. $result = $res_697;
  4166. $this->pos = $pos_697;
  4167. $_744 = FALSE; break;
  4168. }
  4169. while(0);
  4170. if( $_744 === TRUE ) { $_746 = TRUE; break; }
  4171. $result = $res_695;
  4172. $this->pos = $pos_695;
  4173. $_746 = FALSE; break;
  4174. }
  4175. while(0);
  4176. if( $_746 === FALSE) { $_748 = FALSE; break; }
  4177. $_748 = TRUE; break;
  4178. }
  4179. while(0);
  4180. if( $_748 === FALSE) {
  4181. $result = $res_749;
  4182. $this->pos = $pos_749;
  4183. unset( $res_749 );
  4184. unset( $pos_749 );
  4185. break;
  4186. }
  4187. $count += 1;
  4188. }
  4189. if ($count > 0) { return $this->finalise($result); }
  4190. else { return FALSE; }
  4191. }
  4192. /**
  4193. * The TopTemplate also includes the opening stanza to start off the template
  4194. */
  4195. function TopTemplate__construct(&$res) {
  4196. $res['php'] = "<?php" . PHP_EOL;
  4197. }
  4198. /* Text: (
  4199. / [^<${\\]+ / |
  4200. / (\\.) / |
  4201. '<' !'%' |
  4202. '$' !(/[A-Za-z_]/) |
  4203. '{' !'$' |
  4204. '{$' !(/[A-Za-z_]/)
  4205. )+ */
  4206. protected $match_Text_typestack = array('Text');
  4207. function match_Text ($stack = array()) {
  4208. $matchrule = "Text"; $result = $this->construct($matchrule, $matchrule, null);
  4209. $count = 0;
  4210. while (true) {
  4211. $res_788 = $result;
  4212. $pos_788 = $this->pos;
  4213. $_787 = NULL;
  4214. do {
  4215. $_785 = NULL;
  4216. do {
  4217. $res_750 = $result;
  4218. $pos_750 = $this->pos;
  4219. if (( $subres = $this->rx( '/ [^<${\\\\]+ /' ) ) !== FALSE) {
  4220. $result["text"] .= $subres;
  4221. $_785 = TRUE; break;
  4222. }
  4223. $result = $res_750;
  4224. $this->pos = $pos_750;
  4225. $_783 = NULL;
  4226. do {
  4227. $res_752 = $result;
  4228. $pos_752 = $this->pos;
  4229. if (( $subres = $this->rx( '/ (\\\\.) /' ) ) !== FALSE) {
  4230. $result["text"] .= $subres;
  4231. $_783 = TRUE; break;
  4232. }
  4233. $result = $res_752;
  4234. $this->pos = $pos_752;
  4235. $_781 = NULL;
  4236. do {
  4237. $res_754 = $result;
  4238. $pos_754 = $this->pos;
  4239. $_757 = NULL;
  4240. do {
  4241. if (substr($this->string,$this->pos,1) == '<') {
  4242. $this->pos += 1;
  4243. $result["text"] .= '<';
  4244. }
  4245. else { $_757 = FALSE; break; }
  4246. $res_756 = $result;
  4247. $pos_756 = $this->pos;
  4248. if (substr($this->string,$this->pos,1) == '%') {
  4249. $this->pos += 1;
  4250. $result["text"] .= '%';
  4251. $result = $res_756;
  4252. $this->pos = $pos_756;
  4253. $_757 = FALSE; break;
  4254. }
  4255. else {
  4256. $result = $res_756;
  4257. $this->pos = $pos_756;
  4258. }
  4259. $_757 = TRUE; break;
  4260. }
  4261. while(0);
  4262. if( $_757 === TRUE ) { $_781 = TRUE; break; }
  4263. $result = $res_754;
  4264. $this->pos = $pos_754;
  4265. $_779 = NULL;
  4266. do {
  4267. $res_759 = $result;
  4268. $pos_759 = $this->pos;
  4269. $_764 = NULL;
  4270. do {
  4271. if (substr($this->string,$this->pos,1) == '$') {
  4272. $this->pos += 1;
  4273. $result["text"] .= '$';
  4274. }
  4275. else { $_764 = FALSE; break; }
  4276. $res_763 = $result;
  4277. $pos_763 = $this->pos;
  4278. $_762 = NULL;
  4279. do {
  4280. if (( $subres = $this->rx( '/[A-Za-z_]/' ) ) !== FALSE) { $result["text"] .= $subres; }
  4281. else { $_762 = FALSE; break; }
  4282. $_762 = TRUE; break;
  4283. }
  4284. while(0);
  4285. if( $_762 === TRUE ) {
  4286. $result = $res_763;
  4287. $this->pos = $pos_763;
  4288. $_764 = FALSE; break;
  4289. }
  4290. if( $_762 === FALSE) {
  4291. $result = $res_763;
  4292. $this->pos = $pos_763;
  4293. }
  4294. $_764 = TRUE; break;
  4295. }
  4296. while(0);
  4297. if( $_764 === TRUE ) { $_779 = TRUE; break; }
  4298. $result = $res_759;
  4299. $this->pos = $pos_759;
  4300. $_777 = NULL;
  4301. do {
  4302. $res_766 = $result;
  4303. $pos_766 = $this->pos;
  4304. $_769 = NULL;
  4305. do {
  4306. if (substr($this->string,$this->pos,1) == '{') {
  4307. $this->pos += 1;
  4308. $result["text"] .= '{';
  4309. }
  4310. else { $_769 = FALSE; break; }
  4311. $res_768 = $result;
  4312. $pos_768 = $this->pos;
  4313. if (substr($this->string,$this->pos,1) == '$') {
  4314. $this->pos += 1;
  4315. $result["text"] .= '$';
  4316. $result = $res_768;
  4317. $this->pos = $pos_768;
  4318. $_769 = FALSE; break;
  4319. }
  4320. else {
  4321. $result = $res_768;
  4322. $this->pos = $pos_768;
  4323. }
  4324. $_769 = TRUE; break;
  4325. }
  4326. while(0);
  4327. if( $_769 === TRUE ) { $_777 = TRUE; break; }
  4328. $result = $res_766;
  4329. $this->pos = $pos_766;
  4330. $_775 = NULL;
  4331. do {
  4332. if (( $subres = $this->literal( '{$' ) ) !== FALSE) { $result["text"] .= $subres; }
  4333. else { $_775 = FALSE; break; }
  4334. $res_774 = $result;
  4335. $pos_774 = $this->pos;
  4336. $_773 = NULL;
  4337. do {
  4338. if (( $subres = $this->rx( '/[A-Za-z_]/' ) ) !== FALSE) { $result["text"] .= $subres; }
  4339. else { $_773 = FALSE; break; }
  4340. $_773 = TRUE; break;
  4341. }
  4342. while(0);
  4343. if( $_773 === TRUE ) {
  4344. $result = $res_774;
  4345. $this->pos = $pos_774;
  4346. $_775 = FALSE; break;
  4347. }
  4348. if( $_773 === FALSE) {
  4349. $result = $res_774;
  4350. $this->pos = $pos_774;
  4351. }
  4352. $_775 = TRUE; break;
  4353. }
  4354. while(0);
  4355. if( $_775 === TRUE ) { $_777 = TRUE; break; }
  4356. $result = $res_766;
  4357. $this->pos = $pos_766;
  4358. $_777 = FALSE; break;
  4359. }
  4360. while(0);
  4361. if( $_777 === TRUE ) { $_779 = TRUE; break; }
  4362. $result = $res_759;
  4363. $this->pos = $pos_759;
  4364. $_779 = FALSE; break;
  4365. }
  4366. while(0);
  4367. if( $_779 === TRUE ) { $_781 = TRUE; break; }
  4368. $result = $res_754;
  4369. $this->pos = $pos_754;
  4370. $_781 = FALSE; break;
  4371. }
  4372. while(0);
  4373. if( $_781 === TRUE ) { $_783 = TRUE; break; }
  4374. $result = $res_752;
  4375. $this->pos = $pos_752;
  4376. $_783 = FALSE; break;
  4377. }
  4378. while(0);
  4379. if( $_783 === TRUE ) { $_785 = TRUE; break; }
  4380. $result = $res_750;
  4381. $this->pos = $pos_750;
  4382. $_785 = FALSE; break;
  4383. }
  4384. while(0);
  4385. if( $_785 === FALSE) { $_787 = FALSE; break; }
  4386. $_787 = TRUE; break;
  4387. }
  4388. while(0);
  4389. if( $_787 === FALSE) {
  4390. $result = $res_788;
  4391. $this->pos = $pos_788;
  4392. unset( $res_788 );
  4393. unset( $pos_788 );
  4394. break;
  4395. }
  4396. $count += 1;
  4397. }
  4398. if ($count > 0) { return $this->finalise($result); }
  4399. else { return FALSE; }
  4400. }
  4401. /**
  4402. * We convert text
  4403. */
  4404. function Text__finalise(&$res) {
  4405. $text = $res['text'];
  4406. // Unescape any escaped characters in the text, then put back escapes for any single quotes and backslashes
  4407. $text = stripslashes($text);
  4408. $text = addcslashes($text, '\'\\');
  4409. // TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this
  4410. // non-dynamically calculated
  4411. $code = <<<'EOC'
  4412. (\Config::inst()->get('SSViewer', 'rewrite_hash_links')
  4413. ? \Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) )
  4414. : "")
  4415. EOC;
  4416. // Because preg_replace replacement requires escaped slashes, addcslashes here
  4417. $text = preg_replace(
  4418. '/(<a[^>]+href *= *)"#/i',
  4419. '\\1"\' . ' . addcslashes($code, '\\') . ' . \'#',
  4420. $text
  4421. );
  4422. $res['php'] .= '$val .= \'' . $text . '\';' . PHP_EOL;
  4423. }
  4424. /******************
  4425. * Here ends the parser itself. Below are utility methods to use the parser
  4426. */
  4427. /**
  4428. * Compiles some passed template source code into the php code that will execute as per the template source.
  4429. *
  4430. * @throws SSTemplateParseException
  4431. * @param $string The source of the template
  4432. * @param string $templateName The name of the template, normally the filename the template source was loaded from
  4433. * @param bool $includeDebuggingComments True is debugging comments should be included in the output
  4434. * @param bool $topTemplate True if this is a top template, false if it's just a template
  4435. * @return mixed|string The php that, when executed (via include or exec) will behave as per the template source
  4436. */
  4437. public function compileString($string, $templateName = "", $includeDebuggingComments=false, $topTemplate = true) {
  4438. if (!trim($string)) {
  4439. $code = '';
  4440. }
  4441. else {
  4442. parent::__construct($string);
  4443. $this->includeDebuggingComments = $includeDebuggingComments;
  4444. // Ignore UTF8 BOM at begining of string. TODO: Confirm this is needed, make sure SSViewer handles UTF
  4445. // (and other encodings) properly
  4446. if(substr($string, 0,3) == pack("CCC", 0xef, 0xbb, 0xbf)) $this->pos = 3;
  4447. // Match the source against the parser
  4448. if ($topTemplate) {
  4449. $result = $this->match_TopTemplate();
  4450. } else {
  4451. $result = $this->match_Template();
  4452. }
  4453. if(!$result) throw new SSTemplateParseException('Unexpected problem parsing template', $this);
  4454. // Get the result
  4455. $code = $result['php'];
  4456. }
  4457. // Include top level debugging comments if desired
  4458. if($includeDebuggingComments && $templateName && stripos($code, "<?xml") === false) {
  4459. $code = $this->includeDebuggingComments($code, $templateName);
  4460. }
  4461. return $code;
  4462. }
  4463. /**
  4464. * @param string $code
  4465. * @return string $code
  4466. */
  4467. protected function includeDebuggingComments($code, $templateName) {
  4468. // If this template contains a doctype, put it right after it,
  4469. // if not, put it after the <html> tag to avoid IE glitches
  4470. if(stripos($code, "<!doctype") !== false) {
  4471. $code = preg_replace('/(<!doctype[^>]*("[^"]")*[^>]*>)/im', "$1\r\n<!-- template $templateName -->", $code);
  4472. $code .= "\r\n" . '$val .= \'<!-- end template ' . $templateName . ' -->\';';
  4473. } elseif(stripos($code, "<html") !== false) {
  4474. $code = preg_replace_callback('/(.*)(<html[^>]*>)(.*)/i', function($matches) use ($templateName) {
  4475. if (stripos($matches[3], '<!--') === false && stripos($matches[3], '-->') !== false) {
  4476. // after this <html> tag there is a comment close but no comment has been opened
  4477. // this most likely means that this <html> tag is inside a comment
  4478. // we should not add a comment inside a comment (invalid html)
  4479. // lets append it at the end of the comment
  4480. // an example case for this is the html5boilerplate: <!--[if IE]><html class="ie"><![endif]-->
  4481. return $matches[0];
  4482. } else {
  4483. // all other cases, add the comment and return it
  4484. return "{$matches[1]}{$matches[2]}<!-- template $templateName -->{$matches[3]}";
  4485. }
  4486. }, $code);
  4487. $code = preg_replace('/(<\/html[^>]*>)/i', "<!-- end template $templateName -->$1", $code);
  4488. } else {
  4489. $code = str_replace('<?php' . PHP_EOL, '<?php' . PHP_EOL . '$val .= \'<!-- template ' . $templateName .
  4490. ' -->\';' . "\r\n", $code);
  4491. $code .= "\r\n" . '$val .= \'<!-- end template ' . $templateName . ' -->\';';
  4492. }
  4493. return $code;
  4494. }
  4495. /**
  4496. * Compiles some file that contains template source code, and returns the php code that will execute as per that
  4497. * source
  4498. *
  4499. * @static
  4500. * @param $template - A file path that contains template source code
  4501. * @return mixed|string - The php that, when executed (via include or exec) will behave as per the template source
  4502. */
  4503. public function compileFile($template) {
  4504. return $this->compileString(file_get_contents($template), $template);
  4505. }
  4506. }