Completed
Push — feature-output-formats ( a25fbf...c04345 )
by Arnaud
01:55
created

Page   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 406
Duplicated Lines 0 %

Coupling/Cohesion

Components 4
Dependencies 8

Importance

Changes 0
Metric Value
wmc 32
lcom 4
cbo 8
dl 0
loc 406
rs 9.84
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 68 7
A slugify() 0 6 1
A isVirtual() 0 4 1
A setType() 0 6 1
A getType() 0 4 1
A parse() 0 9 1
A setName() 0 6 1
A getName() 0 4 1
A setPath() 0 6 1
A getPath() 0 4 1
A setPathname() 0 6 1
A getPathname() 0 4 1
A setSection() 0 6 1
A getSection() 0 8 3
A setPermalink() 0 6 1
A getPermalink() 0 8 2
A getFrontmatter() 0 4 1
A getBody() 0 4 1
A setBodyHtml() 0 6 1
A getBodyHtml() 0 4 1
A getContent() 0 4 1
A setLayout() 0 6 1
A getLayout() 0 4 1
1
<?php
2
/*
3
 * Copyright (c) Arnaud Ligny <[email protected]>
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Cecil\Collection\Page;
10
11
use Cecil\Collection\Item;
12
use Cecil\Page\Parser;
13
use Cecil\Page\Prefix;
14
use Cecil\Page\Type;
15
use Cecil\Page\VariableTrait;
16
use Cecil\Util;
17
use Cocur\Slugify\Slugify;
18
use Symfony\Component\Finder\SplFileInfo;
19
20
/**
21
 * Class Page.
22
 */
23
class Page extends Item
24
{
25
    use VariableTrait;
26
27
    const SLUGIFY_PATTERN = '/(^\/|[^a-z0-9\/]|-)+/';
28
29
    /**
30
     * @var SplFileInfo
31
     */
32
    protected $file;
33
    /**
34
     * @var string
35
     */
36
    protected $fileExtension;
37
    /**
38
     * @var string
39
     */
40
    protected $filePath;
41
    /**
42
     * @var string
43
     */
44
    protected $fileName;
45
    /**
46
     * @var string
47
     */
48
    protected $filePathname;
49
    /**
50
     * @var bool
51
     */
52
    protected $virtual = false;
53
    /**
54
     * @var string
55
     */
56
    protected $type;
57
    /**
58
     * @var string
59
     */
60
    protected $id;
61
    /**
62
     * @var string
63
     */
64
    protected $pathname;
65
    /**
66
     * @var string
67
     */
68
    protected $path;
69
    /**
70
     * @var string
71
     */
72
    protected $name;
73
    /**
74
     * @var string
75
     */
76
    protected $frontmatter;
77
    /**
78
     * @var string
79
     */
80
    protected $body;
81
    /**
82
     * @var string
83
     */
84
    protected $html;
85
86
    /**
87
     * Constructor.
88
     *
89
     * @param SplFileInfo|null $file
90
     */
91
    public function __construct(SplFileInfo $file = null)
92
    {
93
        $this->file = $file;
94
95
        // physical page
96
        if ($this->file instanceof SplFileInfo) {
97
            /**
98
             * File path components
99
             */
100
            // ie: content/Blog/Post 1.md
101
            //             |    |      └─ fileExtension
102
            //             |    └─ fileName
103
            //             └─ filePath
104
            $this->fileExtension = pathinfo($this->file, PATHINFO_EXTENSION);
105
            $this->filePath = str_replace(DIRECTORY_SEPARATOR, '/', $this->file->getRelativePath());
106
            $this->fileName = $this->file->getBasename('.'.$this->fileExtension);
107
            // filePathname = ilePath + '/' + fileName
108
            // ie: "Blog/Post 1"
109
            $this->filePathname = ($this->filePath ? $this->filePath.'/' : '')
110
                .($this->filePath && $this->fileName == 'index' ? '' : $this->fileName);
111
            /*
112
             * Set properties
113
             */
114
            // ID. ie: "blog/post-1"
115
            $this->id = $this->slugify(Prefix::subPrefix($this->filePathname));
116
            // Path. ie: "blog"
117
            $this->path = $this->slugify($this->filePath);
118
            // Name. ie: "post-1"
119
            $this->name = $this->slugify(Prefix::subPrefix($this->fileName));
120
            // Pathname. ie: "blog/post-1"
121
            $this->pathname = $this->slugify(Prefix::subPrefix($this->filePathname));
122
            /*
123
             * Set default values
124
             */
125
            // Section. ie: "blog"
126
            $this->setSection(explode('/', $this->path)[0]);
127
            /*
128
             * Set variables default values (overridden by front matter)
129
             */
130
            // title. ie: "Post 1"
131
            $this->setVariable('title', Prefix::subPrefix($this->fileName));
132
            // date (from file meta)
133
            $this->setVariable('date', filemtime($this->file->getPathname()));
134
            // url
135
            $this->setPermalink($this->pathname.'/');
136
            // special case: file has a prefix
137
            if (Prefix::hasPrefix($this->filePathname)) {
138
                // prefix is a valid date?
139
                if (Util::isValidDate(Prefix::getPrefix($this->filePathname))) {
140
                    $this->setVariable('date', (string) Prefix::getPrefix($this->filePathname));
141
                } else {
142
                    // prefix is an integer, use for sorting
143
                    $this->setVariable('weight', (int) Prefix::getPrefix($this->filePathname));
144
                }
145
            }
146
147
            parent::__construct($this->id);
148
        } else {
149
            // virtual page
150
            $this->virtual = true;
151
152
            parent::__construct();
153
        }
154
        $this->setType(Type::PAGE);
155
        $this->setVariable('virtual', $this->virtual);
156
        $this->setVariable('published', true);
157
        $this->setVariable('content_template', 'page.content.twig');
158
    }
159
160
    /**
161
     * Turn a path (string) into a slung (URL).
162
     *
163
     * @param string $string
164
     *
165
     * @return string
166
     */
167
    public static function slugify(string $string): string
168
    {
169
        return Slugify::create([
170
            'regexp' => self::SLUGIFY_PATTERN,
171
        ])->slugify($string);
172
    }
173
174
    /**
175
     * Is current page is virtual?
176
     *
177
     * @return bool
178
     */
179
    public function isVirtual(): bool
180
    {
181
        return $this->virtual;
182
    }
183
184
    /**
185
     * Set page type.
186
     *
187
     * @param string $type
188
     *
189
     * @return self
190
     */
191
    public function setType(string $type): self
192
    {
193
        $this->type = new Type($type);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Cecil\Page\Type($type) of type object<Cecil\Page\Type> is incompatible with the declared type string of property $type.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
194
195
        return $this;
196
    }
197
198
    /**
199
     * Get page type.
200
     *
201
     * @return string|null
202
     */
203
    public function getType(): ?string
204
    {
205
        return $this->type;
206
    }
207
208
    /**
209
     * Parse file content.
210
     *
211
     * @return self
212
     */
213
    public function parse(): self
214
    {
215
        $parser = new Parser($this->file);
216
        $parsed = $parser->parse();
217
        $this->frontmatter = $parsed->getFrontmatter();
218
        $this->body = $parsed->getBody();
219
220
        return $this;
221
    }
222
223
    /**
224
     * Set name.
225
     *
226
     * @param string $name
227
     *
228
     * @return self
229
     */
230
    public function setName(string $name): self
231
    {
232
        $this->name = $name;
233
234
        return $this;
235
    }
236
237
    /**
238
     * Get name.
239
     *
240
     * @return string|null
241
     */
242
    public function getName(): ?string
243
    {
244
        return $this->name;
245
    }
246
247
    /**
248
     * Set path.
249
     *
250
     * @param $path
251
     *
252
     * @return self
253
     */
254
    public function setPath(string $path): self
255
    {
256
        $this->path = $path;
257
258
        return $this;
259
    }
260
261
    /**
262
     * Get path.
263
     *
264
     * @return string
265
     */
266
    public function getPath(): string
267
    {
268
        return $this->path;
269
    }
270
271
    /**
272
     * Set path name.
273
     *
274
     * @param string $pathname
275
     *
276
     * @return self
277
     */
278
    public function setPathname(string $pathname): self
279
    {
280
        $this->pathname = $pathname;
281
282
        return $this;
283
    }
284
285
    /**
286
     * Get path name.
287
     *
288
     * @return string
289
     */
290
    public function getPathname(): string
291
    {
292
        return $this->pathname;
293
    }
294
295
    /**
296
     * Set section.
297
     *
298
     * @param string $section
299
     *
300
     * @return self
301
     */
302
    public function setSection(string $section): self
303
    {
304
        $this->setVariable('section', $section);
305
306
        return $this;
307
    }
308
309
    /**
310
     * Get section.
311
     *
312
     * @return string|false
313
     */
314
    public function getSection(): ?string
315
    {
316
        if (empty($this->getVariable('section')) && !empty($this->path)) {
317
            $this->setSection(explode('/', $this->path)[0]);
318
        }
319
320
        return $this->getVariable('section');
321
    }
322
323
    /**
324
     * Set permalink.
325
     *
326
     * @param string $permalink
327
     *
328
     * @return self
329
     */
330
    public function setPermalink(string $permalink): self
331
    {
332
        $this->setVariable('permalink', $permalink);
333
334
        return $this;
335
    }
336
337
    /**
338
     * Get permalink.
339
     *
340
     * @return string|false
341
     */
342
    public function getPermalink(): ?string
343
    {
344
        if (empty($this->getVariable('permalink'))) {
345
            $this->setPermalink($this->getPathname().'/');
346
        }
347
348
        return $this->getVariable('permalink');
349
    }
350
351
    /**
352
     * Get frontmatter.
353
     *
354
     * @return string|null
355
     */
356
    public function getFrontmatter(): ?string
357
    {
358
        return $this->frontmatter;
359
    }
360
361
    /**
362
     * Get body as raw.
363
     *
364
     * @return string
365
     */
366
    public function getBody(): ?string
367
    {
368
        return $this->body;
369
    }
370
371
    /**
372
     * Set body as HTML.
373
     *
374
     * @param string $html
375
     *
376
     * @return self
377
     */
378
    public function setBodyHtml(string $html): self
379
    {
380
        $this->html = $html;
381
382
        return $this;
383
    }
384
385
    /**
386
     * Get body as HTML.
387
     *
388
     * @return string|null
389
     */
390
    public function getBodyHtml(): ?string
391
    {
392
        return $this->html;
393
    }
394
395
    /**
396
     * @see getBodyHtml()
397
     *
398
     * @return string|null
399
     */
400
    public function getContent(): ?string
401
    {
402
        return $this->getBodyHtml();
403
    }
404
405
    /**
406
     * Set layout.
407
     *
408
     * @param string $layout
409
     *
410
     * @return self
411
     */
412
    public function setLayout(string $layout): self
413
    {
414
        $this->setVariable('layout', $layout);
415
416
        return $this;
417
    }
418
419
    /**
420
     * Get layout.
421
     *
422
     * @return string|false
423
     */
424
    public function getLayout(): ?string
425
    {
426
        return $this->getVariable('layout');
427
    }
428
}
429