/protected/components/ezcomponents/Template/src/parsers/source_to_tst/implementations/custom_block.php

https://github.com/kamarulismail/kamarul-playground · PHP · 215 lines · 134 code · 37 blank · 44 comment · 26 complexity · f6954b0a83bdd5db80713bdd54ffe47c MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the ezcTemplateCustomBlockSourceToTstParser class
  4. *
  5. * @package Template
  6. * @version 1.4.2
  7. * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. * @access private
  10. */
  11. /**
  12. * Parser for custom template blocks following a generic syntax.
  13. *
  14. * @package Template
  15. * @version 1.4.2
  16. * @access private
  17. */
  18. class ezcTemplateCustomBlockSourceToTstParser extends ezcTemplateSourceToTstParser
  19. {
  20. /**
  21. * Passes control to parent.
  22. *
  23. * @param ezcTemplateParser $parser
  24. * @param ezcTemplateSourceToTstParser $parentParser
  25. * @param ezcTemplateCursor $startCursor
  26. */
  27. function __construct( ezcTemplateParser $parser, /*ezcTemplateSourceToTstParser*/ $parentParser, /*ezcTemplateCursor*/ $startCursor )
  28. {
  29. parent::__construct( $parser, $parentParser, $startCursor );
  30. $this->block = null;
  31. }
  32. /**
  33. * Returns the custom block definition.
  34. *
  35. * @param string $name
  36. * @return ezcTemplateCustomBlockDefinition
  37. */
  38. function getCustomBlockDefinition( $name )
  39. {
  40. foreach ( $this->parser->template->configuration->customBlocks as $class )
  41. {
  42. $def = call_user_func( array( $class, "getCustomBlockDefinition" ), $name );
  43. if ( $def instanceof ezcTemplateCustomBlockDefinition )
  44. {
  45. return $def;
  46. }
  47. }
  48. return false;
  49. }
  50. /**
  51. * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  52. *
  53. * @param ezcTemplateCursor $cursor
  54. * @return bool
  55. */
  56. protected function parseCurrent( ezcTemplateCursor $cursor )
  57. {
  58. if ( $this->block->isClosingBlock )
  59. {
  60. $this->findNextElement();
  61. $matches = $cursor->pregMatchComplete( "#^([a-zA-Z_][a-zA-Z0-9_-]*)(?:[^a-zA-Z])#i" );
  62. if ( $matches === false )
  63. return false;
  64. $name = $matches[1][0];
  65. // If the custom block is not defined we have to return false.
  66. $def = $this->getCustomBlockDefinition( $name );
  67. if ( $def === false )
  68. {
  69. return false;
  70. }
  71. $cursor->advance( strlen( $name ) );
  72. $this->findNextElement( $cursor );
  73. if ( !$cursor->match( "}" ) )
  74. {
  75. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE );
  76. }
  77. $cb = new ezcTemplateCustomBlockTstNode( $this->parser->source, $this->startCursor, $cursor );
  78. $cb->name = $name;
  79. $cb->isClosingBlock = true;
  80. $this->appendElement( $cb );
  81. return true;
  82. }
  83. // Check for the name of the custom block
  84. // Note: The code inside the ( ?: ) brace ensures that the next character
  85. // is not an alphabetical character ie. a word boundary
  86. $matches = $cursor->pregMatchComplete( "#^([a-zA-Z_][a-zA-Z0-9_-]*)(?:[^a-zA-Z])#i" );
  87. if ( $matches === false )
  88. {
  89. return false;
  90. }
  91. $name = $matches[1][0];
  92. $cursor->advance( strlen( $name ) );
  93. $this->findNextElement( $cursor );
  94. // $def = ezcTemplateCustomBlockManager::getInstance()->getDefinition( $name );
  95. $def = $this->getCustomBlockDefinition( $name );
  96. if ( $def === false )
  97. {
  98. return false;
  99. }
  100. $cb = new ezcTemplateCustomBlockTstNode( $this->parser->source, $this->startCursor, $cursor );
  101. $cb->definition = $def;
  102. $cb->name = $name;
  103. $this->block->isNestingBlock = $cb->isNestingBlock = $def->hasCloseTag;
  104. $excessParameters = isset( $def->excessParameters ) && $def->excessParameters ? true : false;
  105. if ( isset( $def->startExpressionName ) && $def->startExpressionName != "" )
  106. {
  107. if ( !in_array( $def->startExpressionName, $def->optionalParameters ) && !in_array( $def->startExpressionName, $def->requiredParameters ) )
  108. {
  109. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor,
  110. sprintf( ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_REQUIRED_OR_OPTIONAL_PARAMETER_DEFINITION_IN_CUSTOM_BLOCK, $def->startExpressionName ) );
  111. }
  112. if ( !$this->parseOptionalType( 'Expression', null, false ) )
  113. {
  114. if ( in_array( $def->startExpressionName, $def->requiredParameters ) )
  115. {
  116. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_EXPRESSION );
  117. }
  118. }
  119. else
  120. {
  121. if ( $this->lastParser->rootOperator instanceof ezcTemplateModifyingOperatorTstNode )
  122. {
  123. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_MODIFYING_EXPRESSION_NOT_ALLOWED );
  124. }
  125. $cb->namedParameters[ $def->startExpressionName ] = $this->lastParser->rootOperator;
  126. $this->findNextElement( $cursor );
  127. }
  128. }
  129. while ( !$cursor->match( "}" ) )
  130. {
  131. $match = $cursor->pregMatch( "#^[a-zA-Z_][a-zA-Z0-9_-]*#");
  132. if ( !$match )
  133. {
  134. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor,
  135. sprintf( ezcTemplateSourceToTstErrorMessages::MSG_UNEXPECTED_TOKEN, $cursor->current( 1 ) ) );
  136. }
  137. if ( !$excessParameters && !in_array( $match, $def->optionalParameters ) && !in_array( $match, $def->requiredParameters ) )
  138. {
  139. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor,
  140. sprintf( ezcTemplateSourceToTstErrorMessages::MSG_UNKNOWN_CUSTOM_BLOCK_PARAMETER, $match) );
  141. }
  142. if ( array_key_exists( $match, $cb->namedParameters ) )
  143. {
  144. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor,
  145. sprintf( ezcTemplateSourceToTstErrorMessages::MSG_REASSIGNMENT_CUSTOM_BLOCK_PARAMETER, $match ) );
  146. }
  147. $this->findNextElement( $cursor );
  148. // The '=' is optional.
  149. if ( $cursor->match( "=" ) )
  150. {
  151. $this->findNextElement( $cursor );
  152. }
  153. // The parameter has an expression.
  154. if ( !$this->parseOptionalType( 'Expression', null, false ) )
  155. {
  156. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_EXPRESSION );
  157. }
  158. if ( $this->lastParser->rootOperator instanceof ezcTemplateModifyingOperatorTstNode )
  159. {
  160. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_MODIFYING_EXPRESSION_NOT_ALLOWED );
  161. }
  162. // Append the parameter to the "namedParameters" array.
  163. $cb->namedParameters[ $match ] = $this->lastParser->rootOperator;
  164. }
  165. // Check if all requiredParameters are set.
  166. foreach ( $def->requiredParameters as $val )
  167. {
  168. if ( !array_key_exists( $val, $cb->namedParameters) )
  169. {
  170. throw new ezcTemplateParserException( $this->parser->source, $this->startCursor, $this->currentCursor,
  171. sprintf( ezcTemplateSourceToTstErrorMessages::MSG_MISSING_CUSTOM_BLOCK_PARAMETER, $val ) );
  172. }
  173. }
  174. $this->appendElement( $cb );
  175. return true;
  176. }
  177. }
  178. ?>