Completed
Pull Request — master (#6)
by Tomáš
04:54
created

TwigFormatter::massageTemplate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 0
cts 12
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 3
nop 1
crap 12
1
<?php
2
3
/*
4
 * This file is a part of Sculpin.
5
 *
6
 * (c) Dragonfly Development Inc.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Symplify\PHP7_Sculpin\Bundle\TwigBundle;
13
14
use Symplify\PHP7_Sculpin\Core\Formatter\FormatContext;
15
use Symplify\PHP7_Sculpin\Core\Formatter\FormatterInterface;
16
17
final class TwigFormatter implements FormatterInterface
18
{
19
    /**
20
     * @var \Twig_Environment
21
     */
22
    private $twig;
23
24
    /**
25
     * @var \Twig_Loader_Array
26
     */
27
    private $arrayLoader;
28
29
    /**
30
     * Constructor.
31
     *
32
     * @param \Twig_Environment  $twig        Twig
33
     * @param \Twig_Loader_Array $arrayLoader Array Loader
34
     */
35
    public function __construct(\Twig_Environment $twig, \Twig_Loader_Array $arrayLoader)
36
    {
37
        $this->twig = $twig;
38
        $this->arrayLoader = $arrayLoader;
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function formatBlocks(FormatContext $formatContext) : array
45
    {
46
        try {
47
            $this->arrayLoader->setTemplate($formatContext->templateId(), $this->massageTemplate($formatContext));
48
            $data = $formatContext->data()->export();
49
            $template = $this->twig->loadTemplate($formatContext->templateId());
50
51
            if (!count($blockNames = $this->findAllBlocks($template, $data))) {
0 ignored issues
show
Compatibility introduced by
$template of type object<Twig_TemplateInterface> is not a sub-type of object<Twig_Template>. It seems like you assume a concrete implementation of the interface Twig_TemplateInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
52
                return ['content' => $template->render($data)];
53
            }
54
            $blocks = [];
55
            foreach ($blockNames as $blockName) {
56
                $blocks[$blockName] = $template->renderBlock($blockName, $data);
0 ignored issues
show
Bug introduced by
The method renderBlock() does not exist on Twig_TemplateInterface. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
57
            }
58
59
            return $blocks;
60
        } catch (\Exception $e) {
61
            echo ' [ '.get_class($e).': '.$e->getMessage()." ]\n";
62
        }
63
    }
64
65
    public function findAllBlocks(\Twig_Template $template, array $context)
66
    {
67
        if (false !== $parent = $template->getParent($context)) {
68
            return array_unique(array_merge($this->findAllBlocks($parent, $context), $template->getBlockNames()));
0 ignored issues
show
Compatibility introduced by
$parent of type object<Twig_TemplateInterface> is not a sub-type of object<Twig_Template>. It seems like you assume a concrete implementation of the interface Twig_TemplateInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
69
        }
70
71
        return $template->getBlockNames();
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function formatPage(FormatContext $formatContext) : string
78
    {
79
        try {
80
            $this->arrayLoader->setTemplate(
81
                $formatContext->templateId(),
82
                $this->massageTemplate($formatContext)
83
            );
84
85
            $data = $formatContext->data()->export();
86
87
            return $this->twig->render($formatContext->templateId(), $data);
88
        } catch (\Exception $e) {
89
            echo ' [ '.get_class($e).': '.$e->getMessage()." ]\n";
90
        }
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function reset()
97
    {
98
        $this->twig->clearCacheFiles();
0 ignored issues
show
Deprecated Code introduced by
The method Twig_Environment::clearCacheFiles() has been deprecated with message: since 1.22 (to be removed in 2.0)

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
99
        $this->twig->clearTemplateCache();
0 ignored issues
show
Deprecated Code introduced by
The method Twig_Environment::clearTemplateCache() has been deprecated with message: since 1.18.3 (to be removed in 2.0)

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
100
    }
101
102
    private function massageTemplate(FormatContext $formatContext)
103
    {
104
        $template = $formatContext->template();
105
        if ($layout = $formatContext->data()->get('layout')) {
106
            // Completely remove anything in verbatim sections so that any blocks defined in there will
107
            // not trigger the "you've already defined blocks!" check since this is almost certainly
108
            // NOT the intention of the source's author.
109
            $verbatim = preg_replace('/{%\s+verbatim\s+%}(.*?){%\s+endverbatim\s+%}/si', '', $template);
110
111
            if (!preg_match_all('/{%\s+block\s+(\w+)\s+%}(.*?){%\s+endblock\s+%}/si', $verbatim, $matches)) {
112
                $template = '{% block content %}'.$template.'{% endblock %}';
113
            }
114
            $template = '{% extends "'.$layout.'" %}'.$template;
115
        }
116
117
        return $template;
118
    }
119
}
120