Skip to content

Commit 97673e2

Browse files
Support twig version 3
Co-authored-by: Dieter Holvoet <dieter.holvoet@gmail.com>
1 parent 1f9c983 commit 97673e2

9 files changed

Lines changed: 274 additions & 71 deletions
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Drupal\wmcontroller\EventSubscriber;
4+
5+
use Drupal\wmcontroller\Event\PresentedEvent;
6+
use Drupal\wmcontroller\WmcontrollerEvents;
7+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8+
9+
class TemplateParameterCacheableDependencySubscriber implements EventSubscriberInterface
10+
{
11+
protected static $dispatched = [];
12+
13+
public static function getSubscribedEvents(): array
14+
{
15+
$events[WmcontrollerEvents::PRESENTED][] = ['onTemplateParameter'];
16+
17+
return $events;
18+
}
19+
20+
public function onTemplateParameter(PresentedEvent $event): void
21+
{
22+
$value = $event->getItem();
23+
24+
if (!($value instanceof \Drupal\Core\Entity\EntityInterface)) {
25+
return;
26+
}
27+
28+
$key = sprintf('%s:%s', $value->getEntityTypeId(), $value->id());
29+
if (isset(self::$dispatched[$key])) {
30+
return;
31+
}
32+
33+
self::$dispatched[$key] = true;
34+
\Drupal::service('wmcontroller.cache.dispatcher')
35+
->dispatchPresented($value);
36+
}
37+
38+
}

src/Twig/Extension.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Drupal\wmcontroller\Twig;
4+
5+
use Drupal\wmcontroller\Twig\NodeVisitor\DebugNodeVisitor;
6+
use Drupal\wmcontroller\Twig\NodeVisitor\DispatchParameterEventNodeVisitor;
7+
use Twig\Extension\AbstractExtension;
8+
9+
class Extension extends AbstractExtension
10+
{
11+
public function getNodeVisitors(): array
12+
{
13+
return [
14+
new DebugNodeVisitor(),
15+
new DispatchParameterEventNodeVisitor(),
16+
];
17+
}
18+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Drupal\wmcontroller\Twig\Node;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Node;
7+
8+
class DispatchParameterEventNode extends Node
9+
{
10+
public function compile(Compiler $compiler)
11+
{
12+
parent::compile($compiler);
13+
14+
$compiler->raw('
15+
foreach ($context as $key => $value) {
16+
$event = new \Drupal\wmcontroller\Event\PresentedEvent($value);
17+
$this->getDispatcher()->dispatch(
18+
$event,
19+
\Drupal\wmcontroller\WmcontrollerEvents::PRESENTED
20+
);
21+
22+
$context[$key] = $event->getItem();
23+
}
24+
');
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Drupal\wmcontroller\Twig\Node;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Node;
7+
8+
class InjectEventDispatcherNode extends Node
9+
{
10+
public function compile(Compiler $compiler)
11+
{
12+
parent::compile($compiler);
13+
14+
$compiler->raw('
15+
protected \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher;
16+
17+
protected function getDispatcher()
18+
{
19+
if (isset($this->dispatcher)) {
20+
return $this->dispatcher;
21+
}
22+
23+
return $this->dispatcher = \Drupal::service("event_dispatcher");
24+
}
25+
');
26+
}
27+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace Drupal\wmcontroller\Twig\NodeVisitor;
4+
5+
use Twig\Environment;
6+
use Twig\Node\ModuleNode;
7+
use Twig\Node\Node;
8+
use Twig\Node\TextNode;
9+
use Twig\NodeVisitor\NodeVisitorInterface;
10+
11+
/**
12+
* A Twig node visitor that adds debug information around components.
13+
*/
14+
class DebugNodeVisitor implements NodeVisitorInterface
15+
{
16+
/**
17+
* {@inheritdoc}
18+
*/
19+
public function enterNode(Node $node, Environment $env): Node
20+
{
21+
if (!$env->isDebug()) {
22+
return $node;
23+
}
24+
25+
if (!$node instanceof ModuleNode) {
26+
return $node;
27+
}
28+
29+
if (!$source = $node->getSourceContext()) {
30+
return $node;
31+
}
32+
33+
$name = $source->getName();
34+
$path = str_replace(DRUPAL_ROOT . '/', '', $source->getPath());
35+
36+
if ($this->isNodeEmpty($node->getNode('body'))) {
37+
// This node is empty.
38+
return $node;
39+
}
40+
41+
$nodes = [
42+
new TextNode('<!-- TWIG DEBUG -->', 0),
43+
new TextNode(sprintf('<!-- Template: %s -->', $name), 0),
44+
];
45+
46+
if ($name !== $path) {
47+
$nodes[] = new TextNode(sprintf('<!-- Path: %s -->', $path), 0);
48+
}
49+
50+
$node->getNode('display_start')
51+
->setNode('_components_debug', new Node($nodes));
52+
53+
return $node;
54+
}
55+
56+
/**
57+
* {@inheritdoc}
58+
*/
59+
public function leaveNode(Node $node, Environment $env): ?Node
60+
{
61+
return $node;
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*/
67+
public function getPriority(): int
68+
{
69+
return 0;
70+
}
71+
72+
/**
73+
* Checks whether a node - or one of its subnodes - actually contain something.
74+
*/
75+
protected function isNodeEmpty(Node $node): bool
76+
{
77+
$subNodes = iterator_to_array($node);
78+
if (count($subNodes) > 1) {
79+
return FALSE;
80+
}
81+
82+
foreach ($subNodes as $subNode) {
83+
if (!$this->isNodeEmpty($subNode)) {
84+
return FALSE;
85+
}
86+
}
87+
88+
return TRUE;
89+
}
90+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace Drupal\wmcontroller\Twig\NodeVisitor;
4+
5+
use Drupal\wmcontroller\Twig\Node\DispatchParameterEventNode;
6+
use Drupal\wmcontroller\Twig\Node\InjectEventDispatcherNode;
7+
use Twig\Environment;
8+
use Twig\Node\ModuleNode;
9+
use Twig\Node\Node;
10+
use Twig\NodeVisitor\NodeVisitorInterface;
11+
12+
class DispatchParameterEventNodeVisitor implements NodeVisitorInterface
13+
{
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
public function enterNode(Node $node, Environment $env): Node
18+
{
19+
if (!$node instanceof ModuleNode) {
20+
return $node;
21+
}
22+
23+
if ($this->isNodeEmpty($node->getNode('body'))) {
24+
// This node is empty.
25+
return $node;
26+
}
27+
28+
$node->getNode('display_start')
29+
->setNode('_wmcontroller_template_parameter_event_dispatch', new DispatchParameterEventNode());
30+
31+
$node->getNode('class_end')
32+
->setNode('_wmcontroller_template_parameter_event_dispatch', new InjectEventDispatcherNode());
33+
34+
return $node;
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function leaveNode(Node $node, Environment $env): ?Node
41+
{
42+
return $node;
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
public function getPriority(): int
49+
{
50+
return 0;
51+
}
52+
53+
/**
54+
* Checks whether a node - or one of its subnodes - actually contain something.
55+
*/
56+
protected function isNodeEmpty(Node $node): bool
57+
{
58+
$subNodes = iterator_to_array($node);
59+
if (count($subNodes) > 1) {
60+
return FALSE;
61+
}
62+
63+
foreach ($subNodes as $subNode) {
64+
if (!$this->isNodeEmpty($subNode)) {
65+
return FALSE;
66+
}
67+
}
68+
69+
return TRUE;
70+
}
71+
}

src/Twig/Template.php

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/WmcontrollerServiceProvider.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,5 @@ public function alter(ContainerBuilder $container)
1212
if ($container->getParameter('wmcontroller.cache.tags')) {
1313
$container->removeDefinition('http_middleware.page_cache');
1414
}
15-
16-
$container->setParameter(
17-
'twig.config',
18-
$container->getParameter('twig.config') +
19-
[
20-
'base_template_class' => '\\Drupal\\wmcontroller\\Twig\\Template',
21-
]
22-
);
2315
}
2416
}

wmcontroller.services.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,7 @@ services:
347347
- '@wmcontroller.presenter.factory'
348348
- '@wmcontroller.cache.dispatcher'
349349
tags: [{ name: twig.extension }]
350+
351+
wmcontroller.twig_extension:
352+
class: Drupal\wmcontroller\Twig\Extension
353+
tags: [{ name: twig.extension }]

0 commit comments

Comments
 (0)