Passed
Push — master ( ded0cd...0a9f5b )
by Paul
05:42
created

SiteReviews::getExcerpt()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 2
nop 1
dl 0
loc 15
ccs 0
cts 15
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules\Html\Partials;
4
5
use GeminiLabs\SiteReviews\Database;
6
use GeminiLabs\SiteReviews\Database\OptionManager;
7
use GeminiLabs\SiteReviews\Helper;
8
use GeminiLabs\SiteReviews\Modules\Date;
9
use GeminiLabs\SiteReviews\Modules\Html;
10
use GeminiLabs\SiteReviews\Modules\Html\Builder;
11
use GeminiLabs\SiteReviews\Modules\Html\Partial;
12
use GeminiLabs\SiteReviews\Modules\Html\Template;
13
use GeminiLabs\SiteReviews\Modules\Rating;
14
use GeminiLabs\SiteReviews\Modules\Schema;
15
use WP_Post;
16
17
class SiteReviews
18
{
19
	/**
20
	 * @var array
21
	 */
22
	protected $args;
23
24
	/**
25
	 * @var array
26
	 */
27
	protected $options;
28
29
	/**
30
	 * @var object
31
	 */
32
	protected $reviews;
33
34
	/**
35
	 * @return void|string
36
	 */
37
	public function build( array $args = [] )
38
	{
39
		$this->args = $args;
40
		$this->options = glsr( Helper::class )->flattenArray( glsr( OptionManager::class )->all() );
41
		$this->reviews = glsr( Database::class )->getReviews( $args );
42
		$this->generateSchema();
43
		$navigation = wp_validate_boolean( $this->args['pagination'] )
44
			? glsr( Partial::class )->build( 'pagination', ['total' => $this->reviews->max_num_pages] )
45
			: '';
46
		return glsr( Template::class )->build( 'templates/reviews', [
47
			'context' => [
48
				'class' => $this->getClass(),
49
				'id' => $this->args['id'],
50
				'navigation' => $navigation,
51
			],
52
			'reviews' => $this->buildReviews(),
53
		]);
54
	}
55
56
	/**
57
	 * @return array
58
	 */
59
	public function buildReviews()
60
	{
61
		$reviews = [];
62
		foreach( $this->reviews->results as $review ) {
63
			$reviews[] = $this->buildReview( $review );
64
		}
65
		return $reviews;
66
	}
67
68
	/**
69
	 * @param object $review
70
	 * @return object
71
	 */
72
	protected function buildReview( $review )
73
	{
74
		$generatedReview = [];
75
		foreach( $review as $key => $value ) {
76
			$method = glsr( Helper::class )->buildMethodName( $key, 'buildReview' );
77
			if( !method_exists( $this, $method ))continue;
78
			$generatedReview[$key] = $this->$method( $key, $value );
79
		}
80
		return (object)$generatedReview;
81
	}
82
83
	/**
84
	 * @param string $key
85
	 * @param string $value
86
	 * @return void|string
87
	 */
88
	protected function buildReviewAssignedTo( $key, $value )
89
	{
90
		if( !$this->isOptionEnabled( 'settings.reviews.assigned_links.enabled' )
91
			|| empty( $value )
92
		)return;
93
		$post = get_post( $value );
0 ignored issues
show
Bug introduced by
$value of type string is incompatible with the type null|integer|WP_Post expected by parameter $post of get_post(). ( Ignorable by Annotation )

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

93
		$post = get_post( /** @scrutinizer ignore-type */ $value );
Loading history...
94
		if( !( $post instanceof WP_Post ))return;
95
		$permalink = glsr( Builder::class )->a( get_the_title( $post->ID ), [
96
			'href' => get_the_permalink( $post->ID ),
97
		]);
98
		$permalink = sprintf( __( 'Review of %s', 'site-reviews' ), $permalink );
99
		return $this->wrap( $key, $permalink );
100
	}
101
102
	/**
103
	 * @param string $key
104
	 * @param string $value
105
	 * @return void|string
106
	 */
107
	protected function buildReviewAuthor( $key, $value )
108
	{
109
		if( $this->isHidden( $key ))return;
110
		$prefix = !$this->isOptionEnabled( 'settings.reviews.avatars.enabled' )
111
			? apply_filters( 'site-reviews/review/author/prefix', '&mdash;' )
112
			: '';
113
		return $this->wrap( $key, $prefix.'<span>'.$value.'</span>' );
114
	}
115
116
	/**
117
	 * @param string $key
118
	 * @param string $value
119
	 * @return void|string
120
	 */
121
	protected function buildReviewAvatar( $key, $value )
122
	{
123
		if( $this->isHidden( $key, 'settings.reviews.avatars.enabled' ))return;
124
		return $this->wrap( $key, '<img src="'.$value.'" width="36">');
125
	}
126
127
	/**
128
	 * @param string $key
129
	 * @param string $value
130
	 * @return void|string
131
	 */
132
	protected function buildReviewContent( $key, $value )
133
	{
134
		$text = $this->normalizeText( $value );
135
		if( $this->isHiddenOrEmpty( $key, $text ))return;
136
		return $this->wrap( $key, $text );
137
	}
138
139
	/**
140
	 * @param string $key
141
	 * @param string $value
142
	 * @return void|string
143
	 */
144
	protected function buildReviewDate( $key, $value )
145
	{
146
		if( $this->isHidden( $key ))return;
147
		$dateFormat = $this->getOption( 'settings.reviews.date.format', 'default' );
148
		if( $dateFormat == 'relative' ) {
149
			$date = glsr( Date::class )->relative( $value );
150
		}
151
		else {
152
			$format = $dateFormat == 'custom'
153
				? $this->getOption( 'settings.reviews.date.custom', 'M j, Y' )
154
				: (string)get_option( 'date_format' );
155
			$date = date_i18n( $format, strtotime( $value ));
156
		}
157
		return $this->wrap( $key, $date );
158
	}
159
160
	/**
161
	 * @param string $key
162
	 * @param string $value
163
	 * @return void|string
164
	 */
165
	protected function buildReviewRating( $key, $value )
166
	{
167
		if( $this->isHiddenOrEmpty( $key, $value ))return;
168
		$rating = glsr( Html::class )->buildPartial( 'star-rating', [
169
			'rating' => $value,
170
		]);
171
		return $this->wrap( $key, $rating );
172
	}
173
174
	/**
175
	 * @param string $key
176
	 * @param string $value
177
	 * @return void|string
178
	 */
179
	protected function buildReviewResponse( $key, $value )
180
	{
181
		if( $this->isHiddenOrEmpty( $key, $value ))return;
182
		$title = sprintf( __( 'Response from %s', 'site-reviews' ), get_bloginfo( 'name' ));
183
		$text = $this->normalizeText( $value );
184
		return $this->wrap( $key, '<p><strong>'.$title.'</strong></p>'.$text );
185
	}
186
187
	/**
188
	 * @param string $key
189
	 * @param string $value
190
	 * @return void|string
191
	 */
192
	protected function buildReviewTitle( $key, $value )
193
	{
194
		if( $this->isHidden( $key ))return;
195
		if( empty( $value )) {
196
			$value = __( 'No Title', 'site-reviews' );
197
		}
198
		return $this->wrap( $key, '<h3>'.$value.'</h3>' );
199
	}
200
201
	/**
202
	 * @return void
203
	 */
204
	protected function generateSchema()
205
	{
206
		if( !wp_validate_boolean( $this->args['schema'] ))return;
207
		glsr( Schema::class )->store( glsr( Schema::class )->build( $this->args ));
208
	}
209
210
	/**
211
	 * @return string
212
	 */
213
	protected function getClass()
214
	{
215
		return $this->args['pagination'] == 'ajax'
216
			? trim( $this->args['class'].' glsr-ajax-pagination' )
217
			: $this->args['class'];
218
	}
219
220
	/**
221
	 * @param string $text
222
	 * @return string
223
	 */
224
	protected function getExcerpt( $text )
225
	{
226
		$limit = $this->getOption( 'settings.reviews.excerpt.length', 55 );
227
		if( str_word_count( $text, 0 ) > $limit ) {
228
			$words = array_keys( str_word_count( $text, 2 ));
229
			$excerpt = ltrim( substr( $text, 0, $words[$limit] ));
230
			$hiddenText = substr( $text, strlen( $excerpt ));
231
			$showMore = glsr( Builder::class )->span( $hiddenText, [
232
				'class' => 'glsr-hidden glsr-hidden-text',
233
				'data-show-less' => __( 'Show less', 'site-reviews' ),
234
				'data-show-more' => __( 'Show more', 'site-reviews' ),
235
			]);
236
			$text = $excerpt.$showMore;
237
		}
238
		return nl2br( $text );
239
	}
240
241
	/**
242
	 * @param string $path
243
	 * @param mixed $fallback
244
	 * @return mixed
245
	 */
246
	protected function getOption( $path, $fallback = '' )
247
	{
248
		if( array_key_exists( $path, $this->options )) {
249
			return $this->options[$path];
250
		}
251
		return $fallback;
252
	}
253
254
	/**
255
	 * @param string $key
256
	 * @param string $path
257
	 * @return bool
258
	 */
259
	protected function isHidden( $key, $path = '' )
260
	{
261
		$isOptionEnabled = !empty( $path )
262
			? $this->isOptionEnabled( $path )
263
			: true;
264
		return in_array( $key, $this->args['hide'] ) || !$isOptionEnabled;
265
	}
266
267
	/**
268
	 * @param string $key
269
	 * @param string $value
270
	 * @return bool
271
	 */
272
	protected function isHiddenOrEmpty( $key, $value )
273
	{
274
		return $this->isHidden( $key ) || empty( $value );
275
	}
276
277
	/**
278
	 * @param string $path
279
	 * @return bool
280
	 */
281
	protected function isOptionEnabled( $path )
282
	{
283
		return $this->getOption( $path ) == 'yes';
284
	}
285
286
	/**
287
	 * @param string $text
288
	 * @return string
289
	 */
290
	protected function normalizeText( $text )
291
	{
292
		$text = wp_kses( $text, wp_kses_allowed_html() );
293
		$text = convert_smilies( wptexturize( strip_shortcodes( $text )));
294
		$text = str_replace( ']]>', ']]&gt;', $text );
295
		$text = $this->isOptionEnabled( 'settings.reviews.excerpt.enabled' )
296
			? $this->getExcerpt( $text )
297
			: $text;
298
		return '<p>'.$text.'</p>';
299
	}
300
301
	/**
302
	 * @param string $key
303
	 * @param string $value
304
	 * @return string
305
	 */
306
	protected function wrap( $key, $value )
307
	{
308
		return glsr( Builder::class )->div( $value, [
309
			'class' => 'glsr-review-'.$key,
310
		]);
311
	}
312
}
313