Passed
Push — master ( 04d195...416185 )
by Paul
07:31
created

Review::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace GeminiLabs\SiteReviews;
4
5
use GeminiLabs\SiteReviews\Database\Query;
6
use GeminiLabs\SiteReviews\Defaults\ReviewDefaults;
7
use GeminiLabs\SiteReviews\Helpers\Arr;
8
use GeminiLabs\SiteReviews\Helpers\Cast;
9
use GeminiLabs\SiteReviews\Helpers\Str;
10
use GeminiLabs\SiteReviews\Modules\Avatar;
11
use GeminiLabs\SiteReviews\Modules\Html\ReviewHtml;
12
13
/**
14
 * @property bool $approved  This property is mapped to $is_approved
15
 * @property array $assigned_posts
16
 * @property array $assigned_terms
17
 * @property array $assigned_users
18
 * @property string $author
19
 * @property int $author_id
20
 * @property string $avatar;
21
 * @property string $content
22
 * @property Arguments $custom
23
 * @property string $date
24
 * @property string $date_gmt
25
 * @property string $name  This property is mapped to $author
26
 * @property string $email
27
 * @property bool $has_revisions  This property is mapped to $is_modified
28
 * @property int $ID
29
 * @property string $ip_address
30
 * @property bool $is_approved
31
 * @property bool $is_modified
32
 * @property bool $is_pinned
33
 * @property bool $modified  This property is mapped to $is_modified
34
 * @property bool $pinned  This property is mapped to $is_pinned
35
 * @property int $rating
36
 * @property int $rating_id
37
 * @property string $response
38
 * @property string $status
39
 * @property string $title
40
 * @property string $type
41
 * @property string $url
42
 * @property int $user_id  This property is mapped to $author_id
43
 */
44
class Review extends Arguments
45
{
46
    /**
47
     * @var Arguments
48
     */
49
    protected $_meta;
50
51
    /**
52
     * @var \WP_Post
53
     */
54
    protected $_post;
55
56
    /**
57
     * @var object
58
     */
59
    protected $_review;
60
61
    /**
62
     * @var bool
63
     */
64
    protected $has_checked_revisions;
65
66
    /**
67
     * @var int
68
     */
69
    protected $id;
70
71
    /**
72
     * @param array|object $values
73
     */
74 13
    public function __construct($values)
75
    {
76 13
        $values = glsr()->args($values);
77 13
        $this->id = Cast::toInt($values->review_id);
78 13
        $args = glsr(ReviewDefaults::class)->restrict($values->toArray());
79 13
        $args['custom'] = $this->custom();
80 13
        $args['ID'] = $this->id;
81 13
        $args['response'] = $this->meta()->_response;
82 13
        parent::__construct($args);
83 13
    }
84
85
    /**
86
     * @return mixed
87
     */
88
    public function __call($method, $args)
89
    {
90
        array_unshift($args, $this);
91
        $result = apply_filters_ref_array(glsr()->id.'/review/call/'.$method, $args);
92
        if (!is_a($result, get_class($this))) {
93
            return $result;
94
        }
95
    }
96
97
    /**
98
     * @return string
99
     */
100 6
    public function __toString()
101
    {
102 6
        return (string) $this->build();
103
    }
104
105
    /**
106
     * @return array
107
     */
108
    public function assignedPosts()
109
    {
110
        if (empty($this->assigned_posts)) {
111
            return $this->assigned_posts;
112
        }
113
        return get_posts([
114
            'post__in' => $this->assigned_posts,
115
            'post_type' => 'any',
116
            'posts_per_page' => -1,
117
        ]);
118
    }
119
120
    /**
121
     * @return array
122
     */
123 6
    public function assignedTerms()
124
    {
125 6
        if (empty($this->assigned_terms)) {
126 6
            return $this->assigned_terms;
127
        }
128
        $terms = get_terms(glsr()->taxonomy, ['include' => $this->assigned_terms]);
129
        if (is_wp_error($terms)) {
130
            return $this->assigned_terms;
131
        }
132
        return $terms;
133
    }
134
135
    /**
136
     * @return array
137
     */
138 6
    public function assignedUsers()
139
    {
140 6
        if (empty($this->assigned_users)) {
141 6
            return $this->assigned_users;
142
        }
143
        return get_users([
144
            'fields' => ['display_name', 'ID', 'user_email', 'user_nicename', 'user_url'],
145
            'include' => $this->assigned_users,
146
        ]);
147
    }
148
149
    /**
150
     * @param int $size
151
     * @return string
152
     */
153
    public function avatar($size = null)
154
    {
155
        return glsr(Avatar::class)->img($this->get('avatar'), $size);
156
    }
157
158
    /**
159
     * @return ReviewHtml
160
     */
161 6
    public function build(array $args = [])
162
    {
163 6
        return new ReviewHtml($this, $args);
164
    }
165
166
    /**
167
     * @return Arguments
168
     */
169 13
    public function custom()
170
    {
171
        $custom = array_filter($this->meta()->toArray(), function ($key) {
172 13
            return Str::startsWith('_custom', $key);
173 13
        }, ARRAY_FILTER_USE_KEY);
174 13
        $custom = Arr::unprefixKeys($custom, '_custom_');
175 13
        $custom = Arr::unprefixKeys($custom, '_');
176 13
        return glsr()->args($custom);
177
    }
178
179
    /**
180
     * @return string
181
     */
182
    public function date($format = 'F j, Y')
183
    {
184
        return get_date_from_gmt($this->get('date'), $format);
185
    }
186
187
    /**
188
     * @param int|\WP_Post $post
189
     * @return bool
190
     */
191
    public static function isEditable($post)
192
    {
193
        $postId = Helper::getPostId($post);
194
        return static::isReview($postId)
195
            && post_type_supports(glsr()->post_type, 'title')
196
            && 'local' === glsr(Query::class)->review($postId)->type;
197
    }
198
199
    /**
200
     * @param \WP_Post|int|false $post
201
     * @return bool
202
     */
203 5
    public static function isReview($post)
204
    {
205 5
        return glsr()->post_type === get_post_type($post);
206
    }
207
208
    /**
209
     * @return bool
210
     */
211 13
    public function isValid()
212
    {
213 13
        return !empty($this->id) && !empty($this->get('rating_id'));
214
    }
215
216
    /**
217
     * @return Arguments
218
     */
219 13
    public function meta()
220
    {
221 13
        if (!$this->_meta instanceof Arguments) {
222 13
            $meta = Arr::consolidate(get_post_meta($this->id));
223
            $meta = array_map(function ($item) {
224 13
                return array_shift($item);
225 13
            }, array_filter($meta));
226 13
            $meta = array_filter($meta, 'strlen');
227 13
            $meta = array_map('maybe_unserialize', $meta);
228 13
            $this->_meta = glsr()->args($meta);
229
        }
230 13
        return $this->_meta;
231
    }
232
233
    /**
234
     * @param mixed $key
235
     * @return bool
236
     */
237 6
    public function offsetExists($key)
238
    {
239 6
        return parent::offsetExists($key) || !is_null($this->custom()->$key);
240
    }
241
242
    /**
243
     * @param mixed $key
244
     * @return mixed
245
     */
246 13
    public function offsetGet($key)
247
    {
248
        $alternateKeys = [
249 13
            'approved' => 'is_approved',
250
            'has_revisions' => 'is_modified',
251
            'modified' => 'is_modified',
252
            'name' => 'author',
253
            'pinned' => 'is_pinned',
254
            'user_id' => 'author_id',
255
        ];
256 13
        if (array_key_exists($key, $alternateKeys)) {
257
            return $this->offsetGet($alternateKeys[$key]);
258
        }
259 13
        if ('is_modified' === $key) {
260
            return $this->hasRevisions();
261
        }
262 13
        if (is_null($value = parent::offsetGet($key))) {
263
            return $this->custom()->$key;
264
        }
265 13
        return $value;
266
    }
267
268
    /**
269
     * @param mixed $key
270
     * @return void
271
     */
272
    public function offsetSet($key, $value)
273
    {
274
        // This class is read-only, except for custom fields
275
        if ('custom' === $key) {
276
            $value = Arr::consolidate($value);
277
            $value = Arr::prefixKeys($value, '_custom_');
278
            $meta = wp_parse_args($this->_meta->toArray(), $value);
279
            $this->_meta = glsr()->args($meta);
280
            parent::offsetSet($key, $this->custom());
281
        }
282
    }
283
284
    /**
285
     * @param mixed $key
286
     * @return void
287
     */
288
    public function offsetUnset($key)
289
    {
290
        // This class is read-only
291
    }
292
293
    /**
294
     * @return \WP_Post|null
295
     */
296
    public function post()
297
    {
298
        if (!$this->_post instanceof \WP_Post) {
299
            $this->_post = get_post($this->id);
300
        }
301
        return $this->_post;
302
    }
303
304
    /**
305
     * @return void
306
     */
307
    public function render()
308
    {
309
        echo $this->build();
310
    }
311
312
    /**
313
     * @return string
314
     */
315
    public function rating()
316
    {
317
        return glsr_star_rating($this->get('rating'));
318
    }
319
320
    /**
321
     * @return string
322
     */
323
    public function type()
324
    {
325
        $type = $this->get('type');
326
        $reviewTypes = glsr()->retrieveAs('array', 'review_types');
327
        return Arr::get($reviewTypes, $type, _x('Unknown', 'admin-text', 'site-reviews'));
328
    }
329
330
    /**
331
     * @return bool
332
     */
333
    protected function hasRevisions()
334
    {
335
        if (!$this->has_checked_revisions) {
336
            $modified = glsr(Query::class)->hasRevisions($this->ID);
337
            $this->set('is_modified', $modified);
338
            $this->has_checked_revisions = true;
339
        }
340
        return $this->get('is_modified');
341
    }
342
}
343