Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
}
],
"require": {
"php": ">=5.3.3",
"twig/twig": "1.*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
"php": ">=7.2.5",
"twig/twig": "^3"
},
"autoload": {
"psr-0" : {
"TwigStack" : "lib/"
}
},
"require-dev": {
"phpunit/phpunit": "^9.5"
}
}
25 changes: 14 additions & 11 deletions lib/TwigStack/Extension/StackExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@

namespace TwigStack\Extension;

use Twig\NodeVisitor\NodeVisitorInterface;
use TwigStack\NodeVisitor\StackNodeVisitor;
use TwigStack\Stack;
use TwigStack\TokenParser\StackPopTokenParser;
use TwigStack\TokenParser\StackPushTokenParser;
use Twig;

/**
* The Twig extension, which should be added to the Twig environment to enable TwigStack
*
* @package TwigStack\Extension
* @author Arno Geurts
*/
class StackExtension extends \Twig_Extension
class StackExtension extends Twig\Extension\AbstractExtension
{
/**
* @var array|Stack[]
Expand All @@ -34,8 +36,9 @@ class StackExtension extends \Twig_Extension
*
* @param string $stackName
* @param string $content
* @return void
*/
public function pushStack($stackName, $content)
public function pushStack(string $stackName, string $content): void
{
if (!array_key_exists($stackName, $this->stacks)) {
$this->stacks[$stackName] = new Stack();
Expand All @@ -49,12 +52,12 @@ public function pushStack($stackName, $content)
* @param string $output
* @return string
*/
public function render($output)
public function render(string $output): string
{
$stacks = $this->stacks;
// try to find the following string in the output
// stack_pop_[stashName]([seperator])
$regex = '/stack\_pop\_([\w]*)\(([^\)]*)\)/';
$regex = '/stack_pop_([\w]*)\(([^)]*)\)/';
$callback = function($matches) use ($stacks) {
// if the requested stack does not exists, replace it with an empty string
if (!array_key_exists($matches[1], $stacks)) {
Expand All @@ -76,23 +79,23 @@ public function render($output)
*
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
public function getTokenParsers(): array
{
return array(
new StackPushTokenParser(),
new StackPopTokenParser()
new StackPushTokenParser($this),
new StackPopTokenParser($this)
);
}

/**
* Returns the node visitor instances to add to the existing list.
*
* @return \Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
* @return NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
*/
public function getNodeVisitors()
public function getNodeVisitors(): array
{
return array(
new StackNodeVisitor()
new StackNodeVisitor($this)
);
}

Expand All @@ -101,7 +104,7 @@ public function getNodeVisitors()
*
* @return string The extension name
*/
public function getName()
public function getName(): string
{
return 'stack';
}
Expand Down
27 changes: 18 additions & 9 deletions lib/TwigStack/Node/StackBodyNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,38 @@

namespace TwigStack\Node;

use Twig\Node\Node;
use Twig;

/**
* Class StackBodyNode
* @package TwigStack\Node
*/
class StackBodyNode extends \Twig_Node
class StackBodyNode extends Node
{
/**
* Consturct the stack body with the original body
* @var Twig\Extension\ExtensionInterface
*/
private $ext;

/**
* Construct the stack body with the original body
*
* @param \Twig_Node $body
* @param Twig\Extension\ExtensionInterface $ext
* @param Node $body
*/
public function __construct(\Twig_Node $body)
public function __construct(Twig\Extension\ExtensionInterface $ext, Node $body)
{
parent::__construct(array('body' => $body));
$this->ext = $ext;
}

/**
* Compiles the node to PHP.
*
* @param \Twig_Compiler A Twig_Compiler instance
* @param Twig\Compiler $compiler A Twig_Compiler instance
*/
public function compile(\Twig_Compiler $compiler)
public function compile(Twig\Compiler $compiler)
{
$compiler
->write("ob_start();\n")
Expand All @@ -45,7 +55,6 @@ public function compile(\Twig_Compiler $compiler)
->write("throw \$e;\n")
->outdent()
->write("}\n\n")
->write("echo \$this->env->getExtension('stack')->render(ob_get_clean());\n\n")
;
->write("echo \$this->env->getExtension(" . get_class($this->ext) . "::class)->render(ob_get_clean());\n\n");
}
}
}
25 changes: 19 additions & 6 deletions lib/TwigStack/Node/StackPopNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,41 @@

namespace TwigStack\Node;

use Twig;

/**
* Class StackPopNode
* @package TwigStack\Node
*/
class StackPopNode extends \Twig_Node
class StackPopNode extends Twig\Node\Node
{
/**
* @var Twig\Extension\ExtensionInterface
*/
private $ext;

/**
* @param Twig\Extension\ExtensionInterface $ext,
* @param string $name
* @param \Twig_Node $separator
* @param Twig\Node\Node $separator
* @param int $lineno
*/
public function __construct($name, \Twig_Node $separator, $lineno = 0)
{
public function __construct(
Twig\Extension\ExtensionInterface $ext,
string $name,
Twig\Node\Node $separator,
int $lineno = 0
) {
parent::__construct(array('separator' => $separator), array('name' => $name), $lineno);
$this->ext = $ext;
}

/**
* Compiles the node to PHP.
*
* @param \Twig_Compiler A Twig_Compiler instance
* @param Twig\Compiler $compiler A Twig_Compiler instance
*/
public function compile(\Twig_Compiler $compiler)
public function compile(Twig\Compiler $compiler)
{
$compiler
->write(sprintf("echo 'stack_pop_%s(' . ", $this->getAttribute('name')))
Expand Down
34 changes: 24 additions & 10 deletions lib/TwigStack/Node/StackPushNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,46 @@

namespace TwigStack\Node;

use Twig;
use TwigStack\Extension\StackExtension;

/**
* Class StackPushNode
* @package TwigStack\Node
*/
class StackPushNode extends \Twig_Node
class StackPushNode extends Twig\Node\Node
{
/**
* @var Twig\Extension\ExtensionInterface
*/
private $ext;

/**
* Construct the stack body with the original body
*
* @param Twig\Extension\ExtensionInterface $ext
* @param string $name
* @param \Twig_Node $body
* @param Twig\Node\Node $body
* @param int $lineno
* @param string $tag
* @param string|null $tag
*/
public function __construct($name, \Twig_Node $body, $lineno = 0, $tag = null)
{
public function __construct(
Twig\Extension\ExtensionInterface $ext,
string $name,
Twig\Node\Node $body,
int $lineno = 0,
string $tag = null
) {
parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
$this->ext = $ext;
}

/**
* Compiles the node to PHP.
*
* @param \Twig_Compiler A Twig_Compiler instance
* @param Twig\Compiler $compiler A Twig\Compiler instance
*/
public function compile(\Twig_Compiler $compiler)
public function compile(Twig\Compiler $compiler)
{
$compiler
->write("ob_start();\n")
Expand All @@ -49,7 +64,6 @@ public function compile(\Twig_Compiler $compiler)
->outdent()
->write("}\n\n")
->write("\$result = ob_get_clean();\n")
->write(sprintf("\$this->env->getExtension('stack')->pushStack('%s', \$result);\n\n", $this->getAttribute('name')));
;
->write(sprintf("\$this->env->getExtension(" . get_class($this->ext) . "::class)->pushStack('%s', \$result);\n\n", $this->getAttribute('name')));
}
}
}
45 changes: 24 additions & 21 deletions lib/TwigStack/NodeVisitor/StackNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,64 +10,67 @@

namespace TwigStack\NodeVisitor;

use Twig\Environment;
use Twig\Node\Node;
use TwigStack\Node\StackBodyNode;
use Twig;

/**
* Class StackNodeVisitor
* @package TwigStack\NodeVisitor
*/
class StackNodeVisitor implements \Twig_NodeVisitorInterface
class StackNodeVisitor extends Twig\NodeVisitor\AbstractNodeVisitor
{
/**
* Called before child nodes are visited.
*
* @param \Twig_NodeInterface $node The node to visit
* @param \Twig_Environment $env The Twig environment instance
* @return \Twig_NodeInterface The modified node
* @var Twig\Extension\ExtensionInterface
*/
private $ext;

public function __construct(Twig\Extension\ExtensionInterface $ext)
{
$this->ext = $ext;
}
/**
* @inheritDoc
*/
public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
protected function doEnterNode(Node $node, Environment $env): Node
{
return $node;
}

/**
* Called after child nodes are visited.
*
* @param \Twig_NodeInterface $node The node to visit
* @param \Twig_Environment $env The Twig environment instance
* @return \Twig_NodeInterface|false The modified node or false if the node must be removed
* @inheritDoc
*/
public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
protected function doLeaveNode(Node $node, Environment $env): Node
{
if ($node instanceof \Twig_Node_Module) {
if ($node instanceof Twig\Node\ModuleNode) {
$this->handleModuleNode($node);
}

return $node;
}

/**
* Handle the module node
* Add a render stash node to the end of the module body, only when the template does not have a parent
*
* @param \Twig_Node_Module $node
* @param Twig\Node\ModuleNode $node
*/
private function handleModuleNode(\Twig_Node_Module $node)
private function handleModuleNode(Twig\Node\ModuleNode $node)
{
if ($node->hasNode('body') && !$node->hasNode('parent')) {
$body = $node->getNode('body');
$node->setNode('body', new StackBodyNode($body));
$node->setNode('body', new StackBodyNode($this->ext, $body));
}
}

/**
* Returns the priority for this visitor.
* Priority should be between -10 and 10 (0 is the default).
*
* @return integer The priority level
* @return int The priority level
*/
public function getPriority()
public function getPriority(): int
{
return -10;
}
}
}
9 changes: 6 additions & 3 deletions lib/TwigStack/Stack.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@

namespace TwigStack;

use ArrayObject;

/**
* Class Stack
* @package TwigStack
*/
class Stack extends \ArrayObject
class Stack extends ArrayObject
{
/**
* Separator which is used to join the stack, when cast to string
Expand All @@ -37,8 +39,9 @@ public function push($content)
* Set the separator which is used to join the stack
*
* @param string $separator
* @return void
*/
public function setSeparator($separator)
public function setSeparator(string $separator): void
{
$this->separator = $separator;
}
Expand All @@ -54,4 +57,4 @@ public function __toString()
{
return join($this->separator, $this->getArrayCopy());
}
}
}
Loading