PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 2.25
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v2.25
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
photonic / extensions / Photonic_Flickr_Processor.php

Photonic_Flickr_Processor.php in Photonic Gallery & Lightbox for Flickr, SmugMug & Others 2.25, at extensions/Photonic_Flickr_Processor.php

1,119 lines 41.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Processor for Flickr Galleries
4 *
5 * @package Photonic
6 * @subpackage Extensions
7 */
8
9 class Photonic_Flickr_Processor extends Photonic_OAuth1_Processor {
10 var $base_url;
11 function __construct() {
12 parent::__construct();
13 global $photonic_flickr_api_key, $photonic_flickr_api_secret, $photonic_flickr_disable_title_link, $photonic_flickr_access_token, $photonic_flickr_token_secret;
14 $this->api_key = trim($photonic_flickr_api_key);
15 $this->api_secret = trim($photonic_flickr_api_secret);
16 $this->token = trim($photonic_flickr_access_token);
17 $this->token_secret = trim($photonic_flickr_token_secret);
18
19 $this->provider = 'flickr';
20 $this->link_lightbox_title = empty($photonic_flickr_disable_title_link);
21 $this->base_url = 'https://api.flickr.com/services/rest/';
22
23 $this->doc_links = array(
24 'general' => 'https://aquoid.com/plugins/photonic/flickr/',
25 'photo' => 'https://aquoid.com/plugins/photonic/flickr/flickr-photo',
26 'photos' => 'https://aquoid.com/plugins/photonic/flickr/flickr-photos/',
27 'photosets' => 'https://aquoid.com/plugins/photonic/flickr/flickr-photosets/',
28 'galleries' => 'https://aquoid.com/plugins/photonic/flickr/flickr-galleries/',
29 'collections' => 'https://aquoid.com/plugins/photonic/flickr/flickr-collections/',
30 'auth' => 'https://aquoid.com/plugins/photonic/flickr/flickr-authentication',
31 );
32
33 $this->set_oauth_done();
34 }
35
36 /**
37 * A very flexible function to display a user's photos from Flickr. This makes use of the Flickr API, hence it requires the user's API key.
38 * The API key is defined in the options. The function makes use of three different APIs:
39 * 1. <a href='https://www.flickr.com/services/api/flickr.photos.search.html'>flickr.photos.search</a> - for retrieving photos based on search critiera
40 * 2. <a href='https://www.flickr.com/services/api/flickr.photosets.getPhotos.html'>flickr.photosets.getPhotos</a> - for retrieving photo sets
41 * 3. <a href='https://www.flickr.com/services/api/flickr.galleries.getPhotos.html'>flickr.galleries.getPhotos</a> - for retrieving galleries
42 *
43 * The following short-code parameters are supported:
44 * All
45 * - per_page: number of photos to display
46 * - view: photos | collections | galleries | photosets, displays hierarchically if user_id is passed
47 * Photosets
48 * - photoset_id
49 * Galleries
50 * - gallery_id
51 * Photos
52 * - user_id: can be obtained from the Helpers page
53 * - tags: comma-separated list of tags
54 * - tag_mode: any | all, tells whether any tag should be used or all
55 * - text: string for text search
56 * - sort: date-posted-desc | date-posted-asc | date-taken-asc | date-taken-desc | interestingness-desc | interestingness-asc | relevance
57 * - group_id: group id for which photos will be displayed
58 *
59 * @param array $attr
60 * @return string
61 * @since 1.02
62 */
63 function get_gallery_images($attr = array()) {
64 global $photonic_flickr_allow_oauth, $photonic_flickr_oauth_done, $photonic_flickr_title_caption,
65 $photonic_flickr_thumb_size, $photonic_flickr_main_size, $photonic_flickr_tile_size, $photonic_flickr_video_size, $photonic_flickr_media, $photonic_flickr_default_user;
66
67 $this->gallery_index++;
68 $this->push_to_stack('Get gallery images');
69 $attr = array_merge(
70 $this->common_parameters,
71 array(
72 // Common overrides ...
73 'caption' => $photonic_flickr_title_caption,
74 'thumb_size' => $photonic_flickr_thumb_size,
75 'main_size' => $photonic_flickr_main_size,
76 'tile_size' => $photonic_flickr_tile_size,
77 'video_size' => $photonic_flickr_video_size,
78
79 // Flickr-Specific ...
80 // 'view' => 'photos' // photos | collections | galleries | photosets: if only a user id is passed, what should be displayed?
81 'privacy_filter' => '',
82 'count' => 500,
83 'page' => 1,
84 'paginate' => false,
85 'collections_display' => 'expanded',
86 'user_id' => $photonic_flickr_default_user,
87 'collection_id' => '',
88 'photoset_id' => '',
89 'gallery_id' => '',
90 'photo_id' => '',
91 'media' => $photonic_flickr_media,
92 ),
93 $attr);
94 $attr = array_map('trim', $attr);
95
96 extract($attr);
97
98 if (empty($this->api_key)) {
99 $this->pop_from_stack();
100 return $this->error(esc_html__('Flickr API Key not defined.', 'photonic').Photonic::doc_link($this->doc_links['general']));
101 }
102
103 $query_urls = array();
104 $flickr_params = array();
105
106 $flickr_params['extras'] = 'description,url_c,c_dims,url_h,h_dims,url_k,k_dims,url_o,o_dims,url_b,b_dims,media';
107
108 $ret = "";
109 $attr['iterate_level_3'] = $attr['collections_display'] === 'expanded';
110 $attr['per_page'] = empty($attr['per_page']) ? $attr['count'] : $attr['per_page'];
111 $attr['photo_count'] = empty($attr['photo_count']) ? $attr['per_page'] : $attr['photo_count'];
112
113 $attr['overlay_size'] = empty($attr['overlay_size']) ? $attr['thumb_size'] : $attr['overlay_size'];
114 $attr['overlay_video_size'] = empty($attr['overlay_video_size']) ? $attr['video_size'] : $attr['overlay_video_size'];
115
116 if (empty($attr['group_id'])) {
117 $user = empty($attr['user_id']) ? $photonic_flickr_default_user : $attr['user_id'];
118 }
119
120 if (isset($view) && $view == 'photos' && !empty($attr['group_id']) && empty($attr['photoset_id'])) {
121 $query_urls[] = $this->base_url.'?method=flickr.photos.search';
122 }
123 else if (isset($view) && $view == 'photo' && !empty($attr['photo_id'])) {
124 $query_urls[] = $this->base_url.'?method=flickr.photos.getInfo';
125 }
126 else if (isset($view) && (!empty($user))) {
127 switch ($view) {
128 case 'collections':
129 if (empty($attr['collection_id'])) {
130 $collections = $this->get_collection_list($user, '', $attr['filter']);
131 foreach ($collections as $collection) {
132 $query_urls[] = $this->base_url.'?method=flickr.collections.getTree&collection_id='.$collection['id'];
133 }
134 }
135 break;
136
137 case 'galleries':
138 if (empty($attr['gallery_id'])) {
139 $query_urls[] = $this->base_url.'?method=flickr.galleries.getList';
140 }
141 break;
142
143 case 'photosets':
144 if (empty($attr['photoset_id'])) {
145 $query_urls[] = $this->base_url.'?method=flickr.photosets.getList';
146 }
147 break;
148
149 case 'photo':
150 if (!empty($attr['photo_id'])) {
151 $query_urls[] = $this->base_url.'?method=flickr.photos.getInfo';
152 }
153 break;
154
155 case 'photos':
156 default:
157 if (empty($attr['photoset_id']) && empty($attr['gallery_id']) && empty($attr['collection_id']) && empty($attr['photo_id']))
158 $query_urls[] = $this->base_url.'?method=flickr.photos.search';
159 break;
160 }
161 }
162
163 // Collection > galleries > photosets
164 if (!empty($attr['collection_id'])) {
165 $collections = $this->get_collection_list($user, $attr['collection_id']);
166 $attr['iterate_level_3'] = true;
167 foreach ($collections as $collection) {
168 $query_urls[] = $this->base_url.'?method=flickr.collections.getTree&collection_id='.$collection['id'];
169 }
170 }
171 else if (!empty($attr['gallery_id'])) {
172 if (empty($gallery_id_computed)) {
173 if (empty($user)) {
174 $this->pop_from_stack();
175 return esc_html__('User id or default user is required for displaying a single gallery', 'photonic');
176 }
177
178 $this->push_to_stack("Gallery list (user '$user')");
179 $feed = $this->make_call($this->base_url.'?method=flickr.galleries.getList', $flickr_params);
180
181 if (!is_wp_error($feed)) {
182 if ($feed['response']['code'] == 200) {
183 $feed = $feed['body'];
184 $feed = json_decode($feed);
185 if (isset($feed->galleries)) {
186 $galleries = $feed->galleries;
187 $galleries = $galleries->gallery;
188 if (is_array($galleries) && count($galleries) > 0) {
189 $gallery = $galleries[0];
190 $global_dbid = $gallery->id;
191 $global_dbid = substr($global_dbid, 0, stripos($global_dbid, '-'));
192 }
193 }
194 }
195 }
196
197 if (isset($global_dbid)) {
198 $attr['gallery_id'] = $global_dbid.'-'.$attr['gallery_id'];
199 }
200 $this->pop_from_stack();
201 }
202 $query_urls[] = $this->base_url.'?method=flickr.galleries.getInfo';
203 $query_urls[] = $this->base_url.'?method=flickr.galleries.getPhotos';
204 }
205 else if (!empty($attr['photoset_id'])) {
206 $query_urls[] = $this->base_url.'?method=flickr.photosets.getInfo';
207 $query_urls[] = $this->base_url.'?method=flickr.photosets.getPhotos';
208 }
209
210 if (!empty($user) && empty($photoset_id) && empty($photo_id)) {
211 $flickr_params['user_id'] = $user;
212 }
213
214 if (!empty($attr['collection_id'])) {
215 $flickr_params['collection_id'] = $attr['collection_id'];
216 }
217 else if (!empty($attr['gallery_id'])) {
218 $flickr_params['gallery_id'] = $attr['gallery_id'];
219 }
220 else if (!empty($attr['photoset_id'])) {
221 $flickr_params['photoset_id'] = $attr['photoset_id'];
222 }
223 else if (!empty($attr['photo_id'])) {
224 $flickr_params['photo_id'] = $attr['photo_id'];
225 }
226
227 if (!empty($attr['tags'])) {
228 $flickr_params['tags'] = $attr['tags'];
229 }
230
231 if (!empty($attr['tag_mode'])) {
232 $flickr_params['tag_mode'] = $attr['tag_mode'];
233 }
234
235 if (!empty($attr['text'])) {
236 $flickr_params['text'] = $attr['text'];
237 }
238
239 if (!empty($attr['sort'])) {
240 $flickr_params['sort'] = $attr['sort'];
241 }
242
243 if (!empty($attr['group_id'])) {
244 $flickr_params['group_id'] = $attr['group_id'];
245 }
246
247 global $photonic_archive_thumbs;
248 if (is_archive() || is_home()) {
249 if (isset($photonic_archive_thumbs) && !empty($photonic_archive_thumbs)) {
250 if (!empty($attr['per_page']) && $photonic_archive_thumbs < $attr['per_page']) {
251 $flickr_params['per_page'] = $photonic_archive_thumbs;
252 $this->show_more_link = true;
253 }
254 else if (!empty($attr['per_page'])) {
255 $flickr_params['per_page'] = $attr['per_page'];
256 }
257 }
258 else if (!empty($attr['per_page'])) {
259 $flickr_params['per_page'] = $attr['per_page'];
260 }
261 }
262 else if (!empty($attr['per_page'])) {
263 $flickr_params['per_page'] = $attr['per_page'];
264 }
265
266 if (!empty($attr['page'])) {
267 $flickr_params['page'] = $attr['page'];
268 }
269
270 if (!empty($attr['privacy_filter'])) {
271 $flickr_params['privacy_filter'] = $attr['privacy_filter'];
272 }
273
274 if (!empty($attr['media'])) {
275 $flickr_params['media'] = $attr['media'];
276 }
277
278 // Allow users to define additional query parameters
279 $query_urls = apply_filters('photonic_flickr_query_urls', $query_urls, $attr);
280
281 if ($photonic_flickr_allow_oauth && is_singular() && !$photonic_flickr_oauth_done && !empty($attr['privacy_filter'])) {
282 $post_id = get_the_ID();
283 $ret .= $this->get_login_box($post_id);
284 }
285
286 $header_display = $this->get_header_display($attr);
287 $attr['header_display'] = $header_display;
288
289 $call_return = '';
290 foreach ($query_urls as $query_url) {
291 $method = 'flickr.photos.getInfo';
292 $iterator = array();
293 if (is_array($query_url)) {
294 $iterator = $query_url;
295 }
296 else {
297 $iterator[] = $query_url;
298 }
299
300 foreach ($iterator as $nested_query_url) {
301 $this->push_to_stack("Nested call $method");
302 $method = wp_parse_args(substr($nested_query_url, stripos($nested_query_url, '?') + 1));
303 $method = $method['method'];
304 $response = $this->make_call($nested_query_url, $flickr_params);
305 $flickr_params['method'] = $method;
306
307 $processed_response = $this->process_query($response, $flickr_params, $attr);
308 $call_return .= $processed_response;
309 $this->pop_from_stack();
310 }
311
312 if ($this->show_more_link && $method != 'flickr.photosets.getInfo' && $method != 'flickr.photos.getInfo' && $method != 'flickr.galleries.getInfo') {
313 $call_return .= $this->more_link_button(get_permalink().'#photonic-flickr-stream-'.$this->gallery_index);
314 }
315 }
316 $this->pop_from_stack();
317
318 $ret .= $this->finalize_markup($call_return, $attr);
319
320 return $ret.$this->get_stack_markup();
321 }
322
323 function make_call($query, $flickr_params) {
324 global $photonic_flickr_oauth_done;
325 $params = substr($query, strlen($this->base_url));
326 if (strlen($params) > 1) {
327 $params = substr($params, 1);
328 }
329 $params = Photonic_Processor::parse_parameters($params);
330 $params['format'] = 'json';
331 $params['nojsoncallback'] = 1;
332 $params['api_key'] = $this->api_key;
333
334 $params = array_merge($flickr_params, $params);
335
336 // We only worry about signing the call if the authentication is done. Otherwise we just show what is available.
337 if ($photonic_flickr_oauth_done || $this->oauth_done) {
338 $signed_args = $this->sign_call($this->base_url, 'GET', $params);
339 $params = $signed_args;
340 }
341
342 $this->push_to_stack("Make call ({$params['method']})");
343 $response = Photonic::http($this->base_url, 'GET', $params);
344 $this->pop_from_stack();
345 return $response;
346 }
347
348 /**
349 * Retrieves a list of collection objects for a given user. This first invokes the web-service, then iterates through the collections returned.
350 * For each collection returned it recursively looks for nested collections and sets.
351 *
352 * @param $user_id
353 * @param string $collection_id
354 * @param string $filters
355 * @return array
356 */
357 function get_collection_list($user_id, $collection_id = '', $filters = '') {
358 $this->push_to_stack("Collection list (collection id '$collection_id')");
359 $query = $this->base_url.'?method=flickr.collections.getTree';
360 $flickr_params = array();
361 if (!empty($collection_id)) {
362 $flickr_params['collection_id'] = $collection_id;
363 }
364 if (!empty($user_id)) {
365 $flickr_params['user_id'] = $user_id;
366 }
367
368 $collection_list = array();
369 if (!empty($filters)) {
370 $collection_list = explode(',', $filters);
371 }
372
373 $feed = $this->make_call($query, $flickr_params);
374 if (!is_wp_error($feed) && 200 == $feed['response']['code']) {
375 $feed = $feed['body'];
376 $feed = json_decode($feed);
377 if ($feed->stat == 'ok') {
378 $collections = $feed->collections;
379 $collections = $collections->collection;
380 $ret = array();
381 $processed = array();
382 foreach ($collections as $collection) {
383 if (isset($collection->id)) {
384 if (!in_array($collection->id, $processed)) {
385 $iterative = $this->get_nested_collections($collection, $processed);
386 $ret = array_merge($ret, $iterative);
387 }
388 }
389 }
390
391 $filtered_ret = array();
392 if (!empty($collection_list)) {
393 foreach ($ret as $collection) {
394 if (in_array($collection['id'], $collection_list)) {
395 $filtered_ret[] = $collection;
396 }
397 }
398 $this->pop_from_stack();
399 return $filtered_ret;
400 }
401
402 $this->pop_from_stack();
403 return $ret;
404 }
405 }
406 $this->pop_from_stack();
407 return array();
408 }
409
410 /**
411 * Goes through a Flickr collection and recursively fetches all sets and other collections within it. This is returned as
412 * a flattened array.
413 *
414 * @param $collection
415 * @param $processed
416 * @return array
417 */
418 function get_nested_collections($collection, &$processed) {
419 $id = isset($collection->id) ? (string)$collection->id : '';
420 if (in_array($id, $processed)) {
421 return array();
422 }
423
424 $processed[] = $id;
425 $id = substr($id, strpos($id, '-') + 1);
426 $title = isset($collection->title) ? (string)$collection->title : '';
427 $description = isset($collection->description) ? (string)$collection->description : '';
428 $thumb = isset($collection->iconsmall) ? (string)$collection->iconsmall : (isset($collection->iconlarge) ? (string)$collection->iconlarge : '');
429
430 $ret = array();
431
432 if (isset($collection->set)) {
433 $inner_sets = $collection->set;
434 $sets = array();
435 if (count($inner_sets) > 0) {
436 foreach ($inner_sets as $inner_set) {
437 $sets[] = array(
438 'id' => (string)$inner_set->id,
439 'title' => (string)$inner_set->title,
440 'description' => (string)$inner_set->description,
441 );
442 }
443 }
444
445 $ret[] = array(
446 'id' => $id,
447 'title' => $title,
448 'description' => $description,
449 'thumb' => $thumb,
450 'sets' => $sets,
451 );
452 }
453
454 if (isset($collection->collection)) {
455 $inner_collections = $collection->collection;
456 if (count($inner_collections) > 0) {
457 foreach ($inner_collections as $inner_collection) {
458 $inner_ret = $this->get_nested_collections($inner_collection, $processed);
459 $ret = array_merge($ret, $inner_ret);
460 // $processed[] = $inner_collection->id;
461 }
462 }
463 }
464 return $ret;
465 }
466
467 function process_query($response, $flickr_params, $short_code = array()) {
468 $this->push_to_stack('Process response');
469 $ret = '';
470
471 $filter_list = array();
472 if (!empty($short_code['filter'])) {
473 $filter_list = explode(',', $short_code['filter']);
474 }
475
476 if (!is_wp_error($response)) {
477 if ($response['response']['code'] == 200) {
478 $body = $response['body'];
479 $body = json_decode($body);
480 switch ($flickr_params['method']) {
481 case 'flickr.photos.getInfo':
482 if (isset($body->photo)) {
483 $photo = $body->photo;
484 $ret .= $this->process_photo($photo, $short_code);
485 }
486 break;
487
488 case 'flickr.photos.search':
489 if (isset($body->photos) && isset($body->photos->photo)) {
490 $photos = $body->photos->photo;
491 $ret .= $this->process_photos($photos, '', 'stream', $flickr_params, $short_code,
492 array(
493 'total' => $body->photos->total,
494 'start' => ($body->photos->page - 1) * $body->photos->perpage + 1,
495 'end' => $body->photos->page * $body->photos->perpage > $body->photos->total ? $body->photos-> total : $body->photos->page * $body->photos->perpage,
496 'per-page' => $body->photos->perpage,
497 )
498 );
499 }
500 break;
501
502 case 'flickr.photosets.getInfo':
503 if (isset($body->photoset)) {
504 $photoset = $body->photoset;
505 $ret .= $this->process_photoset_header($photoset, $short_code);
506 }
507 break;
508
509 case 'flickr.photosets.getPhotos':
510 if (isset($body->photoset)) {
511 $photoset = $body->photoset;
512 if (isset($photoset->photo) && isset($photoset->owner)) {
513 $owner = $photoset->owner;
514 $ret .= $this->process_photos($photoset->photo, $owner, 'set', $flickr_params, $short_code,
515 array(
516 'total' => $photoset->total,
517 'start' => ($photoset->page - 1) * $photoset->perpage + 1,
518 'end' => $photoset->page * $photoset->perpage > $photoset->total ? $photoset-> total : $photoset->page * $photoset->perpage,
519 'per-page' => $photoset->perpage,
520 )
521 );
522 }
523 }
524 break;
525
526 case 'flickr.photosets.getList':
527 if (isset($body->photosets)) {
528 $photosets = $body->photosets;
529 $ret .= $this->process_photosets($photosets, $filter_list, $short_code);
530 }
531 break;
532
533 case 'flickr.galleries.getInfo':
534 if (isset($body->gallery)) {
535 $gallery = $body->gallery;
536 $ret .= $this->process_gallery_header($gallery, $short_code);
537 }
538 break;
539
540 case 'flickr.galleries.getPhotos':
541 if (isset($body->photos)) {
542 $photos = $body->photos;
543 if (isset($photos->photo)) {
544 $ret .= $this->process_photos($photos->photo, '', 'gallery', $flickr_params, $short_code,
545 array(
546 'total' => $body->photos->total,
547 'start' => ($body->photos->page - 1) * $body->photos->perpage + 1,
548 'end' => $body->photos->page * $body->photos->perpage > $body->photos->total ? $body->photos-> total : $body->photos->page * $body->photos->perpage,
549 'per-page' => $body->photos->perpage,
550 )
551 );
552 }
553 }
554 break;
555
556 case 'flickr.galleries.getList':
557 if (isset($body->galleries)) {
558 $galleries = $body->galleries;
559 $ret .= $this->process_galleries($galleries, $filter_list, $short_code);
560 }
561 break;
562
563 case 'flickr.collections.getTree':
564 if (isset($body->collections)) {
565 $collections = $body->collections;
566 $ret .= $this->process_collections($collections, $short_code);
567 }
568 break;
569 }
570 }
571 }
572 else {
573 $this->pop_from_stack();
574 return $this->wp_error_message($response);
575 }
576
577 $this->pop_from_stack();
578 return $ret;
579 }
580
581 /**
582 * Prints a single photo with the title as an <h3> and the caption as the image caption.
583 *
584 * @param $photo
585 * @param $short_code
586 * @return string
587 */
588 function process_photo($photo, $short_code) {
589 return $this->generate_single_photo_markup('flickr', array(
590 'src' => "https://farm".$photo->farm.".static.flickr.com/".$photo->server."/".$photo->id."_".$photo->secret.($short_code['main_size'] == 'none' ? '' : '_'.$short_code['main_size']).".jpg",
591 'href' => (isset($photo->urls) && isset($photo->urls->url) && count($photo->urls->url) > 0) ? $photo->urls->url[0]->_content : '',
592 'title' => isset($photo->title) ? $photo->title->_content : '',
593 'caption' => isset($photo->description) ? $photo->description->_content : '',
594 )
595 );
596 }
597
598 /**
599 * Prints thumbnails for all photos returned in a query. This is used for printing the results of a search, tag, photoset or gallery.
600 * The photos are printed in-page.
601 *
602 * @param $photos
603 * @param string $owner
604 * @param string $parent
605 * @param $flickr_params
606 * @param $short_code
607 * @param array $level_2_meta
608 * @return string
609 */
610 function process_photos($photos, $owner, $parent, $flickr_params, $short_code, $level_2_meta = array()) {
611 global $photonic_flickr_photo_title_display, $photonic_flickr_photo_pop_title_display;
612 global $photonic_flickr_photos_per_row_constraint, $photonic_flickr_photos_constrain_by_padding, $photonic_flickr_photos_constrain_by_count;
613 global $photonic_flickr_photos_pop_per_row_constraint, $photonic_flickr_photos_pop_constrain_by_padding, $photonic_flickr_photos_pop_constrain_by_count;
614
615 if ($short_code['display'] == 'in-page') {
616 $title_position = $photonic_flickr_photo_title_display;
617 $row_constraints = array('constraint-type' => $photonic_flickr_photos_per_row_constraint, 'padding' => $photonic_flickr_photos_constrain_by_padding, 'count' => $photonic_flickr_photos_constrain_by_count);
618 }
619 else {
620 $title_position = $photonic_flickr_photo_pop_title_display;
621 $row_constraints = array('constraint-type' => $photonic_flickr_photos_pop_per_row_constraint, 'padding' => $photonic_flickr_photos_pop_constrain_by_padding, 'count' => $photonic_flickr_photos_pop_constrain_by_count);
622 }
623 $photo_objects = $this->build_level_1_objects($photos, $owner, $flickr_params, $short_code, $parent);
624 $ret = $this->display_level_1_gallery($photo_objects,
625 array(
626 'title_position' => $title_position,
627 'row_constraints' => $row_constraints,
628 'parent' => $parent,
629 'level_2_meta' => $level_2_meta,
630 ),
631 $short_code
632 );
633 return $ret;
634 }
635
636 function find_largest_image($photo, $size = 'o') {
637 if (in_array($size, array('z','','n','m','q','t','s'))) {
638 $ret_size = $size == '' ? '' : '_'.$size;
639 return 'https://farm'.$photo->farm.'.static.flickr.com/'.$photo->server.'/'.$photo->id.'_'.$photo->secret.$ret_size.'.jpg';
640 }
641
642 $max_to_min = array('o','k','h','b','c');
643 $pos = array_search($size, $max_to_min);
644 for ($idx = $pos; $idx < count($max_to_min); $idx++) {
645 $value = $max_to_min[$idx];
646 if (isset($photo->{'url_'.$value})) {
647 return $photo->{'url_'.$value};
648 }
649 }
650 return 'https://farm'.$photo->farm.'.static.flickr.com/'.$photo->server.'/'.$photo->id.'_'.$photo->secret.'_z'.'.jpg';
651 }
652
653 function build_level_1_objects($photos, $owner, $flickr_params, $short_code, $parent) {
654 $photo_objects = array();
655 $video_size = in_array($this->library, array('colorbox', 'fancybox', 'fancybox2', 'fancybox3', 'featherlight', 'lightgallery', 'magnific', 'swipebox')) ? $short_code['video_size'] : 'Video Player';
656 // $video_size = $short_code['video_size'];
657
658 $main_size = $short_code['main_size'] == 'none' ? '' : $short_code['main_size'];
659 $tile_size = (empty($short_code['tile_size']) || $short_code['tile_size'] == 'same') ? $main_size : ($short_code['tile_size'] == 'none' ? '' : $short_code['tile_size']);
660
661 foreach ($photos as $photo) {
662 $photo_object = array();
663 $photo_object['thumbnail'] = 'https://farm'.$photo->farm.'.static.flickr.com/'.$photo->server.'/'.$photo->id.'_'.$photo->secret.'_'.$short_code['thumb_size'].'.jpg';
664 $photo_object['main_image'] = $this->find_largest_image($photo, $main_size);
665 $download = $this->find_largest_image($photo);
666 $photo_object['download'] = substr($download, 0, strlen($download)-4).'_d'.substr($download, -4);
667 $photo_object['tile_image'] = $this->find_largest_image($photo, $tile_size);
668 $photo_object['alt_title'] = esc_attr($photo->title);
669 if (isset($photo->owner)) {
670 $owner = $photo->owner;
671 }
672
673 $specific = '';
674 if ($parent === 'set' && !empty($flickr_params['photoset_id'])) {
675 $specific = '/in/set-'.$flickr_params['photoset_id'];
676 }
677 $url = "https://www.flickr.com/photos/".$owner."/".$photo->id.$specific;
678 $photo_object['main_page'] = $url;
679
680 $title = $photo->title;
681 $photo_object['title'] = $title;
682
683 if (isset($photo->description)) {
684 $photo_object['description'] = $photo->description->_content;
685 }
686 else {
687 $photo_object['description'] = '';
688 }
689
690 if (!empty($photo->media) && $photo->media == 'video') {
691 $video_response = $this->make_call($this->base_url.'?method=flickr.photos.getSizes&photo_id='.$photo->id, $flickr_params);
692 if (!is_wp_error($video_response) && 200 == $video_response['response']['code']) {
693 $video_response = $video_response['body'];
694 $video_response = json_decode($video_response);
695 if ($video_response->stat == 'ok') {
696 $video_response = $video_response->sizes;
697 $video_response = $video_response->size;
698 if (is_array($video_response)) {
699 foreach ($video_response as $size) {
700 if ($size->label != $video_size) {
701 continue;
702 }
703 else {
704 $photo_object['video'] = $size->source;
705 $photo_object['mime'] = 'video/mp4';
706 break;
707 }
708 }
709 }
710 }
711 }
712 }
713
714 $photo_object['id'] = $photo->id;
715 $photo_object['provider'] = $this->provider;
716 $photo_object['gallery_index'] = $this->gallery_index;
717 $photo_objects[] = $photo_object;
718 }
719
720 return $photo_objects;
721 }
722
723 function build_level_2_objects($flickr_objects, $type, $filter_list = array(), $short_code = array()) {
724 $main_size = $short_code['main_size'] == 'none' ? '' : '_'.$short_code['main_size'];
725 $tile_size = (empty($short_code['tile_size']) || $short_code['tile_size'] == 'same') ? $main_size : ($short_code['tile_size'] == 'none' ? '' : '_'.$short_code['tile_size']);
726
727 $objects = array();
728
729 foreach ($flickr_objects as $flickr_object) {
730 if (!empty($filter_list) &&
731 (($type == 'photoset' && ((!in_array($flickr_object->id, $filter_list) && strtolower($short_code['filter_type']) !== 'exclude') ||
732 (in_array($flickr_object->id, $filter_list) && strtolower($short_code['filter_type']) === 'exclude'))) ||
733 ($type == 'gallery' && ((!in_array(substr($flickr_object->id, stripos($flickr_object->id, '-') + 1), $filter_list) && strtolower($short_code['filter_type']) !== 'exclude') ||
734 (in_array(substr($flickr_object->id, stripos($flickr_object->id, '-') + 1), $filter_list) && strtolower($short_code['filter_type']) === 'exclude'))))) {
735 continue;
736 }
737
738 $object = array();
739 $object['id_1'] = $flickr_object->id;
740 $object['title'] = esc_attr($flickr_object->title->_content);
741 $object['description'] = esc_attr($flickr_object->description->_content);
742 if ($type == 'gallery') {
743 $object['thumbnail'] = "https://farm".$flickr_object->primary_photo_farm.".static.flickr.com/".$flickr_object->primary_photo_server."/".$flickr_object->primary_photo_id."_".$flickr_object->primary_photo_secret."_".$short_code['thumb_size'].".jpg";
744 $object['tile_image'] = "https://farm".$flickr_object->primary_photo_farm.".static.flickr.com/".$flickr_object->primary_photo_server."/".$flickr_object->primary_photo_id."_".$flickr_object->primary_photo_secret.$tile_size.".jpg";
745 $object['main_page'] = $flickr_object->url;
746 $object['counter'] = $flickr_object->count_photos;
747 $object['classes'] = array("photonic-flickr-gallery-thumb-user-{$short_code['user_id']}");
748 }
749 else if ($type == 'photoset') {
750 $object['thumbnail'] = "https://farm".$flickr_object->farm.".static.flickr.com/".$flickr_object->server."/".$flickr_object->primary."_".$flickr_object->secret."_".$short_code['thumb_size'].".jpg";
751 $object['tile_image'] = "https://farm".$flickr_object->farm.".static.flickr.com/".$flickr_object->server."/".$flickr_object->primary."_".$flickr_object->secret.$tile_size.".jpg";
752 $owner = isset($flickr_object->owner) ? $flickr_object->owner : $short_code['user_id'];
753 $object['main_page'] = "https://www.flickr.com/photos/$owner/sets/{$flickr_object->id}";
754 $object['counter'] = $flickr_object->photos;
755 }
756 $object['data_attributes'] = array(
757 'photo-count' => $short_code['photo_count'],
758 'photo-more' => empty($short_code['photo_more']) ? '' : $short_code['photo_more'],
759 'overlay-size' => $short_code['overlay_size'],
760 'overlay-video-size' => $short_code['overlay_video_size'],
761 );
762
763 $objects[] = $object;
764 }
765 return $objects;
766 }
767
768 /**
769 * Prints the header for an in-page photoset.
770 *
771 * @param $photoset
772 * @param array $short_code
773 * @return string
774 */
775 function process_photoset_header($photoset, $short_code = array()) {
776 global $photonic_flickr_hide_set_thumbnail, $photonic_flickr_hide_set_title, $photonic_flickr_hide_set_photo_count;
777 $owner = $photoset->owner;
778 $header = array(
779 'title' => $photoset->title->_content,
780 'thumb_url' => "https://farm".$photoset->farm.".static.flickr.com/".$photoset->server."/".$photoset->primary."_".$photoset->secret."_".$short_code['thumb_size'].".jpg",
781 'link_url' => 'https://www.flickr.com/photos/'.$owner.'/sets/'.$photoset->id,
782 );
783
784 $hidden = array('thumbnail' => !empty($photonic_flickr_hide_set_thumbnail), 'title' => !empty($photonic_flickr_hide_set_title), 'counter' => !empty($photonic_flickr_hide_set_photo_count));
785 $counters = array('photos' => $photoset->photos);
786
787 $ret = $this->process_object_header($header,
788 array(
789 'type' => 'set',
790 'hidden' => $this->get_hidden_headers($short_code['header_display'], $hidden),
791 'counters' => $counters,
792 'link' => true,
793 'display' => $short_code['display'],
794 )
795 );
796
797 return $ret;
798 }
799
800 /**
801 * Prints thumbnails for each photoset returned in a query.
802 *
803 * @param $photosets
804 * @param array $filter_list
805 * @param array $short_code
806 * @return string
807 */
808 function process_photosets($photosets, $filter_list = array(), $short_code = array()) {
809 global $photonic_flickr_collection_set_per_row_constraint, $photonic_flickr_collection_set_constrain_by_count, $photonic_flickr_collection_set_constrain_by_padding,
810 $photonic_flickr_collection_set_title_display, $photonic_flickr_hide_collection_set_photos_count_display;
811 $objects = $this->build_level_2_objects($photosets->photoset, 'photoset', $filter_list, $short_code);
812 $row_constraints = array('constraint-type' => $photonic_flickr_collection_set_per_row_constraint, 'padding' => $photonic_flickr_collection_set_constrain_by_padding, 'count' => $photonic_flickr_collection_set_constrain_by_count);
813 $ret = $this->display_level_2_gallery($objects,
814 array(
815 'row_constraints' => $row_constraints,
816 'type' => 'photosets',
817 'singular_type' => 'set',
818 'title_position' => $photonic_flickr_collection_set_title_display,
819 'level_1_count_display' => $photonic_flickr_hide_collection_set_photos_count_display,
820 'pagination' => array(
821 'total' => $photosets->total,
822 'start' => ($photosets->page - 1) * $photosets->perpage + 1,
823 'end' => $photosets->page * $photosets->perpage > $photosets->total ? $photosets-> total : $photosets->page * $photosets->perpage,
824 'per-page' => $photosets->perpage,
825 ),
826 ),
827 $short_code
828 );
829 return $ret;
830 }
831
832 /**
833 * Shows the header for a gallery invoked in-page.
834 *
835 * @param $gallery
836 * @param $short_code
837 * @return string
838 */
839 function process_gallery_header($gallery, $short_code) {
840 global $photonic_flickr_hide_gallery_thumbnail, $photonic_flickr_hide_gallery_title, $photonic_flickr_hide_gallery_photo_count;
841 $header = array(
842 'title' => $gallery->title->_content,
843 'thumb_url' => "https://farm".$gallery->primary_photo_farm.".static.flickr.com/".$gallery->primary_photo_server."/".$gallery->primary_photo_id."_".$gallery->primary_photo_secret."_".$short_code['thumb_size'].".jpg",
844 'link_url' => $gallery->url,
845 );
846
847 $hidden = array('thumbnail' => !empty($photonic_flickr_hide_gallery_thumbnail), 'title' => !empty($photonic_flickr_hide_gallery_title), 'counter' => !empty($photonic_flickr_hide_gallery_photo_count));
848 $counters = array('photos' => $gallery->count_photos);
849
850 $ret = $this->process_object_header($header,
851 array(
852 'type' => 'gallery',
853 'hidden' => $this->get_hidden_headers($short_code['header_display'], $hidden),
854 'counters' => $counters,
855 'link' => true,
856 'display' => $short_code['display'],
857 )
858 );
859 return $ret;
860 }
861
862 /**
863 * Prints out the thumbnails for all galleries belonging to a user.
864 *
865 * @param $galleries
866 * @param array $filter_list
867 * @param array $short_code
868 * @return string
869 */
870 function process_galleries($galleries, $filter_list = array(), $short_code = array()) {
871 global $photonic_flickr_galleries_per_row_constraint, $photonic_flickr_galleries_constrain_by_padding,
872 $photonic_flickr_galleries_constrain_by_count, $photonic_flickr_gallery_title_display, $photonic_flickr_hide_gallery_photos_count_display;
873
874 $objects = $this->build_level_2_objects($galleries->gallery, 'gallery', $filter_list, $short_code);
875 $row_constraints = array('constraint-type' => $photonic_flickr_galleries_per_row_constraint, 'padding' => $photonic_flickr_galleries_constrain_by_padding, 'count' => $photonic_flickr_galleries_constrain_by_count);
876 $ret = $this->display_level_2_gallery($objects,
877 array(
878 'row_constraints' => $row_constraints,
879 'type' => 'galleries',
880 'singular_type' => 'gallery',
881 'title_position' => $photonic_flickr_gallery_title_display,
882 'level_1_count_display' => $photonic_flickr_hide_gallery_photos_count_display,
883 'pagination' => array(
884 'total' => $galleries->total,
885 'start' => ($galleries->page - 1) * $galleries->per_page + 1,
886 'end' => $galleries->page * $galleries->per_page > $galleries->total ? $galleries->total : $galleries->page * $galleries->per_page,
887 'per-page' => $galleries->per_page,
888 )
889 ),
890 $short_code
891 );
892 return $ret;
893 }
894
895 /**
896 * Prints a collection header, followed by thumbnails of all sets in that collection.
897 *
898 * @param $collections
899 * @param array $short_code
900 * @return string
901 */
902 function process_collections($collections, $short_code = array()) {
903 global $photonic_flickr_hide_empty_collection_details, $photonic_flickr_collection_set_per_row_constraint, $photonic_flickr_collection_set_constrain_by_padding,
904 $photonic_flickr_collection_set_constrain_by_count, $photonic_flickr_hide_collection_thumbnail, $photonic_flickr_hide_collection_title, $photonic_flickr_hide_collection_set_count, $photonic_flickr_collection_set_title_display, $photonic_flickr_hide_collection_set_photos_count_display;
905 $ret = '';
906
907 $row_constraints = array('constraint-type' => $photonic_flickr_collection_set_per_row_constraint, 'padding' => $photonic_flickr_collection_set_constrain_by_padding, 'count' => $photonic_flickr_collection_set_constrain_by_count);
908 $collection_headers = array();
909 $collection_sets = array();
910 $all_parallel = array();
911
912 foreach ($collections->collection as $collection) {
913 $dont_show = false;
914 if (empty($collection->set) && !empty($photonic_flickr_hide_empty_collection_details)) {
915 $dont_show = true;
916 }
917 $id = $collection->id;
918 if (!$dont_show) {
919 $url_id = substr($id, stripos($id, '-') + 1);
920 $header = array('id' => $id.'-'.$short_code['user_id'], 'title' => $collection->title, 'thumb_url' => $collection->iconsmall, 'link_url' => "https://www.flickr.com/photos/".$short_code['user_id']."/collections/".$url_id);
921 $hidden = array('thumbnail' => !empty($photonic_flickr_hide_collection_thumbnail), 'title' => !empty($photonic_flickr_hide_collection_title), 'counter' => !empty($photonic_flickr_hide_collection_set_count));
922 $counters = array();
923 if (isset($collection->set)) {
924 $photosets = $collection->set;
925 $counters['sets'] = count($photosets);
926 }
927
928 $header = $this->process_object_header($header,
929 array(
930 'type' => 'collection',
931 'hidden' => $this->get_hidden_headers($short_code['header_display'], $hidden),
932 'counters' => $counters,
933 'link' => true,
934 'iterate_level_3' => $short_code['iterate_level_3'],
935 'layout' => $short_code['layout'],
936 )
937 );
938
939 $ret .= $header;
940 $collection_headers[] = array('collection' => $id, 'header' => $header);
941 }
942
943 if (isset($collection->set) && !empty($collection->set) && $short_code['iterate_level_3']) {
944 $flickr_objects = array();
945 $photosets = $collection->set;
946
947 $parallel = array();
948 $psets = array();
949 $hooks = new Requests_Hooks();
950 $hooks->register('curl.before_multi_add', array($this, 'ssl_verify_peer'), 100);
951 foreach ($photosets as $set) {
952 $parallel_params = array();
953 $parallel_params['format'] = 'json';
954 $parallel_params['nojsoncallback'] = 1;
955 $parallel_params['api_key'] = $this->api_key;
956 $parallel_params['method'] = 'flickr.photosets.getInfo';
957 $parallel_params['photoset_id'] = $set->id;
958 // We only worry about signing the call if the authentication is done. Otherwise we just show what is available.
959 if ($this->oauth_done) {
960 $signed_args = $this->sign_call($this->base_url, 'GET', $parallel_params);
961 $parallel_params = $signed_args;
962 }
963
964 // $hooks = new Requests_Hooks();
965 // $hooks->register('curl.before_multi_add', array($this, 'ssl_verify_peer'), 100);
966 $parallel[] = array(
967 'url' => $this->base_url,
968 'type' => 'GET',
969 'data' => $parallel_params,
970 // 'options' => array('hooks' => $hooks)
971 );
972 $psets[] = $set->id;
973 }
974 $collection_sets[] = array('collection' => $id, 'count' => count($parallel));
975
976 if (!empty($parallel)) {
977 // $parallel_responses = Requests::request_multiple($parallel);
978 $parallel_responses = Requests::request_multiple($parallel, array('hooks' => $hooks));
979 foreach ($parallel_responses as $ps_response) {
980 if (is_a($ps_response, 'Requests_Response')) {
981 $ps_response = json_decode($ps_response->body);
982 if (!empty($ps_response->photoset->id)) {
983 $flickr_objects[array_search($ps_response->photoset->id, $psets)] = $ps_response->photoset;
984 }
985 }
986 }
987 }
988 ksort($flickr_objects);
989
990 $objects = $this->build_level_2_objects($flickr_objects, 'photoset', array(), $short_code); // No filters passed for this
991 $ret .= $this->display_level_2_gallery($objects,
992 array(
993 'row_constraints' => $row_constraints,
994 'type' => 'photosets',
995 'singular_type' => 'set',
996 'title_position' => $photonic_flickr_collection_set_title_display,
997 'level_1_count_display' => $photonic_flickr_hide_collection_set_photos_count_display,
998 ),
999 $short_code
1000 );
1001 }
1002 }
1003 return $ret;
1004 }
1005
1006 /**
1007 * Access Token URL
1008 *
1009 * @return string
1010 */
1011 public function access_token_URL() {
1012 return 'https://www.flickr.com/services/oauth/access_token';
1013 }
1014
1015 /**
1016 * Authenticate URL
1017 *
1018 * @return string
1019 */
1020 public function authenticate_URL() {
1021 return 'https://www.flickr.com/services/oauth/authorize';
1022 }
1023
1024 /**
1025 * Authorize URL
1026 *
1027 * @return string
1028 */
1029 public function authorize_URL() {
1030 return 'https://www.flickr.com/services/oauth/authorize';
1031 }
1032
1033 /**
1034 * Request Token URL
1035 *
1036 * @return string
1037 */
1038 public function request_token_URL() {
1039 return 'https://www.flickr.com/services/oauth/request_token';
1040 }
1041
1042 public function end_point() {
1043 return $this->base_url;
1044 }
1045
1046 function parse_token($response) {
1047 $body = $response['body'];
1048 $token = Photonic_Processor::parse_parameters($body);
1049 return $token;
1050 }
1051
1052 public function check_access_token_method() {
1053 return 'flickr.test.login';
1054 }
1055
1056 /**
1057 * Method to validate that the stored token is indeed authenticated.
1058 *
1059 * @param $token
1060 * @return array|WP_Error
1061 */
1062 function check_access_token($token) {
1063 $parameters = array('method' => $this->check_access_token_method(), 'format' => 'json', 'nojsoncallback' => 1);
1064 $signed_parameters = $this->sign_call($this->end_point(), 'GET', $parameters);
1065 $end_point = $this->end_point();
1066 $end_point .= '?'.Photonic_Processor::build_query($signed_parameters);
1067 $parameters = null;
1068
1069 $response = Photonic::http($end_point, 'GET', $parameters);
1070 return $response;
1071 }
1072
1073 function execute_helper($args) {
1074 if (!empty($args['user'])) {
1075 $url = 'https://api.flickr.com/services/rest/?format=json&nojsoncallback=1&api_key='.$this->api_key.'&method=flickr.urls.lookupUser&url='.urlencode('https://www.flickr.com/photos/').$args['user'];
1076 }
1077 else if (!empty($args['group'])) {
1078 $url = 'https://api.flickr.com/services/rest/?format=json&nojsoncallback=1&api_key='.$this->api_key.'&method=flickr.urls.lookupGroup&url='.urlencode('https://www.flickr.com/groups/').$args['group'];
1079 }
1080 else {
1081 return '<div class="photonic-helper">'.sprintf(esc_html__('Please pass the %1$s or %2$s attribute.', 'photonic'), '<code>user</code>', '<code>group</code>').'</div>';
1082 }
1083
1084 $response = wp_remote_request($url, array('sslverify' => PHOTONIC_SSL_VERIFY));
1085 if (!is_wp_error($response)) {
1086 if (isset($response['response']) && isset($response['response']['code'])) {
1087 if ($response['response']['code'] == 200) {
1088 $body = json_decode(wp_remote_retrieve_body($response));
1089 if (isset($body->stat) && $body->stat == 'fail') {
1090 Photonic::log($response);
1091 return '<div class="photonic-helper">'.$body->message.'</div>';
1092 }
1093
1094 if (isset($body->user)) {
1095 return '<div class="photonic-helper">'.sprintf(esc_html__('User id: %s', 'photonic'), $body->user->id).'</div>';
1096 }
1097 else if (isset($body->group)) {
1098 return '<div class="photonic-helper">'.sprintf(esc_html__('Group id: %s', 'photonic'), $body->group->id).'</div>';
1099 }
1100 else {
1101 return '<div class="photonic-helper">'.esc_html__('No data returned.', 'photonic').'</div>';
1102 }
1103 }
1104 else {
1105 Photonic::log($response['response']);
1106 return '<div class="photonic-helper">'.sprintf(esc_html__('No data returned. Error code %s', 'photonic'), $response['response']['code']).'</div>';
1107 }
1108 }
1109 else {
1110 Photonic::log($response);
1111 return '<div class="photonic-helper">'.esc_html__('No data returned. Empty response, or empty error code.', 'photonic').'</div>';
1112 }
1113 }
1114 else {
1115 return '<div class="photonic-helper">'.$response->get_error_message().'</div>';
1116 }
1117 }
1118 }
1119