Test Failed
Push — master ( 59b255...755753 )
by Paul
04:04
created

Database::setReviewTerms()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 2
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews;
4
5
use GeminiLabs\SiteReviews\Application;
6
use GeminiLabs\SiteReviews\Database\Cache;
7
use GeminiLabs\SiteReviews\Commands\CreateReview;
8
use GeminiLabs\SiteReviews\Database\OptionManager;
9
use GeminiLabs\SiteReviews\Database\QueryBuilder;
10
use GeminiLabs\SiteReviews\Database\SqlQueries;
11
use GeminiLabs\SiteReviews\Defaults\CreateReviewDefaults;
12
use GeminiLabs\SiteReviews\Defaults\GetReviewsDefaults;
13
use WP_Error;
14
use WP_Post;
15
use WP_Query;
16
17
class Database
18
{
19
	/**
20
	 * @return int|bool
21
	 */
22 1
	public function createReview( CreateReview $command )
23
	{
24 1
		$review = glsr( CreateReviewDefaults::class )->restrict( (array)$command );
25 1
		$review = apply_filters( 'site-reviews/create/review-values', $review, $command );
26
		$post = [
27 1
			'comment_status' => 'closed',
28 1
			'meta_input' => $review,
29 1
			'ping_status' => 'closed',
30 1
			'post_content' => $review['content'],
31 1
			'post_date' => $review['date'],
32 1
			'post_name' => $review['review_type'].'-'.$review['review_id'],
33 1
			'post_status' => $this->getNewPostStatus( $review, $command->blacklisted ),
34
			'post_title' => $review['title'],
35
			'post_type' => Application::POST_TYPE,
36 1
		];
37 1
		$postId = wp_insert_post( $post, true );
38
		if( is_wp_error( $postId )) {
39
			glsr_log()->error( $postId->get_error_message() );
40
			return false;
41 1
		}
42 1
		$this->setReviewTerms( $postId, $command->category );
0 ignored issues
show
Bug introduced by
It seems like $postId can also be of type WP_Error; however, parameter $postId of GeminiLabs\SiteReviews\Database::setReviewTerms() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

42
		$this->setReviewTerms( /** @scrutinizer ignore-type */ $postId, $command->category );
Loading history...
43 1
		do_action( 'site-reviews/create/review', $post, $review, $postId );
44
		return $postId;
45
	}
46
47
	/**
48
	 * Delete review based on a review_id meta value
49
	 * @param string $metaReviewId
50
	 * @return void
51
	 */
52
	public function deleteReview( $metaReviewId )
53
	{
54
		if( $postId = $this->getReviewPostId( $metaReviewId )) {
55
			wp_delete_post( $postId, true );
56
		}
57
	}
58
59
	/**
60
	 * @param int|WP_post $post
61
	 * @param string $assignedTo
62
	 * @return void|WP_Post
63
	 */
64
	public function getAssignedToPost( $post, $assignedTo = '' )
65
	{
66
		$post = get_post( $post );
67
		if( !( $post instanceof WP_Post ))return;
68
		if( empty( $assignedTo )) {
69
			$assignedTo = get_post_meta( $post->ID, 'assigned_to', true );
70
		}
71
		$assignedPost = get_post( $assignedTo );
72
		if( !empty( $assignedTo )
73
			&& $assignedPost instanceof WP_Post
74
			&& $assignedPost->ID != $post->ID ) {
75
			return $assignedPost;
76
		}
77
	}
78
79
	/**
80
	 * @param \WP_Post|null $post
81
	 * @return null|object
82
	 */
83
	public function getReview( $post )
84
	{
85
		if( !( $post instanceof WP_Post ) || $post->post_type != Application::POST_TYPE )return;
86
		$review = $this->getReviewMeta( $post->ID );
87
		$modified = $this->isReviewModified( $post, $review );
88
		$review->content = $post->post_content;
89
		$review->data = $post->post_date;
90
		$review->ID = $post->ID;
91
		$review->modifed = $modified;
92
		$review->status = $post->post_status;
93
		$review->title = $post->post_title;
94
		$review->user_id = $post->post_author;
95
		return apply_filters( 'site-reviews/get/review', $review, $post );
96
	}
97
98
	/**
99
	 * @param string $metaKey
100
	 * @param string $metaValue
101
	 * @return array|int
102
	 */
103
	public function getReviewCount( $metaKey = '', $metaValue = '' )
104
	{
105
		$metaKey = $this->normalizeMetaKey( $metaKey );
106
		if( !$metaKey ) {
107
			return (array) wp_count_posts( Application::POST_TYPE );
108
		}
109
		$counts = glsr( Cache::class )->getReviewCountsFor( $metaKey );
110
		if( !$metaValue ) {
111
			return $counts;
112
		}
113
		return isset( $counts[$metaValue] )
114
			? $counts[$metaValue]
115
			: 0;
116
	}
117
118
	/**
119
	 * @param string $metaReviewType
120
	 * @return array
121
	 */
122
	public function getReviewIdsByType( $metaReviewType )
123
	{
124
		return glsr( SqlQueries::class )->getReviewIdsByType( $metaReviewType );
125
	}
126
127
	/**
128
	 * @param int $postId
129
	 * @return object
130
	 */
131
	public function getReviewMeta( $postId )
132
	{
133
		$meta = get_post_type( $postId ) == Application::POST_TYPE
134
			? array_map( 'array_shift', (array) get_post_meta( $postId ))
135
			: [];
136
		return (object) $this->normalizeMeta( array_filter( $meta, 'strlen' ));
137
	}
138
139
	/**
140
	 * @param string $metaReviewId
141
	 * @return int
142
	 */
143
	public function getReviewPostId( $metaReviewId )
144
	{
145
		return glsr( SqlQueries::class )->getReviewPostId( $metaReviewId );
146
	}
147
148
	/**
149
	 * @return object
150
	 */
151
	public function getReviews( array $args = [] )
152
	{
153
		$args = glsr( GetReviewsDefaults::class )->restrict( $args );
154
		$metaQuery = glsr( QueryBuilder::class )->buildQuery(
155
			['assigned_to', 'type', 'rating'],
156
			$args
157
		);
158
		$taxQuery = glsr( QueryBuilder::class )->buildQuery(
159
			['category'],
160
			['category' => $this->normalizeTerms( $args['category'] )]
161
		);
162
		$paged = glsr( QueryBuilder::class )->getPaged(
163
			wp_validate_boolean( $args['pagination'] )
164
		);
165
		$reviews = new WP_Query([
166
			'meta_key' => 'pinned',
167
			'meta_query' => $metaQuery,
168
			'offset' => $args['offset'],
169
			'order' => $args['order'],
170
			'orderby' => 'meta_value '.$args['orderby'],
171
			'paged' => $paged,
172
			'post__in' => $args['post__in'],
173
			'post__not_in' => $args['post__not_in'],
174
			'post_status' => 'publish',
175
			'post_type' => Application::POST_TYPE,
176
			'posts_per_page' => $args['count'] ? $args['count'] : -1,
177
			'tax_query' => $taxQuery,
178
		]);
179
		return (object) [
180
			'results' => array_map( [$this, 'getReview'], $reviews->posts ),
181
			'max_num_pages' => $reviews->max_num_pages,
182
		];
183
	}
184
185
	/**
186
	 * @param string|array $keys
187
	 * @param string $status
188
	 * @return array
189
	 */
190
	public function getReviewsMeta( $keys, $status = 'publish' )
191
	{
192
		$keys = array_map( [$this, 'normalizeMetaKey'], (array)$keys );
193
		if( $status == 'all' || empty( $status )) {
194
			$status = get_post_stati( ['exclude_from_search' => false] );
195
		}
196
		return glsr( SqlQueries::class )->getReviewsMeta( $keys, $status );
197
	}
198
199
	/**
200
	 * @param string $taxonomy
201
	 * @return array
202 1
	 */
203
	public function getTerms( array $args = [] )
204 1
	{
205 1
		$args = wp_parse_args( $args, [
206
			'fields' => 'id=>name',
207
			'hide_empty' => false,
208
			'taxonomy' => Application::TAXONOMY,
209 1
		]);
210 1
		unset( $args['count'] ); //we don't want a term count
211 1
		$terms = get_terms( $args );
212
		if( is_wp_error( $terms )) {
213
			glsr_log()->error( $terms->get_error_message() );
214
			return [];
215 1
		}
216
		return $terms;
217
	}
218
219
	/**
220
	 * @return array
221
	 */
222
	public function normalizeMeta( array $meta )
223
	{
224
		if( empty( $meta )) {
225
			return [];
226
		}
227
		$defaults = wp_parse_args( $meta, [
228
			'author' => __( 'Anonymous', 'site-reviews' ),
229
			'date' => '',
230
			'review_id' => '',
231
			'review_type' => '',
232
		]);
233
		return glsr( CreateReviewDefaults::class )->restrict( $defaults );
234
	}
235
236
	/**
237
	 * @param string $metaKey
238
	 * @return string
239
	 */
240
	public function normalizeMetaKey( $metaKey )
241
	{
242
		$metaKey = strtolower( $metaKey );
243
		if( in_array( $metaKey, ['id', 'type'] )) {
244
			$metaKey = 'review_'.$metaKey;
245
		}
246
		return $metaKey;
247
	}
248
249
	/**
250
	 * @param string $termIds string of comma-separated term IDs
251
	 * @return array
252 1
	 */
253
	public function normalizeTerms( $termIds )
254 1
	{
255 1
		$terms = [];
256 1
		$termIds = array_map( 'trim', explode( ',', $termIds ));
257 1
		foreach( $termIds as $termId ) {
258 1
			$term = term_exists( $termId, Application::TAXONOMY );
259
			if( !isset( $term['term_id'] ))continue;
260
			$terms[] = intval( $term['term_id'] );
261 1
		}
262
		return $terms;
263
	}
264
265
	/**
266
	 * @param int $postId
267
	 * @return void
268
	 */
269
	public function revertReview( $postId )
270
	{
271
		if( get_post_field( 'post_type', $postId ) != Application::POST_TYPE )return;
272
		delete_post_meta( $postId, '_edit_last' );
273
		$result = wp_update_post([
274
			'ID' => $postId,
275
			'post_content' => get_post_meta( $postId, 'content', true ),
276
			'post_date' => get_post_meta( $postId, 'date', true ),
277
			'post_title' => get_post_meta( $postId, 'title', true ),
278
		]);
279
		if( is_wp_error( $result )) {
280
			glsr_log()->error( $result->get_error_message() );
281
		}
282
	}
283
284
	/**
285
	 * @param string $searchTerm
286
	 * @return void|string
287
	 */
288
	public function searchPosts( $searchTerm )
289
	{
290
		$args = [
291
			'post_status' => 'publish',
292
			'post_type' => 'any',
293
		];
294
		if( is_numeric( $searchTerm )) {
295
			$args['post__in'] = [$searchTerm];
296
		}
297
		else {
298
			$args['orderby'] = 'relevance';
299
			$args['posts_per_page'] = 10;
300
			$args['s'] = $searchTerm;
301
		}
302
		$queryBuilder = glsr( QueryBuilder::class );
303
		add_filter( 'posts_search', [$queryBuilder, 'filterSearchByTitle'], 500, 2 );
304
		$search = new WP_Query( $args );
305
		remove_filter( 'posts_search', [$queryBuilder, 'filterSearchByTitle'], 500 );
306
		if( !$search->have_posts() )return;
307
		$results = '';
308
		while( $search->have_posts() ) {
309
			$search->the_post();
310
			ob_start();
311
			glsr()->render( 'partials/editor/search-result', [
312
				'ID' => get_the_ID(),
313
				'permalink' => esc_url( (string) get_permalink() ),
314
				'title' => esc_attr( get_the_title() ),
315
			]);
316
			$results .= ob_get_clean();
317
		}
318
		wp_reset_postdata();
319
		return $results;
320
	}
321
322
	/**
323
	 * @param int $postId
324
	 * @param string $termIds
325
	 * @return void
326
	 */
327 1
	public function setReviewTerms( $postId, $termIds )
328
	{
329 1
		$terms = $this->normalizeTerms( $termIds );
330 1
		if( empty( $terms ))return;
331
		$result = wp_set_object_terms( $postId, $terms, Application::TAXONOMY );
332 1
		if( is_wp_error( $result )) {
333 1
			glsr_log()->error( $result->get_error_message() );
334
		}
335
	}
336
337
	/**
338
	 * @param bool $isBlacklisted
339
	 * @return string
340
	 */
341
	protected function getNewPostStatus( array $review, $isBlacklisted )
342
	{
343
		$requireApprovalOption = glsr( OptionManager::class )->get( 'settings.general.require.approval' );
344 1
		return $review['review_type'] == 'local' && ( $requireApprovalOption == 'yes' || $isBlacklisted )
345
			? 'pending'
346 1
			: 'publish';
347 1
	}
348
349 1
	/**
350
	 * @param object $review
351
	 * @return bool
352
	 */
353
	protected function isReviewModified( WP_Post $post, $review )
354
	{
355
		return $post->post_date != $review->date
356
			|| $post->post_content != $review->content
357
			|| $post->post_title != $review->title;
358
	}
359
}
360