Completed
Pull Request — master (#3)
by David
02:00
created

Page::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 14
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
namespace TheCodingMachine\CMS\StaticRegistry\Loaders;
3
4
use Mni\FrontYAML\Parser;
5
use Symfony\Component\Yaml\Yaml;
6
7
class Page
8
{
9
    /**
10
     * @var string|null
11
     */
12
    private $id;
13
    /**
14
     * @var string
15
     */
16
    private $title;
17
    /**
18
     * @var string
19
     */
20
    private $content;
21
    /**
22
     * @var string
23
     */
24
    private $url;
25
    /**
26
     * @var string
27
     */
28
    private $lang;
29
    /**
30
     * @var null|string
31
     */
32
    private $website;
33
    /**
34
     * @var null|string[]
35
     */
36
    private $menu;
37
    /**
38
     * @var int|null
39
     */
40
    private $menuOrder;
41
    /**
42
     * @var null|string
43
     */
44
    private $metaTitle;
45
    /**
46
     * @var null|string
47
     */
48
    private $metaDescription;
49
    /**
50
     * @var null|string
51
     */
52
    private $theme;
53
    /**
54
     * @var null|string
55
     */
56
    private $menuCssClass;
57
    /**
58
     * @var null|string
59
     */
60
    private $template;
61
    /**
62
     * @var array
63
     */
64
    private $context;
65
66
    /**
67
     * @param string[]|null $menu
68
     */
69
    public function __construct(?string $id, string $title, string $content, string $url, string $lang, ?string $website, ?array $menu, ?int $menuOrder, ?string $menuCssClass, ?string $metaTitle, ?string $metaDescription, ?string $theme, ?string $template, array $context = [])
70
    {
71
        $this->id = $id;
72
        $this->title = $title;
73
        $this->content = $content;
74
        $this->url = $url;
75
        $this->lang = $lang;
76
        $this->website = $website;
77
        $this->menu = $menu;
78
        $this->menuOrder = $menuOrder;
79
        $this->menuCssClass = $menuCssClass;
80
        $this->metaTitle = $metaTitle;
81
        $this->metaDescription = $metaDescription;
82
        $this->theme = $theme;
83
        $this->template = $template;
84
        $this->context = $context;
85
    }
86
87
    public static function fromFile(string $file): self
88
    {
89
        if (!is_readable($file)) {
90
            throw new UnableToLoadFileException('Cannot read file '.$file);
91
        }
92
93
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
94
95
        switch ($extension) {
96
            case 'md':
97
                $parseMarkDown = true;
98
                break;
99
            case 'html':
100
                $parseMarkDown = false;
101
                break;
102
            default:
103
                throw new InvalidExtensionException(sprintf('Invalid extension for block %s. Valid extensions are .md and .html', $file));
104
        }
105
106
        $parser = new Parser();
107
108
        $document = $parser->parse(file_get_contents($file), $parseMarkDown);
109
110
        $yaml = $document->getYAML();
111
112
        if (isset($yaml['inherits'])) {
113
            $baseYaml = self::loadBaseYamlFile(dirname($file).'/'.$yaml['inherits']);
114
            $yaml = self::mergeYaml($baseYaml, $yaml, dirname($file).'/'.$yaml['inherits']);
115
        }
116
117
        $compulsoryFields = ['title', 'url', 'lang'];
118
119
        foreach ($compulsoryFields as $field) {
120
            if (!isset($yaml[$field])) {
121
                throw new UnableToLoadFileException('Missing field '.$field.' in YAML front matter of file '.$file);
122
            }
123
        }
124
125
        return new self(
126
            $yaml['id'] ?? null,
127
            $yaml['title'],
128
            $document->getContent(),
129
            '/'.ltrim($yaml['url'], '/'),
130
            $yaml['lang'],
131
            $yaml['website'] ?? null,
132
            isset($yaml['menu']) ? array_map('trim', explode('/', $yaml['menu'])) : null,
133
            $yaml['menu_order'] ?? null,
134
            $yaml['menu_css_class'] ?? null,
135
            $yaml['meta_title'] ?? null,
136
            $yaml['meta_description'] ?? null,
137
            $yaml['theme'] ?? null,
138
            $yaml['template'] ?? null,
139
            $yaml['context'] ?? []
140
        );
141
    }
142
143
    private static function loadBaseYamlFile(string $path): array
144
    {
145
        if (!is_readable($path)) {
146
            throw new UnableToLoadFileException('Cannot read base page '.$path.' (used in "inherits" option)');
147
        }
148
149
        return Yaml::parse(file_get_contents($path));
150
    }
151
152
    private static function mergeYaml(array $baseYaml, array $yaml, string $file): array
153
    {
154
        if (isset($baseYaml['inherits'])) {
155
            $baseYaml2 = self::loadBaseYamlFile(dirname($file).'/'.$baseYaml['inherits']);
156
            $baseYaml = self::mergeYaml($baseYaml2, $baseYaml, dirname($file).'/'.$baseYaml['inherits']);
157
        }
158
159
        $arrayMerger = new YamlUtils();
160
        return $arrayMerger->mergeArrays($baseYaml, $yaml, [
161
            'title' => YamlUtils::OVERRIDE,
162
            'lang' => YamlUtils::OVERRIDE,
163
            'website' => YamlUtils::OVERRIDE,
164
            'menu_css_class' => YamlUtils::OVERRIDE,
165
            'meta_title' => YamlUtils::OVERRIDE,
166
            'meta_description' => YamlUtils::OVERRIDE,
167
            'theme' => YamlUtils::OVERRIDE,
168
            'template' => YamlUtils::OVERRIDE,
169
            'context' => YamlUtils::MERGE_ARRAY,
170
        ]);
171
    }
172
173
    /**
174
     * @return null|string
175
     */
176
    public function getId(): ?string
177
    {
178
        return $this->id;
179
    }
180
181
    /**
182
     * @return string
183
     */
184
    public function getTitle(): string
185
    {
186
        return $this->title;
187
    }
188
189
    /**
190
     * @return string
191
     */
192
    public function getContent(): string
193
    {
194
        return $this->content;
195
    }
196
197
    /**
198
     * @return string
199
     */
200
    public function getUrl(): string
201
    {
202
        return $this->url;
203
    }
204
205
    /**
206
     * @return string
207
     */
208
    public function getLang(): string
209
    {
210
        return $this->lang;
211
    }
212
213
    /**
214
     * @return string|null
215
     */
216
    public function getWebsite(): ?string
217
    {
218
        return $this->website;
219
    }
220
221
    /**
222
     * @return null|string[]
223
     */
224
    public function getMenu(): ?array
225
    {
226
        return $this->menu;
227
    }
228
229
    /**
230
     * @return int
231
     */
232
    public function getMenuOrder(): int
233
    {
234
        return $this->menuOrder ?? 0;
235
    }
236
237
    /**
238
     * @return null|string
239
     */
240
    public function getMenuCssClass(): ?string
241
    {
242
        return $this->menuCssClass;
243
    }
244
245
    /**
246
     * @return null|string
247
     */
248
    public function getMetaTitle(): ?string
249
    {
250
        return $this->metaTitle;
251
    }
252
253
    /**
254
     * @return null|string
255
     */
256
    public function getMetaDescription(): ?string
257
    {
258
        return $this->metaDescription;
259
    }
260
261
    /**
262
     * @return null|string
263
     */
264
    public function getTheme(): ?string
265
    {
266
        return $this->theme;
267
    }
268
269
    /**
270
     * @return null|string
271
     */
272
    public function getTemplate(): ?string
273
    {
274
        return $this->template;
275
    }
276
277
    /**
278
     * @return array
279
     */
280
    public function getContext(): array
281
    {
282
        return $this->context;
283
    }
284
}
285