first commit

This commit is contained in:
root
2020-02-19 16:42:35 +01:00
commit d668d90f82
2224 changed files with 334338 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
<?php
namespace Phive\Twig\Extensions\Deferred;
class DeferredBlockNode extends \Twig_Node_Block
{
public function compile(\Twig_Compiler $compiler)
{
$name = $this->getAttribute('name');
$compiler
->write("public function block_$name(\$context, array \$blocks = array())\n", "{\n")
->indent()
->write("\$this->env->getExtension('Phive\\Twig\\Extensions\\Deferred\\DeferredExtension')->defer(\$this, '$name');\n")
->outdent()
->write("}\n\n")
;
$compiler
->addDebugInfo($this)
->write("public function block_{$name}_deferred(\$context, array \$blocks = array())\n", "{\n")
->indent()
->subcompile($this->getNode('body'))
->write("\$this->env->getExtension('Phive\\Twig\\Extensions\\Deferred\\DeferredExtension')->resolve(\$this, \$context, \$blocks);\n")
->outdent()
->write("}\n\n")
;
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Phive\Twig\Extensions\Deferred;
class DeferredExtension extends \Twig_Extension
{
/**
* @var array
*/
private $blocks = array();
/**
* {@inheritdoc}
*/
public function getTokenParsers()
{
return array(new DeferredTokenParser());
}
/**
* {@inheritdoc}
*/
public function getNodeVisitors()
{
return array(new DeferredNodeVisitor());
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'deferred';
}
public function defer(\Twig_Template $template, $blockName)
{
$templateName = $template->getTemplateName();
$this->blocks[$templateName][] = $blockName;
ob_start();
}
public function resolve(\Twig_Template $template, array $context, array $blocks)
{
$templateName = $template->getTemplateName();
if (empty($this->blocks[$templateName])) {
return;
}
while ($blockName = array_pop($this->blocks[$templateName])) {
$buffer = ob_get_clean();
$blocks[$blockName] = array($template, 'block_'.$blockName.'_deferred');
$template->displayBlock($blockName, $context, $blocks);
echo $buffer;
}
if ($parent = $template->getParent($context)) {
$this->resolve($parent, $context, $blocks);
}
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Phive\Twig\Extensions\Deferred;
class DeferredNode extends \Twig_Node
{
public function compile(\Twig_Compiler $compiler)
{
$compiler
->write("\$this->env->getExtension('Phive\\Twig\\Extensions\\Deferred\\DeferredExtension')->resolve(\$this, \$context, \$blocks);\n")
;
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Phive\Twig\Extensions\Deferred;
class DeferredNodeVisitor implements \Twig_NodeVisitorInterface
{
private $hasDeferred = false;
/**
* {@inheritdoc}
*/
public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
{
if (!$this->hasDeferred && $node instanceof DeferredBlockNode) {
$this->hasDeferred = true;
}
return $node;
}
/**
* {@inheritdoc}
*/
public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
{
if ($this->hasDeferred && $node instanceof \Twig_Node_Module) {
$node->setNode('display_end', new \Twig_Node(array(new DeferredNode(), $node->getNode('display_end'))));
$this->hasDeferred = false;
}
return $node;
}
/**
* {@inheritdoc}
*/
public function getPriority()
{
return 0;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Phive\Twig\Extensions\Deferred;
class DeferredTokenParser extends \Twig_TokenParser
{
private $blockTokenParser;
public function setParser(\Twig_Parser $parser)
{
parent::setParser($parser);
$this->blockTokenParser = new \Twig_TokenParser_Block();
$this->blockTokenParser->setParser($parser);
}
public function parse(\Twig_Token $token)
{
$stream = $this->parser->getStream();
$nameToken = $stream->next();
$deferredToken = $stream->nextIf(\Twig_Token::NAME_TYPE, 'deferred');
$stream->injectTokens(array($nameToken));
$node = $this->blockTokenParser->parse($token);
if ($deferredToken) {
$this->replaceBlockNode($nameToken->getValue());
}
return $node;
}
public function getTag()
{
return 'block';
}
private function replaceBlockNode($name)
{
$block = $this->parser->getBlock($name)->getNode(0);
$this->parser->setBlock($name, $this->createDeferredBlockNode($block));
}
private function createDeferredBlockNode(\Twig_Node_Block $block)
{
$name = $block->getAttribute('name');
$deferredBlock = new DeferredBlockNode($name, new \Twig_Node(array()), $block->getTemplateLine());
foreach ($block as $nodeName => $node) {
$deferredBlock->setNode($nodeName, $node);
}
$deferredBlock->setTemplateName($block->getTemplateName());
return $deferredBlock;
}
}