Test Failed
Push — master ( c4aa6a...a5e42e )
by Mathieu
03:19
created

PublishableTrait::getPublishStatus()   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
namespace Charcoal\Object;
4
5
use DateTime;
6
use DateTimeInterface;
7
use InvalidArgumentException;
8
use UnexpectedValueException;
9
use Exception;
10
11
/**
12
 * Publishable Object
13
 *
14
 * A full implementation, as trait, of the {@see \Charcoal\Object\PublishableInterface}.
15
 */
16
trait PublishableTrait
17
{
18
    /**
19
     * The publication date.
20
     *
21
     * @var DateTimeInterface $publishDate
22
     */
23
    protected $publishDate;
24
25
    /**
26
     * The expiration date.
27
     *
28
     * @var DateTimeInterface $expiryDate
29
     */
30
    protected $expiryDate;
31
32
    /**
33
     * The publication status.
34
     *
35
     * @var string|null
36
     */
37
    protected $publishStatus;
38
39
    /**
40
     * Set the object's publication date.
41
     *
42
     * @param  string|DateTimeInterface|null $time The date/time value.
43
     * @throws UnexpectedValueException If the date/time value is invalid.
44
     * @throws InvalidArgumentException If the value is not a date/time instance.
45
     * @return PublishableInterface Chainable
46
     */
47 View Code Duplication
    public function setPublishDate($time)
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...
48
    {
49
        if ($time === null || $time === '') {
50
            $this->publishDate = null;
51
            return $this;
52
        }
53
54
        if (is_string($time)) {
55
            try {
56
                $time = new DateTime($time);
57
            } catch (Exception $e) {
58
                throw new UnexpectedValueException(sprintf(
59
                    'Invalid Publication Date: %s',
60
                    $e->getMessage()
61
                ), $e->getCode(), $e);
62
            }
63
        }
64
65
        if (!$time instanceof DateTimeInterface) {
66
            throw new InvalidArgumentException(
67
                'Publication Date must be a date/time string or an instance of DateTimeInterface'
68
            );
69
        }
70
71
        $this->publishDate = $time;
72
73
        return $this;
74
    }
75
76
    /**
77
     * Retrieve the object's publication date.
78
     *
79
     * @return DateTimeInterface|null
80
     */
81
    public function getPublishDate()
82
    {
83
        return $this->publishDate;
84
    }
85
86
    /**
87
     * Set the object's expiration date.
88
     *
89
     * @param  string|DateTimeInterface|null $time The date/time value.
90
     * @throws UnexpectedValueException If the date/time value is invalid.
91
     * @throws InvalidArgumentException If the value is not a date/time instance.
92
     * @return PublishableInterface Chainable
93
     */
94 View Code Duplication
    public function setExpiryDate($time)
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...
95
    {
96
        if ($time === null || $time === '') {
97
            $this->expiryDate = null;
98
            return $this;
99
        }
100
101
        if (is_string($time)) {
102
            try {
103
                $time = new DateTime($time);
104
            } catch (Exception $e) {
105
                throw new UnexpectedValueException(sprintf(
106
                    'Invalid Expiration Date: %s',
107
                    $e->getMessage()
108
                ), $e->getCode(), $e);
109
            }
110
        }
111
112
        if (!$time instanceof DateTimeInterface) {
113
            throw new InvalidArgumentException(
114
                'Expiration Date must be a date/time string or an instance of DateTimeInterface'
115
            );
116
        }
117
118
        $this->expiryDate = $time;
119
120
        return $this;
121
    }
122
123
    /**
124
     * Retrieve the object's expiration date.
125
     *
126
     * @return DateTimeInterface|null
127
     */
128
    public function getExpiryDate()
129
    {
130
        return $this->expiryDate;
131
    }
132
133
    /**
134
     * Set the object's publication status.
135
     *
136
     * @param  string $status A publication status.
137
     * @throws InvalidArgumentException If the status is invalid.
138
     * @return PublishableInterface Chainable
139
     */
140
    public function setPublishStatus($status)
141
    {
142
        if ($status === null || $status === '') {
143
            $this->publishStatus = null;
144
            return $this;
145
        }
146
147
        $specialStatus = [
148
            static::STATUS_EXPIRED  => static::STATUS_PUBLISHED,
149
            static::STATUS_UPCOMING => static::STATUS_PUBLISHED
150
        ];
151
152
        /** Resolve any special statuses */
153
        if (isset($specialStatus[$status])) {
154
            $status = $specialStatus[$status];
155
        }
156
157
        $validStatus = [
158
            static::STATUS_DRAFT,
159
            static::STATUS_PENDING,
160
            static::STATUS_PUBLISHED
161
        ];
162
163
        if (!in_array($status, $validStatus)) {
164
            throw new InvalidArgumentException(sprintf(
165
                'Status "%s" is not a valid publish status.',
166
                $status
167
            ));
168
        }
169
170
        $this->publishStatus = $status;
171
172
        return $this;
173
    }
174
175
    /**
176
     * Retrieve the object's publication status.
177
     *
178
     * @return string|null
179
     */
180
    public function getPublishStatus()
181
    {
182
        return $this->publishStatus;
183
    }
184
185
    /**
186
     * Retrieve the object's publication status based on publication and expiration dates.
187
     *
188
     * - If the publication status is not "published", that status is returned (e.g., "draft", "pending", NULL).
189
     * - If no publication date is set, then it's assumed to be always published (or "expired").
190
     * - If no expiration date is set, then it's assumed to never expire.
191
     * - If a publication date is set to a future date, then it's assumed to be scheduled to be published ("upcoming").
192
     *
193
     * @return string|null
194
     */
195
    public function publishDateStatus()
196
    {
197
        $now = new DateTime();
198
        $publish = $this['publishDate'];
199
        $expiry  = $this['expiryDate'];
200
        $status  = $this['publishStatus'];
201
202
        if ($status !== static::STATUS_PUBLISHED) {
203
            return $status;
204
        }
205
206
        if (!$publish) {
207
            if (!$expiry || $now < $expiry) {
208
                return static::STATUS_PUBLISHED;
209
            } else {
210
                return static::STATUS_EXPIRED;
211
            }
212
        } else {
213
            if ($now < $publish) {
214
                return static::STATUS_UPCOMING;
215
            } else {
216
                if (!$expiry || $now < $expiry) {
217
                    return static::STATUS_PUBLISHED;
218
                } else {
219
                    return static::STATUS_EXPIRED;
220
                }
221
            }
222
        }
223
    }
224
225
    /**
226
     * Determine if the object is published.
227
     *
228
     * @return boolean
229
     */
230
    public function isPublished()
231
    {
232
        return ($this->publishDateStatus() === static::STATUS_PUBLISHED);
233
    }
234
}
235