Completed
Push — include-lib ( fd24a6...4173d3 )
by Arnaud
13:24
created

Page::getDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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 Cocur\Slugify\Slugify;
12
use Cecil\Collection\Item;
13
use Cecil\Page\NodeType;
14
use Cecil\Page\Parser;
15
use Cecil\Page\VariableTrait;
16
use Symfony\Component\Finder\SplFileInfo;
17
18
/**
19
 * Class Page.
20
 */
21
class Page extends Item
22
{
23
    use VariableTrait;
24
25
    const SLUGIFY_PATTERN = '/(^\/|[^a-z0-9\/]|-)+/';
26
    // https://regex101.com/r/tJWUrd/1
27
    const PREFIX_PATTERN = '^(.*?)(([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])|[0-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 $fileId;
49
50
    /**
51
     * @var bool
52
     */
53
    protected $virtual = false;
54
    /**
55
     * @var string
56
     */
57
    protected $nodeType;
58
59
    /**
60
     * @var string
61
     */
62
    protected $id;
63
    /**
64
     * @var string
65
     */
66
    protected $pathname;
67
    /**
68
     * @var string
69
     */
70
    protected $path;
71
    /**
72
     * @var string
73
     */
74
    protected $name;
75
76
    /**
77
     * @var string
78
     */
79
    protected $frontmatter;
80
    /**
81
     * @var string
82
     */
83
    protected $body;
84
    /**
85
     * @var string
86
     */
87
    protected $html;
88
89
    /**
90
     * Constructor.
91
     *
92
     * @param null|SplFileInfo $file
93
     */
94
    public function __construct(SplFileInfo $file = null)
95
    {
96
        $this->file = $file;
97
98
        if ($this->file instanceof SplFileInfo) {
99
            // file extension: "md"
100
            $this->fileExtension = pathinfo($this->file, PATHINFO_EXTENSION);
101
            // file path: "Blog"
102
            $this->filePath = str_replace(DIRECTORY_SEPARATOR, '/', $this->file->getRelativePath());
103
            // file name: "Post 1"
104
            $this->fileName = basename($this->file->getBasename(), '.'.$this->fileExtension);
105
            // file id: "Blog/Post 1"
106
            $this->fileId = ($this->filePath ? $this->filePath.'/' : '')
107
                .($this->filePath && $this->fileName == 'index' ? '' : $this->fileName);
108
            /*
109
             * variables default values
110
             */
111
            // id - ie: "blog/post-1"
112
            $this->id = $this->urlize(self::subPrefix($this->fileId));
113
            // pathname - ie: "blog/post-1"
114
            $this->pathname = $this->urlize(self::subPrefix($this->fileId));
115
            // path - ie: "blog"
116
            $this->path = $this->urlize($this->filePath);
117
            // name - ie: "post-1"
118
            $this->name = $this->urlize(self::subPrefix($this->fileName));
119
            /*
120
             * front matter default values
121
             */
122
            // title - ie: "Post 1"
123
            $this->setTitle(self::subPrefix($this->fileName));
124
            // section - ie: "blog"
125
            $this->setSection(explode('/', $this->path)[0]);
126
            // date from file meta
127
            $this->setDate(filemtime($this->file->getPathname()));
128
            // file as a prefix?
129
            if (false !== self::getPrefix($this->fileId)) {
130
                // prefix is a valid date?
131
                $isValidDate = function ($date, $format = 'Y-m-d') {
132
                    $d = \DateTime::createFromFormat($format, $date);
133
134
                    return $d && $d->format($format) === $date;
135
                };
136
                if ($isValidDate(self::getPrefix($this->fileId))) {
137
                    $this->setDate(self::getPrefix($this->fileId));
138
                } else {
139
                    // prefix is an integer
140
                    $this->setWeight(self::getPrefix($this->fileId));
141
                }
142
            }
143
            // permalink
144
            $this->setPermalink($this->pathname);
145
146
            parent::__construct($this->id);
147
        } else {
148
            $this->virtual = true;
149
150
            parent::__construct();
151
        }
152
        $this->setVariable('virtual', $this->virtual);
153
        $this->setVariable('published', true);
154
        $this->setVariable('content_template', 'page.content.twig');
155
    }
156
157
    /**
158
     * Return matches array if prefix exist or false.
159
     *
160
     * @param $string
161
     *
162
     * @return string[]|false
163
     */
164
    public static function asPrefix($string)
165
    {
166
        if (preg_match('/'.self::PREFIX_PATTERN.'/', $string, $matches)) {
167
            return $matches;
168
        } else {
169
            return false;
170
        }
171
    }
172
173
    /**
174
     * Return prefix if prefix or false.
175
     *
176
     * @param $string
177
     *
178
     * @return string[]|false
0 ignored issues
show
Documentation introduced by
Should the return type not be string|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
179
     */
180 View Code Duplication
    public static function getPrefix($string)
181
    {
182
        if (false !== ($matches = self::asPrefix($string))) {
183
            return $matches[2];
184
        }
185
186
        return false;
187
    }
188
189
    /**
190
     * Return string without prefix (if exist).
191
     *
192
     * @param $string
193
     *
194
     * @return string
195
     */
196 View Code Duplication
    public static function subPrefix($string)
197
    {
198
        if (false !== ($matches = self::asPrefix($string))) {
199
            return $matches[1].$matches[7];
200
        }
201
202
        return $string;
203
    }
204
205
    /**
206
     * Format string into URL.
207
     *
208
     * @param $string
209
     *
210
     * @return string
211
     */
212
    public static function urlize($string)
213
    {
214
        return Slugify::create([
215
            'regexp' => self::SLUGIFY_PATTERN,
216
        ])->slugify($string);
217
    }
218
219
    /**
220
     * Is current page is virtual?
221
     *
222
     * @return bool
223
     */
224
    public function isVirtual()
225
    {
226
        return $this->virtual;
227
    }
228
229
    /**
230
     * Set node type.
231
     *
232
     * @param string $nodeType
233
     *
234
     * @return self
235
     */
236
    public function setNodeType($nodeType)
237
    {
238
        $this->nodeType = new NodeType($nodeType);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Cecil\Page\NodeType($nodeType) of type object<Cecil\Page\NodeType> is incompatible with the declared type string of property $nodeType.

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...
239
240
        return $this;
241
    }
242
243
    /**
244
     * Get node type.
245
     *
246
     * @return string
247
     */
248
    public function getNodeType()
249
    {
250
        return $this->nodeType;
251
    }
252
253
    /**
254
     * Parse file content.
255
     *
256
     * @return $this
257
     */
258
    public function parse()
259
    {
260
        $parser = new Parser($this->file);
261
        $parsed = $parser->parse();
262
        $this->frontmatter = $parsed->getFrontmatter();
263
        $this->body = $parsed->getBody();
264
265
        return $this;
266
    }
267
268
    /**
269
     * Set name.
270
     *
271
     * @param $name
272
     *
273
     * @return $this
274
     */
275
    public function setName($name)
276
    {
277
        $this->name = $name;
278
279
        return $this;
280
    }
281
282
    /**
283
     * Get name.
284
     *
285
     * @return string
286
     */
287
    public function getName()
288
    {
289
        return $this->name;
290
    }
291
292
    /**
293
     * Set path.
294
     *
295
     * @param $path
296
     *
297
     * @return $this
298
     */
299
    public function setPath($path)
300
    {
301
        $this->path = $path;
302
303
        return $this;
304
    }
305
306
    /**
307
     * Get path.
308
     *
309
     * @return string
310
     */
311
    public function getPath()
312
    {
313
        return $this->path;
314
    }
315
316
    /**
317
     * Set path name.
318
     *
319
     * @param string $pathname
320
     *
321
     * @return $this
322
     */
323
    public function setPathname($pathname)
324
    {
325
        $this->pathname = $pathname;
326
327
        return $this;
328
    }
329
330
    /**
331
     * Get path name.
332
     *
333
     * @return string
334
     */
335
    public function getPathname()
336
    {
337
        return $this->pathname;
338
    }
339
340
    /**
341
     * Set section.
342
     *
343
     * @param $section
344
     *
345
     * @return $this
346
     */
347
    public function setSection($section)
348
    {
349
        $this->setVariable('section', $section);
350
351
        return $this;
352
    }
353
354
    /**
355
     * Get section.
356
     *
357
     * @return mixed|false
358
     */
359
    public function getSection()
360
    {
361
        if (empty($this->getVariable('section')) && !empty($this->path)) {
362
            $this->setSection(explode('/', $this->path)[0]);
363
        }
364
365
        return $this->getVariable('section');
366
    }
367
368
    /**
369
     * Set title.
370
     *
371
     * @param $title
372
     *
373
     * @return $this
374
     */
375
    public function setTitle($title)
376
    {
377
        $this->setVariable('title', $title);
378
379
        return $this;
380
    }
381
382
    /**
383
     * Get title.
384
     *
385
     * @return mixed|false
386
     */
387
    public function getTitle()
388
    {
389
        return $this->getVariable('title');
390
    }
391
392
    /**
393
     * Set date.
394
     *
395
     * @param $date
396
     *
397
     * @return $this
398
     */
399
    public function setDate($date)
400
    {
401
        $this->setVariable('date', $date);
402
403
        return $this;
404
    }
405
406
    /**
407
     * Get Date.
408
     *
409
     * @return \DateTime|false
410
     */
411
    public function getDate()
412
    {
413
        return $this->getVariable('date');
414
    }
415
416
    /**
417
     * Set weight.
418
     *
419
     * @param $int
420
     *
421
     * @return $this
422
     */
423
    public function setWeight($int)
424
    {
425
        $this->setVariable('weight', $int);
426
427
        return $this;
428
    }
429
430
    /**
431
     * Get weight.
432
     *
433
     * @return int
434
     */
435
    public function getWeight()
436
    {
437
        return $this->getVariable('weight');
438
    }
439
440
    /**
441
     * Set permalink.
442
     *
443
     * @param $permalink
444
     *
445
     * @return $this
446
     */
447
    public function setPermalink($permalink)
448
    {
449
        $this->setVariable('permalink', $permalink);
450
451
        return $this;
452
    }
453
454
    /**
455
     * Get permalink.
456
     *
457
     * @return mixed|false
458
     */
459
    public function getPermalink()
460
    {
461
        if (empty($this->getVariable('permalink'))) {
462
            $this->setPermalink($this->getPathname());
463
        }
464
465
        return $this->getVariable('permalink');
466
    }
467
468
    /**
469
     * Get frontmatter.
470
     *
471
     * @return string
472
     */
473
    public function getFrontmatter()
474
    {
475
        return $this->frontmatter;
476
    }
477
478
    /**
479
     * Get body.
480
     *
481
     * @return string
482
     */
483
    public function getBody()
484
    {
485
        return $this->body;
486
    }
487
488
    /**
489
     * Set HTML.
490
     *
491
     * @param string $html
492
     *
493
     * @return $this
494
     */
495
    public function setHtml($html)
496
    {
497
        $this->html = $html;
498
499
        return $this;
500
    }
501
502
    /**
503
     * Get HTML alias.
504
     *
505
     * @return string
506
     */
507
    public function getContent()
508
    {
509
        return $this->html;
510
    }
511
512
    /**
513
     * Set layout.
514
     *
515
     * @param $layout
516
     *
517
     * @return $this
518
     */
519
    public function setLayout($layout)
520
    {
521
        $this->setVariable('layout', $layout);
522
523
        return $this;
524
    }
525
526
    /**
527
     * Get layout.
528
     *
529
     * @return mixed|false
530
     */
531
    public function getLayout()
532
    {
533
        return $this->getVariable('layout');
534
    }
535
}
536