Passed
Push — master ( 4c211f...58f014 )
by Brent
02:47
created

PageParser::parseAdapters()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 4
nop 2
dl 0
loc 19
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Parser\Site;
4
5
use Brendt\Stitcher\Exception\TemplateNotFoundException;
6
use Brendt\Stitcher\Factory\AdapterFactory;
7
use Brendt\Stitcher\Factory\HeaderCompilerFactory;
8
use Brendt\Stitcher\Factory\ParserFactory;
9
use Brendt\Stitcher\Factory\TemplateEngineFactory;
10
use Brendt\Stitcher\Site\Http\HeaderCompiler;
11
use Brendt\Stitcher\Site\Meta\MetaCompiler;
12
use Brendt\Stitcher\Site\Page;
13
use Brendt\Stitcher\Template\TemplatePlugin;
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\Finder\SplFileInfo;
16
17
class PageParser
18
{
19
20
    /**
21
     * @var ParserFactory
22
     */
23
    private $parserFactory;
24
25
    /**
26
     * @var MetaCompiler
27
     */
28
    private $metaCompiler;
29
30
    /**
31
     * @var TemplatePlugin
32
     */
33
    private $templatePlugin;
34
35
    /**
36
     * @var string
37
     */
38
    private $templateDir;
39
40
    /**
41
     * @var AdapterFactory
42
     */
43
    private $adapterFactory;
44
45
    /**
46
     * @var HeaderCompiler|null
47
     */
48
    private $headerCompiler;
49
50
    public function __construct(
51
        string $templateDir,
52
        AdapterFactory $adapterFactory,
53
        ParserFactory $parserFactory,
54
        HeaderCompilerFactory $headerCompilerFactory,
55
        TemplateEngineFactory $templateEngineFactory,
56
        TemplatePlugin $templatePlugin,
57
        MetaCompiler $metaCompiler
58
    ) {
59
        $this->templateDir = $templateDir;
60
61
        $this->adapterFactory = $adapterFactory;
62
        $this->parserFactory = $parserFactory;
63
        $this->metaCompiler = $metaCompiler;
64
        $this->templatePlugin = $templatePlugin;
65
66
        $this->templateEngine = $templateEngineFactory->getDefault();
0 ignored issues
show
Bug introduced by
The property templateEngine does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
67
        $this->templates = $this->loadTemplates();
0 ignored issues
show
Bug introduced by
The property templates does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
68
        $this->headerCompiler = $headerCompilerFactory->getHeaderCompilerByEnvironment();
69
    }
70
71
    /**
72
     * Load all templates from either the `directories.template` directory. Depending on the configured template
73
     * engine, set with `engines.template`; .html or .tpl files will be loaded.
74
     *
75
     * @return SplFileInfo[]
76
     */
77
    public function loadTemplates() {
78
        $templateExtension = $this->templateEngine->getTemplateExtension();
79
80
        /** @var SplFileInfo[] $files */
81
        $files = Finder::create()->files()->in($this->templateDir)->name("*.{$templateExtension}");
82
        $templates = [];
83
84
        foreach ($files as $file) {
85
            $id = str_replace(".{$templateExtension}", '', $file->getRelativePathname());
86
            $templates[$id] = $file;
87
        }
88
89
        return $templates;
90
    }
91
92
    /**
93
     * @param Page $page
94
     *
95
     * @return string
96
     */
97
    public function parsePage(Page $page) : string {
98
        $entryPage = $this->parseVariables($page);
99
        $this->metaCompiler->compilePage($page);
100
101
        $this->templatePlugin->setPage($entryPage);
102
        $this->templateEngine->addTemplateVariables($entryPage->getVariables());
103
104
        $pageTemplate = $this->templates[$page->getTemplatePath()];
105
        $result = $this->templateEngine->renderTemplate($pageTemplate);
106
107
        if ($this->headerCompiler) {
108
            $this->headerCompiler->compilePage($page);
109
        }
110
111
        $this->templateEngine->clearTemplateVariables();
112
113
        return $result;
114
    }
115
116
    /**
117
     * This function takes a page and optional entry id. The page's adapters will be loaded and looped.
118
     * An adapter will transform a page's original configuration and variables to one or more pages.
119
     * An entry id can be provided as a filter. This filter can be used in an adapter to skip rendering unnecessary
120
     * pages. The filter parameter is used to render pages on the fly when using the developer controller.
121
     *
122
     * @param Page   $page
123
     * @param string $entryId
124
     *
125
     * @return Page[]
126
     *
127
     * @see  \Brendt\Stitcher\Adapter\Adapter::transform()
128
     * @see  \Brendt\Stitcher\Application\DevController::run()
129
     */
130
    public function parseAdapters(Page $page, $entryId = null) {
131
        if (!$page->getAdapters()) {
132
            return [$page->getId() => $page];
133
        }
134
135
        $pages = [$page];
136
137
        foreach ($page->getAdapters() as $type => $adapterConfig) {
138
            $adapter = $this->adapterFactory->getByType($type);
139
140
            if ($entryId !== null) {
141
                $pages = $adapter->transform($pages, $entryId);
142
            } else {
143
                $pages = $adapter->transform($pages);
144
            }
145
        }
146
147
        return $pages;
148
    }
149
150
    /**
151
     * This function takes a Page object and parse its variables using a Parser. It will only parse variables which
152
     * weren't parsed already by an adapter.
153
     *
154
     * @param Page $page
155
     *
156
     * @return Page
157
     *
158
     * @see \Brendt\Stitcher\Factory\ParserFactory
159
     * @see \Brendt\Stitcher\Parser\Parser
160
     * @see \Brendt\Stitcher\Site\Page::isParsedVariable()
161
     */
162
    public function parseVariables(Page $page) {
163
        foreach ($page->getVariables() as $name => $value) {
164
            if ($page->isParsedVariable($name)) {
165
                continue;
166
            }
167
168
            $page
169
                ->setVariableValue($name, $this->getData($value))
170
                ->setVariableIsParsed($name);
171
        }
172
173
        return $page;
174
    }
175
176
    /**
177
     * @param Page $page
178
     *
179
     * @throws TemplateNotFoundException
180
     */
181
    public function validate(Page $page) {
182
        $templateIsset = isset($this->templates[$page->getTemplatePath()]);
183
184
        if (!$templateIsset) {
185
            if ($template = $page->getTemplatePath()) {
186
                throw new TemplateNotFoundException("Template {$template} not found.");
187
            } else {
188
                throw new TemplateNotFoundException('No template was set.');
189
            }
190
        }
191
    }
192
193
    /**
194
     * This function will get the parser based on the value. This value is parsed by the parser, or returned if no
195
     * suitable parser was found.
196
     *
197
     * @param $value
198
     *
199
     * @return mixed
200
     *
201
     * @see \Brendt\Stitcher\Factory\ParserFactory
202
     */
203
    private function getData($value) {
204
        $parser = $this->parserFactory->getByFileName($value);
205
206
        if (!$parser) {
207
            return $value;
208
        }
209
210
        return $parser->parse($value);
211
    }
212
}
213