/** * Compile the attribute value into it's PHP code. * * @param ExpressCompiler $compiler * @param integer $flags Raw mode is used when the element is going to be morphed from a TagBuilder. */ public function compile(ExpressCompiler $compiler, $flags = 0) { try { if ($flags & self::FLAG_RAW) { if (empty($this->childNodes)) { $compiler->write("''"); } else { $compiler->write('('); foreach ($this->childNodes as $i => $node) { if ($i > 0) { $compiler->write(' . '); } $node->compile($compiler, self::FLAG_RAW); } $compiler->write(')'); } } else { foreach ($this->childNodes as $node) { $node->compile($compiler); } } } catch (ExpressViewException $e) { throw $e; } catch (\Exception $e) { throw new ExpressViewException(sprintf('Unable to compile attribute "%s"', $this->name), $compiler->getResource(), $this->line, $e); } }
public function getHelper(ExpressCompiler $compiler) { if ($this->helper === NULL) { $this->helper = $compiler->getHelper($this->namespace, $this->name); } return $this->helper; }
public function compile(ExpressCompiler $compiler, $flags = 0) { try { $sub = $compiler->createCompiler(); foreach ($this->childNodes as $node) { $node->compile($sub); } $compiler->writeBlock($this->name, $sub); } catch (ExpressViewException $e) { throw $e; } catch (\Exception $e) { throw new ExpressViewException(sprintf('Unable to compile block "%s"', $this->name), $compiler->getResource(), $this->line, $e); } }
/** * Compiles the text node into it's PHP code. * * @param ExpressCompiler $compiler * @param integer $flags Raw mode is used when an element is morphed using a tag builder. */ public function compile(ExpressCompiler $compiler, $flags = 0) { try { if ($flags & self::FLAG_RAW) { $compiler->write(var_export($this->text, true)); } else { // Using ENT_COMPAT due to Knockout JS (and others) data binding, this is not risky // in Express-parsed attribute values due to the fact that all attribute values // are normalized to be quoted using double quotes. $compiler->out(htmlspecialchars($this->text, ENT_COMPAT | ENT_XML1 | ENT_SUBSTITUTE, 'UTF-8')); } } catch (ExpressViewException $e) { throw $e; } catch (\Exception $e) { throw new ExpressViewException('Unable to compile text node', $compiler->getResource(), $this->line, $e); } }
public function compile(ExpressCompiler $compiler, $flags = 0) { try { $compiler->setExtends($this->extends); foreach ($this->childNodes as $node) { $node->compile($compiler); } } catch (ExpressViewException $e) { throw $e; } catch (\Exception $e) { if ($this->extends === NULL) { throw new ExpressViewException(sprintf('Unable to compile express view'), '', $this->line, $e); } $extends = ''; foreach ($this->extends as $node) { if ($node instanceof ExpressionNode) { $extends .= $node->getExpression(); } elseif ($node instanceof TextNode) { $extends .= $node->getText(); } } throw new ExpressViewException(sprintf('Unable to compile express composition extending "%s"', $extends), $compiler->getResource(), $this->line, $e); } }
/** * Compile the given XML source and return a compiler object. * * @param string $data * @return ExpressCompiler */ protected function parseView(ExpressViewRenderer $renderer, $data, $resource = '') { try { // This ugly pre-processing is neccessary due to DOM XML forgetting about self-closing elements. $reader = new XmlStreamReader(); $reader->XML($data); $buffer = '<?xml version="1.0"?>' . "\n"; while ($reader->read()) { switch ($reader->nodeType) { case XmlStreamReader::ELEMENT: $buffer .= '<' . $reader->name; $namespaces = []; while ($reader->moveToNextAttribute()) { if ($reader->namespaceURI == self::NS_XML) { switch ($reader->localName) { case 'nsdec': case 'empty': continue 2; } } if ($reader->namespaceURI == self::NS_XMLNS) { $namespaces[$reader->name] = $reader->value; } $buffer .= ' ' . $reader->name . '="' . htmlspecialchars($reader->value, ENT_COMPAT | ENT_XML1 | ENT_SUBSTITUTE, 'UTF-8') . '"'; } $reader->moveToElement(); if (!empty($namespaces)) { $encoded = base64_encode(json_encode($namespaces, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); $buffer .= ' xml:nsdec="' . htmlspecialchars($encoded, ENT_QUOTES | ENT_XML1 | ENT_SUBSTITUTE, 'UTF-8') . '"'; } if ($reader->isEmptyElement) { $buffer .= ' xml:empty="" />'; } else { $buffer .= '>'; } break; case XmlStreamReader::END_ELEMENT: $buffer .= '</' . $reader->name . '>'; break; case XmlStreamReader::SIGNIFICANT_WHITESPACE: case XmlStreamReader::TEXT: case XmlStreamReader::WHITESPACE: $buffer .= htmlspecialchars($reader->value, ENT_QUOTES | ENT_XML1 | ENT_SUBSTITUTE, 'UTF-8'); break; } } // Parse XML buffer into a DOM document. $builder = new XmlDocumentBuilder(); $xml = $builder->buildFromSource($buffer); $compiler = new ExpressCompiler($renderer); $compiler->setResource($resource); $parser = new ExpressViewParser(); $view = $parser->parseSource($xml); $view->compile($compiler); return $compiler; } catch (\Exception $e) { $ex = $e; do { if ($ex instanceof ExpressViewException) { if ($ex->getErrorFile() === NULL) { $ex->setErrorFile($resource); } } } while ($ex = $ex->getPrevious()); throw $e; } }
/** * Compiles an expression into PHP code. * * @param ExpressCompiler $compiler * @param integer $flags Raw mode is active when an element is morphed from a TagBuilder. */ public function compile(ExpressCompiler $compiler, $flags = 0) { try { if ($flags & self::FLAG_RAW) { $compiler->write($this->expression->compile($compiler->getExpressionContextFactory(), false, '$this->exp')); } else { $compiler->write("\t\ttry {\n"); if ($this->stringify) { if ($this->expression->hasPipedFilter('raw')) { $contents = '$out->write(' . $this->expression->compile($compiler->getExpressionContextFactory(), false, '$this->exp') . ');'; } else { $contents = '$out->writeEscaped(' . $this->expression->compile($compiler->getExpressionContextFactory(), false, '$this->exp') . ');'; } } else { $contents = 'return ' . $this->expression->compile($compiler->getExpressionContextFactory(), false, $this->exp) . ';'; } $compiler->write("\t\t" . $contents . "\n"); $compiler->write("\t\t} catch(ExpressViewException \$ex) {\n"); $compiler->write("\t\t\tthrow \$ex;\n"); $compiler->write("\t\t} catch(\\Exception \$ex) {\n"); $compiler->write("\t\t\tthrow new ExpressViewException("); $compiler->write(var_export('Error during evaluation of expression "' . $this->expression . '"', true)); $compiler->write(", \$this->getResource(), {$this->line}, \$ex);\n"); $compiler->write("\t\t}\n"); } } catch (ExpressViewException $e) { throw $e; } catch (\Exception $e) { throw new ExpressViewException(sprintf('Unable to compile expression "%s"', $this->expression), $compiler->getResource(), $this->line, $e); } }
public function compile(ExpressCompiler $compiler, $flags = 0) { try { $id = $compiler->nextId(); $compiler->write("\t\ttry {\n"); $compiler->write("\t\t\$dec{$id} = new DecoratedTemplate(\$this->factory, \$this->renderer);\n"); $compiler->write("\t\t\$dec" . $id . "->bindOuterContext(\$this->context, \$this->exp);\n"); $compiler->write("\t\t\$dec" . $id . "->setResource(\$this->resolveResource("); $view = ''; foreach ($this->view as $i => $node) { if ($i != 0) { $compiler->write(' . '); } $node->compile($compiler, self::FLAG_RAW); if ($node instanceof TextNode) { $view .= $node->getText(); } elseif ($node instanceof ExpressionNode) { $view .= $node->getExpression(); } } $compiler->write("));\n"); $compiler->write("\t\t\$dec" . $id . "->setBlocks(["); $num = 0; foreach ($this->childNodes as $node) { if (!$node instanceof BlockNode) { if ($node instanceof TextNode || trim($node->getText()) == '') { continue; } throw new \InvalidArgumentException('Decorators must only habe child elements of type "block"'); } if ($num++ != 0) { $compiler->write(",\n"); } $compiler->write(var_export($node->getName(), true) . ' => function(OutputBuffer $out) { ' . "\n"); foreach ($node->getChildNodes() as $childNode) { $childNode->compile($compiler); } $compiler->write("\t\t}"); } $compiler->write("]);\n"); $compiler->write("\t\t} catch(ExpressViewException \$ex) {\n"); $compiler->write("\t\t\tthrow \$ex;\n"); $compiler->write("\t\t} catch(\\Exception \$ex) {\n"); $compiler->write("\t\t\tthrow new ExpressViewException("); $compiler->write(var_export(sprintf('Unable to create decorator for view "%s"', $view), true)); $compiler->write(", \$this->getResource(), {$this->line}, \$ex);\n"); $compiler->write("\t\t}\n"); if (!($flags & self::FLAG_NO_OUTPUT)) { $compiler->write("\t\ttry {\n"); $compiler->write("\t\t\$dec" . $id . "->__invoke(\$out);\n"); $compiler->write("\t\t} catch(ExpressViewException \$ex) {\n"); $compiler->write("\t\t\tthrow \$ex;\n"); $compiler->write("\t\t} catch(\\Exception \$ex) {\n"); $compiler->write("\t\t\tthrow new ExpressViewException("); $compiler->write(var_export(sprintf('Unable to invoke decorator for view "%s"', $view), true)); $compiler->write(", \$this->getResource(), {$this->line}, \$ex);\n"); $compiler->write("\t\t}\n"); } return '$dec' . $id; } catch (ExpressViewException $e) { throw $e; } catch (\Exception $e) { throw new ExpressViewException('Unable to compile decorator node', $compiler->getResource(), $this->line, $e); } }