Completed
Push — master ( 913b4d...beeffb )
by Mathieu
02:48
created

AbstractEvent::preSave()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace Charcoal\Cms;
4
5
use \DateTime;
6
use \DateTimeInterface;
7
use \Exception;
8
use \InvalidArgumentException;
9
10
use \Psr\Http\Message\RequestInterface;
11
use \Psr\Http\Message\ResponseInterface;
12
13
// Module `charcoal-base` dependencies
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
// Module `charcoal-translation` depdencies
23
use \Charcoal\Translation\TranslationString;
24
25
// Intra-module (`charcoal-cms`) dependencies
26
use \Charcoal\Cms\MetatagInterface;
27
use \Charcoal\Cms\SearchableInterface;
28
29
/**
30
 *
31
 */
32
abstract class AbstractEvent extends Content implements
33
    CategorizableInterface,
34
    MetatagInterface,
35
    PublishableInterface,
36
    RoutableInterface,
37
    SearchableInterface
38
{
39
    use CategorizableTrait;
40
    use PublishableTrait;
41
    use MetatagTrait;
42
    use RoutableTrait;
43
    use SearchableTrait;
44
45
    /**
46
     * @var TranslationString $title
47
     */
48
    private $title;
49
50
    /**
51
     * @var TranslationString $title
52
     */
53
    private $subtitle;
54
55
    /**
56
     * @var TranslationString $content
57
     */
58
    private $content;
59
60
    /**
61
     * @var TranslationString $image
62
     */
63
    private $image;
64
65
    /**
66
     * @var DateTime $startDate
67
     */
68
    private $startDate;
69
    /**
70
     * @var DateTime $startDate
71
     */
72
    private $endDate;
73
74
    /**
75
     * @param mixed $title The event title (localized).
76
     * @return TranslationString
77
     */
78
    public function setTitle($title)
79
    {
80
        $this->title = new TranslationString($title);
81
        return $this;
82
    }
83
84
    /**
85
     * @return TranslationString
86
     */
87
    public function title()
88
    {
89
        return $this->title;
90
    }
91
92
    /**
93
     * @param mixed $subtitle The event subtitle (localized).
94
     * @return Event Chainable
95
     */
96
    public function setSubtitle($subtitle)
97
    {
98
        $this->subtitle = new TranslationString($subtitle);
99
        return $this;
100
    }
101
102
    /**
103
     * @return TranslationString
104
     */
105
    public function subtitle()
106
    {
107
        return $this->subtitle;
108
    }
109
110
    /**
111
     * @param mixed $content The event content (localized).
112
     * @return Event Chainable
113
     */
114
    public function setContent($content)
115
    {
116
        $this->content = new TranslationString($content);
117
        return $this;
118
    }
119
120
    /**
121
     * @return TranslationString
122
     */
123
    public function content()
124
    {
125
        return $this->content;
126
    }
127
128
    /**
129
     * @param mixed $image The section main image (localized).
130
     * @return Section Chainable
131
     */
132
    public function setImage($image)
133
    {
134
        $this->image = new TranslationString($image);
135
        return $this;
136
    }
137
138
    /**
139
     * @return TranslationString
140
     */
141
    public function image()
142
    {
143
        return $this->image;
144
    }
145
146
    /**
147
     * @param string|DateTime $startDate Event starting date.
148
     * @throws InvalidArgumentException If the timestamp is invalid.
149
     * @return EventInterface Chainable
150
     */
151 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...
152
    {
153
        if ($startDate === null) {
154
            $this->startDate = null;
155
            return $this;
156
        }
157
        if (is_string($startDate)) {
158
            $startDate = new DateTime($startDate);
159
        }
160
        if (!($startDate instanceof DateTimeInterface)) {
161
            throw new InvalidArgumentException(
162
                'Invalid "Start Date" value. Must be a date/time string or a DateTime object.'
163
            );
164
        }
165
        $this->startDate = $startDate;
166
        return $this;
167
    }
168
169
    /**
170
     * @return DateTime|null
171
     */
172
    public function startDate()
173
    {
174
        return $this->startDate;
175
    }
176
177
    /**
178
     * @param string|DateTime $endDate Event end date.
179
     * @throws InvalidArgumentException If the timestamp is invalid.
180
     * @return EventInterface Chainable
181
     */
182 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...
183
    {
184
        if ($endDate === null) {
185
            $this->endDate = null;
186
            return $this;
187
        }
188
        if (is_string($endDate)) {
189
            $endDate = new DateTime($endDate);
190
        }
191
        if (!($endDate instanceof DateTimeInterface)) {
192
            throw new InvalidArgumentException(
193
                'Invalid "End Date" value. Must be a date/time string or a DateTime object.'
194
            );
195
        }
196
        $this->endDate = $endDate;
197
        return $this;
198
    }
199
200
    /**
201
     * @return DateTime|null
202
     */
203
    public function endDate()
204
    {
205
        return $this->endDate;
206
    }
207
208
    /**
209
     * @param mixed $template The section template (ident).
210
     * @return SectionInterface Chainable
211
     */
212
    public function setTemplateIdent($template)
213
    {
214
        $this->templateIdent = $template;
0 ignored issues
show
Bug introduced by
The property templateIdent cannot be accessed from this context as it is declared private in class Charcoal\View\ViewableTrait.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
215
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Charcoal\Cms\AbstractEvent) is incompatible with the return type of the parent method Charcoal\Model\AbstractModel::setTemplateIdent of type Charcoal\View\ViewableTrait.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
216
    }
217
218
    /**
219
     * @return mixed
220
     */
221
    public function templateIdent()
222
    {
223
        if (!$this->templateIdent) {
0 ignored issues
show
Bug introduced by
The property templateIdent cannot be accessed from this context as it is declared private in class Charcoal\View\ViewableTrait.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
224
            $metadata = $this->metadata();
225
            return $metadata['template_ident'];
226
        }
227
        return $this->templateIdent;
0 ignored issues
show
Bug introduced by
The property templateIdent cannot be accessed from this context as it is declared private in class Charcoal\View\ViewableTrait.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
228
    }
229
230
    /**
231
     * @param array|string $templateOptions Extra template options, if any.
232
     * @return SectionInterface Chainable
233
     */
234
    public function setTemplateOptions($templateOptions)
235
    {
236
        $this->templateOptions = $templateOptions;
0 ignored issues
show
Bug introduced by
The property templateOptions does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
237
        return $this;
238
    }
239
240
    /**
241
     * @return array
242
     */
243
    public function templateOptions()
244
    {
245
        if (!$this->templateOptions) {
246
            $metadata = $this->metadata();
247
            return $metadata['template_options'];
248
        }
249
        return $this->templateOptions;
250
    }
251
252
    /**
253
     * @return TranslationString
254
     */
255
    public function defaultMetaTitle()
256
    {
257
        return $this->title();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->title(); (Charcoal\Translation\TranslationString) is incompatible with the return type declared by the interface Charcoal\Cms\MetatagInterface::defaultMetaTitle of type Charcoal\Cms\TranslationString.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
258
    }
259
260
    /**
261
     * @return TranslationString
262
     */
263
    public function defaultMetaDescription()
264
    {
265
        return $this->content();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->content(); (Charcoal\Translation\TranslationString) is incompatible with the return type declared by the interface Charcoal\Cms\MetatagInte...:defaultMetaDescription of type Charcoal\Cms\TranslationString.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
266
    }
267
268
    /**
269
     * @return TranslationString
270
     */
271
    public function defaultMetaImage()
272
    {
273
        return $this->image();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->image(); (Charcoal\Translation\TranslationString) is incompatible with the return type declared by the interface Charcoal\Cms\MetatagInterface::defaultMetaImage of type Charcoal\Cms\TranslationString.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
274
    }
275
276
        /**
277
     * {@inheritdoc}
278
     */
279
    public function preSave()
280
    {
281
        $this->setSlug($this->generateSlug());
282
        return parent::preSave();
283
    }
284
285
    /**
286
     *{@inheritdoc}
287
     */
288
    public function preUpdate(array $properties = null)
289
    {
290
        if (!$this->slug) {
291
            $this->setSlug($this->generateSlug());
292
        }
293
        return parent::preUpdate($properties);
294
    }
295
}
296