PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/Opl/Opt/Instruction/Selector.php

https://bitbucket.org/kandsten/hitta.sverok.se
PHP | 253 lines | 161 code | 21 blank | 71 comment | 23 complexity | d6d42a015048cc8538e52ff5b1ca4021 MD5 | raw file
Possible License(s): GPL-3.0, MIT
  1. <?php
  2. /*
  3. * OPEN POWER LIBS <http://www.invenzzia.org>
  4. *
  5. * This file is subject to the new BSD license that is bundled
  6. * with this package in the file LICENSE. It is also available through
  7. * WWW at this URL: <http://www.invenzzia.org/license/new-bsd>
  8. *
  9. * Copyright (c) Invenzzia Group <http://www.invenzzia.org>
  10. * and other contributors. See website for details.
  11. *
  12. * $Id: Selector.php 231 2009-09-19 07:13:14Z zyxist $
  13. */
  14. /**
  15. * The instruction processor for selectors.
  16. */
  17. class Opt_Instruction_Selector extends Opt_Instruction_BaseSection
  18. {
  19. /**
  20. * The processor name required by the parent.
  21. * @internal
  22. * @var string
  23. */
  24. protected $_name = 'section';
  25. /**
  26. * The list of extra opt:selector attributes for the section manager.
  27. * @internal
  28. * @var array
  29. */
  30. protected $_extraAttributes = array('test' => array(self::OPTIONAL, self::ID, 'item'));
  31. /**
  32. * Configures the instruction processor.
  33. *
  34. * @internal
  35. */
  36. public function configure()
  37. {
  38. $this->_addInstructions(array('opt:selector', 'opt:selectorelse'));
  39. $this->_addAttributes('opt:selector');
  40. } // end configure();
  41. /**
  42. * Processes the opt:selector element using the section API.
  43. * @internal
  44. * @param Opt_Xml_Node $node The found element.
  45. */
  46. protected function _processSelector(Opt_Xml_Node $node)
  47. {
  48. $section = $this->_sectionCreate($node, null, array('test' => array(self::OPTIONAL, self::ID, 'item')));
  49. $this->_sectionStart($section);
  50. if($section['order'] == 'asc')
  51. {
  52. $code = $section['format']->get('section:startAscLoop');
  53. }
  54. else
  55. {
  56. $code = $section['format']->get('section:startDescLoop');
  57. }
  58. $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $code);
  59. $this->processSeparator('$__sect_'.$section['name'], $section['separator'], $node);
  60. $this->_internalMagic($node, $section, 0);
  61. // $this->_sortSectionContents($node, 'opt', 'selectorelse');
  62. $node->set('postprocess', true);
  63. $this->_process($node);
  64. } // end _processSelector();
  65. /**
  66. * Postprocessing routine for opt:selector.
  67. * @param Opt_Xml_Node $node The found element.
  68. */
  69. protected function _postprocessSelector(Opt_Xml_Node $node)
  70. {
  71. $section = self::getSection($node->get('priv:section'));
  72. if(!$node->get('priv:alternative'))
  73. {
  74. $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, $section['format']->get('section:endLoop'));
  75. $this->_sectionEnd($node);
  76. }
  77. } // end _postprocessSelector();
  78. /**
  79. * Processes the opt:selectorelse element.
  80. * @param Opt_Xml_Element $node
  81. * @throws Opt_InstructionInvalidParent_Exception
  82. */
  83. protected function _processSelectorelse(Opt_Xml_Element $node)
  84. {
  85. $parent = $node->getParent();
  86. if($parent instanceof Opt_Xml_Element && $parent->getXmlName() == 'opt:selector')
  87. {
  88. $parent->set('priv:alternative', true);
  89. $section = self::getSection($parent->get('priv:section'));
  90. $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, ' } '.$section['format']->get('section:endLoop').' } else { ');
  91. $this->_sectionEnd($parent);
  92. $this->_process($node);
  93. }
  94. else
  95. {
  96. throw new Opt_InstructionInvalidParent_Exception($node->getXmlName(), 'opt:section');
  97. }
  98. } // end _processSelectorelse();
  99. /**
  100. * Processes the attribute version of opt:selector
  101. * @internal
  102. * @param Opt_Xml_Node $node
  103. * @param Opt_Xml_Attribute $attr
  104. */
  105. protected function _processAttrSelector(Opt_Xml_Node $node, Opt_Xml_Attribute $attr)
  106. {
  107. $section = $this->_sectionCreate($node, $attr, array('test' => array(self::OPTIONAL, self::ID, 'item')));
  108. $this->_sectionStart($section);
  109. $code = '';
  110. if($section['order'] == 'asc')
  111. {
  112. $code .= $section['format']->get('section:startAscLoop');
  113. }
  114. else
  115. {
  116. $code .= $section['format']->get('section:startDescLoop');
  117. }
  118. $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $code);
  119. $this->processSeparator('$__sect_'.$section['name'], $section['separator'], $node);
  120. $this->_internalMagic($node, $section, 1);
  121. $attr->set('postprocess', true);
  122. } // end _processAttrSelector();
  123. /**
  124. * A postprocessing routine for attributed opt:selector
  125. * @internal
  126. * @param Opt_Xml_Node $node
  127. * @param Opt_Xml_Attribute $attr
  128. */
  129. protected function _postprocessAttrSelector(Opt_Xml_Node $node, Opt_Xml_Attribute $attr)
  130. {
  131. $section = self::getSection($node->get('priv:section'));
  132. $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, $section['format']->get('section:endLoop'));
  133. $this->_sectionEnd($node);
  134. } // end _postprocessAttrSelector();
  135. /**
  136. * The internal magic shared by the selector elements. Locates the node elements
  137. * and constructs the switch() statement for them.
  138. * @internal
  139. * @param Opt_Xml_Element $node The found element
  140. * @param array $section The reference to the section data.
  141. * @param string $type The name of the selection item.
  142. * @throws Opt_InstructionTooManyItems_Exception
  143. */
  144. private function _internalMagic($node, &$section, $type)
  145. {
  146. $section['format']->assign('item', (!$type ? $section['test'] : 'item'));
  147. // Check, if there are no instruction tags in the children list.
  148. $instructions = array();
  149. $cases = array();
  150. $alternative = null;
  151. foreach($node as $subnode)
  152. {
  153. if($subnode instanceof Opt_Xml_Element && $this->_compiler->isNamespace($subnode->getNamespace()))
  154. {
  155. if($this->_compiler->isInstruction($subnode->getXmlName()) || $subnode->getXmlName() == 'opt:separator')
  156. {
  157. if($subnode != 'opt:selectorelse')
  158. {
  159. $instructions[] = $subnode;
  160. }
  161. else
  162. {
  163. if(!is_null($alternative))
  164. {
  165. throw new Opt_InstructionTooManyItems_Exception('opt:selectorelse', $node->getXmlName(), 'Zero or one');
  166. }
  167. $alternative = $subnode;
  168. }
  169. }
  170. else
  171. {
  172. $cases[] = $subnode;
  173. }
  174. }
  175. else
  176. {
  177. $node->removeChild($subnode);
  178. }
  179. }
  180. if(sizeof($instructions) > 0)
  181. {
  182. // There are instructions in opt:selector. We have to move the
  183. // cases to a fake node in order to sanitize them.
  184. $node->removeChildren();
  185. foreach($instructions as $instruction)
  186. {
  187. $node->appendChild($instruction);
  188. }
  189. $fake = new Opt_Xml_Element('opt:_');
  190. foreach($cases as $case)
  191. {
  192. $fake->appendChild($case);
  193. }
  194. $fake->set('processAll', true);
  195. $fake->set('hidden', false);
  196. $node->appendChild($fake);
  197. if(!is_null($alternative))
  198. {
  199. $node->appendChild($alternative);
  200. }
  201. }
  202. else
  203. {
  204. $fake = $node;
  205. }
  206. $fake->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, 'switch('.$section['format']->get('section:variable').'){');
  207. // If opt:selectorelse is used, the ending curly bracket is created by
  208. // _processSelectorelse().
  209. if(is_null($alternative))
  210. {
  211. $fake->addBefore(Opt_Xml_Buffer::TAG_CONTENT_AFTER, ' } ');
  212. }
  213. foreach($cases as $case)
  214. {
  215. if($case->getXmlName() == 'opt:separator')
  216. {
  217. Opl_Debug::write('Print shit');
  218. }
  219. if($case->getName() == 'default')
  220. {
  221. $case->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, ' default: ');
  222. }
  223. else
  224. {
  225. $case->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, ' case \''.$case->getName().'\': ');
  226. }
  227. $case->addBefore(Opt_Xml_Buffer::TAG_CONTENT_AFTER, ' break; ');
  228. $case->set('processAll', true);
  229. $case->set('hidden', false);
  230. }
  231. } // end _internalMagic();
  232. } // end Opt_Instruction_Selector;