Test Failed
Push — master ( 653e6c...3b4aec )
by Paul
03:40
created

CountsManager::decrease()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Database;
4
5
use GeminiLabs\SiteReviews\Database\OptionManager;
6
use GeminiLabs\SiteReviews\Database\ReviewManager;
7
use GeminiLabs\SiteReviews\Database\SqlQueries;
8
use GeminiLabs\SiteReviews\Modules\Rating;
9
use GeminiLabs\SiteReviews\Review;
10
11
class CountsManager
12
{
13
	const META_COUNT = '_glsr_count';
14
15
	/**
16
	 * @param int $limit
17
	 * @return array
18
	 */
19 6
	public function buildCounts( $limit = 500 )
20
	{
21 6
		return $this->build( $limit );
22
	}
23
24
	/**
25
	 * @param int $postId
26
	 * @param int $limit
27
	 * @return array
28
	 */
29
	public function buildPostCounts( $postId, $limit = 500 )
30
	{
31
		return $this->build( $limit, ['post_id' => $postId] );
32
	}
33
34
	/**
35
	 * @param int $termId
36
	 * @param int $limit
37
	 * @return array
38
	 */
39
	public function buildTermCounts( $termId, $limit = 500 )
40
	{
41
		return $this->build( $limit, ['term_id' => $termId] );
42
	}
43
44
	/**
45
	 * @return void
46
	 */
47
	public function decrease( Review $review )
48
	{
49
		$this->decreaseCounts( $review );
50
		$this->decreasePostCounts( $review );
51
		$this->decreaseTermCounts( $review );
52
	}
53
54
	/**
55
	 * @return void
56
	 */
57
	public function decreaseCounts( Review $review )
58
	{
59
		$this->setCounts( $this->decreaseRating(
60
			$this->getCounts(),
61
			$review->review_type,
62
			$review->rating
63
		));
64
	}
65
66
	/**
67
	 * @return void
68
	 */
69
	public function decreasePostCounts( Review $review )
70
	{
71
		if( empty( $counts = $this->getPostCounts( $review->assigned_to )))return;
72
		$this->setPostCounts( $review->assigned_to, $this->decreaseRating(
73
			$counts,
74
			$review->review_type,
75
			$review->rating
76
		));
77
	}
78
79
	/**
80
	 * @return void
81
	 */
82
	public function decreaseTermCounts( Review $review )
83
	{
84
		foreach( $review->term_ids as $termId ) {
85
			if( empty( $counts = $this->getTermCounts( $termId )))continue;
86
			$this->setTermCounts( $termId, $this->decreaseRating(
87
				$counts,
88
				$review->review_type,
89
				$review->rating
90
			));
91
		}
92
	}
93
94
	/**
95
	 * @return array
96
	 */
97
	public function flatten( array $reviewCounts )
98
	{
99
		$counts = [];
100
		array_walk_recursive( $reviewCounts, function( $num, $index ) use( &$counts ) {
101
			$counts[$index] = isset( $counts[$index] )
102
				? $num + $counts[$index]
103
				: $num;
104
		});
105
		return $counts;
106
	}
107
108
	/**
109
	 * @return array
110
	 */
111
	public function getCounts()
112
	{
113
		return glsr( OptionManager::class )->get( 'count', [] );
114
	}
115
116
	/**
117
	 * @param int $postId
118
	 * @return array
119
	 */
120
	public function getPostCounts( $postId )
121
	{
122
		return (array)get_post_meta( $postId, static::META_COUNT, true );
123
	}
124
125
	/**
126
	 * @param int $termId
127
	 * @return array
128
	 */
129
	public function getTermCounts( $termId )
130
	{
131
		return (array)get_term_meta( $termId, static::META_COUNT, true );
132
	}
133
134
	/**
135
	 * @return void
136
	 */
137
	public function increase( Review $review )
138
	{
139
		$this->increaseCounts( $review );
140
		$this->increasePostCounts( $review );
141
		$this->increaseTermCounts( $review );
142
	}
143
144
	/**
145
	 * @return void
146
	 */
147
	public function increaseCounts( Review $review )
148
	{
149
		if( empty( $counts = $this->getCounts() )) {
150
			$counts = $this->buildCounts();
151
		}
152
		$this->setCounts( $this->increaseRating(
153
			$counts,
154
			$review->review_type,
155
			$review->rating
156
		));
157
	}
158
159
	/**
160
	 * @return void
161
	 */
162
	public function increasePostCounts( Review $review )
163
	{
164
		if( empty( $counts = $this->getPostCounts( $review->assigned_to ))) {
165
			$counts = $this->buildPostCounts( $review->assigned_to );
166
		}
167
		$this->setPostCounts( $review->assigned_to, $this->increaseRating(
168
			$counts,
169
			$review->review_type,
170
			$review->rating
171
		));
172
	}
173
174
	/**
175
	 * @return void
176
	 */
177
	public function increaseTermCounts( Review $review )
178
	{
179
		foreach( $review->term_ids as $termId ) {
180
			if( empty( $counts = $this->getTermCounts( $termId ))) {
181
				$counts = $this->buildTermCounts( $termId );
182
			}
183
			$this->setTermCounts( $termId, $this->increaseRating(
184
				$counts,
185
				$review->review_type,
186
				$review->rating
187
			));
188
		}
189
	}
190
191
	/**
192
	 * @return void
193
	 */
194
	public function setCounts( array $reviewCounts )
195
	{
196
		glsr( OptionManager::class )->set( 'count', $reviewCounts );
197
	}
198
199
	/**
200
	 * @param int $postId
201
	 * @return void
202
	 */
203
	public function setPostCounts( $postId, array $reviewCounts )
204
	{
205
		update_post_meta( $postId, static::META_COUNT, $reviewCounts );
206
	}
207
208
	/**
209
	 * @param int $termId
210
	 * @return void
211
	 */
212
	public function setTermCounts( $termId, array $reviewCounts )
213
	{
214
		update_term_meta( $termId, static::META_COUNT, $reviewCounts );
215
	}
216
217
	/**
218
	 * @param int $limit
219
	 * @return array
220
	 */
221 6
	protected function build( $limit, array $args = [] )
222
	{
223 6
		$counts = [];
224 6
		$lastPostId = 0;
225 6
		while( $reviews = $this->queryReviews( $args, $lastPostId, $limit )) {
226
			$types = array_keys( array_flip( array_column( $reviews, 'type' )));
227
			foreach( $types as $type ) {
228
				if( isset( $counts[$type] ))continue;
229
				$counts[$type] = array_fill_keys( range( 0, Rating::MAX_RATING ), 0 );
230
			}
231
			foreach( $reviews as $review ) {
232
				$counts[$review->type][$review->rating]++;
233
			}
234
			$lastPostId = end( $reviews )->ID;
235
		}
236 6
		return $counts;
237
	}
238
239
	/**
240
	 * @param string $type
241
	 * @param int $rating
242
	 * @return array
243
	 */
244
	protected function decreaseRating( array $reviewCounts, $type, $rating )
245
	{
246
		if( isset( $reviewCounts[$type][$rating] )) {
247
			$reviewCounts[$type][$rating] = max( 0, $reviewCounts[$type][$rating] - 1 );
248
		}
249
		return $reviewCounts;
250
	}
251
252
	/**
253
	 * @param string $type
254
	 * @param int $rating
255
	 * @return array
256
	 */
257
	protected function increaseRating( array $reviewCounts, $type, $rating )
258
	{
259
		if( !array_key_exists( $type, glsr()->reviewTypes )) {
260
			return $reviewCounts;
261
		}
262
		if( !array_key_exists( $type, $reviewCounts )) {
263
			$reviewCounts[$type] = [];
264
		}
265
		$reviewCounts = $this->normalize( $reviewCounts );
266
		$reviewCounts[$type][$rating] = intval( $reviewCounts[$type][$rating] ) + 1;
267
		return $reviewCounts;
268
	}
269
270
	/**
271
	 * @return array
272
	 */
273
	protected function normalize( array $reviewCounts )
274
	{
275
		foreach( $reviewCounts as &$counts ) {
276
			foreach( range( 0, Rating::MAX_RATING ) as $index ) {
277
				if( isset( $counts[$index] ))continue;
278
				$counts[$index] = 0;
279
			}
280
			ksort( $counts );
281
		}
282
		return $reviewCounts;
283
	}
284
285
	/**
286
	 * @param int $lastPostId
287
	 * @param int $limit
288
	 * @return void|array
289
	 */
290 6
	protected function queryReviews( array $args = [], $lastPostId, $limit )
291
	{
292 6
		$args = wp_parse_args( $args, array_fill_keys( ['post_id', 'term_id'], '' ));
293 6
		if( empty( array_filter( $args ))) {
294 6
			return glsr( SqlQueries::class )->getReviewCounts( $lastPostId, $limit );
295
		}
296
		if( !empty( $args['post_id'] )) {
297
			return glsr( SqlQueries::class )->getReviewPostCounts( $args['post_id'], $lastPostId, $limit );
298
		}
299
		if( !empty( $args['term_id'] )) {
300
			return glsr( SqlQueries::class )->getReviewTermCounts( $args['term_id'], $lastPostId, $limit );
301
		}
302
	}
303
}
304