Passed
Pull Request — master (#22)
by
unknown
02:53
created

ModelNodeVisitor::for()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 7
ccs 3
cts 4
cp 0.75
rs 10
cc 2
nc 2
nop 1
crap 2.0625
1
<?php
2
declare(strict_types=1);
3
4
namespace Shoot\Shoot\Twig\NodeVisitor;
5
6
use Shoot\Shoot\ModelAlreadyAssignedException;
7
use Shoot\Shoot\PresentationModel;
8
use Shoot\Shoot\Twig\Node\DisplayEndNode;
9
use Shoot\Shoot\Twig\Node\DisplayStartNode;
10
use Shoot\Shoot\Twig\Node\FindPresentationModelInterface;
11
use Shoot\Shoot\Twig\Node\ModelNode;
12
use SplObjectStorage;
13
use Twig\Environment;
14
use Twig\Node\ModuleNode;
15
use Twig\Node\Node;
16
use Twig\NodeVisitor\NodeVisitorInterface;
17
use Twig\Source;
18
19
/**
20
 * Walks through model tags to assign presentation models to templates.
21
 *
22
 * @internal
23
 */
24
final class ModelNodeVisitor implements FindPresentationModelInterface, NodeVisitorInterface
25
{
26
    /** @var SplObjectStorage */
27
    private $presentationModels;
28
29 7
    public function __construct()
30
    {
31 7
        $this->presentationModels = new SplObjectStorage();
32 7
    }
33
34
    /**
35
     * @param Node        $node
36
     * @param Environment $environment
37
     *
38
     * @return Node
39
     */
40 7
    public function enterNode(Node $node, Environment $environment): Node
41
    {
42 7
        if ($node instanceof ModelNode) {
43 7
            $this->assign($node->getSourceContext(), $node->getAttribute('presentation_model'));
0 ignored issues
show
Bug introduced by
It seems like $node->getSourceContext() can also be of type null; however, parameter $source of Shoot\Shoot\Twig\NodeVis...elNodeVisitor::assign() does only seem to accept Twig\Source, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

43
            $this->assign(/** @scrutinizer ignore-type */ $node->getSourceContext(), $node->getAttribute('presentation_model'));
Loading history...
44
        }
45
46 7
        return $node;
47
    }
48
49
    /**
50
     * @param Node        $node
51
     * @param Environment $environment
52
     *
53
     * @return Node
54
     */
55 7
    public function leaveNode(Node $node, Environment $environment): Node
56
    {
57 7
        if (!($node instanceof ModuleNode)) {
58 7
            return $node;
59
        }
60
61 6
        if (!isset($this->presentationModels[$node->getSourceContext()])) {
62 2
            return $node;
63
        }
64
65 6
        if ($node->hasAttribute('embedded_templates')) {
66
            /** @var ModuleNode $embeddedTemplate */
67 6
            foreach ($node->getAttribute('embedded_templates') as $embeddedTemplate) {
68 1
                $embeddedTemplate->setAttribute('is_embedded', true);
69
            }
70
        }
71
72 6
        $node->setNode('display_start', new DisplayStartNode($node, $this));
73 6
        $node->setNode('display_end', new DisplayEndNode($node));
74
75 6
        return $node;
76
    }
77
78
    /**
79
     * Returns the presentation model for the given view.
80
     *
81
     * @param Source $source
82
     *
83
     * @return string
84
     */
85 6
    public function for(Source $source): string
86
    {
87 6
        if (isset($this->presentationModels[$source])) {
88 6
            return (string)$this->presentationModels[$source];
89
        }
90
91
        return PresentationModel::class;
92
    }
93
94
    /**
95
     * @return int
96
     */
97 7
    public function getPriority(): int
98
    {
99
        // Should be between -10 and 10, with 0 as the default
100 7
        return -10;
101
    }
102
103
    /**
104
     * @param Source $source
105
     * @param string $presentationModel
106
     *
107
     * @return void
108
     *
109
     * @throws ModelAlreadyAssignedException
110
     */
111 7
    private function assign(Source $source, string $presentationModel): void
112
    {
113 7
        if (isset($this->presentationModels[$source])) {
114 1
            throw new ModelAlreadyAssignedException("A presentation model has already been assigned to {$source->getName()}");
115
        }
116
117 7
        $this->presentationModels[$source] = $presentationModel;
118 7
    }
119
}
120