Gallery::renderImageCaption()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 9
rs 10
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 WP_Post;
9
use WP_Query;
10
11
class Gallery
12
{
13
    public $gallery;
14
15
    protected $args;
16
    protected $image;
17
    protected $postmeta;
18
    protected $theme;
19
    protected $utility;
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 static
31
     */
32
    public function get(array $args = [])
33
    {
34
        $this->normalizeArgs($args);
35
36
        $this->gallery = 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
        return $this;
46
    }
47
48
    /**
49
     * @return string
50
     */
51
    public function render()
52
    {
53
        if (empty($this->args['media'])) {
54
            return;
55
        }
56
        $images = array_reduce($this->gallery->posts, function ($images, $attachment) {
57
            return $images.$this->renderImage($attachment);
58
        });
59
        return sprintf('<div class="gallery-images" itemscope itemtype="http://schema.org/ImageGallery">%s</div>%s',
60
            $images,
61
            $this->renderPagination()
62
        );
63
    }
64
65
    /**
66
     * @return string|null
67
     */
68
    public function renderImage(WP_Post $attachment)
69
    {
70
        $image = $this->image->get($attachment->ID)->image;
71
72
        if (!$image) {
73
            return;
74
        }
75
        return sprintf(
76
            '<figure class="gallery-image" data-w="%s" data-h="%s" data-ps=\'%s\' itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">'.
77
                '%s%s'.
78
            '</figure>',
79
            $image->thumbnail['width'],
80
            $image->thumbnail['height'],
81
            $this->getPhotoswipeData($image),
82
            $this->renderImageTag($image),
83
            $this->renderImageCaption($image)
84
        );
85
    }
86
87
    /**
88
     * @return string|null
89
     */
90
    public function renderPagination()
91
    {
92
        if (!$this->args['pagination']) {
93
            return;
94
        }
95
        return paginate_links([
0 ignored issues
show
Bug Best Practice introduced by
The expression return paginate_links(ar...allery->max_num_pages)) also could return the type string[] which is incompatible with the documented return type null|string.
Loading history...
96
            'before_page_number' => '<span class="screen-reader-text">'.__('Page', 'castor').' </span>',
97
            'current' => $this->gallery->query['paged'],
98
            'mid_size' => 1,
99
            'next_text' => __('Next', 'castor'),
100
            'prev_text' => __('Previous', 'castor'),
101
            'total' => $this->gallery->max_num_pages,
102
        ]);
103
    }
104
105
    /**
106
     * @param string $key
107
     * @param mixed  $value
108
     *
109
     * @return bool
110
     */
111
    protected function getBoolValue($key, $value = null)
112
    {
113
        $bool = $this->getValue($key, $value);
114
115
        if (is_null(filter_var($bool, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE))) {
116
            $bool = $this->postmeta->get($bool);
117
        }
118
        return wp_validate_boolean($bool);
119
    }
120
121
    /**
122
     * @param mixed $value
123
     *
124
     * @return int
125
     */
126
    protected function getGalleryArg($value = null)
127
    {
128
        $gallery = $this->getValue('gallery', $value);
129
130
        if (!is_numeric($gallery) && is_string($gallery)) {
131
            $gallery = intval($this->postmeta->get($gallery));
132
        }
133
        return !is_null(get_post($gallery))
134
            ? intval($gallery)
135
            : 0;
136
    }
137
138
    /**
139
     * @param mixed $value
140
     *
141
     * @return int
142
     */
143
    protected function getImagesPerPageArg($value = null)
144
    {
145
        $perPage = $this->getValue('images_per_page', $value);
146
147
        if (!is_numeric($perPage) && is_string($perPage)) {
148
            $perPage = $this->postmeta->get($perPage);
149
        }
150
        return (bool) intval($perPage)
151
            ? $perPage
152
            : -1;
153
    }
154
155
    /**
156
     * @param mixed $value
157
     *
158
     * @return bool
159
     */
160
    protected function getLazyloadArg($value = null)
161
    {
162
        return $this->getBoolValue('lazyload', $value);
163
    }
164
165
    /**
166
     * @param mixed $value
167
     *
168
     * @return array
169
     */
170
    protected function getMediaArg($value = null)
171
    {
172
        $media = $this->getValue('media', $value);
173
174
        if (is_string($media)) {
175
            $media = $this->postmeta->get($media, [
176
                'ID' => $this->getGalleryArg(),
177
                'single' => false,
178
            ]);
179
        }
180
        return is_array($media)
181
            ? wp_parse_id_list($media)
182
            : [];
183
    }
184
185
    /**
186
     * @return int
187
     */
188
    protected function getPaged()
189
    {
190
        return intval(get_query_var((is_front_page() ? 'page' : 'paged'))) ?: 1;
191
    }
192
193
    /**
194
     * @param mixed $value
195
     *
196
     * @return bool
197
     */
198
    protected function getPaginationArg($value = null)
199
    {
200
        return $this->getBoolValue('pagination', $value);
201
    }
202
203
    /**
204
     * @param mixed $value
205
     *
206
     * @return bool
207
     */
208
    protected function getPermalinksArg($value = null)
209
    {
210
        return $this->getBoolValue('permalinks', $value);
211
    }
212
213
    /**
214
     * @return string
215
     */
216
    protected function getPhotoswipeData($image)
217
    {
218
        return sprintf('{"l":{"src":"%s","w":%d,"h":%d},"m":{"src":"%s","w":%d,"h":%d}}',
219
            $image->large['url'],
220
            $image->large['width'],
221
            $image->large['height'],
222
            $image->medium['url'],
223
            $image->medium['width'],
224
            $image->medium['height']
225
        );
226
    }
227
228
    /**
229
     * @param string $key
230
     * @param mixed  $value
231
     *
232
     * @return mixed
233
     */
234
    protected function getValue($key, $value = null)
235
    {
236
        if (is_null($value) && isset($this->args[$key])) {
237
            $value = $this->args[$key];
238
        }
239
        return $value;
240
    }
241
242
    /**
243
     * @return array
244
     */
245
    protected function normalizeArgs(array $args = [])
246
    {
247
        $defaults = [
248
            'gallery',         // (string) meta_key | (int) post_id
249
            'lazyload',        // (string) meta_key | (bool)
250
            'media',           // (string) meta_key | (array) post_ids
251
            'pagination',      // (string) meta_key | (bool)
252
            'images_per_page', // (string) meta_key | (int) number
253
            'permalinks',      // (string) meta_key | (bool)
254
        ];
255
256
        $this->args = shortcode_atts(array_combine($defaults, $defaults), $args);
257
258
        array_walk($this->args, function (&$value, $key) {
259
            $method = $this->utility->buildMethodName($key.'_arg');
260
            if (method_exists($this, $method)) {
261
                $value = call_user_func([$this, $method], $value);
262
            }
263
        });
264
265
        return $this->args;
266
    }
267
268
    /**
269
     * @param object $image
270
     * @return string|null
271
     */
272
    protected function renderImageCaption($image)
273
    {
274
        if (!empty($image->copyright)) {
275
            $image->caption .= sprintf(' <span itemprop="copyrightHolder">%s</span>', $image->copyright);
276
        }
277
        if (empty($image->caption)) {
278
            return;
279
        }
280
        return sprintf('<figcaption itemprop="caption description">%s</figcaption>', $image->caption);
281
    }
282
283
    /**
284
     * @param object $image
285
     * @return string|null
286
     */
287
    protected function renderImageTag($image)
288
    {
289
        $imgSrc = $this->getLazyloadArg()
290
            ? $this->theme->imageUri('blank.gif')
291
            : $image->thumbnail['url'];
292
293
        $imgTag = sprintf('<img src="%s" data-src="%s" itemprop="thumbnail" alt="%s"/>',
294
            $imgSrc,
295
            $image->thumbnail['url'],
296
            $image->alt
297
        );
298
299
        return $this->getPermalinksArg()
300
            ? sprintf('<a href="%s" itemprop="contentUrl">%s</a>', $image->permalink, $imgTag)
301
            : $imgTag;
302
    }
303
}
304