/web/vendor/nette/forms/src/Bridges/FormsLatte/FormMacros.php

https://gitlab.com/adam.kvita/MI-VMM-SIFT · PHP · 256 lines · 187 code · 32 blank · 37 comment · 22 complexity · 15bdb221b01fbd1726c8fe579b027f2d MD5 · raw file

  1. <?php
  2. /**
  3. * This file is part of the Nette Framework (https://nette.org)
  4. * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  5. */
  6. namespace Nette\Bridges\FormsLatte;
  7. use Nette;
  8. use Latte;
  9. use Latte\MacroNode;
  10. use Latte\PhpWriter;
  11. use Latte\CompileException;
  12. use Latte\Macros\MacroSet;
  13. use Nette\Forms\Form;
  14. /**
  15. * Latte macros for Nette\Forms.
  16. *
  17. * - {form name} ... {/form}
  18. * - {input name}
  19. * - {label name /} or {label name}... {/label}
  20. * - {inputError name}
  21. * - {formContainer name} ... {/formContainer}
  22. */
  23. class FormMacros extends MacroSet
  24. {
  25. public static function install(Latte\Compiler $compiler)
  26. {
  27. $me = new static($compiler);
  28. $me->addMacro('form', [$me, 'macroForm'], 'echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack));');
  29. $me->addMacro('formContainer', [$me, 'macroFormContainer'], 'array_pop($this->global->formsStack); $formContainer = $_form = end($this->global->formsStack)');
  30. $me->addMacro('label', [$me, 'macroLabel'], [$me, 'macroLabelEnd'], NULL, self::AUTO_EMPTY);
  31. $me->addMacro('input', [$me, 'macroInput']);
  32. $me->addMacro('name', [$me, 'macroName'], [$me, 'macroNameEnd'], [$me, 'macroNameAttr']);
  33. $me->addMacro('inputError', [$me, 'macroInputError']);
  34. }
  35. /********************* macros ****************d*g**/
  36. /**
  37. * {form ...}
  38. */
  39. public function macroForm(MacroNode $node, PhpWriter $writer)
  40. {
  41. if ($node->modifiers) {
  42. throw new CompileException('Modifiers are not allowed in ' . $node->getNotation());
  43. }
  44. if ($node->prefix) {
  45. throw new CompileException('Did you mean <form n:name=...> ?');
  46. }
  47. $name = $node->tokenizer->fetchWord();
  48. if ($name === FALSE) {
  49. throw new CompileException('Missing form name in ' . $node->getNotation());
  50. }
  51. $node->replaced = TRUE;
  52. $node->tokenizer->reset();
  53. return $writer->write(
  54. "/* line $node->startLine */\n"
  55. . 'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsStack[] = '
  56. . ($name[0] === '$' ? 'is_object(%node.word) ? %node.word : ' : '')
  57. . '$this->global->uiControl[%node.word], %node.array);'
  58. );
  59. }
  60. /**
  61. * {formContainer ...}
  62. */
  63. public function macroFormContainer(MacroNode $node, PhpWriter $writer)
  64. {
  65. if ($node->modifiers) {
  66. throw new CompileException('Modifiers are not allowed in ' . $node->getNotation());
  67. }
  68. $name = $node->tokenizer->fetchWord();
  69. if ($name === FALSE) {
  70. throw new CompileException('Missing name in ' . $node->getNotation());
  71. }
  72. $node->tokenizer->reset();
  73. return $writer->write(
  74. '$this->global->formsStack[] = $formContainer = $_form = '
  75. . ($name[0] === '$' ? 'is_object(%node.word) ? %node.word : ' : '')
  76. . 'end($this->global->formsStack)[%node.word];'
  77. );
  78. }
  79. /**
  80. * {label ...}
  81. */
  82. public function macroLabel(MacroNode $node, PhpWriter $writer)
  83. {
  84. if ($node->modifiers) {
  85. throw new CompileException('Modifiers are not allowed in ' . $node->getNotation());
  86. }
  87. $words = $node->tokenizer->fetchWords();
  88. if (!$words) {
  89. throw new CompileException('Missing name in ' . $node->getNotation());
  90. }
  91. $node->replaced = true;
  92. $name = array_shift($words);
  93. return $writer->write(
  94. ($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : end($this->global->formsStack)[%0.word]; if ($_label = $_input' : 'if ($_label = end($this->global->formsStack)[%0.word]')
  95. . '->%1.raw) echo $_label'
  96. . ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : ''),
  97. $name,
  98. $words ? ('getLabelPart(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')') : 'getLabel()'
  99. );
  100. }
  101. /**
  102. * {/label}
  103. */
  104. public function macroLabelEnd(MacroNode $node, PhpWriter $writer)
  105. {
  106. if ($node->content != NULL) {
  107. $node->openingCode = rtrim($node->openingCode, '?> ') . '->startTag() ?>';
  108. return $writer->write('if ($_label) echo $_label->endTag()');
  109. }
  110. }
  111. /**
  112. * {input ...}
  113. */
  114. public function macroInput(MacroNode $node, PhpWriter $writer)
  115. {
  116. if ($node->modifiers) {
  117. throw new CompileException('Modifiers are not allowed in ' . $node->getNotation());
  118. }
  119. $words = $node->tokenizer->fetchWords();
  120. if (!$words) {
  121. throw new CompileException('Missing name in ' . $node->getNotation());
  122. }
  123. $node->replaced = true;
  124. $name = array_shift($words);
  125. return $writer->write(
  126. ($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : end($this->global->formsStack)[%0.word]; echo $_input' : 'echo end($this->global->formsStack)[%0.word]')
  127. . '->%1.raw'
  128. . ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : '')
  129. . " /* line $node->startLine */",
  130. $name,
  131. $words ? 'getControlPart(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')' : 'getControl()'
  132. );
  133. }
  134. /**
  135. * <form n:name>, <input n:name>, <select n:name>, <textarea n:name>, <label n:name> and <button n:name>
  136. */
  137. public function macroNameAttr(MacroNode $node, PhpWriter $writer)
  138. {
  139. $words = $node->tokenizer->fetchWords();
  140. if (!$words) {
  141. throw new CompileException('Missing name in ' . $node->getNotation());
  142. }
  143. $name = array_shift($words);
  144. $tagName = strtolower($node->htmlNode->name);
  145. $node->empty = $tagName === 'input';
  146. if ($tagName === 'form') {
  147. $node->openingCode = $writer->write(
  148. '<?php $form = $_form = $this->global->formsStack[] = '
  149. . ($name[0] === '$' ? 'is_object(%0.word) ? %0.word : ' : '')
  150. . '$this->global->uiControl[%0.word]; ?>',
  151. $name
  152. );
  153. return $writer->write(
  154. 'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin(end($this->global->formsStack), %0.var, FALSE)',
  155. array_fill_keys(array_keys($node->htmlNode->attrs), NULL)
  156. );
  157. } else {
  158. $method = $tagName === 'label' ? 'getLabel' : 'getControl';
  159. return $writer->write(
  160. '$_input = ' . ($name[0] === '$' ? 'is_object(%0.word) ? %0.word : ' : '')
  161. . 'end($this->global->formsStack)[%0.word]; echo $_input->%1.raw'
  162. . ($node->htmlNode->attrs ? '->addAttributes(%2.var)' : '') . '->attributes()',
  163. $name,
  164. $method . 'Part(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')',
  165. array_fill_keys(array_keys($node->htmlNode->attrs), NULL)
  166. );
  167. }
  168. }
  169. public function macroName(MacroNode $node, PhpWriter $writer)
  170. {
  171. if (!$node->prefix) {
  172. throw new CompileException("Unknown macro {{$node->name}}, use n:{$node->name} attribute.");
  173. } elseif ($node->prefix !== MacroNode::PREFIX_NONE) {
  174. throw new CompileException("Unknown attribute n:{$node->prefix}-{$node->name}, use n:{$node->name} attribute.");
  175. }
  176. }
  177. public function macroNameEnd(MacroNode $node, PhpWriter $writer)
  178. {
  179. $tagName = strtolower($node->htmlNode->name);
  180. if ($tagName === 'form') {
  181. $node->innerContent .= '<?php echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), FALSE); ?>';
  182. } elseif ($tagName === 'label') {
  183. if ($node->htmlNode->empty) {
  184. $node->innerContent = "<?php echo \$_input->getLabelPart()->getHtml() ?>";
  185. }
  186. } elseif ($tagName === 'button') {
  187. if ($node->htmlNode->empty) {
  188. $node->innerContent = '<?php echo htmlspecialchars($_input->caption) ?>';
  189. }
  190. } else { // select, textarea
  191. $node->innerContent = '<?php echo $_input->getControl()->getHtml() ?>';
  192. }
  193. }
  194. /**
  195. * {inputError ...}
  196. */
  197. public function macroInputError(MacroNode $node, PhpWriter $writer)
  198. {
  199. if ($node->modifiers) {
  200. throw new CompileException('Modifiers are not allowed in ' . $node->getNotation());
  201. }
  202. $name = $node->tokenizer->fetchWord();
  203. $node->replaced = true;
  204. if (!$name) {
  205. return $writer->write('echo %escape($_input->getError());');
  206. } elseif ($name[0] === '$') {
  207. return $writer->write('$_input = is_object(%0.word) ? %0.word : end($this->global->formsStack)[%0.word]; echo %escape($_input->getError());', $name);
  208. } else {
  209. return $writer->write('echo %escape(end($this->global->formsStack)[%0.word]->getError());', $name);
  210. }
  211. }
  212. /** @deprecated */
  213. public static function renderFormBegin(Form $form, array $attrs, $withTags = TRUE)
  214. {
  215. trigger_error(__METHOD__ . '() is deprecated, use Nette\Bridges\FormsLatte\Runtime::renderFormBegin()', E_USER_DEPRECATED);
  216. echo Runtime::renderFormBegin($form, $attrs, $withTags);
  217. }
  218. /** @deprecated */
  219. public static function renderFormEnd(Form $form, $withTags = TRUE)
  220. {
  221. trigger_error(__METHOD__ . '() is deprecated, use Nette\Bridges\FormsLatte\Runtime::renderFormEnd()', E_USER_DEPRECATED);
  222. echo Runtime::renderFormEnd($form, $withTags);
  223. }
  224. }