PluginProbe
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels / 2.3.8
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels v2.3.8
2.9.1 2.9.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 2.0.0 2.1.0 2.2.0 2.3.2 2.3.3 2.3.5 2.3.6 2.3.8 2.3.9 2.4.3 All 37 releases
automatic-youtube-gallery / includes / youtube-api.php

youtube-api.php in Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels 2.3.8, at includes/youtube-api.php

892 lines 22.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * A wrapper class for the Youtube Data API v3.
5 *
6 * @link https://plugins360.com
7 * @since 1.0.0
8 *
9 * @package Automatic_YouTube_Gallery
10 */
11
12 // Exit if accessed directly
13 if ( ! defined( 'WPINC' ) ) {
14 die;
15 }
16
17 /**
18 * AYG_YouTube_API class.
19 *
20 * @since 1.0.0
21 */
22 class AYG_YouTube_API {
23
24 /**
25 * The YouTube API Key.
26 *
27 * @since 1.0.0
28 * @access protected
29 * @var string
30 */
31 protected $api_key;
32
33 /**
34 * The YouTube API URLs.
35 *
36 * @since 1.0.0
37 * @access protected
38 * @var array
39 */
40 public $api_urls = array(
41 'playlistItems.list' => 'https://www.googleapis.com/youtube/v3/playlistItems',
42 'channels.list' => 'https://www.googleapis.com/youtube/v3/channels',
43 'search.list' => 'https://www.googleapis.com/youtube/v3/search',
44 'videos.list' => 'https://www.googleapis.com/youtube/v3/videos'
45 );
46
47 /**
48 * Is development mode enabled?
49 *
50 * @since 2.3.0
51 * @access protected
52 * @var bool
53 */
54 protected $is_development_mode = false;
55
56 /**
57 * Get videos.
58 *
59 * @since 1.0.0
60 * @param array $params Array of query params.
61 * @return mixed
62 */
63 public function query( $params = array() ) {
64 // Get YouTube API Key
65 $general_settings = get_option( 'ayg_general_settings' );
66
67 if ( empty( $general_settings['api_key'] ) ) {
68 return $this->get_error( __( 'YouTube API key not found.', 'automatic-youtube-gallery' ) . ' ' . sprintf( __( 'Kindly follow this URL <a href="%s" target="_blank">this guide</a> to get your own API key.', 'automatic-youtube-gallery' ), 'https://plugins360.com/automatic-youtube-gallery/how-to-get-youtube-api-key/' ) );
69 }
70
71 $this->api_key = $general_settings['api_key'];
72
73 // Is development mode enabled?
74 if ( isset( $general_settings['development_mode'] ) && ! empty( $general_settings['development_mode'] ) ) {
75 $this->is_development_mode = true;
76 }
77
78 // Process output
79 $response = array();
80
81 switch ( $params['type'] ) {
82 case 'playlist':
83 if ( empty( $params['src'] ) ) {
84 return $this->get_error( __( 'YouTube Playlist ID (or) URL is required.', 'automatic-youtube-gallery' ) );
85 }
86
87 $response = $this->request_api_playlist_items( $params );
88 break;
89
90 case 'channel':
91 if ( empty( $params['src'] ) ) {
92 return $this->get_error( __( 'YouTube Channel ID (or) or a YouTube Video URL from the Channel is required.', 'automatic-youtube-gallery' ) );
93 }
94
95 $params['id'] = $this->get_channel_id( $params );
96
97 if ( empty( $params['id'] ) ) {
98 return $this->get_error( __( 'Invalid YouTube Channel ID.', 'automatic-youtube-gallery' ) );
99 }
100
101 // Get playlist id from the channel
102 $playlist_id = $this->get_playlist_id( $params );
103
104 if ( is_object( $playlist_id ) && isset( $playlist_id->error ) ) {
105 return $playlist_id;
106 }
107
108 if ( empty( $playlist_id ) ) {
109 return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
110 }
111
112 // Get videos using the playlist id
113 $params['src'] = $playlist_id;
114 $response = $this->request_api_playlist_items( $params );
115 break;
116
117 case 'username':
118 if ( empty( $params['src'] ) ) {
119 return $this->get_error( __( 'YouTube Account Username is required.', 'automatic-youtube-gallery' ) );
120 }
121
122 // Get playlist id from the channel
123 $params['forUsername'] = $this->parse_youtube_id_from_url( $params['src'], 'username' );
124 $playlist_id = $this->get_playlist_id( $params );
125
126 if ( is_object( $playlist_id ) && isset( $playlist_id->error ) ) {
127 return $playlist_id;
128 }
129
130 if ( empty( $playlist_id ) ) {
131 return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
132 }
133
134 // Get videos using the playlist id
135 $params['src'] = $playlist_id;
136 $response = $this->request_api_playlist_items( $params );
137 break;
138
139 case 'search':
140 if ( empty( $params['src'] ) ) {
141 return $this->get_error( __( 'Cannot search an empty string. A search keyword is required.', 'automatic-youtube-gallery' ) );
142 }
143
144 $response = $this->request_api_search( $params );
145 break;
146
147 case 'videos':
148 if ( empty( $params['src'] ) ) {
149 return $this->get_error( __( 'Atleast one YouTube Video ID (or) URL is required.', 'automatic-youtube-gallery' ) );
150 }
151
152 $response = $this->request_api_videos( $params );
153 break;
154
155 case 'livestream':
156 if ( empty( $params['src'] ) ) {
157 return $this->get_error( __( 'YouTube Channel ID (or) or a YouTube Video URL from the Channel is required.', 'automatic-youtube-gallery' ) );
158 }
159
160 $params['channelId'] = $this->get_channel_id( $params );
161
162 if ( empty( $params['channelId'] ) ) {
163 return $this->get_error( __( 'Invalid YouTube Channel ID.', 'automatic-youtube-gallery' ) );
164 }
165
166 // Get live video using the channel id
167 $response = $this->request_api_live_video( $params );
168 break;
169
170 default: // video
171 if ( empty( $params['src'] ) ) {
172 return $this->get_error( __( 'YouTube Video ID (or) URL is required.', 'automatic-youtube-gallery' ) );
173 }
174
175 $response = $this->request_api_video( $params );
176 break;
177 }
178
179 return $response;
180 }
181
182 /**
183 * Grab the playlist, channel or video ID using the YouTube URL given.
184 *
185 * @since 1.0.0
186 * @access private
187 * @param string $url YouTube URL.
188 * @param string $type Type of the URL (playlist|channel|video).
189 * @return mixed
190 */
191 private function parse_youtube_id_from_url( $url, $type = 'video' ) {
192 $url = trim( $url );
193 $id = $url;
194
195 switch ( $type ) {
196 case 'playlist':
197 if ( preg_match( '/list=(.*)&?\/?/', $url, $matches ) ) {
198 $id = $matches[1];
199 }
200 break;
201
202 case 'channel':
203 if ( wp_http_validate_url( $id ) ) {
204 $id = '';
205 }
206
207 $url = parse_url( rtrim( $url, '/' ) );
208
209 if ( isset( $url['path'] ) && preg_match( '/^\/channel\/(([^\/])+?)$/', $url['path'], $matches ) ) {
210 $id = $matches[1];
211 }
212 break;
213
214 case 'username':
215 $url = parse_url( rtrim( $url, '/' ) );
216
217 if ( isset( $url['path'] ) && preg_match( '/^\/user\/(([^\/])+?)$/', $url['path'], $matches ) ) {
218 $id = $matches[1];
219 }
220 break;
221
222 default: // video
223 $url = parse_url( $url );
224
225 if ( array_key_exists( 'host', $url ) ) {
226 if ( 0 === strcasecmp( $url['host'], 'youtu.be' ) ) {
227 $id = substr( $url['path'], 1 );
228 } elseif ( 0 === strcasecmp( $url['host'], 'www.youtube.com' ) ) {
229 if ( isset( $url['query'] ) ) {
230 parse_str( $url['query'], $url['query'] );
231
232 if ( isset( $url['query']['v'] ) ) {
233 $id = $url['query']['v'];
234 }
235 }
236
237 if ( empty( $id ) ) {
238 $url['path'] = explode( '/', substr( $url['path'], 1 ) );
239
240 if ( in_array( $url['path'][0], array( 'e', 'embed', 'v' ) ) ) {
241 $id = $url['path'][1];
242 }
243 }
244 }
245 }
246 }
247
248 return $id;
249 }
250
251 /**
252 * Get the channel ID.
253 *
254 * @since 2.0.0
255 * @access private
256 * @param array $params Array of query params.
257 * @return string
258 */
259 private function get_channel_id( $params = array() ) {
260 // Parse channel ID from URL: https://www.youtube.com/channel/XXXXXXXXXX
261 $id = $this->parse_youtube_id_from_url( $params['src'], 'channel' );
262
263 if ( empty( $id ) ) {
264 // Get channel ID from a Video URL: https://www.youtube.com/watch?v=XXXXXXXXXX
265 $video_id = $this->parse_youtube_id_from_url( $params['src'], 'video' );
266
267 // Request from cache
268 $channel_ids = get_option( 'ayg_channel_ids', array() );
269 if ( ! is_array( $channel_ids ) ) {
270 $channel_ids = (array) $channel_ids;
271 }
272
273 if ( isset( $channel_ids[ $video_id ] ) && ! empty( $channel_ids[ $video_id ] ) ) {
274 return $channel_ids[ $video_id ];
275 }
276
277 // Request from API
278 $api_url = $this->get_api_url( 'videos.list' );
279
280 $params['id'] = $video_id;
281
282 $api_params = $this->safe_merge_params(
283 array(
284 'id' => '',
285 'part' => 'id,snippet,contentDetails,status',
286 'cache' => 0
287 ),
288 $params
289 );
290
291 $api_response = $this->request_api( $api_url, $api_params, 'channel_id' );
292 if ( isset( $api_response->error ) ) {
293 return $id;
294 }
295
296 $videos = $this->parse_videos( $api_response );
297 if ( isset( $videos->error ) ) {
298 return $id;
299 }
300
301 // Process output
302 if ( $id = $videos[0]->channel_id ) {
303 // Store in cache
304 $channel_ids[ $video_id ] = $id;
305 update_option( 'ayg_channel_ids', $channel_ids );
306 }
307 }
308
309 return $id;
310 }
311
312 /**
313 * Get playlist id using channels API.
314 *
315 * @since 1.0.0
316 * @access private
317 * @param array $params Array of query params.
318 * @return mixed
319 */
320 private function get_playlist_id( $params = array() ) {
321 // Request from cache
322 $playlist_ids = get_option( 'ayg_playlist_ids', array() );
323 if ( ! is_array( $playlist_ids ) ) {
324 $playlist_ids = (array) $playlist_ids;
325 }
326
327 $key = '';
328
329 if ( isset( $params['forUsername'] ) && ! empty( $params['forUsername'] ) ) {
330 $key = $params['forUsername'];
331 }
332
333 if ( isset( $params['id'] ) && ! empty( $params['id'] ) ) {
334 unset( $params['forUsername'] );
335 $key = $params['id'];
336 }
337
338 if ( isset( $playlist_ids[ $key ] ) && ! empty( $playlist_ids[ $key ] ) ) {
339 return $playlist_ids[ $key ];
340 }
341
342 // Request from API
343 $api_url = $this->get_api_url( 'channels.list' );
344
345 $api_params = $this->safe_merge_params(
346 array(
347 'id' => '',
348 'forUsername' => '',
349 'part' => 'contentDetails',
350 'cache' => 0
351 ),
352 $params
353 );
354
355 $api_response = $this->request_api( $api_url, $api_params, 'playlist_id' );
356 if ( isset( $api_response->error ) ) {
357 return $api_response;
358 }
359
360 if ( ! isset( $api_response->items ) ) {
361 return false;
362 }
363
364 $items = $api_response->items;
365 if ( ! is_array( $items ) || count( $items ) == 0 ) {
366 return false;
367 }
368
369 // Process output
370 if ( $id = $items[0]->contentDetails->relatedPlaylists->uploads ) {
371 // Store in cache
372 $playlist_ids[ $key ] = $id;
373 update_option( 'ayg_playlist_ids', $playlist_ids );
374
375 // Return
376 return $id;
377 }
378
379 return false;
380 }
381
382 /**
383 * Get videos using playlistItems API.
384 *
385 * @since 1.0.0
386 * @access private
387 * @param array $params Array of query params.
388 * @return stdClass
389 */
390 private function request_api_playlist_items( $params = array() ) {
391 $api_url = $this->get_api_url( 'playlistItems.list' );
392
393 $params['playlistId'] = $this->parse_youtube_id_from_url( $params['src'], 'playlist' );
394
395 $api_params = $this->safe_merge_params(
396 array(
397 'playlistId' => '',
398 'part' => 'id,snippet,contentDetails,status',
399 'maxResults' => 50,
400 'pageToken' => '',
401 'cache' => 0
402 ),
403 $params
404 );
405
406 $api_response = $this->request_api( $api_url, $api_params );
407 if ( isset( $api_response->error ) ) {
408 return $api_response;
409 }
410
411 $videos = $this->parse_videos( $api_response );
412 if ( isset( $videos->error ) ) {
413 return $videos;
414 }
415
416 // Process output
417 $response = new stdClass();
418 $response->page_info = $this->parse_page_info( $api_response );
419 $response->videos = $videos;
420
421 return $response;
422 }
423
424 /**
425 * Get videos using search API.
426 *
427 * @since 1.0.0
428 * @access private
429 * @param array $params Array of query params.
430 * @return stdClass
431 */
432 private function request_api_search( $params = array() ) {
433 $api_url = $this->get_api_url( 'search.list' );
434
435 $params['q'] = $params['src'];
436
437 if ( ! empty( $params['q'] ) ) {
438 $params['q'] = str_replace( '|', '%7C', $params['q'] );
439 }
440
441 $params['type'] = 'video'; // Overrides user defined type value 'search'
442
443 $api_params = $this->safe_merge_params(
444 array(
445 'q' => '',
446 'channelId' => '',
447 'type' => 'video',
448 'videoEmbeddable' => true,
449 'part' => 'id,snippet',
450 'order' => 'date',
451 'maxResults' => 50,
452 'pageToken' => '',
453 'cache' => 0
454 ),
455 $params
456 );
457
458 $api_response = $this->request_api( $api_url, $api_params );
459 if ( isset( $api_response->error ) ) {
460 return $api_response;
461 }
462
463 $videos = $this->parse_videos( $api_response );
464 if ( isset( $videos->error ) ) {
465 return $videos;
466 }
467
468 // Process output
469 $response = new stdClass();
470 $response->page_info = $this->parse_page_info( $api_response );
471 $response->videos = $videos;
472
473 return $response;
474 }
475
476 /**
477 * Get live video using search API.
478 *
479 * @since 2.3.7
480 * @access private
481 * @param array $params Array of query params.
482 * @return mixed
483 */
484 private function request_api_live_video( $params = array() ) {
485 $api_url = $this->get_api_url( 'search.list' );
486
487 $params['type'] = 'video'; // Overrides user defined type value 'livestream'
488
489 $api_params = $this->safe_merge_params(
490 array(
491 'type' => 'video',
492 'eventType' => 'live',
493 'part' => 'snippet',
494 'channelId' => '',
495 'cache' => 0
496 ),
497 $params
498 );
499
500 $api_response = $this->request_api( $api_url, $api_params );
501 if ( isset( $api_response->error ) ) {
502 return $api_response;
503 }
504
505 $videos = $this->parse_videos( $api_response );
506 if ( isset( $videos->error ) ) {
507 $livestream_settings = get_option( 'ayg_livestream_settings' );
508 return $this->get_error( '<div class="ayg-livestream-fallback-message">' . $livestream_settings['fallback_message'] . '</div>' );
509 }
510
511 // Process output
512 $response = new stdClass();
513 $response->videos = $videos;
514
515 return $response;
516 }
517
518 /**
519 * Get details of the given video ID.
520 *
521 * @since 1.0.0
522 * @access private
523 * @param array $params Array of query params.
524 * @return stdClass
525 */
526 private function request_api_video( $params = array() ) {
527 $api_url = $this->get_api_url( 'videos.list' );
528
529 $params['id'] = $this->parse_youtube_id_from_url( $params['src'], 'video' );
530
531 $api_params = $this->safe_merge_params(
532 array(
533 'id' => '',
534 'part' => 'id,snippet,contentDetails,status',
535 'cache' => 0
536 ),
537 $params
538 );
539
540 $api_response = $this->request_api( $api_url, $api_params );
541 if ( isset( $api_response->error ) ) {
542 return $api_response;
543 }
544
545 $videos = $this->parse_videos( $api_response );
546 if ( isset( $videos->error ) ) {
547 return $videos;
548 }
549
550 // Process output
551 $response = new stdClass();
552 $response->videos = $videos;
553
554 return $response;
555 }
556
557 /**
558 * Get details of the given video IDs.
559 *
560 * @since 1.0.0
561 * @access private
562 * @param array $params Array of query params.
563 * @return stdClass
564 */
565 private function request_api_videos( $params = array() ) {
566 $api_url = $this->get_api_url( 'videos.list' );
567
568 $urls = str_replace( "\n\r", ',', $params['src'] );
569 $urls = str_replace( ' ', ',', $urls );
570 $urls = explode( ',', $urls );
571 $urls = array_filter( $urls );
572
573 $all_ids = array();
574 foreach ( $urls as $url ) {
575 $all_ids[] = $this->parse_youtube_id_from_url( $url, 'video' );
576 }
577 $total_videos = count( $all_ids );
578 $total_pages = ceil( $total_videos / $params['maxResults'] );
579
580 $current_page = isset( $params['pageToken'] ) ? (int) $params['pageToken'] : 1;
581 $current_page = max( $current_page, 1 );
582 $current_page = min( $current_page, $total_pages );
583
584 $offset = ( $current_page - 1 ) * $params['maxResults'];
585 if ( $offset < 0 ) {
586 $offset = 0;
587 }
588
589 $current_ids = array_slice( $all_ids, $offset, $params['maxResults'] );
590 $params['id'] = implode( ',', $current_ids );
591
592 $api_params = $this->safe_merge_params(
593 array(
594 'id' => '',
595 'part' => 'id,snippet,contentDetails,status',
596 'cache' => 0
597 ),
598 $params
599 );
600
601 $api_response = $this->request_api( $api_url, $api_params );
602 if ( isset( $api_response->error ) ) {
603 return $api_response;
604 }
605
606 $videos = $this->parse_videos( $api_response );
607 if ( isset( $videos->error ) ) {
608 return $videos;
609 }
610
611 // Process output
612 $response = new stdClass();
613 $response->videos = $videos;
614
615 $response->page_info = array(
616 'videos_found' => $total_videos
617 );
618
619 if ( $current_page > 1 ) {
620 $response->page_info['prev_page_token'] = $current_page - 1;
621 }
622
623 if ( $current_page < $total_pages ) {
624 $response->page_info['next_page_token'] = $current_page + 1;
625 }
626
627 return $response;
628 }
629
630 /**
631 * Get API URL by request.
632 *
633 * @since 1.0.0
634 * @access private
635 * @param array $name
636 * @return string
637 */
638 private function get_api_url( $name ) {
639 return $this->api_urls[ $name ];
640 }
641
642 /**
643 * Request data from the API server.
644 *
645 * @since 1.0.0
646 * @access private
647 * @param string $url YouTube API URL.
648 * @param array $params Array of query params.
649 * @param string $context "channel_id", "playlist_id", or "videos"
650 * @return mixed
651 */
652 private function request_api( $url, $params, $context = 'videos' ) {
653 $params['key'] = $this->api_key;
654
655 // Request from cache
656 if ( ! $this->is_development_mode ) {
657 $cache_url = $url . ( strpos( $url, '?' ) === false ? '?' : '' ) . http_build_query( $params );
658 $cache_key = 'ayg_' . md5( $cache_url );
659 $cache_data = get_transient( $cache_key );
660
661 if ( ! empty( $cache_data ) ) {
662 return $cache_data;
663 }
664 }
665
666 // Request from API
667 $cache_duration = 0;
668 if ( isset( $params['cache'] ) ) {
669 $cache_duration = (int) $params['cache'];
670 unset( $params['cache'] );
671 }
672
673 $q = '';
674 if ( isset( $params['q'] ) ) {
675 $q = $params['q'];
676 unset( $params['q'] );
677 }
678
679 $url = $url . ( strpos( $url, '?' ) === false ? '?' : '' ) . http_build_query( $params );
680 if ( ! empty( $q ) ) {
681 $url .= '&q=' . $q;
682 }
683
684 $request = wp_remote_get( $url, array(
685 'headers' => [ 'referer' => home_url() ],
686 ) );
687
688 if ( is_wp_error( $request ) ) {
689 return $this->get_error( $request->get_error_message() );
690 }
691
692 $body = wp_remote_retrieve_body( $request );
693
694 $data = json_decode( $body );
695
696 if ( isset( $data->error ) ) {
697 $message = "Error " . $data->error->code . " " . $data->error->message;
698
699 if ( isset( $data->error->errors[0] ) ) {
700 $message .= " : " . $data->error->errors[0]->reason;
701 }
702
703 return $this->get_error( $message );
704 }
705
706 // Store in cache (transients)
707 if ( ! $this->is_development_mode && 'videos' == $context && $cache_duration > 0 ) {
708 if ( isset( $data->items ) && is_array( $data->items ) && count( $data->items ) > 0 ) {
709 set_transient( $cache_key, $data, $cache_duration );
710
711 // Get the current list of transients
712 $cache_keys = get_option( 'ayg_transient_keys', array() );
713 if ( ! is_array( $cache_keys ) ) {
714 $cache_keys = (array) $cache_keys;
715 }
716
717 // Append our new one
718 if ( ! in_array( $cache_key, $cache_keys ) ) {
719 $cache_keys[] = $cache_key;
720 }
721
722 // Save it to the DB
723 update_option( 'ayg_transient_keys', $cache_keys );
724 }
725 }
726
727 // Store videos in our custom database table "{$wpdb->prefix}ayg_videos"
728 ayg_db_store_videos( $data );
729
730 // Finally return the data
731 return $data;
732 }
733
734 /**
735 * Parse videos from the YouTube API response object.
736 *
737 * @since 1.0.0
738 * @access private
739 * @param object $data YouTube API response object.
740 * @return mixed
741 */
742 private function parse_videos( $data ) {
743 if ( ! isset( $data->items ) ) {
744 return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
745 }
746
747 $items = $data->items;
748 if ( ! is_array( $items ) || 0 == count( $items ) ) {
749 return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
750 }
751
752 $videos = array();
753
754 foreach ( $items as $item ) {
755 $video = new stdClass();
756
757 // Video ID
758 $video->id = '';
759
760 if ( isset( $item->snippet->resourceId ) && isset( $item->snippet->resourceId->videoId ) ) {
761 $video->id = $item->snippet->resourceId->videoId;
762 } elseif ( isset( $item->contentDetails ) && isset( $item->contentDetails->videoId ) ) {
763 $video->id = $item->contentDetails->videoId;
764 } elseif ( isset( $item->id ) && isset( $item->id->videoId ) ) {
765 $video->id = $item->id->videoId;
766 } elseif ( isset( $item->id ) ) {
767 $video->id = $item->id;
768 }
769
770 // Video channel ID
771 $video->channel_id = '';
772
773 if ( isset( $item->snippet->channelId ) ) {
774 $video->channel_id = $item->snippet->channelId;
775 }
776
777 // Video title
778 $video->title = $item->snippet->title;
779
780 // Video description
781 $video->description = $item->snippet->description;
782
783 // Video thumbnails
784 if ( isset( $item->snippet->thumbnails ) ) {
785 $video->thumbnails = $item->snippet->thumbnails;
786 }
787
788 // Video publish date
789 $video->published_at = $item->snippet->publishedAt;
790
791 // Push resulting object to the main array
792 $status = 'private';
793
794 if ( isset( $item->status ) && ( 'public' == $item->status->privacyStatus || 'unlisted' == $item->status->privacyStatus ) ) {
795 $status = 'public';
796 }
797
798 if ( isset( $item->snippet->status ) && ( 'public' == $item->snippet->status->privacyStatus || 'unlisted' == $item->snippet->status->privacyStatus ) ) {
799 $status = 'public';
800 }
801
802 if ( 'youtube#searchResult' == $item->kind ) {
803 $status = 'public';
804 }
805
806 if ( 'public' == $status ) {
807 $videos[] = $video;
808 }
809 }
810
811 if ( 0 == count( $videos ) ) {
812 return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
813 }
814
815 return $videos;
816 }
817
818 /**
819 * Parse page info from the YouTube API response object.
820 *
821 * @since 1.0.0
822 * @access private
823 * @param object $data YouTube API response object.
824 * @return array
825 */
826 private function parse_page_info( $data ) {
827 $page_info = array();
828
829 // Total count of videos found
830 if ( isset( $data->pageInfo ) && isset( $data->pageInfo->totalResults ) ) {
831 $page_info['videos_found'] = $data->pageInfo->totalResults;
832 }
833
834 // Token for the previous page
835 if ( isset( $data->prevPageToken ) ) {
836 $page_info['prev_page_token'] = $data->prevPageToken;
837 }
838
839 // Token for the next page
840 if ( isset( $data->nextPageToken ) ) {
841 $page_info['next_page_token'] = $data->nextPageToken;
842 }
843
844 return $page_info;
845 }
846
847 /**
848 * Combine user params with known params and fill in defaults when needed.
849 *
850 * @since 1.0.0
851 * @access private
852 * @param array $pairs Entire list of supported params and their defaults.
853 * @param array $params User defined params.
854 * @return array $out Combined and filtered params array.
855 */
856 private function safe_merge_params( $pairs, $params ) {
857 $params = (array) $params;
858 $out = array();
859
860 foreach ( $pairs as $name => $default ) {
861 if ( array_key_exists( $name, $params ) ) {
862 $out[ $name ] = $params[ $name ];
863 } else {
864 $out[ $name ] = $default;
865 }
866
867 if ( empty( $out[ $name ] ) ) {
868 unset( $out[ $name ] );
869 }
870 }
871
872 return $out;
873 }
874
875 /**
876 * Build error object.
877 *
878 * @since 1.0.0
879 * @access private
880 * @param string $message Error message.
881 * @return object Error object.
882 */
883 private function get_error( $message ) {
884 $obj = new stdClass();
885 $obj->error = 1;
886 $obj->error_message = $message;
887
888 return $obj;
889 }
890
891 }
892