Passed
Push — master ( e6c7a1...9c0977 )
by Brent
03:16
created

SiteParser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 5
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Parser\Site;
4
5
use Brendt\Html\Meta\Meta;
6
use Brendt\Stitcher\Event\Event;
7
use Brendt\Stitcher\Exception\InvalidSiteException;
8
use Brendt\Stitcher\Exception\TemplateNotFoundException;
9
use Brendt\Stitcher\Site\Http\Htaccess;
10
use Brendt\Stitcher\Site\Page;
11
use Brendt\Stitcher\Site\Site;
12
use Symfony\Component\EventDispatcher\EventDispatcher;
13
use Symfony\Component\Finder\Finder;
14
use Symfony\Component\Finder\SplFileInfo;
15
use Symfony\Component\Yaml\Exception\ParseException;
16
use Symfony\Component\Yaml\Yaml;
17
18
class SiteParser
19
{
20
    const EVENT_PARSER_INIT = 'parser.initialised';
21
22
    const EVENT_PAGE_PARSING = 'page.parsing';
23
24
    const EVENT_PAGE_PARSED = 'page.parsed';
25
26
    const TOKEN_REDIRECT = 'redirect';
27
28
    /**
29
     * @var string
30
     */
31
    private $filter;
32
33
    /**
34
     * @var string
35
     */
36
    private $srcDir;
37
38
    /**
39
     * @var array
40
     */
41
    private $metaConfig;
42
43
    /**
44
     * @var EventDispatcher
45
     */
46
    private $eventDispatcher;
47
48
    /**
49
     * @var PageParser
50
     */
51
    private $pageParser;
52
53
    /**
54
     * @var Htaccess
55
     */
56
    private $htaccess;
57
58
    /**
59
     * SiteParser constructor.
60
     *
61
     * @param string          $srcDir
62
     * @param EventDispatcher $eventDispatcher
63
     * @param PageParser      $pageParser
64
     * @param Htaccess        $htaccess
65
     * @param array           $metaConfig
66
     */
67
    public function __construct(
68
        string $srcDir,
69
        EventDispatcher $eventDispatcher,
70
        PageParser $pageParser,
71
        Htaccess $htaccess,
72
        array $metaConfig = []
73
    ) {
74
        $this->srcDir = $srcDir;
75
        $this->eventDispatcher = $eventDispatcher;
76
        $this->pageParser = $pageParser;
77
        $this->htaccess = $htaccess;
78
        $this->metaConfig = $metaConfig;
79
    }
80
81
    /**
82
     * Load a site from YAML configuration files in the `directories.src`/site directory.
83
     * All YAML files are loaded and parsed into Page objects and added to a Site collection.
84
     *
85
     * @param array $routes
86
     *
87
     * @return Site
88
     * @throws InvalidSiteException
89
     * @see \Brendt\Stitcher\Site\Page
90
     * @see \Brendt\Stitcher\Site\Site
91
     */
92
    public function loadSite(array $routes = []) : Site {
93
        /** @var SplFileInfo[] $files */
94
        $files = Finder::create()->files()->in("{$this->srcDir}/site")->name('*.yml');
95
        $site = new Site();
96
97
        foreach ($files as $file) {
98
            try {
99
                $fileContents = (array) Yaml::parse($file->getContents());
100
            } catch (ParseException $e) {
101
                throw new InvalidSiteException("{$file->getRelativePathname()}: {$e->getMessage()}");
102
            }
103
104
            foreach ($fileContents as $route => $config) {
105
                if (count($routes) && !in_array($route, $routes)) {
106
                    continue;
107
                }
108
109
                $this->loadPage($site, $route, $config);
110
            }
111
        }
112
113
        return $site;
114
    }
115
116
    /**
117
     * @param Site   $site
118
     * @param string $route
119
     * @param array  $config
120
     */
121
    private function loadPage(Site $site, string $route, array $config) {
122
        if (isset($config[self::TOKEN_REDIRECT])) {
123
            $this->htaccess->addRedirect($route, $config[self::TOKEN_REDIRECT]);
124
125
            return;
126
        }
127
128
        $page = new Page($route, $config, $this->createMeta());
129
        $site->addPage($page);
130
    }
131
132
    /**
133
     * Parse a path into usable data.
134
     *
135
     * @param array  $routes
136
     * @param string $filterValue
137
     *
138
     * @return array|mixed
139
     * @throws TemplateNotFoundException
140
     */
141
    public function parse($routes = [], string $filterValue = null) : array {
142
        $blanket = [];
143
144
        $site = $this->loadSite((array) $routes);
145
        $this->eventDispatcher->dispatch(self::EVENT_PARSER_INIT, Event::create(['site' => $site]));
146
147
        foreach ($site as $page) {
148
            $this->eventDispatcher->dispatch(self::EVENT_PAGE_PARSING, Event::create(['page' => $page]));
149
150
            $this->pageParser->validate($page);
151
            $pages = $this->pageParser->parseAdapters($page, $filterValue);
152
153
            /** @var Page $entryPage */
154
            foreach ($pages as $entryPage) {
155
                $blanket[$entryPage->getId()] = $this->pageParser->parsePage($entryPage);
156
            }
157
158
            $this->eventDispatcher->dispatch(self::EVENT_PAGE_PARSED, Event::create(['page' => $page]));
159
        }
160
161
        return $blanket;
162
    }
163
164
    /**
165
     * @param string $filter
166
     *
167
     * @return SiteParser
168
     */
169
    public function setFilter(string $filter) : SiteParser {
170
        $this->filter = $filter;
171
172
        return $this;
173
    }
174
175
    /**
176
     * @return Meta
177
     */
178
    private function createMeta() : Meta {
179
        $meta = new Meta();
180
181
        foreach ($this->metaConfig as $name => $value) {
182
            $meta->name($name, $value);
183
        }
184
185
        return $meta;
186
    }
187
}
188