Passed
Push — master ( 43e885...6ea935 )
by Paul
13:24 queued 06:45
created

Review   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Test Coverage

Coverage 46.85%

Importance

Changes 5
Bugs 0 Features 2
Metric Value
wmc 39
eloc 96
c 5
b 0
f 2
dl 0
loc 304
ccs 52
cts 111
cp 0.4685
rs 9.28

24 Methods

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