Passed
Push — master ( 203c84...bd5512 )
by Paul
04:35
created

Database::getAssignedToPost()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

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