PluginProbe
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels / 2.6.4
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels v2.6.4
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
← All changes | includes/youtube-api.php +375 -117 2.1.02.6.4 View file →
@@ -30,8 +30,26 @@
30 30 */
31 31 protected $api_key;
32 32
33 33 /**
34 + * Array of query params.
35 + *
36 + * @since 2.5.7
37 + * @access protected
38 + * @var array
39 + */
40 + protected $params = array();
41 +
42 + /**
43 + * Is development mode enabled?
44 + *
45 + * @since 2.3.0
46 + * @access protected
47 + * @var bool
48 + */
49 + protected $is_development_mode = false;
50 +
51 + /**
34 52 * The YouTube API URLs.
35 53 *
36 54 * @since 1.0.0
37 55 * @access protected
@@ -44,21 +62,12 @@
44 62 'videos.list' => 'https://www.googleapis.com/youtube/v3/videos'
45 63 );
46 64
47 65 /**
48 - * Is API cache enabled?
49 - *
50 - * @since 2.0.0
51 - * @access protected
52 - * @var bool
53 - */
54 - protected $cache_api_results = true;
55 -
56 - /**
57 66 * Get videos.
58 67 *
59 68 * @since 1.0.0
60 - * @param array $params Array of query params.
69 + * @param array $params Array of query params.
61 70 * @return mixed
62 71 */
63 72 public function query( $params = array() ) {
64 73 // Get YouTube API Key
@@ -64,21 +73,27 @@
64 73 // Get YouTube API Key
65 74 $general_settings = get_option( 'ayg_general_settings' );
66 75
67 76 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/' ) );
77 + return $this->get_error( __( 'YouTube API key not found.', 'automatic-youtube-gallery' ) . ' ' . sprintf( __( 'Kindly follow this URL <a href="%s" target="_blank" rel="noopener noreferrer">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 78 }
70 79
71 80 $this->api_key = $general_settings['api_key'];
81 + $this->params = $params;
72 82
73 - // Is API cache enabled?
83 + // Is development mode enabled?
74 84 if ( isset( $general_settings['development_mode'] ) && ! empty( $general_settings['development_mode'] ) ) {
75 - $this->cache_api_results = false;
85 + $this->is_development_mode = true;
76 86 }
77 87
78 88 // Process output
79 89 $response = array();
80 90
91 + if ( ! empty( $params['searchTerm'] ) ) {
92 + $response = $this->get_videos_from_db( $params );
93 + return $response;
94 + }
95 +
81 96 switch ( $params['type'] ) {
82 97 case 'playlist':
83 98 if ( empty( $params['src'] ) ) {
84 99 return $this->get_error( __( 'YouTube Playlist ID (or) URL is required.', 'automatic-youtube-gallery' ) );
@@ -97,16 +112,22 @@
97 112 if ( empty( $params['id'] ) ) {
98 113 return $this->get_error( __( 'Invalid YouTube Channel ID.', 'automatic-youtube-gallery' ) );
99 114 }
100 115
101 - // Find playlistId from the channel
102 - $response = $this->request_api_channels( $params );
116 + // Get playlist id from the channel
117 + $playlist_id = $this->get_playlist_id( $params );
103 118
104 - // Get videos using the playlistId
105 - if ( ! isset( $response->error ) ) {
106 - $params['src'] = $response->playlistId;
107 - $response = $this->request_api_playlist_items( $params );
119 + if ( is_object( $playlist_id ) && isset( $playlist_id->error ) ) {
120 + return $playlist_id;
108 121 }
122 +
123 + if ( empty( $playlist_id ) ) {
124 + return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
125 + }
126 +
127 + // Get videos using the playlist id
128 + $params['src'] = $playlist_id;
129 + $response = $this->request_api_playlist_items( $params );
109 130 break;
110 131
111 132 case 'username':
112 133 if ( empty( $params['src'] ) ) {
@@ -112,22 +133,28 @@
112 133 if ( empty( $params['src'] ) ) {
113 134 return $this->get_error( __( 'YouTube Account Username is required.', 'automatic-youtube-gallery' ) );
114 135 }
115 136
116 - // Find playlistId from the channel
137 + // Get playlist id from the channel
117 138 $params['forUsername'] = $this->parse_youtube_id_from_url( $params['src'], 'username' );
118 - $response = $this->request_api_channels( $params );
139 + $playlist_id = $this->get_playlist_id( $params );
119 140
120 - // Get videos using the playlistId
121 - if ( ! isset( $response->error ) ) {
122 - $params['src'] = $response->playlistId;
123 - $response = $this->request_api_playlist_items( $params );
141 + if ( is_object( $playlist_id ) && isset( $playlist_id->error ) ) {
142 + return $playlist_id;
124 143 }
144 +
145 + if ( empty( $playlist_id ) ) {
146 + return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
147 + }
148 +
149 + // Get videos using the playlist id
150 + $params['src'] = $playlist_id;
151 + $response = $this->request_api_playlist_items( $params );
125 152 break;
126 153
127 154 case 'search':
128 155 if ( empty( $params['src'] ) ) {
129 - return $this->get_error( __( 'Cannot search an empty string. A search term is required.', 'automatic-youtube-gallery' ) );
156 + return $this->get_error( __( 'Cannot search an empty string. A search keyword is required.', 'automatic-youtube-gallery' ) );
130 157 }
131 158
132 159 $response = $this->request_api_search( $params );
133 160 break;
@@ -144,14 +171,16 @@
144 171 if ( empty( $params['src'] ) ) {
145 172 return $this->get_error( __( 'YouTube Channel ID (or) or a YouTube Video URL from the Channel is required.', 'automatic-youtube-gallery' ) );
146 173 }
147 174
148 - $response = new stdClass();
149 - $response->id = $this->get_channel_id( $params );
175 + $params['channelId'] = $this->get_channel_id( $params );
150 176
151 - if ( empty( $response->id ) ) {
177 + if ( empty( $params['channelId'] ) ) {
152 178 return $this->get_error( __( 'Invalid YouTube Channel ID.', 'automatic-youtube-gallery' ) );
153 179 }
180 +
181 + // Get live video using the channel id
182 + $response = $this->request_api_live_video( $params );
154 183 break;
155 184
156 185 default: // video
157 186 if ( empty( $params['src'] ) ) {
@@ -179,9 +208,9 @@
179 208 $id = $url;
180 209
181 210 switch ( $type ) {
182 211 case 'playlist':
183 - if ( preg_match( '/list=(.*)&?\/?/', $url, $matches ) ) {
212 + if ( preg_match( '/[?&]list=([^&]+)/', $url, $matches ) ) {
184 213 $id = $matches[1];
185 214 }
186 215 break;
187 216
@@ -205,14 +234,18 @@
205 234 }
206 235 break;
207 236
208 237 default: // video
238 + if ( wp_http_validate_url( $id ) ) {
239 + $id = '';
240 + }
241 +
209 242 $url = parse_url( $url );
210 243
211 244 if ( array_key_exists( 'host', $url ) ) {
212 245 if ( 0 === strcasecmp( $url['host'], 'youtu.be' ) ) {
213 246 $id = substr( $url['path'], 1 );
214 - } elseif ( 0 === strcasecmp( $url['host'], 'www.youtube.com' ) ) {
247 + } elseif ( 0 === strcasecmp( $url['host'], 'www.youtube.com' ) || 0 === strcasecmp( $url['host'], 'youtube.com' ) ) {
215 248 if ( isset( $url['query'] ) ) {
216 249 parse_str( $url['query'], $url['query'] );
217 250
218 251 if ( isset( $url['query']['v'] ) ) {
@@ -221,10 +254,9 @@
221 254 }
222 255
223 256 if ( empty( $id ) ) {
224 257 $url['path'] = explode( '/', substr( $url['path'], 1 ) );
225 -
226 - if ( in_array( $url['path'][0], array( 'e', 'embed', 'v' ) ) ) {
258 + if ( in_array( $url['path'][0], array( 'e', 'embed', 'v', 'shorts', 'live' ) ) ) {
227 259 $id = $url['path'][1];
228 260 }
229 261 }
230 262 }
@@ -242,16 +274,55 @@
242 274 * @param array $params Array of query params.
243 275 * @return string
244 276 */
245 277 private function get_channel_id( $params = array() ) {
278 + // Parse channel ID from URL: https://www.youtube.com/channel/XXXXXXXXXX
246 279 $id = $this->parse_youtube_id_from_url( $params['src'], 'channel' );
247 280
248 281 if ( empty( $id ) ) {
249 - $response = $this->request_api_video( $params );
282 + // Get channel ID from a Video URL: https://www.youtube.com/watch?v=XXXXXXXXXX
283 + $video_id = $this->parse_youtube_id_from_url( $params['src'], 'video' );
250 284
251 - if ( isset( $response->videos ) ) {
252 - $id = $response->videos[0]->channel_id;
285 + // Request from cache
286 + $channel_ids = get_option( 'ayg_channel_ids', array() );
287 + if ( ! is_array( $channel_ids ) ) {
288 + $channel_ids = (array) $channel_ids;
253 289 }
290 +
291 + if ( isset( $channel_ids[ $video_id ] ) && ! empty( $channel_ids[ $video_id ] ) ) {
292 + return $channel_ids[ $video_id ];
293 + }
294 +
295 + // Request from API
296 + $api_url = $this->get_api_url( 'videos.list' );
297 +
298 + $params['id'] = $video_id;
299 +
300 + $api_params = $this->safe_merge_params(
301 + array(
302 + 'id' => '',
303 + 'part' => 'id,snippet,contentDetails,status',
304 + 'cache' => 0
305 + ),
306 + $params
307 + );
308 +
309 + $api_response = $this->request_api( $api_url, $api_params, 'channel_id' );
310 + if ( isset( $api_response->error ) ) {
311 + return $id;
312 + }
313 +
314 + $videos = $this->parse_videos( $api_response );
315 + if ( isset( $videos->error ) ) {
316 + return $id;
317 + }
318 +
319 + // Process output
320 + if ( $id = $videos[0]->channel_id ) {
321 + // Store in cache
322 + $channel_ids[ $video_id ] = $id;
323 + update_option( 'ayg_channel_ids', $channel_ids );
324 + }
254 325 }
255 326
256 327 return $id;
257 328 }
@@ -256,8 +327,78 @@
256 327 return $id;
257 328 }
258 329
259 330 /**
331 + * Get playlist id using channels API.
332 + *
333 + * @since 1.0.0
334 + * @access private
335 + * @param array $params Array of query params.
336 + * @return mixed
337 + */
338 + private function get_playlist_id( $params = array() ) {
339 + // Request from cache
340 + $playlist_ids = get_option( 'ayg_playlist_ids', array() );
341 + if ( ! is_array( $playlist_ids ) ) {
342 + $playlist_ids = (array) $playlist_ids;
343 + }
344 +
345 + $key = '';
346 +
347 + if ( isset( $params['forUsername'] ) && ! empty( $params['forUsername'] ) ) {
348 + $key = $params['forUsername'];
349 + }
350 +
351 + if ( isset( $params['id'] ) && ! empty( $params['id'] ) ) {
352 + unset( $params['forUsername'] );
353 + $key = $params['id'];
354 + }
355 +
356 + if ( isset( $playlist_ids[ $key ] ) && ! empty( $playlist_ids[ $key ] ) ) {
357 + return $playlist_ids[ $key ];
358 + }
359 +
360 + // Request from API
361 + $api_url = $this->get_api_url( 'channels.list' );
362 +
363 + $api_params = $this->safe_merge_params(
364 + array(
365 + 'id' => '',
366 + 'forUsername' => '',
367 + 'part' => 'contentDetails',
368 + 'cache' => 0
369 + ),
370 + $params
371 + );
372 +
373 + $api_response = $this->request_api( $api_url, $api_params, 'playlist_id' );
374 + if ( isset( $api_response->error ) ) {
375 + return $api_response;
376 + }
377 +
378 + if ( ! isset( $api_response->items ) ) {
379 + return false;
380 + }
381 +
382 + $items = $api_response->items;
383 + if ( ! is_array( $items ) || count( $items ) == 0 ) {
384 + return false;
385 + }
386 +
387 + // Process output
388 + if ( $id = $items[0]->contentDetails->relatedPlaylists->uploads ) {
389 + // Store in cache
390 + $playlist_ids[ $key ] = $id;
391 + update_option( 'ayg_playlist_ids', $playlist_ids );
392 +
393 + // Return
394 + return $id;
395 + }
396 +
397 + return false;
398 + }
399 +
400 + /**
260 401 * Get videos using playlistItems API.
261 402 *
262 403 * @since 1.0.0
263 404 * @access private
@@ -295,53 +436,11 @@
295 436 $response->page_info = $this->parse_page_info( $api_response );
296 437 $response->videos = $videos;
297 438
298 439 return $response;
299 - }
440 + }
300 441
301 442 /**
302 - * Find playlistId using channels API.
303 - *
304 - * @since 1.0.0
305 - * @access private
306 - * @param array $params Array of query params.
307 - * @return mixed
308 - */
309 - private function request_api_channels( $params = array() ) {
310 - $api_url = $this->get_api_url( 'channels.list' );
311 -
312 - $api_params = $this->safe_merge_params(
313 - array(
314 - 'id' => '',
315 - 'forUsername' => '',
316 - 'part' => 'contentDetails',
317 - 'cache' => 0
318 - ),
319 - $params
320 - );
321 -
322 - $api_response = $this->request_api( $api_url, $api_params );
323 - if ( isset( $api_response->error ) ) {
324 - return $api_response;
325 - }
326 -
327 - if ( ! isset( $api_response->items ) ) {
328 - return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
329 - }
330 -
331 - $items = $api_response->items;
332 - if ( ! is_array( $items ) || count( $items ) == 0 ) {
333 - return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
334 - }
335 -
336 - // Process output
337 - $response = new stdClass();
338 - $response->playlistId = $items[0]->contentDetails->relatedPlaylists->uploads;
339 -
340 - return $response;
341 - }
342 -
343 - /**
344 443 * Get videos using search API.
345 444 *
346 445 * @since 1.0.0
347 446 * @access private
@@ -392,8 +491,50 @@
392 491 return $response;
393 492 }
394 493
395 494 /**
495 + * Get live video using search API.
496 + *
497 + * @since 2.3.7
498 + * @access private
499 + * @param array $params Array of query params.
500 + * @return mixed
501 + */
502 + private function request_api_live_video( $params = array() ) {
503 + $api_url = $this->get_api_url( 'search.list' );
504 +
505 + $params['type'] = 'video'; // Overrides user defined type value 'livestream'
506 +
507 + $api_params = $this->safe_merge_params(
508 + array(
509 + 'type' => 'video',
510 + 'eventType' => 'live',
511 + 'part' => 'snippet',
512 + 'channelId' => '',
513 + 'cache' => 0
514 + ),
515 + $params
516 + );
517 +
518 + $api_response = $this->request_api( $api_url, $api_params, 'live' );
519 + if ( isset( $api_response->error ) ) {
520 + return $api_response;
521 + }
522 +
523 + $videos = $this->parse_videos( $api_response );
524 + if ( isset( $videos->error ) ) {
525 + $livestream_settings = get_option( 'ayg_livestream_settings' );
526 + return $this->get_error( '<div class="ayg-livestream-fallback-message">' . $livestream_settings['fallback_message'] . '</div>' );
527 + }
528 +
529 + // Process output
530 + $response = new stdClass();
531 + $response->videos = $videos;
532 +
533 + return $response;
534 + }
535 +
536 + /**
396 537 * Get details of the given video ID.
397 538 *
398 539 * @since 1.0.0
399 540 * @access private
@@ -457,12 +598,9 @@
457 598 $current_page = isset( $params['pageToken'] ) ? (int) $params['pageToken'] : 1;
458 599 $current_page = max( $current_page, 1 );
459 600 $current_page = min( $current_page, $total_pages );
460 601
461 - $offset = ( $current_page - 1 ) * $params['maxResults'];
462 - if ( $offset < 0 ) {
463 - $offset = 0;
464 - }
602 + $offset = max( 0, ( $current_page - 1 ) * $params['maxResults'] );
465 603
466 604 $current_ids = array_slice( $all_ids, $offset, $params['maxResults'] );
467 605 $params['id'] = implode( ',', $current_ids );
468 606
@@ -489,9 +627,11 @@
489 627 $response = new stdClass();
490 628 $response->videos = $videos;
491 629
492 630 $response->page_info = array(
493 - 'videos_found' => $total_videos
631 + 'videos_found' => $total_videos,
632 + 'total_pages' => $total_pages,
633 + 'paged' => $current_page
494 634 );
495 635
496 636 if ( $current_page > 1 ) {
497 637 $response->page_info['prev_page_token'] = $current_page - 1;
@@ -502,8 +642,96 @@
502 642 }
503 643
504 644 return $response;
505 645 }
646 +
647 + /**
648 + * Get videos from our custom database table "{$wpdb->prefix}ayg_videos".
649 + *
650 + * @since 2.5.7
651 + * @access private
652 + * @param array $params Array of query params.
653 + * @return stdClass
654 + */
655 + private function get_videos_from_db( $params = array() ) {
656 + global $wpdb;
657 +
658 + $videos_table = $wpdb->prefix . 'ayg_videos';
659 + $galleries_table = $wpdb->prefix . 'ayg_galleries';
660 +
661 + $search_term = '%' . $wpdb->esc_like( $params['searchTerm'] ) . '%';
662 + $gallery_id = $params['uid'];
663 +
664 + // Get Total Videos Count
665 + $total_query = $wpdb->prepare(
666 + "SELECT COUNT(*)
667 + FROM $videos_table AS v
668 + INNER JOIN $galleries_table AS g ON v.id = g.video_id
669 + WHERE g.gallery_id = %s
670 + AND (v.title LIKE %s OR v.description LIKE %s)",
671 + $gallery_id, $search_term, $search_term
672 + );
673 +
674 + $total_videos = $wpdb->get_var( $total_query );
675 +
676 + if ( empty( $total_videos ) ) {
677 + return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
678 + }
679 +
680 + // Fetch Paginated Videos
681 + $limit = $params['maxResults'];
682 +
683 + $total_pages = ceil( $total_videos / $limit );
684 +
685 + $current_page = isset( $params['pageToken'] ) ? (int) $params['pageToken'] : 1;
686 + $current_page = max( $current_page, 1 );
687 + $current_page = min( $current_page, $total_pages );
688 +
689 + $offset = max( 0, ( $current_page - 1 ) * $limit );
690 +
691 + $query = $wpdb->prepare(
692 + "SELECT v.*
693 + FROM $videos_table AS v
694 + INNER JOIN $galleries_table AS g ON v.id = g.video_id
695 + WHERE g.gallery_id = %s
696 + AND (v.title LIKE %s OR v.description LIKE %s)
697 + ORDER BY v.published_at_datetime DESC
698 + LIMIT %d OFFSET %d",
699 + $gallery_id, $search_term, $search_term, $limit, $offset
700 + );
701 +
702 + $videos = $wpdb->get_results( $query );
703 +
704 + if ( empty( $videos ) ) {
705 + return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
706 + }
707 +
708 + foreach ( $videos as $index => $video ) {
709 + if ( ! empty( $video->thumbnails ) ) {
710 + $videos[ $index ]->thumbnails = maybe_unserialize( $video->thumbnails );
711 + }
712 + }
713 +
714 + // Process output
715 + $response = new stdClass();
716 + $response->videos = $videos;
717 +
718 + $response->page_info = array(
719 + 'videos_found' => $total_videos,
720 + 'total_pages' => $total_pages,
721 + 'paged' => $current_page
722 + );
723 +
724 + if ( $current_page > 1 ) {
725 + $response->page_info['prev_page_token'] = $current_page - 1;
726 + }
727 +
728 + if ( $current_page < $total_pages ) {
729 + $response->page_info['next_page_token'] = $current_page + 1;
730 + }
731 +
732 + return $response;
733 + }
506 734
507 735 /**
508 736 * Get API URL by request.
509 737 *
@@ -520,32 +748,23 @@
520 748 * Request data from the API server.
521 749 *
522 750 * @since 1.0.0
523 751 * @access private
524 - * @param string $url YouTube API URL.
525 - * @param array $params Array of query params.
752 + * @param string $url YouTube API URL.
753 + * @param array $params Array of query params.
754 + * @param string $context "channel_id", "playlist_id", "videos", or "live"
526 755 * @return mixed
527 756 */
528 - private function request_api( $url, $params ) {
757 + private function request_api( $url, $params, $context = 'videos' ) {
529 758 $params['key'] = $this->api_key;
530 -
531 - // Request data from cache
532 - if ( $this->cache_api_results ) {
533 - $cache_url = $url . ( strpos( $url, '?' ) === false ? '?' : '' ) . http_build_query( $params );
534 - $cache_key = 'ayg_' . md5( $cache_url );
535 - $cache_data = get_transient( $cache_key );
536 -
537 - if ( ! empty( $cache_data ) ) {
538 - return $cache_data;
539 - }
540 - }
541 -
542 - // Request data from API server
759 +
760 + // Build API URL
543 761 $cache_duration = 0;
544 762 if ( isset( $params['cache'] ) ) {
545 763 $cache_duration = (int) $params['cache'];
546 764 unset( $params['cache'] );
547 765 }
766 + $cache_duration = min( $cache_duration, 2419200 ); // Max cache duration: 1 Month
548 767
549 768 $q = '';
550 769 if ( isset( $params['q'] ) ) {
551 770 $q = $params['q'];
@@ -551,15 +770,29 @@
551 770 $q = $params['q'];
552 771 unset( $params['q'] );
553 772 }
554 773
555 - $url = $url . ( strpos( $url, '?' ) === false ? '?' : '' ) . http_build_query( $params );
774 + $api_url = $url . ( strpos( $url, '?' ) === false ? '?' : '&' ) . http_build_query( $params );
556 775 if ( ! empty( $q ) ) {
557 - $url .= '&q=' . $q;
776 + $api_url .= '&q=' . $q;
558 777 }
559 778
560 - $request = wp_remote_get( $url, array(
779 + // Request from cache
780 + if ( ! $this->is_development_mode && $cache_duration > 0 ) {
781 + $cache_key = 'ayg_' . md5( $api_url );
782 + $cache_data = get_transient( $cache_key );
783 +
784 + if ( ! empty( $cache_data ) ) {
785 + return $cache_data;
786 + }
787 + }
788 +
789 + // Request from API
790 + $timeout = apply_filters( 'ayg_api_request_timeout', 15 );
791 +
792 + $request = wp_remote_get( $api_url, array(
561 793 'headers' => [ 'referer' => home_url() ],
794 + 'timeout' => $timeout, // Increase timeout if needed
562 795 ) );
563 796
564 797 if ( is_wp_error( $request ) ) {
565 798 return $this->get_error( $request->get_error_message() );
@@ -565,10 +798,13 @@
565 798 return $this->get_error( $request->get_error_message() );
566 799 }
567 800
568 801 $body = wp_remote_retrieve_body( $request );
802 + $data = json_decode( $body );
569 803
570 - $data = json_decode( $body );
804 + if ( empty( $data ) ) {
805 + return $this->get_error( __( 'Empty or invalid API response', 'automatic-youtube-gallery' ) );
806 + }
571 807
572 808 if ( isset( $data->error ) ) {
573 809 $message = "Error " . $data->error->code . " " . $data->error->message;
574 810
@@ -578,10 +814,24 @@
578 814
579 815 return $this->get_error( $message );
580 816 }
581 817
582 - // Store data in cache (transients)
583 - if ( $this->cache_api_results && $cache_duration > 0 ) {
818 + // Store in cache (transients)
819 + $cache_enabled = false;
820 +
821 + if ( ! $this->is_development_mode && $cache_duration > 0 ) {
822 + if ( 'videos' === $context ) {
823 + if ( ! empty( $data->items ) && is_array( $data->items ) ) {
824 + $cache_enabled = true;
825 + }
826 + }
827 +
828 + if ( 'live' === $context ) {
829 + $cache_enabled = true;
830 + }
831 + }
832 +
833 + if ( $cache_enabled ) {
584 834 set_transient( $cache_key, $data, $cache_duration );
585 835
586 836 // Get the current list of transients
587 837 $cache_keys = get_option( 'ayg_transient_keys', array() );
@@ -598,9 +848,9 @@
598 848 update_option( 'ayg_transient_keys', $cache_keys );
599 849 }
600 850
601 851 // Store videos in our custom database table "{$wpdb->prefix}ayg_videos"
602 - ayg_db_store_videos( $data );
852 + ayg_db_store_videos( $data, $this->params );
603 853
604 854 // Finally return the data
605 855 return $data;
606 856 }
@@ -613,17 +863,13 @@
613 863 * @param object $data YouTube API response object.
614 864 * @return mixed
615 865 */
616 866 private function parse_videos( $data ) {
617 - if ( ! isset( $data->items ) ) {
867 + if ( empty( $data->items ) || ! is_array( $data->items ) ) {
618 868 return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
619 869 }
620 870
621 - $items = $data->items;
622 - if ( ! is_array( $items ) || 0 == count( $items ) ) {
623 - return $this->get_error( __( 'No videos found matching your query.', 'automatic-youtube-gallery' ) );
624 - }
625 -
871 + $items = $data->items;
626 872 $videos = array();
627 873
628 874 foreach ( $items as $item ) {
629 875 $video = new stdClass();
@@ -697,14 +943,26 @@
697 943 * @param object $data YouTube API response object.
698 944 * @return array
699 945 */
700 946 private function parse_page_info( $data ) {
701 - $page_info = array();
947 + $page_info = array(
948 + 'videos_found' => 0
949 + );
702 950
703 - // Total count of videos found
951 + // Total number of videos found
704 952 if ( isset( $data->pageInfo ) && isset( $data->pageInfo->totalResults ) ) {
705 - $page_info['videos_found'] = $data->pageInfo->totalResults;
706 - }
953 + $page_info['videos_found'] = (int) $data->pageInfo->totalResults;
954 + }
955 +
956 + // Calculate total number of pages
957 + if ( $page_info['videos_found'] > 0 ) {
958 + if ( 'search' == $this->params['type'] ) {
959 + $limit = min( (int) $this->params['limit'], $page_info['videos_found'] );
960 + $page_info['total_pages'] = ceil( $limit / (int) $this->params['maxResults'] );
961 + } else {
962 + $page_info['total_pages'] = ceil( $page_info['videos_found'] / (int) $this->params['maxResults'] );
963 + }
964 + }
707 965
708 966 // Token for the previous page
709 967 if ( isset( $data->prevPageToken ) ) {
710 968 $page_info['prev_page_token'] = $data->prevPageToken;