Passed
Push — master ( 211fe0...c1039b )
by Paul
03:43
created

CountsManager::increasePostCounts()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 5.667

Importance

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