Completed
Push — develop ( f6ac94...a82602 )
by Paul
01:59
created

Gallery::query()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 10
nc 1
nop 1
1
<?php
2
3
namespace GeminiLabs\Castor;
4
5
use GeminiLabs\Castor\Helpers\PostMeta;
6
use GeminiLabs\Castor\Helpers\Theme;
7
use GeminiLabs\Castor\Helpers\Utility;
8
use GeminiLabs\Castor\Image;
9
use WP_Post;
10
use WP_Query;
11
12
class Gallery
13
{
14
	public $image;
15
	public $postmeta;
16
	public $theme;
17
	public $utility;
18
19
	protected $args;
20
21
	public function __construct( Image $image, PostMeta $postmeta, Theme $theme, Utility $utility )
22
	{
23
		$this->image    = $image;
24
		$this->postmeta = $postmeta;
25
		$this->theme    = $theme;
26
		$this->utility  = $utility;
27
	}
28
29
	/**
30
	 * @return WP_Query
31
	 */
32
	public function query( array $args = [] )
33
	{
34
		$this->normalizeArgs( $args );
35
36
		return new WP_Query([
37
			'orderby'        => 'post__in',
38
			'paged'          => $this->getPaged(),
39
			'post__in'       => $this->args['media'],
40
			'post_mime_type' => 'image',
41
			'post_type'      => 'attachment',
42
			'post_status'    => 'inherit',
43
			'posts_per_page' => $this->args['images_per_page'],
44
		]);
45
	}
46
47
	/**
48
	 * @return string
49
	 */
50
	public function render( WP_Query $gallery )
51
	{
52
		$images = array_reduce( $gallery->posts, function( $images, $attachment ) {
53
			return $images . $this->renderImage( $attachment );
54
		});
55
		return sprintf( '<div class="gallery-images" itemscope itemtype="http://schema.org/ImageGallery">%s</div>', $images );
56
	}
57
58
	/**
59
	 * @return null|string
60
	 */
61
	public function renderImage( WP_Post $attachment )
62
	{
63
		$image = $this->image->get( $attachment->ID );
64
		if( !$image )return;
65
		return sprintf(
66
			'<figure class="gallery-image" data-w="%s" data-h="%s" data-ps=\'%s\' itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">' .
67
				'%s<figcaption itemprop="caption description">' .
68
					'%s <span itemprop="copyrightHolder">%s</span>' .
69
				'</figcaption>' .
70
			'</figure>',
71
			$image->thumbnail['width'],
72
			$image->thumbnail['height'],
73
			$this->getPhotoswipeData( $image ),
74
			$this->renderImageTag( $image ),
75
			$image->caption,
76
			$image->copyright
77
		);
78
	}
79
80
	/**
81
	 * @return null|string
82
	 */
83
	public function renderPagination( WP_Query $query )
84
	{
85
		if( !$this->args['pagination'] )return;
86
		return paginate_links([
87
			'before_page_number' => '<span class="screen-reader-text">' . __( 'Page', 'castor' ) . ' </span>',
88
			'current'            => $query->query['paged'],
89
			'mid_size'           => 1,
90
			'next_text'          => __( 'Next', 'castor' ),
91
			'prev_text'          => __( 'Previous', 'castor' ),
92
			'total'              => $query->max_num_pages,
93
		]);
94
	}
95
96
	/**
97
	 * @param string $key
98
	 * @param mixed  $value
99
	 *
100
	 * @return bool
101
	 */
102
	protected function getBoolValue( $key, $value = null )
103
	{
104
		$bool = $this->getValue( $key, $value );
105
106
		if( is_string( $bool ) && !in_array( $bool, ['true', 'false'] )) {
107
			$bool = wp_validate_boolean( $this->postmeta->get( $bool ));
108
		}
109
		return is_bool( $bool )
110
			? $bool
111
			: false;
112
	}
113
114
	/**
115
	 * @param mixed $value
116
	 *
117
	 * @return int
118
	 */
119
	protected function getGalleryArg( $value = null )
120
	{
121
		$gallery = $this->getValue( 'gallery', $value );
122
123
		if( !is_numeric( $gallery ) && is_string( $gallery )) {
124
			$gallery = intval( $this->postmeta->get( $gallery ));
125
		}
126
		return !is_null( get_post( $gallery ))
127
			? intval( $gallery )
128
			: 0;
129
	}
130
131
	/**
132
	 * @param mixed $value
133
	 *
134
	 * @return int
135
	 */
136
	protected function getImagesPerPageArg( $value = null )
137
	{
138
		$perPage = $this->getValue( 'images_per_page', $value );
139
140
		if( !is_numeric( $perPage ) && is_string( $perPage )) {
141
			$perPage = $this->postmeta->get( $perPage );
142
		}
143
		return is_numeric( $perPage ) && !!$perPage
144
			? $perPage
145
			: -1;
146
	}
147
148
	/**
149
	 * @param mixed $value
150
	 *
151
	 * @return bool
152
	 */
153
	protected function getLazyloadArg( $value = null )
154
	{
155
		return $this->getBoolValue( 'lazyload', $value );
156
	}
157
158
	/**
159
	 * @param mixed $value
160
	 *
161
	 * @return array
162
	 */
163
	protected function getMediaArg( $value = null )
164
	{
165
		$media = $this->getValue( 'media', $value );
166
167
		if( is_string( $media )) {
168
			$media = $this->postmeta->get( $media, [
169
				'ID'     => $this->getGalleryArg(),
170
				'single' => false,
171
			]);
172
		}
173
		return is_array( $media )
174
			? wp_parse_id_list( $media )
175
			: [];
176
	}
177
178
	/**
179
	 * @return int
180
	 */
181
	protected function getPaged()
182
	{
183
		return intval( get_query_var(( is_front_page() ? 'page' : 'paged' ))) ?: 1;
184
	}
185
186
	/**
187
	 * @param mixed $value
188
	 *
189
	 * @return bool
190
	 */
191
	protected function getPaginationArg( $value = null )
192
	{
193
		return $this->getBoolValue( 'pagination', $value );
194
	}
195
196
	/**
197
	 * @param mixed $value
198
	 *
199
	 * @return bool
200
	 */
201
	protected function getPermalinksArg( $value = null )
202
	{
203
		return $this->getBoolValue( 'permalinks', $value );
204
	}
205
206
	/**
207
	 * @return string
208
	 */
209
	protected function getPhotoswipeData( $image )
210
	{
211
		return sprintf( '{"l":{"src":"%s","w":%d,"h":%d},"m":{"src":"%s","w":%d,"h":%d}}',
212
			$image->large['url'],
213
			$image->large['width'],
214
			$image->large['height'],
215
			$image->medium['url'],
216
			$image->medium['width'],
217
			$image->medium['height']
218
		);
219
	}
220
221
	/**
222
	 * @param string $key
223
	 * @param mixed  $value
224
	 *
225
	 * @return mixed
226
	 */
227
	protected function getValue( $key, $value = null )
228
	{
229
		if( is_null( $value ) && isset( $this->args[$key] )) {
230
			$value = $this->args[$key];
231
		}
232
		return $value;
233
	}
234
235
	/**
236
	 * @return array
237
	 */
238
	protected function normalizeArgs( array $args = [] )
239
	{
240
		$defaults = [
241
			'gallery',         // (string) meta_key | (int) post_id
242
			'lazyload',        // (string) meta_key | (bool)
1 ignored issue
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
243
			'media',           // (string) meta_key | (array) post_ids
244
			'pagination',      // (string) meta_key | (bool)
1 ignored issue
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
245
			'images_per_page', // (string) meta_key | (int) number
246
			'permalinks',      // (string) meta_key | (bool)
1 ignored issue
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
247
		];
248
249
		$this->args = shortcode_atts( array_combine( $defaults, $defaults ), $args );
250
251
		array_walk( $this->args, function( &$value, $key ) {
252
			$method = $this->utility->buildMethodName( $key . '_arg' );
253
			if( method_exists( $this, $method )) {
254
				$value = call_user_func([ $this, $method ], $value );
255
			}
256
		});
257
258
		return $this->args;
259
	}
260
261
	/**
262
	 * @param object $image
263
	 *
264
	 * @return null|string
265
	 */
266
	protected function renderImageTag( $image )
267
	{
268
		$imgSrc = $this->getLazyloadArg()
269
			? $this->theme->imageUri( 'blank.gif' )
270
			: $image->thumbnail['url'];
271
272
		$imgTag = sprintf( '<img src="%s" data-src="%s" itemprop="thumbnail" alt="%s"/>',
273
			$imgSrc,
274
			$image->thumbnail['url'],
275
			$image->alt
276
		);
277
278
		return $this->getPermalinksArg()
279
			? sprintf( '<a href="%s" itemprop="contentUrl">%s</a>', $image->permalink, $imgTag )
280
			: $imgTag;
281
	}
282
}
283