Passed
Push — master ( 6b1ebf...63457f )
by Melech
04:00
created

OrkaRenderer::renderFile()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 17
rs 10
c 0
b 0
f 0
cc 4
nc 3
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\View;
15
16
use Valkyrja\Support\Directory;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Support\Directory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Valkyrja\View\Exception\RuntimeException;
18
19
use function array_keys;
20
use function file_get_contents;
21
use function file_put_contents;
22
use function is_file;
23
use function md5;
24
use function preg_replace;
25
26
/**
27
 * Class OrkaRenderer.
28
 *
29
 * @author Melech Mizrachi
30
 */
31
class OrkaRenderer extends PhpRenderer
32
{
33
    /**
34
     * @var array<string, string>
35
     */
36
    protected static array $replace = [
37
        // @layout
38
        '/@layout\s*\(\s*(.*)\s*\)/x'              => '<?php $template->setLayout(${1}); ?>',
39
        '/@block\s*\(\s*(.*)\s*\)/x'               => '<?= $template->getBlock(${1}); ?>',
40
        '/@trimblock\s*\(\s*(.*)\s*\)/x'           => '<?= trim($template->getBlock(${1})); ?>',
41
        '/@startblock\s*\(\s*(.*)\s*\)/x'          => '<?php $template->startBlock(${1}); ?>',
42
        '/@endblock/x'                             => '<?php $template->endBlock(); ?>',
43
        '/@hasblock\s*\(\s*(.*)\s*\)/x'            => '<?php if ($template->hasBlock(${1})) : ?>',
44
        '/@elsehasblock/x'                         => '<?php else : ?>',
45
        '/@elseifhasblock\s*\(\s*(.*)\s*\)/x'      => '<?php elseif ($template->hasBlock(${1})) : ?>',
46
        '/@endhasblock/x'                          => '<?php endif ?>',
47
        '/@unlessblock\s*\(\s*(.*)\s*\)/x'         => '<?php if (! $template->hasBlock(${1})) : ?>',
48
        '/@endunlessblock/x'                       => '<?php endif ?>',
49
        '/@partial\s*\(\s*(.*)\s*\s*\)/x'          => '<?= $template->getPartial(${1}); ?>',
50
        '/@partial\s*\(\s*(.*)\s*,(.*)\s*\)/x'     => '<?= $template->getPartial(${1}, ${2}); ?>',
51
        '/@trimpartial\s*\(\s*(.*)\s*\s*\)/x'      => '<?= trim($template->getPartial(${1})); ?>',
52
        '/@trimpartial\s*\(\s*(.*)\s*,(.*)\s*\)/x' => '<?= trim($template->getPartial(${1}, ${2})); ?>',
53
        '/@setvariables\s*\(\s*(.*)\s*\s*\)/x'     => '<?php $template->setVariables(${1}); ?>',
54
        '/@setvariable\s*\(\s*(.*)\s*,(.*)\s*\)/x' => '<?php $template->setVariable(${1}, ${2}); ?>',
55
        '/@empty\s*\(\s*(.*)\s*\)/x'               => '<?php if (empty(${1})) : ?>',
56
        '/@notempty\s*\(\s*(.*)\s*\)/x'            => '<?php if (! empty(${1})) : ?>',
57
        '/@if\s*\(\s*(.*)\s*\)/x'                  => '<?php if (${1}) : ?>',
58
        '/@elseif\s*\(\s*(.*)\s*\)/x'              => '<?php elseif (${1}) : ?>',
59
        '/@else/x'                                 => '<?php else : ?>',
60
        '/@endif/x'                                => '<?php endif ?>',
61
        '/@isset\s*\(\s*(.*)\s*\)/x'               => '<?php if (isset(${1})) : ?>',
62
        '/@endisset/x'                             => '<?php endif ?>',
63
        '/@unless\s*\(\s*(.*)\s*\)/x'              => '<?php if (! (${1})) : ?>',
64
        '/@elseunless\s*\(\s*(.*)\s*\)/x'          => '<?php elseif (! (${1})) : ?>',
65
        '/@endunless/x'                            => '<?php endif ?>',
66
        '/@foreach\s*\(\s*(.*)\s*\)/x'             => '<?php foreach (${1}) : ?>',
67
        '/@endforeach/x'                           => '<?php endforeach ?>',
68
        '/@for\s*\(\s*(.*)\s*\)/x'                 => '<?php for (${1}) : ?>',
69
        '/@endfor/x'                               => '<?php endfor ?>',
70
        '/@switch\s*\(\s*(.*)\s*\)/x'              => '<?php switch (${1}) :',
71
        '/@firstcase\s*\(\s*(.*)\s*\)/x'           => 'case ${1} : ?>',
72
        '/@case\s*\(\s*(.*)\s*\)/x'                => '<?php case ${1} : ?>',
73
        '/@break/x'                                => '<?php break; ?>',
74
        '/@default/x'                              => '<?php default : ?>',
75
        '/@endswitch/x'                            => '<?php endswitch ?>',
76
        '/@dd\s*\(\s*(.*)\s*\s*\)/x'               => '<?php \Valkyrja\dd(${1}); ?>',
77
        // {{--
78
        '/\{\{\-\-/x'                              => '<?php /** ?>',
79
        // --}}
80
        '/\-\-\}\}/x'                              => '<?php */ ?>',
81
        // {{{ unescaped }}}
82
        '/\{\{\{\s*(.*?)\s*\}\}\}/x'               => '<?= ${1}; ?>',
83
        // {{ escaped }}
84
        '/\{\{\s*(.*?)\s*\}\}/x'                   => '<?= $template->escape(${1}); ?>',
85
    ];
86
87
    /**
88
     * OrkaRenderer constructor.
89
     *
90
     * @param array<string, string> $paths
91
     */
92
    public function __construct(
93
        string $dir,
94
        string $fileExtension = '.orka.phtml',
95
        array $paths = [],
96
        protected bool $debug = false,
97
    ) {
98
        parent::__construct(
99
            dir: $dir,
100
            fileExtension: $fileExtension,
101
            paths: $paths,
102
        );
103
    }
104
105
    /**
106
     * @inheritDoc
107
     */
108
    public function renderFile(string $name, array $variables = []): string
109
    {
110
        $cachedPath = $this->getCachedFilePath($name);
111
112
        if ($this->debug || ! is_file($cachedPath)) {
113
            $fileContents = file_get_contents($this->getFullPath($name));
114
115
            if ($fileContents === false) {
116
                throw new RuntimeException("Contents for file $name could not be retrieved");
117
            }
118
119
            $contents = $this->parseContent($fileContents);
120
121
            file_put_contents($cachedPath, $contents);
122
        }
123
124
        return $this->renderFullPath($cachedPath, $variables);
125
    }
126
127
    /**
128
     * Parse okra written content to PHP parseable.
129
     *
130
     * @param string $contents The contents to parse
131
     *
132
     * @return string
133
     */
134
    protected function parseContent(string $contents): string
135
    {
136
        /** @var non-empty-string[] $regexes */
137
        $regexes = array_keys(self::$replace);
138
139
        return preg_replace($regexes, self::$replace, $contents) ?? $contents;
140
    }
141
142
    /**
143
     * Get the cached file path.
144
     *
145
     * @param string $name The name
146
     *
147
     * @return string
148
     */
149
    protected function getCachedFilePath(string $name): string
150
    {
151
        return Directory::storagePath('views/' . md5($name));
152
    }
153
}
154