Passed
Push — master ( 69dcf5...069c44 )
by Eric
02:20 queued 17s
created

Template::isUsingCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of Esi\SimpleTpl.
7
 *
8
 * (c) 2006 - 2025 Eric Sizemore <[email protected]>
9
 *
10
 * This file is licensed under The MIT License. For the full copyright and
11
 * license information, please view the LICENSE.md file that was distributed
12
 * with this source code.
13
 */
14
15
namespace Esi\SimpleTpl;
16
17
use InvalidArgumentException;
18
use LogicException;
19
use Psr\Cache\CacheItemPoolInterface;
20
use Psr\Cache\InvalidArgumentException as PsrInvalidArgumentException;
21
use RuntimeException;
22
23
use function array_keys;
24
use function array_map;
25
use function array_merge;
26
use function array_values;
27
use function crc32;
28
use function dechex;
29
use function file_get_contents;
30
use function str_replace;
31
32
final class Template
33
{
34
    private string $leftDelimiter = '{';
35
36
    private string $rightDelimiter = '}';
37
38
    /**
39
     * @var array<string>
40
     */
41
    private array $tplVars = [];
42
43
    /**
44
     * Constructor.
45
     */
46 13
    public function __construct(private readonly ?CacheItemPoolInterface $cacheItemPool = null) {}
47
48 1
    public function clearCache(): bool
49
    {
50 1
        if (!$this->isUsingCache()) {
51
            return true;
52
        }
53
54 1
        return $this->cacheItemPool->clear();
55
    }
56
57
    /**
58
     * @throws PsrInvalidArgumentException
59
     */
60 1
    public function display(string $tplFile): void
61
    {
62 1
        echo $this->parse($tplFile);
63
    }
64
65 1
    public function getLeftDelimiter(): string
66
    {
67 1
        return $this->leftDelimiter;
68
    }
69
70 1
    public function getRightDelimiter(): string
71
    {
72 1
        return $this->rightDelimiter;
73
    }
74
75
    /**
76
     * @return array<string>
77
     */
78 2
    public function getTplVars(): array
79
    {
80 2
        return $this->tplVars;
81
    }
82
83
    /**
84
     * @psalm-assert-if-true !null $this->cacheItemPool
85
     */
86 6
    public function isUsingCache(): bool
87
    {
88 6
        return $this->cacheItemPool instanceof CacheItemPoolInterface;
89
    }
90
91
    /**
92
     * @throws InvalidArgumentException    if the file cannot be found or read.
93
     * @throws RuntimeException            if the file has no content.
94
     * @throws LogicException              if there are no template variables set.
95
     * @throws PsrInvalidArgumentException
96
     */
97 9
    public function parse(string $tplFile): string
98
    {
99
        // Make sure it's a valid file, and it exists
100 9
        if (!is_file($tplFile) || !is_readable($tplFile)) {
101 3
            throw new InvalidArgumentException(\sprintf('"%s" does not exist or is not a file.', $tplFile));
102
        }
103
104
        // are we using cache?
105 6
        $cacheKey = self::generateCacheKey($tplFile);
106
107 6
        if ($this->isUsingCache() && $this->cacheItemPool->hasItem($cacheKey)) {
108
            /**
109
             * @var string $templateCache
110
             */
111 1
            $templateCache = $this->cacheItemPool->getItem($cacheKey)->get();
112
113 1
            return $templateCache;
114
        }
115
116 5
        if ($this->tplVars === []) {
117 1
            throw new LogicException('Unable to parse template, no tplVars found');
118
        }
119
120 4
        $contents = (string) file_get_contents($tplFile);
121
122
        // Make sure it has content.
123 4
        if ($contents === '') {
124 1
            throw new RuntimeException(\sprintf('"%s" does not appear to have any valid content.', $tplFile));
125
        }
126
127
        // Perform replacements
128 3
        $contents = str_replace(
129 3
            array_map(
130 3
                fn (int|string $find): string => \sprintf('%s%s%s', $this->leftDelimiter, $find, $this->rightDelimiter),
131 3
                array_keys($this->tplVars)
132 3
            ),
133 3
            array_values($this->tplVars),
134 3
            $contents
135 3
        );
136
137 3
        if ($this->isUsingCache()) {
138 3
            $this->cacheItemPool->save($this->cacheItemPool->getItem($cacheKey)->set($contents));
139
        }
140
141 3
        return $contents;
142
    }
143
144
    /**
145
     * @throws PsrInvalidArgumentException
146
     */
147 1
    public function refreshCache(string $tplFile): bool
148
    {
149 1
        if (!$this->isUsingCache()) {
150
            return true;
151
        }
152
153 1
        return $this->cacheItemPool->deleteItem(self::generateCacheKey($tplFile));
154
    }
155
156 1
    public function setLeftDelimiter(string $delimiter): void
157
    {
158 1
        $this->leftDelimiter = $delimiter;
159
    }
160
161 1
    public function setRightDelimiter(string $delimiter): void
162
    {
163 1
        $this->rightDelimiter = $delimiter;
164
    }
165
166
    /**
167
     * @param array<string> $tplVars Template variables and replacements
168
     */
169 8
    public function setTplVars(array $tplVars): void
170
    {
171 8
        if ($tplVars === []) {
172 2
            $this->tplVars = [];
173
174 2
            return;
175
        }
176
177 7
        $this->tplVars = array_merge($this->tplVars, $tplVars);
178
    }
179
180 6
    private static function generateCacheKey(string $file): string
181
    {
182 6
        return \sprintf('template_%s', dechex(crc32($file)));
183
    }
184
}
185