PluginProbe
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels / 2.3.3
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels v2.3.3
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.3, at includes/youtube-api.php

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