Compiler::loadRules()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 11
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 21
rs 9.9
1
<?php
2
3
namespace Tleckie\Template\Compiler;
4
5
use RuntimeException;
6
use Tleckie\Template\Compiler\Parser\Rules;
7
use Tleckie\Template\Compiler\Parser\RulesInterface;
8
use function array_walk;
9
use function count;
10
use function preg_replace;
11
use function preg_replace_callback;
12
use function sprintf;
13
14
/**
15
 * Class Compiler
16
 *
17
 * @package Tleckie\Template\Compiler
18
 * @author  Teodoro Leckie Westberg <[email protected]>
19
 */
20
class Compiler implements CompilerInterface
21
{
22
    /** @var PathInterface */
23
    private PathInterface $templatePath;
24
25
    /** @var PathInterface */
26
    private PathInterface $compiledPath;
27
28
    /** @var RulesInterface[] */
29
    private array $rules;
30
31
    /**
32
     * Compiler constructor.
33
     *
34
     * @param array $rules
35
     */
36
    public function __construct(array $rules = [])
37
    {
38
        if (!count($rules)) {
39
            $this->addRule(new Rules());
40
        }
41
42
        foreach ($rules as $rule) {
43
            $this->addRule($rule);
44
        }
45
    }
46
47
    /**
48
     * @inheritdoc
49
     */
50
    public function addRule(RulesInterface $rule): CompilerInterface
51
    {
52
        $this->rules[] = $rule;
53
54
        return $this;
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60
    public function rules(): array
61
    {
62
        return $this->rules;
63
    }
64
65
    /**
66
     * @return PathInterface
67
     */
68
    public function getTemplatePath(): PathInterface
69
    {
70
        return $this->templatePath;
71
    }
72
73
    /**
74
     * @inheritdoc
75
     */
76
    public function setTemplatePath(PathInterface $templatePath): CompilerInterface
77
    {
78
        $this->templatePath = $templatePath;
79
80
        return $this;
81
    }
82
83
    /**
84
     * @return PathInterface
85
     */
86
    public function getCompiledPath(): PathInterface
87
    {
88
        return $this->compiledPath;
89
    }
90
91
    /**
92
     * @inheritdoc
93
     */
94
    public function setCompiledPath(PathInterface $compiledPath): CompilerInterface
95
    {
96
        $this->compiledPath = $compiledPath;
97
98
        return $this;
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    public function needsCompile(): bool
105
    {
106
        return !$this->compiledPath->fileExist() ||
107
            $this->templatePath->getModificationTime() >
108
            $this->compiledPath->getModificationTime();
109
    }
110
111
    /**
112
     * @inheritdoc
113
     */
114
    public function compile(): bool
115
    {
116
        if (!$this->templatePath->fileExist()) {
117
            throw new RuntimeException(
118
                sprintf(
119
                    'Template [%s] not found.',
120
                    $this->templatePath->getFullPath()
121
                )
122
            );
123
        }
124
125
        return $this->compiledPath->write(
126
            $this->compact($this->loadRules())
127
        );
128
    }
129
130
    /**
131
     * @param string $content
132
     * @return string
133
     */
134
    private function compact(string $content): string
135
    {
136
        return preg_replace('/\s{2,}/', ' ', $content);
137
    }
138
139
    /**
140
     * @return string
141
     */
142
    private function loadRules(): string
143
    {
144
        $compiler = clone $this;
145
        array_walk(
146
            $this->rules,
147
            static function (RulesInterface $rule) use (&$tags, $compiler) {
148
                $rule->setCompiler($compiler);
149
150
                foreach ($rule->rules() as $regex => $item) {
151
                    $tags[$regex] = $item;
152
                }
153
            }
154
        );
155
156
        $content = $this->templatePath->read();
157
158
        foreach ($tags as $preg => $callback) {
159
            $content = preg_replace_callback($preg, $callback, $content);
160
        }
161
162
        return $content;
163
    }
164
}
165