Completed
Push — master ( 7f99bd...476042 )
by David
01:57
created

TwigTheme::contextValueToString()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 4
nop 2
dl 0
loc 18
rs 9.2
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
        if ($parent !== null) {
61
            $context['parent'] = $parent;
62
        }
63
        if ($page !== null) {
64
            $context['page'] = $page;
65
        }
66
67
        if (!$this->twig->hasExtension(ThemeExtension::class)) {
68
            $this->twig->addExtension(new ThemeExtension());
69
        }
70
        $themeExtension = $this->twig->getExtension(ThemeExtension::class);
71
        /* @var $themeExtension ThemeExtension */
72
73
        $themeExtension->pushThemeUrl($this->themeUrl);
74
        try {
75
            $text = $this->twig->render($this->template, $context);
76
        } finally {
77
            $themeExtension->popThemeUrl();
78
        }
79
80
        $stream = new Stream('php://temp', 'wb+');
81
        $stream->write($text);
82
        $stream->rewind();
83
84
        return $stream;
85
    }
86
87
    /**
88
     * @param mixed $value
89
     * @param mixed[] $context
90
     * @return string
91
     * @throws CMSException
92
     */
93
    private function contextValueToString($value, array $context) : string
94
    {
95
        if ($value instanceof BlockInterface) {
96
            $additionalContext = [
97
                'parent' => $context,
98
                'page' => $context['page'] ?? $context
99
            ];
100
101
            return (string) $this->blockRenderer->renderBlock($value, $additionalContext);
102
        }
103
        if (is_array($value)) {
104
            $str = '';
105
            foreach ($value as $item) {
106
                $str .= $this->contextValueToString($item, $context);
107
            }
108
            return $str;
109
        }
110
        return $value;
111
    }
112
}
113