PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 2.19
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v2.19
3.37 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 All 142 releases
photonic / extensions / Photonic_Flickr_Processor.php

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

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