Passed
Push — master ( 8bf068...43e885 )
by Paul
08:48
created

ReviewManager   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 346
Duplicated Lines 0 %

Test Coverage

Coverage 52.47%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 45
eloc 148
c 2
b 0
f 0
dl 0
loc 346
ccs 85
cts 162
cp 0.5247
rs 8.8

21 Methods

Rating   Name   Duplication   Size   Complexity  
A assignTerm() 0 11 2
A createRaw() 0 22 2
A assignUser() 0 11 2
A createFromPost() 0 5 1
A assignPost() 0 12 2
A create() 0 11 3
A unassignTerm() 0 11 2
A unassignUser() 0 11 2
A reviews() 0 8 1
A get() 0 6 1
A deleteRevisions() 0 5 2
A updateCustom() 0 8 2
A delete() 0 7 2
A updateAssignedPost() 0 7 1
A update() 0 20 5
A unassignPost() 0 11 2
A updateRating() 0 10 2
A total() 0 3 1
A updateResponse() 0 9 1
A updateReview() 0 24 5
A postStatus() 0 6 4

How to fix   Complexity   

Complex Class

Complex classes like ReviewManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ReviewManager, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace GeminiLabs\SiteReviews\Database;
4
5
use GeminiLabs\SiteReviews\Commands\CreateReview;
6
use GeminiLabs\SiteReviews\Database;
7
use GeminiLabs\SiteReviews\Defaults\CustomFieldsDefaults;
8
use GeminiLabs\SiteReviews\Defaults\RatingDefaults;
9
use GeminiLabs\SiteReviews\Defaults\UpdateReviewDefaults;
10
use GeminiLabs\SiteReviews\Helper;
11
use GeminiLabs\SiteReviews\Helpers\Arr;
12
use GeminiLabs\SiteReviews\Helpers\Cast;
13
use GeminiLabs\SiteReviews\Modules\Sanitizer;
14
use GeminiLabs\SiteReviews\Request;
15
use GeminiLabs\SiteReviews\Review;
16
use GeminiLabs\SiteReviews\Reviews;
17
18
class ReviewManager
19
{
20
    /**
21
     * @param int $postId
22
     * @return int|false
23
     */
24 2
    public function assignPost(Review $review, $postId)
25
    {
26
        $where = [
27 2
            'is_published' => 'publish' === get_post_status($postId),
28 2
            'post_id' => $postId,
29 2
            'rating_id' => $review->rating_id,
30
        ];
31 2
        if ($result = glsr(Database::class)->insert('assigned_posts', $where)) {
32 2
            glsr(Cache::class)->delete($review->ID, 'reviews');
33 2
            glsr(CountManager::class)->posts($postId);
34
        }
35 2
        return $result;
36
    }
37
38
    /**
39
     * @param int $termId
40
     * @return int|false
41
     */
42 2
    public function assignTerm(Review $review, $termId)
43
    {
44
        $where = [
45 2
            'rating_id' => $review->rating_id,
46 2
            'term_id' => $termId,
47
        ];
48 2
        if ($result = glsr(Database::class)->insert('assigned_terms', $where)) {
49 2
            glsr(Cache::class)->delete($review->ID, 'reviews');
50 2
            glsr(CountManager::class)->terms($termId);
51
        }
52 2
        return $result;
53
    }
54
55
    /**
56
     * @param int $userId
57
     * @return int|false
58
     */
59 2
    public function assignUser(Review $review, $userId)
60
    {
61
        $where = [
62 2
            'rating_id' => $review->rating_id,
63 2
            'user_id' => $userId,
64
        ];
65 2
        if ($result = glsr(Database::class)->insert('assigned_users', $where)) {
66 2
            glsr(Cache::class)->delete($review->ID, 'reviews');
67 2
            glsr(CountManager::class)->users($userId);
68
        }
69 2
        return $result;
70
    }
71
72
    /**
73
     * @return false|Review
74
     */
75 14
    public function create(CreateReview $command, $postId = null)
76
    {
77 14
        if (empty($postId)) {
78 14
            $postId = $this->createRaw($command);
79
        }
80 14
        $review = $this->get($postId);
81 14
        if ($review->isValid()) {
82 14
            glsr()->action('review/created', $review, $command);
83 14
            return $this->get($review->ID); // return a fresh copy of the review
84
        }
85
        return false;
86
    }
87
88
    /**
89
     * @param int $postId
90
     * @return false|Review
91
     */
92
    public function createFromPost($postId)
93
    {
94
        $command = new CreateReview(new Request([]));
95
        glsr()->action('review/create', $postId, $command);
96
        return $this->create($command, $postId);
97
    }
98
99
    /**
100
     * @return false|int
101
     */
102 14
    public function createRaw(CreateReview $command)
103
    {
104 14
        $values = glsr()->args($command->toArray()); // this filters the values
105
        $postValues = [
106 14
            'comment_status' => 'closed',
107 14
            'meta_input' => ['_submitted' => $command->request->toArray()], // save the original submitted request in metadata
108 14
            'ping_status' => 'closed',
109 14
            'post_content' => $values->content,
110 14
            'post_date' => $values->date,
111 14
            'post_date_gmt' => $values->date_gmt,
112 14
            'post_name' => uniqid($values->type),
113 14
            'post_status' => $this->postStatus($values->type, $values->blacklisted),
114 14
            'post_title' => $values->title,
115 14
            'post_type' => glsr()->post_type,
116
        ];
117 14
        $postId = wp_insert_post($postValues, true);
118 14
        if (is_wp_error($postId)) {
119
            glsr_log()->error($postId->get_error_message())->debug($postValues);
120
            return false;
121
        }
122 14
        glsr()->action('review/create', $postId, $command);
123 14
        return $postId;
124
    }
125
126
    /**
127
     * This only deletes the entry in the ratings table!
128
     * @param int $reviewId
129
     * @return int|false
130
     */
131
    public function delete($reviewId)
132
    {
133
        $result = glsr(Database::class)->delete('ratings', ['review_id' => $reviewId]);
134
        if ($result) {
135
            glsr(Cache::class)->delete($reviewId, 'reviews');
136
        }
137
        return $result;
138
    }
139
140
    /**
141
     * @param int $reviewId
142
     * @return void
143
     */
144
    public function deleteRevisions($reviewId)
145
    {
146
        $revisionIds = glsr(Query::class)->revisionIds($reviewId);
147
        foreach ($revisionIds as $revisionId) {
148
            wp_delete_post_revision($revisionId);
149
        }
150
    }
151
152
    /**
153
     * @param int $reviewId
154
     * @return Review
155
     */
156 14
    public function get($reviewId)
157
    {
158 14
        $reviewId = Helper::getPostId($reviewId);
159 14
        $review = glsr(Query::class)->review($reviewId);
160 14
        glsr()->action('get/review', $review, $reviewId);
161 14
        return $review;
162
    }
163
164
    /**
165
     * @return Reviews
166
     */
167 1
    public function reviews(array $args = [])
168
    {
169 1
        $args = (new NormalizePaginationArgs($args))->toArray();
170 1
        $results = glsr(Query::class)->reviews($args);
171 1
        $total = $this->total($args, $results);
172 1
        $reviews = new Reviews($results, $total, $args);
173 1
        glsr()->action('get/reviews', $reviews, $args);
174 1
        return $reviews;
175
    }
176
177
    /**
178
     * @return int
179
     */
180 1
    public function total(array $args = [], array $reviews = [])
181
    {
182 1
        return glsr(Query::class)->totalReviews($args, $reviews);
183
    }
184
185
    /**
186
     * @param int $postId
187
     * @return int|false
188
     */
189 1
    public function unassignPost(Review $review, $postId)
190
    {
191
        $where = [
192 1
            'post_id' => $postId,
193 1
            'rating_id' => $review->rating_id,
194
        ];
195 1
        if ($result = glsr(Database::class)->delete('assigned_posts', $where)) {
196 1
            glsr(Cache::class)->delete($review->ID, 'reviews');
197 1
            glsr(CountManager::class)->posts($postId);
198
        }
199 1
        return $result;
200
    }
201
202
    /**
203
     * @param int $termId
204
     * @return int|false
205
     */
206 1
    public function unassignTerm(Review $review, $termId)
207
    {
208
        $where = [
209 1
            'rating_id' => $review->rating_id,
210 1
            'term_id' => $termId,
211
        ];
212 1
        if ($result = glsr(Database::class)->delete('assigned_terms', $where)) {
213 1
            glsr(Cache::class)->delete($review->ID, 'reviews');
214 1
            glsr(CountManager::class)->terms($termId);
215
        }
216 1
        return $result;
217
    }
218
219
    /**
220
     * @param int $userId
221
     * @return int|false
222
     */
223 1
    public function unassignUser(Review $review, $userId)
224
    {
225
        $where = [
226 1
            'rating_id' => $review->rating_id,
227 1
            'user_id' => $userId,
228
        ];
229 1
        if ($result = glsr(Database::class)->delete('assigned_users', $where)) {
230 1
            glsr(Cache::class)->delete($review->ID, 'reviews');
231 1
            glsr(CountManager::class)->users($userId);
232
        }
233 1
        return $result;
234
    }
235
236
    /**
237
     * @param int $reviewId
238
     * @return Review|false  Return false on failure
239
     */
240
    public function update($reviewId, array $data = [])
241
    {
242
        if (false === $this->updateRating($reviewId, $data)) {
243
            return false;
244
        }
245
        if (false === $this->updateReview($reviewId, $data)) {
246
            return false;
247
        }
248
        $this->updateCustom($reviewId, $data);
249
        $this->updateResponse($reviewId, Arr::get($data, 'response'));
250
        $review = glsr(Query::class)->review($reviewId);
251
        if ($assignedPosts = Arr::uniqueInt(Arr::get($data, 'assigned_posts'))) {
252
            glsr()->action('review/updated/post_ids', $review, $assignedPosts); // trigger a recount of assigned posts
253
        }
254
        if ($assignedUsers = Arr::uniqueInt(Arr::get($data, 'assigned_users'))) {
255
            glsr()->action('review/updated/user_ids', $review, $assignedUsers); // trigger a recount of assigned posts
256
        }
257
        $review = glsr(Query::class)->review($reviewId); // get a fresh copy of the review
258
        glsr()->action('review/saved', $review, $data);
259
        return $review;
260
    }
261
262
    /**
263
     * @param int $postId
264
     * @param bool $isPublished
265
     * @return int|bool
266
     */
267
    public function updateAssignedPost($postId, $isPublished)
268
    {
269
        $isPublished = wp_validate_boolean($isPublished);
270
        $postId = Cast::toInt($postId);
271
        return glsr(Database::class)->update('assigned_posts',
272
            ['is_published' => $isPublished],
273
            ['post_id' => $postId]
274
        );
275
    }
276
277
    /**
278
     * @param int $reviewId
279
     * @return array
280
     */
281
    public function updateCustom($reviewId, array $data = [])
282
    {
283
        $data = glsr(CustomFieldsDefaults::class)->merge($data);
284
        $data = Arr::prefixKeys($data, 'custom_');
285
        foreach ($data as $metaKey => $metaValue) {
286
            glsr(Database::class)->metaSet($reviewId, $metaKey, $metaValue);
287
        }
288
        return $data;
289
    }
290
291
    /**
292
     * @param int $reviewId
293
     * @return int|false  Returns false on error
294
     */
295
    public function updateRating($reviewId, array $data = [])
296
    {
297
        glsr(Cache::class)->delete($reviewId, 'reviews');
298
        $defaults = glsr(RatingDefaults::class)->restrict($data);
299
        if ($data = array_intersect_key($data, $defaults)) {
300
            return glsr(Database::class)->update('ratings', $data, [
301
                'review_id' => $reviewId,
302
            ]);
303
        }
304
        return 0;
305
    }
306
307
    /**
308
     * @param int $reviewId
309
     * @param string $response
310
     * @return int|bool
311
     */
312
    public function updateResponse($reviewId, $response = '')
313
    {
314
        $response = Cast::toString($response);
315
        $response = glsr(Sanitizer::class)->sanitizeTextHtml($response);
316
        $userId = Helper::ifTrue(empty($response), 0, get_current_user_id());
317
        $review = glsr_get_review($reviewId);
318
        glsr()->action('review/responded', $review, $response, $userId);
319
        glsr(Database::class)->metaSet($reviewId, 'response_by', $userId); // prefixed metakey
320
        return glsr(Database::class)->metaSet($reviewId, 'response', $response); // prefixed metakey
321
    }
322
323
    /**
324
     * @param int $reviewId
325
     * @return int|false  Returns false on failure
326
     */
327
    public function updateReview($reviewId, array $data = [])
328
    {
329
        if (glsr()->post_type !== get_post_type($reviewId)) {
330
            return 0;
331
        }
332
        glsr(Cache::class)->delete($reviewId, 'reviews');
333
        $defaults = glsr(UpdateReviewDefaults::class)->restrict($data);
334
        if ($data = array_intersect_key($data, $defaults)) {
335
            $data = array_filter([
336
                'post_content' => Arr::get($data, 'content'),
337
                'post_date' => Arr::get($data, 'date'),
338
                'post_date_gmt' => Arr::get($data, 'date_gmt'),
339
                'post_status' => Arr::get($data, 'status'),
340
                'post_title' => Arr::get($data, 'title'),
341
            ]);
342
        }
343
        if (!empty($data)) {
344
            $result = wp_update_post(wp_parse_args(['ID' => $reviewId], $data), true);
345
            if (is_wp_error($result)) {
346
                glsr_log()->error($result->get_error_message());
347
                return false;
348
            }
349
        }
350
        return 0;
351
    }
352
353
    /**
354
     * @param string $reviewType
355
     * @param bool $isBlacklisted
356
     * @return string
357
     */
358 14
    protected function postStatus($reviewType, $isBlacklisted)
359
    {
360 14
        $requireApproval = glsr(OptionManager::class)->getBool('settings.general.require.approval');
361 14
        return 'local' == $reviewType && ($requireApproval || $isBlacklisted)
362 1
            ? 'pending'
363 14
            : 'publish';
364
    }
365
}
366