Page::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 15
dl 0
loc 17
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
     * @var string[]
67
     */
68
    private $tags;
69
70
    /**
71
     * @param string[]|null $menu
72
     * @param mixed[] $context
73
     * @param string[] $tags
74
     */
75
    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 = [], array $tags = [])
76
    {
77
        $this->id = $id;
78
        $this->title = $title;
79
        $this->content = $content;
80
        $this->url = $url;
81
        $this->lang = $lang;
82
        $this->website = $website;
83
        $this->menu = $menu;
84
        $this->menuOrder = $menuOrder;
85
        $this->menuCssClass = $menuCssClass;
86
        $this->metaTitle = $metaTitle;
87
        $this->metaDescription = $metaDescription;
88
        $this->theme = $theme;
89
        $this->template = $template;
90
        $this->context = $context;
91
        $this->tags = $tags;
92
    }
93
94
    public static function fromFile(string $file): self
95
    {
96
        if (!is_readable($file)) {
97
            throw new UnableToLoadFileException('Cannot read file '.$file);
98
        }
99
100
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
101
102
        switch ($extension) {
103
            case 'md':
104
                $parseMarkDown = true;
105
                break;
106
            case 'html':
107
                $parseMarkDown = false;
108
                break;
109
            default:
110
                throw new InvalidExtensionException(sprintf('Invalid extension for block %s. Valid extensions are .md and .html', $file));
111
        }
112
113
        $parser = new Parser();
114
115
        $document = $parser->parse(file_get_contents($file), $parseMarkDown);
116
117
        $yaml = $document->getYAML();
118
119
        if (isset($yaml['inherits'])) {
120
            $baseYaml = self::loadBaseYamlFile(dirname($file).'/'.$yaml['inherits']);
121
            $yaml = self::mergeYaml($baseYaml, $yaml, dirname($file).'/'.$yaml['inherits']);
122
        }
123
124
        $compulsoryFields = ['title', 'url', 'lang'];
125
126
        foreach ($compulsoryFields as $field) {
127
            if (!isset($yaml[$field])) {
128
                throw new UnableToLoadFileException('Missing field '.$field.' in YAML front matter of file '.$file);
129
            }
130
        }
131
132
        return new self(
133
            $yaml['id'] ?? null,
134
            $yaml['title'],
135
            $document->getContent(),
136
            '/'.ltrim($yaml['url'], '/'),
137
            $yaml['lang'],
138
            $yaml['website'] ?? null,
139
            isset($yaml['menu']) ? array_map('trim', explode('/', $yaml['menu'])) : null,
140
            $yaml['menu_order'] ?? null,
141
            $yaml['menu_css_class'] ?? null,
142
            $yaml['meta_title'] ?? null,
143
            $yaml['meta_description'] ?? null,
144
            $yaml['theme'] ?? null,
145
            $yaml['template'] ?? null,
146
            $yaml['context'] ?? [],
147
            $yaml['tags'] ?? []
148
        );
149
    }
150
151
    /**
152
     * @return mixed[]
153
     * @throws UnableToLoadFileException
154
     */
155
    private static function loadBaseYamlFile(string $path): array
156
    {
157
        if (!is_readable($path)) {
158
            throw new UnableToLoadFileException('Cannot read base page '.$path.' (used in "inherits" option)');
159
        }
160
161
        return Yaml::parse(file_get_contents($path));
162
    }
163
164
    /**
165
     * @param mixed[] $baseYaml
166
     * @param mixed[] $yaml
167
     * @param string $file
168
     * @return mixed[]
169
     */
170
    private static function mergeYaml(array $baseYaml, array $yaml, string $file): array
171
    {
172
        if (isset($baseYaml['inherits'])) {
173
            $baseYaml2 = self::loadBaseYamlFile(dirname($file).'/'.$baseYaml['inherits']);
174
            $baseYaml = self::mergeYaml($baseYaml2, $baseYaml, dirname($file).'/'.$baseYaml['inherits']);
175
        }
176
177
        $arrayMerger = new YamlUtils();
178
        return $arrayMerger->mergeArrays($baseYaml, $yaml, [
179
            'title' => YamlUtils::OVERRIDE,
180
            'lang' => YamlUtils::OVERRIDE,
181
            'website' => YamlUtils::OVERRIDE,
182
            'menu_css_class' => YamlUtils::OVERRIDE,
183
            'meta_title' => YamlUtils::OVERRIDE,
184
            'meta_description' => YamlUtils::OVERRIDE,
185
            'theme' => YamlUtils::OVERRIDE,
186
            'template' => YamlUtils::OVERRIDE,
187
            'context' => YamlUtils::MERGE_ARRAY,
188
            'tags' => YamlUtils::MERGE_ARRAY,
189
        ]);
190
    }
191
192
    /**
193
     * @return null|string
194
     */
195
    public function getId(): ?string
196
    {
197
        return $this->id;
198
    }
199
200
    /**
201
     * @return string
202
     */
203
    public function getTitle(): string
204
    {
205
        return $this->title;
206
    }
207
208
    /**
209
     * @return string
210
     */
211
    public function getContent(): string
212
    {
213
        return $this->content;
214
    }
215
216
    /**
217
     * @return string
218
     */
219
    public function getUrl(): string
220
    {
221
        return $this->url;
222
    }
223
224
    /**
225
     * @return string
226
     */
227
    public function getLang(): string
228
    {
229
        return $this->lang;
230
    }
231
232
    /**
233
     * @return string|null
234
     */
235
    public function getWebsite(): ?string
236
    {
237
        return $this->website;
238
    }
239
240
    /**
241
     * @return null|string[]
242
     */
243
    public function getMenu(): ?array
244
    {
245
        return $this->menu;
246
    }
247
248
    /**
249
     * @return int
250
     */
251
    public function getMenuOrder(): int
252
    {
253
        return $this->menuOrder ?? 0;
254
    }
255
256
    /**
257
     * @return null|string
258
     */
259
    public function getMenuCssClass(): ?string
260
    {
261
        return $this->menuCssClass;
262
    }
263
264
    /**
265
     * @return null|string
266
     */
267
    public function getMetaTitle(): ?string
268
    {
269
        return $this->metaTitle;
270
    }
271
272
    /**
273
     * @return null|string
274
     */
275
    public function getMetaDescription(): ?string
276
    {
277
        return $this->metaDescription;
278
    }
279
280
    /**
281
     * @return null|string
282
     */
283
    public function getTheme(): ?string
284
    {
285
        return $this->theme;
286
    }
287
288
    /**
289
     * @return null|string
290
     */
291
    public function getTemplate(): ?string
292
    {
293
        return $this->template;
294
    }
295
296
    /**
297
     * @return mixed[]
298
     */
299
    public function getContext(): array
300
    {
301
        return $this->context;
302
    }
303
304
    /**
305
     * @return string[]
306
     */
307
    public function getTags(): array
308
    {
309
        return $this->tags;
310
    }
311
}
312