1: <?php
2:
3: 4: 5: 6: 7: 8: 9:
10:
11: namespace Kdyby\BootstrapFormRenderer\Latte;
12: use Kdyby;
13: use Kdyby\BootstrapFormRenderer\BootstrapRenderer;
14: use Nette;
15: use Nette\Forms\Form;
16: use Nette\Latte;
17: use Nette\Latte\MacroNode;
18: use Nette\Latte\PhpWriter;
19: use Nette\Reflection\ClassType;
20:
21:
22:
23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
55: class FormMacros extends Latte\Macros\MacroSet
56: {
57:
58: 59: 60: 61:
62: public static function install(Latte\Compiler $compiler)
63: {
64: $me = new static($compiler);
65: $me->addMacro('form', array($me, 'macroFormBegin'), array($me, 'macroFormEnd'));
66: $me->addMacro('pair', array($me, 'macroPair'));
67: $me->addMacro('group', array($me, 'macroGroup'));
68: $me->addMacro('container', array($me, 'macroContainer'));
69: return $me;
70: }
71:
72:
73:
74: 75: 76:
77: private function findCurrentToken()
78: {
79: static $positionRef, $tokensRef;
80:
81: if (!property_exists('Nette\Latte\Token', 'empty')) {
82: return NULL;
83: }
84:
85: if (empty($positionRef)) {
86: $compilerRef = ClassType::from($this->getCompiler());
87: $positionRef = $compilerRef->getProperty('position');
88: $positionRef->setAccessible(TRUE);
89: $tokensRef = $compilerRef->getProperty('tokens');
90: $tokensRef->setAccessible(TRUE);
91: }
92:
93: $tokens = $tokensRef->getValue($this->getCompiler());
94: return $tokens[$positionRef->getValue($this->getCompiler())];
95: }
96:
97:
98:
99: 100: 101: 102: 103:
104: public function macroFormBegin(MacroNode $node, PhpWriter $writer)
105: {
106: if ($node->isEmpty = (substr($node->args, -1) === '/')) {
107: $node->setArgs(substr($node->args, 0, -1));
108:
109: return $writer->write('$form = $__form = $_form = (is_object(%node.word) ? %node.word : $_control->getComponent(%node.word)); $__form->render(NULL, %node.array);');
110:
111: } elseif (($token = $this->findCurrentToken()) && $token->empty) {
112:
113: return $writer->write('$form = $__form = $_form = (is_object(%node.word) ? %node.word : $_control->getComponent(%node.word)); $__form->render(NULL, %node.array);');
114: }
115:
116: $word = $node->tokenizer->fetchWord();
117: $node->isEmpty = in_array($word, array('errors', 'body', 'controls', 'buttons'));
118: $node->tokenizer->reset();
119:
120: return $writer->write('$form = $__form = $_form = ' . get_called_class() . '::renderFormPart(%node.word, %node.array, get_defined_vars())');
121: }
122:
123:
124:
125: 126: 127: 128:
129: public function macroFormEnd(MacroNode $node, PhpWriter $writer)
130: {
131: if (($token = $this->findCurrentToken()) && $token->empty) {
132: return '';
133: }
134:
135: return $writer->write('Nette\Latte\Macros\FormMacros::renderFormEnd($__form)');
136: }
137:
138:
139:
140: 141: 142: 143:
144: public function macroPair(MacroNode $node, PhpWriter $writer)
145: {
146: return $writer->write('$__form->render($__form[%node.word], %node.array)');
147: }
148:
149:
150:
151: 152: 153: 154:
155: public function macroGroup(MacroNode $node, PhpWriter $writer)
156: {
157: return $writer->write('$__form->render(is_object(%node.word) ? %node.word : $__form->getGroup(%node.word))');
158: }
159:
160:
161:
162: 163: 164: 165:
166: public function macroContainer(MacroNode $node, PhpWriter $writer)
167: {
168: return $writer->write('$__form->render($__form[%node.word], %node.array)');
169: }
170:
171:
172:
173: 174: 175: 176: 177: 178: 179:
180: public static function renderFormPart($mode, array $args, array $scope)
181: {
182: if ($mode instanceof Form) {
183: self::renderFormBegin($mode, $args);
184: return $mode;
185:
186: } elseif (($control = self::scopeVar($scope, 'control')) && ($form = $control->getComponent($mode, FALSE)) instanceof Form) {
187: self::renderFormBegin($form, $args);
188: return $form;
189:
190: } elseif (($form = self::scopeVar($scope, 'form')) instanceof Form) {
191: $form->render($mode, $args);
192:
193: } else {
194: throw new Nette\InvalidStateException('No instanceof Nette\Forms\Form found in local scope.');
195: }
196:
197: return $form;
198: }
199:
200:
201:
202: 203: 204: 205:
206: private static function renderFormBegin(Form $form, array $args)
207: {
208: if ($form->getRenderer() instanceof BootstrapRenderer) {
209: $form->render('begin', $args);
210:
211: } else {
212: Latte\Macros\FormMacros::renderFormBegin($form, $args);
213: }
214: }
215:
216:
217:
218: 219: 220: 221: 222:
223: private static function scopeVar(array $scope, $var)
224: {
225: return isset($scope['__' . $var])
226: ? $scope['__' . $var]
227: : (isset($scope['_' . $var])
228: ? $scope['_' . $var]
229: : (isset($scope[$var]) ? $scope[$var] : NULL));
230: }
231:
232: }
233: