/** * Adds debugging information. * * @param Apishka_Templater_Node $node The related twig node * * @return Apishka_Templater_Compiler The current compiler instance */ public function addDebugInfo(Apishka_Templater_NodeAbstract $node) { if ($node->getLine() != $this->_last_line) { $this->write(sprintf("// line %d\n", $node->getLine())); // when mbstring.func_overload is set to 2 // mb_substr_count() replaces substr_count() // but they have different signatures! if ((int) ini_get('mbstring.func_overload') & 2) { // this is much slower than the "right" version $this->_source_line += mb_substr_count(mb_substr($this->_source, $this->_source_offset), "\n"); } else { $this->_source_line += substr_count($this->_source, "\n", $this->_source_offset); } $this->_source_offset = strlen($this->_source); $this->_debug_info[$this->_source_line] = $node->getLine(); $this->_last_line = $node->getLine(); } return $this; }
private function getEscaperFilter($type, Apishka_Templater_NodeAbstract $node) { $line = $node->getLine(); $name = Apishka_Templater_Node_Expression_Constant::apishka('escape', $line); $args = Apishka_Templater_Node::apishka(array(Apishka_Templater_Node_Expression_Constant::apishka((string) $type, $line), Apishka_Templater_Node_Expression_Constant::apishka(null, $line), Apishka_Templater_Node_Expression_Constant::apishka(true, $line))); return Apishka_Templater_Node_Expression_Filter::apishka($node, $name, $args, $line); }
private function filterBodyNodes(Apishka_Templater_NodeAbstract $node) { // check that the body does not contain non-empty output nodes if ($node instanceof Apishka_Templater_Node_Text && !ctype_space($node->getAttribute('data')) || !$node instanceof Apishka_Templater_Node_Text && !$node instanceof Apishka_Templater_Node_BlockReference && $node instanceof Apishka_Templater_NodeOutputInterface) { if (false !== strpos((string) $node, chr(0xef) . chr(0xbb) . chr(0xbf))) { throw new Apishka_Templater_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename()); } throw new Apishka_Templater_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename()); } // bypass "set" nodes as they "capture" the output if ($node instanceof Apishka_Templater_Node_Set) { return $node; } if ($node instanceof Apishka_Templater_NodeOutputInterface) { return; } foreach ($node as $k => $n) { if (null !== $n && null === $this->filterBodyNodes($n)) { $node->removeNode($k); } } return $node; }
private function checkLoopUsageBody(Apishka_Templater_TokenStream $stream, Apishka_Templater_NodeAbstract $node) { if ($node instanceof Apishka_Templater_Node_Expression_GetAttr && $node->getNode('node') instanceof Apishka_Templater_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { $attribute = $node->getNode('attribute'); if ($attribute instanceof Apishka_Templater_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) { throw new Apishka_Templater_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename()); } } // should check for parent.loop.XXX usage if ($node instanceof Apishka_Templater_Node_For) { return; } foreach ($node as $n) { if (!$n) { continue; } $this->checkLoopUsageBody($stream, $n); } }