Test Failed
Push — master ( dc68d1...1f5199 )
by Mathieu
02:31
created

AbstractEvent::defaultMetaTitle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Charcoal\Cms;
4
5
use DateTime;
6
use DateTimeInterface;
7
use InvalidArgumentException;
8
9
// From PSR-7
10
use Psr\Http\Message\RequestInterface;
11
use Psr\Http\Message\ResponseInterface;
12
13
// From 'charcoal-object'
14
use Charcoal\Object\Content;
15
use Charcoal\Object\CategorizableInterface;
16
use Charcoal\Object\CategorizableTrait;
17
use Charcoal\Object\PublishableInterface;
18
use Charcoal\Object\PublishableTrait;
19
use Charcoal\Object\RoutableInterface;
20
use Charcoal\Object\RoutableTrait;
21
22
// From 'charcoal-translator'
23
use Charcoal\Translator\Translation;
24
25
// From 'charcoal-cms'
26
use Charcoal\Cms\MetatagInterface;
27
use Charcoal\Cms\SearchableInterface;
28
use Charcoal\Cms\TemplateableInterface;
29
30
use Charcoal\Cms\MetatagTrait;
31
use Charcoal\Cms\SearchableTrait;
32
use Charcoal\Cms\TemplateableTrait;
33
34
/**
35
 *
36
 */
37
abstract class AbstractEvent extends Content implements
38
    CategorizableInterface,
39
    EventInterface,
40
    MetatagInterface,
41
    PublishableInterface,
42
    RoutableInterface,
43
    SearchableInterface,
44
    TemplateableInterface
45
{
46
    use CategorizableTrait;
47
    use PublishableTrait;
48
    use MetatagTrait;
49
    use RoutableTrait;
50
    use SearchableTrait;
51
    use TemplateableTrait;
52
53
    /**
54
     * @var Translation|string|null
55
     */
56
    private $title;
57
58
    /**
59
     * @var Translation|string|null
60
     */
61
    private $subtitle;
62
63
    /**
64
     * @var Translation|string|null
65
     */
66
    private $summary;
67
68
    /**
69
     * @var Translation|string|null
70
     */
71
    private $content;
72
73
    /**
74
     * @var Translation|string|null
75
     */
76
    private $image;
77
78
    /**
79
     * @var DateTimeInterface|null
80
     */
81
    private $startDate;
82
83
    /**
84
     * @var DateTimeInterface|null
85
     */
86
    private $endDate;
87
88
    /**
89
     * @var array
90
     */
91
    protected $keywords;
92
93
    // ==========================================================================
94
    // INIT
95
    // ==========================================================================
96
97
    /**
98
     * Section constructor.
99
     * @param array $data The data.
100
     */
101 View Code Duplication
    public function __construct(array $data = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
    {
103
        parent::__construct($data);
104
105
        if (is_callable([ $this, 'defaultData' ])) {
106
            $this->setData($this->defaultData());
107
        }
108
    }
109
110
    // ==========================================================================
111
    // FUNCTIONS
112
    // ==========================================================================
113
114
    /**
115
     * Some dates cannot be null
116
     * @return void
117
     */
118
    public function verifyDates()
119
    {
120
        if (!$this->startDate()) {
121
            $this->setStartDate('now');
122
        }
123
124
        if (!$this->endDate()) {
125
            $this->setEndDate($this->startDate());
0 ignored issues
show
Bug introduced by
It seems like $this->startDate() can be null; however, setEndDate() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
126
        }
127
128
        if (!$this->publishDate()) {
129
            $this->setPublishDate('now');
130
        }
131
    }
132
133
    /**
134
     * @return string The date filtered for admin dual select input and others.
135
     */
136
    public function adminDateFilter()
137
    {
138
        $start = $this->startDate()->format('Y-m-d');
139
        $end = $this->endDate()->format('Y-m-d');
140
141
        if ($start === $end) {
142
            $date = $start;
143
        } else {
144
            $date = $start.' - '.$end;
145
        }
146
147
        return $date;
148
    }
149
150
    // ==========================================================================
151
    // SETTERS and GETTERS
152
    // ==========================================================================
153
154
    /**
155
     * @param  mixed $title The event title (localized).
156
     * @return self
157
     */
158
    public function setTitle($title)
159
    {
160
        $this->title = $this->translator()->translation($title);
161
162
        return $this;
163
    }
164
165
    /**
166
     * @return Translation|string|null
167
     */
168
    public function title()
169
    {
170
        return $this->title;
171
    }
172
173
    /**
174
     * @param  mixed $subtitle The event subtitle (localized).
175
     * @return self
176
     */
177
    public function setSubtitle($subtitle)
178
    {
179
        $this->subtitle = $this->translator()->translation($subtitle);
180
181
        return $this;
182
    }
183
184
    /**
185
     * @return Translation|string|null
186
     */
187
    public function subtitle()
188
    {
189
        return $this->subtitle;
190
    }
191
192
    /**
193
     * @param  mixed $summary The news summary (localized).
194
     * @return self
195
     */
196
    public function setSummary($summary)
197
    {
198
        $this->summary = $this->translator()->translation($summary);
199
200
        return $this;
201
    }
202
203
    /**
204
     * @return Translation|string|null
205
     */
206
    public function summary()
207
    {
208
        return $this->summary;
209
    }
210
211
    /**
212
     * @param  mixed $content The event content (localized).
213
     * @return self
214
     */
215
    public function setContent($content)
216
    {
217
        $this->content = $this->translator()->translation($content);
218
219
        return $this;
220
    }
221
222
    /**
223
     * @return Translation|string|null
224
     */
225
    public function content()
226
    {
227
        return $this->content;
228
    }
229
230
    /**
231
     * @param  mixed $image The section main image (localized).
232
     * @return self
233
     */
234
    public function setImage($image)
235
    {
236
        $this->image = $this->translator()->translation($image);
237
238
        return $this;
239
    }
240
241
    /**
242
     * @return Translation|string|null
243
     */
244
    public function image()
245
    {
246
        return $this->image;
247
    }
248
249
    /**
250
     * @param  string|DateTimeInterface $startDate Event starting date.
251
     * @throws InvalidArgumentException If the timestamp is invalid.
252
     * @return self
253
     */
254 View Code Duplication
    public function setStartDate($startDate)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
255
    {
256
        if ($startDate === null || $startDate === '') {
257
            $this->startDate = null;
258
259
            return $this;
260
        }
261
        if (is_string($startDate)) {
262
            $startDate = new DateTime($startDate);
263
        }
264
        if (!($startDate instanceof DateTimeInterface)) {
265
            throw new InvalidArgumentException(
266
                'Invalid "Start Date" value. Must be a date/time string or a DateTime object.'
267
            );
268
        }
269
        $this->startDate = $startDate;
270
271
        return $this;
272
    }
273
274
    /**
275
     * @return DateTimeInterface|null
276
     */
277
    public function startDate()
278
    {
279
        return $this->startDate;
280
    }
281
282
    /**
283
     * @param  string|DateTimeInterface $endDate Event end date.
284
     * @throws InvalidArgumentException If the timestamp is invalid.
285
     * @return self
286
     */
287 View Code Duplication
    public function setEndDate($endDate)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
288
    {
289
        if ($endDate === null || $endDate === '') {
290
            $this->endDate = null;
291
292
            return $this;
293
        }
294
        if (is_string($endDate)) {
295
            $endDate = new DateTime($endDate);
296
        }
297
        if (!($endDate instanceof DateTimeInterface)) {
298
            throw new InvalidArgumentException(
299
                'Invalid "End Date" value. Must be a date/time string or a DateTime object.'
300
            );
301
        }
302
        $this->endDate = $endDate;
303
304
        return $this;
305
    }
306
307
    /**
308
     * @return DateTimeInterface|null
309
     */
310
    public function endDate()
311
    {
312
        return $this->endDate;
313
    }
314
315
    // ==========================================================================
316
    // META TAGS
317
    // ==========================================================================
318
319
    /**
320
     * MetatagTrait > canonical_url
321
     *
322
     * @todo
323
     * @return string
324
     */
325
    public function canonicalUrl()
326
    {
327
        return '';
328
    }
329
330
    /**
331
     * @return Translation|string|null
332
     */
333
    public function defaultMetaTitle()
334
    {
335
        return $this->title();
336
    }
337
338
    /**
339
     * @return Translation|string|null
340
     */
341 View Code Duplication
    public function defaultMetaDescription()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
342
    {
343
        $content = $this->translator()->translation($this->content());
344
        if ($content instanceof Translation) {
345
            $desc = [];
346
            foreach ($content->data() as $lang => $text) {
347
                $desc[$lang] = strip_tags($text);
348
            }
349
350
            return $this->translator()->translation($desc);
351
        }
352
353
        return null;
354
    }
355
356
    /**
357
     * @return Translation|string|null
358
     */
359
    public function defaultMetaImage()
360
    {
361
        return $this->image();
362
    }
363
364
    /**
365
     * Retrieve the object's keywords.
366
     *
367
     * @return string[]
368
     */
369
    public function keywords()
370
    {
371
        return $this->keywords;
372
    }
373
374
    // ==========================================================================
375
    // EVENTS
376
    // ==========================================================================
377
378
    /**
379
     * {@inheritdoc}
380
     *
381
     * @return boolean
382
     */
383
    public function preSave()
384
    {
385
        $this->verifyDates();
386
        $this->setSlug($this->generateSlug());
387
        $this->generateDefaultMetaTags();
388
389
        return parent::preSave();
390
    }
391
392
    /**
393
     * {@inheritdoc}
394
     *
395
     * @param  array $properties Optional properties to update.
396
     * @return boolean
397
     */
398
    public function preUpdate(array $properties = null)
399
    {
400
        $this->verifyDates();
401
        $this->setSlug($this->generateSlug());
402
        $this->generateDefaultMetaTags();
403
404
        return parent::preUpdate($properties);
405
    }
406
407
    /**
408
     * @return boolean Parent postSave().
409
     */
410
    public function postSave()
411
    {
412
        // RoutableTrait
413
        $this->generateObjectRoute($this->slug());
414
415
        return parent::postSave();
416
    }
417
418
    /**
419
     * @param array|null $properties Properties.
420
     * @return boolean
421
     */
422
    public function postUpdate(array $properties = null)
423
    {
424
        // RoutableTrait
425
        $this->generateObjectRoute($this->slug());
426
427
        return parent::postUpdate($properties);
0 ignored issues
show
Bug introduced by
It seems like $properties defined by parameter $properties on line 422 can also be of type array; however, Charcoal\Source\StorableTrait::postUpdate() does only seem to accept null|array<integer,string>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
428
    }
429
430
    /**
431
     * GenericRoute checks if the route is active.
432
     * Default in RoutableTrait.
433
     *
434
     * @return boolean
435
     */
436
    public function isActiveRoute()
437
    {
438
        return (
439
            $this->active() &&
440
            $this->isPublished()
441
        );
442
    }
443
}
444