TwigTheme::contextValueToString()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 2
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
4
namespace TheCodingMachine\CMS\Theme;
5
6
use Psr\Http\Message\StreamInterface;
7
use TheCodingMachine\CMS\Block\BlockInterface;
8
use TheCodingMachine\CMS\Block\BlockRendererInterface;
9
use TheCodingMachine\CMS\CMSException;
10
use TheCodingMachine\CMS\RenderableInterface;
11
use TheCodingMachine\CMS\Theme\Extensions\ThemeExtension;
12
use Zend\Diactoros\Stream;
13
14
class TwigTheme implements RenderableInterface
15
{
16
    /**
17
     * @var \Twig_Environment
18
     */
19
    private $twig;
20
21
    /**
22
     * @var string
23
     */
24
    private $template;
25
    /**
26
     * @var BlockRendererInterface
27
     */
28
    private $blockRenderer;
29
    /**
30
     * @var string
31
     */
32
    private $themeUrl;
33
34
    public function __construct(\Twig_Environment $twig, string $template, BlockRendererInterface $blockRenderer, string $themeUrl = null)
35
    {
36
        $this->twig = $twig;
37
        $this->template = $template;
38
        $this->blockRenderer = $blockRenderer;
39
        $this->themeUrl = $themeUrl;
40
    }
41
42
43
    /**
44
     * Renders (as a stream) the data passed in parameter.
45
     *
46
     * @param mixed[] $context
47
     * @return StreamInterface
48
     */
49
    public function render(array $context): StreamInterface
50
    {
51
        $parent = $context['parent'] ?? null;
52
        unset($context['parent']);
53
        $page = $context['page'] ?? null;
54
        unset($context['page']);
55
56
        foreach ($context as $key => &$value) {
57
            $value = $this->contextValueToString($value, $context);
58
        }
59
60
61
        if ($parent !== null) {
62
            $context['parent'] = $parent;
63
        }
64
        if ($page !== null) {
65
            $context['page'] = $page;
66
        }
67
68
        if (!$this->twig->hasExtension(ThemeExtension::class)) {
69
            $this->twig->addExtension(new ThemeExtension());
70
        }
71
        $themeExtension = $this->twig->getExtension(ThemeExtension::class);
72
        /* @var $themeExtension ThemeExtension */
73
74
        $themeExtension->pushThemeUrl($this->themeUrl);
75
        try {
76
            $text = $this->twig->render($this->template, $context);
77
        } finally {
78
            $themeExtension->popThemeUrl();
79
        }
80
81
        $stream = new Stream('php://temp', 'wb+');
82
        $stream->write($text);
83
        $stream->rewind();
84
85
        return $stream;
86
    }
87
88
    /**
89
     * @param mixed $value
90
     * @param mixed[] $context
91
     * @return string|array
92
     * @throws CMSException
93
     */
94
    private function contextValueToString($value, array $context)
95
    {
96
        if ($value instanceof BlockInterface) {
97
            $additionalContext = [
98
                'parent' => $context,
99
                'page' => $context['page'] ?? $context
100
            ];
101
102
            return (string) $this->blockRenderer->renderBlock($value, $additionalContext);
103
        }
104
        if (is_array($value)) {
105
            $value = array_map(function($item) use ($context) {
106
                return $this->contextValueToString($item, $context);
107
            }, $value);
108
        }
109
        return $value;
110
    }
111
}
112