Passed
Push — master ( 78492a...4f268f )
by Paul
04:26
created

Database::getAssignedToPost()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
nc 5
nop 2
dl 0
loc 12
ccs 0
cts 10
cp 0
crap 42
rs 9.2222
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
			'ping_status' => 'closed',
29 1
			'post_content' => $review['content'],
30 1
			'post_date' => $review['date'],
31 1
			'post_name' => $review['review_type'].'-'.$review['review_id'],
32 1
			'post_status' => $this->getNewPostStatus( $review, $command->blacklisted ),
33 1
			'post_title' => $review['title'],
34
			'post_type' => Application::POST_TYPE,
35
		];
36 1
		$postId = wp_insert_post( $post, true );
37 1
		if( is_wp_error( $postId )) {
38
			glsr_log()->error( $postId->get_error_message() );
39
			return false;
40
		}
41 1
		$this->setReviewMeta( $postId, $review, $command->category );
42 1
		do_action( 'site-reviews/create/review', $post, $review, $postId );
43 1
		return $postId;
44
	}
45
46
	/**
47
	 * Delete review based on a review_id meta value
48
	 * @param string $metaReviewId
49
	 * @return void
50
	 */
51
	public function deleteReview( $metaReviewId )
52
	{
53
		if( $postId = $this->getReviewPostId( $metaReviewId )) {
54
			wp_delete_post( $postId, true );
55
		}
56
	}
57
58
	/**
59
	 * @param int|WP_post $post
60
	 * @param string $assignedTo
61
	 * @return void|WP_Post
62
	 */
63
	public function getAssignedToPost( $post, $assignedTo = '' )
64
	{
65
		$post = get_post( $post );
66
		if( !( $post instanceof WP_Post ))return;
67
		if( empty( $assignedTo )) {
68
			$assignedTo = get_post_meta( $post->ID, 'assigned_to', true );
69
		}
70
		$assignedPost = get_post( $assignedTo );
71
		if( !empty( $assignedTo )
72
			&& $assignedPost instanceof WP_Post
73
			&& $assignedPost->ID != $post->ID ) {
74
			return $assignedPost;
75
		}
76
	}
77
78
	/**
79
	 * @param \WP_Post|null $post
80
	 * @return null|object
81
	 */
82
	public function getReview( $post )
83
	{
84
		if( !( $post instanceof WP_Post ) || $post->post_type != Application::POST_TYPE )return;
85
		$review = $this->getReviewMeta( $post->ID );
86
		$modified = $this->isReviewModified( $post, $review );
87
		$review->content = $post->post_content;
88
		$review->data = $post->post_date;
89
		$review->ID = $post->ID;
90
		$review->modifed = $modified;
91
		$review->status = $post->post_status;
92
		$review->title = $post->post_title;
93
		$review->user_id = $post->post_author;
94
		return apply_filters( 'site-reviews/get/review', $review, $post );
95
	}
96
97
	/**
98
	 * @param string $metaKey
99
	 * @param string $metaValue
100
	 * @return array|int
101
	 */
102
	public function getReviewCount( $metaKey = '', $metaValue = '' )
103
	{
104
		$metaKey = $this->normalizeMetaKey( $metaKey );
105
		if( !$metaKey ) {
106
			return (array) wp_count_posts( Application::POST_TYPE );
107
		}
108
		$counts = glsr( Cache::class )->getReviewCountsFor( $metaKey );
109
		if( !$metaValue ) {
110
			return $counts;
111
		}
112
		return isset( $counts[$metaValue] )
113
			? $counts[$metaValue]
114
			: 0;
115
	}
116
117
	/**
118
	 * @param string $metaReviewType
119
	 * @return array
120
	 */
121
	public function getReviewIdsByType( $metaReviewType )
122
	{
123
		return glsr( SqlQueries::class )->getReviewIdsByType( $metaReviewType );
124
	}
125
126
	/**
127
	 * @param int $postId
128
	 * @return object
129
	 */
130
	public function getReviewMeta( $postId )
131
	{
132
		$meta = get_post_type( $postId ) == Application::POST_TYPE
133
			? array_map( 'array_shift', (array) get_post_meta( $postId ))
134
			: [];
135
		return (object) $this->normalizeMeta( array_filter( $meta, 'strlen' ));
136
	}
137
138
	/**
139
	 * @param string $metaReviewId
140
	 * @return int
141
	 */
142
	public function getReviewPostId( $metaReviewId )
143
	{
144
		return glsr( SqlQueries::class )->getReviewPostId( $metaReviewId );
145
	}
146
147
	/**
148
	 * @return object
149
	 */
150
	public function getReviews( array $args = [] )
151
	{
152
		$args = glsr( GetReviewsDefaults::class )->restrict( $args );
153
		$metaQuery = glsr( QueryBuilder::class )->buildQuery(
154
			['assigned_to', 'type', 'rating'],
155
			$args
156
		);
157
		$taxQuery = glsr( QueryBuilder::class )->buildQuery(
158
			['category'],
159
			['category' => $this->normalizeTerms( $args['category'] )]
160
		);
161
		$paged = glsr( QueryBuilder::class )->getPaged(
162
			wp_validate_boolean( $args['pagination'] )
163
		);
164
		$reviews = new WP_Query([
165
			'meta_key' => 'pinned',
166
			'meta_query' => $metaQuery,
167
			'offset' => $args['offset'],
168
			'order' => $args['order'],
169
			'orderby' => 'meta_value '.$args['orderby'],
170
			'paged' => $paged,
171
			'post__in' => $args['post__in'],
172
			'post__not_in' => $args['post__not_in'],
173
			'post_status' => 'publish',
174
			'post_type' => Application::POST_TYPE,
175
			'posts_per_page' => $args['count'] ? $args['count'] : -1,
176
			'tax_query' => $taxQuery,
177
		]);
178
		return (object) [
179
			'results' => array_map( [$this, 'getReview'], $reviews->posts ),
180
			'max_num_pages' => $reviews->max_num_pages,
181
		];
182
	}
183
184
	/**
185
	 * @param string|array $keys
186
	 * @param string $status
187
	 * @return array
188
	 */
189
	public function getReviewsMeta( $keys, $status = 'publish' )
190
	{
191
		$keys = array_map( [$this, 'normalizeMetaKey'], (array)$keys );
192
		if( $status == 'all' || empty( $status )) {
193
			$status = get_post_stati( ['exclude_from_search' => false] );
194
		}
195
		return glsr( SqlQueries::class )->getReviewsMeta( $keys, $status );
196
	}
197
198
	/**
199
	 * @param string $taxonomy
200
	 * @return array
201
	 */
202 1
	public function getTerms( array $args = [] )
203
	{
204 1
		$args = wp_parse_args( $args, [
205 1
			'fields' => 'id=>name',
206
			'hide_empty' => false,
207
			'taxonomy' => Application::TAXONOMY,
208
		]);
209 1
		unset( $args['count'] ); //we don't want a term count
210 1
		$terms = get_terms( $args );
211 1
		if( is_wp_error( $terms )) {
212
			glsr_log()->error( $terms->get_error_message() );
213
			return [];
214
		}
215 1
		return $terms;
216
	}
217
218
	/**
219
	 * @return array
220
	 */
221
	public function normalizeMeta( array $meta )
222
	{
223
		if( empty( $meta )) {
224
			return [];
225
		}
226
		$defaults = wp_parse_args( $meta, [
227
			'author' => __( 'Anonymous', 'site-reviews' ),
228
			'date' => '',
229
			'review_id' => '',
230
			'review_type' => '',
231
		]);
232
		return glsr( CreateReviewDefaults::class )->restrict( $defaults );
233
	}
234
235
	/**
236
	 * @param string $metaKey
237
	 * @return string
238
	 */
239
	public function normalizeMetaKey( $metaKey )
240
	{
241
		$metaKey = strtolower( $metaKey );
242
		if( in_array( $metaKey, ['id', 'type'] )) {
243
			$metaKey = 'review_'.$metaKey;
244
		}
245
		return $metaKey;
246
	}
247
248
	/**
249
	 * @param string $termIds string of comma-separated term IDs
250
	 * @return array
251
	 */
252 1
	public function normalizeTerms( $termIds )
253
	{
254 1
		$terms = [];
255 1
		$termIds = array_map( 'trim', explode( ',', $termIds ));
256 1
		foreach( $termIds as $termId ) {
257 1
			$term = term_exists( $termId, Application::TAXONOMY );
258 1
			if( !isset( $term['term_id'] ))continue;
259
			$terms[] = intval( $term['term_id'] );
260
		}
261 1
		return $terms;
262
	}
263
264
	/**
265
	 * @param int $postId
266
	 * @return void
267
	 */
268
	public function revertReview( $postId )
269
	{
270
		$post = get_post( $postId );
271
		if( !( $post instanceof WP_Post ) || $post->post_type != Application::POST_TYPE )return;
272
		delete_post_meta( $post->ID, '_edit_last' );
273
		$result = wp_update_post([
274
			'ID' => $post->ID,
275
			'post_content' => get_post_meta( $post->ID, 'content', true ),
276
			'post_date' => get_post_meta( $post->ID, 'date', true ),
277
			'post_title' => get_post_meta( $post->ID, '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 setReviewMeta( $postId, array $review, $termIds )
328
	{
329 1
		foreach( $review as $metaKey => $metaValue ) {
330 1
			update_post_meta( $postId, $metaKey, $metaValue );
331
		}
332 1
		$terms = $this->normalizeTerms( $termIds );
333 1
		if( empty( $terms ))return;
334
		$result = wp_set_object_terms( $postId, $terms, Application::TAXONOMY );
335
		if( is_wp_error( $result )) {
336
			glsr_log()->error( $result->get_error_message() );
337
		}
338
	}
339
340
	/**
341
	 * @param bool $isBlacklisted
342
	 * @return string
343
	 */
344 1
	protected function getNewPostStatus( array $review, $isBlacklisted )
345
	{
346 1
		$requireApprovalOption = glsr( OptionManager::class )->get( 'settings.general.require.approval' );
347 1
		return $review['review_type'] == 'local' && ( $requireApprovalOption == 'yes' || $isBlacklisted )
348
			? 'pending'
349 1
			: 'publish';
350
	}
351
352
	/**
353
	 * @param object $review
354
	 * @return bool
355
	 */
356
	protected function isReviewModified( WP_Post $post, $review )
357
	{
358
		return $post->post_date != $review->date
359
			|| $post->post_content != $review->content
360
			|| $post->post_title != $review->title;
361
	}
362
}
363