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/functions.php +322 -99 2.4.32.6.4 View file →
@@ -21,21 +21,30 @@
21 21 * @param array $args An array of gallery options.
22 22 * @return mixed
23 23 */
24 24 function ayg_build_gallery( $args ) {
25 + $general_settings = get_option( 'ayg_general_settings' );
26 + $strings_settings = get_option( 'ayg_strings_settings' );
27 +
25 28 global $post;
26 29
27 30 // Vars
28 - $fields = ayg_get_editor_fields();
31 + $fields = ayg_get_editor_fields();
32 + $excluded_fields = array( 'popup' ); // Fields not part of attributes
29 33 $defaults = array();
30 34
31 35 foreach ( $fields as $key => $value ) {
32 36 foreach ( $value['fields'] as $field ) {
37 + if ( in_array( $field['name'], $excluded_fields ) ) {
38 + continue;
39 + }
40 +
33 41 $defaults[ $field['name'] ] = $field['value'];
34 42 }
35 43 }
36 44
37 - $attributes = shortcode_atts( $defaults, $args );
45 + $defaults = array_merge( $defaults, (array) $strings_settings );
46 + $attributes = shortcode_atts( $defaults, $args, 'automatic_youtube_gallery' );
38 47
39 48 $attributes['post_id'] = 0;
40 49 if ( isset( $post->ID ) ) {
41 50 $attributes['post_id'] = (int) $post->ID;
@@ -60,19 +69,36 @@
60 69 if ( 'livestream' == $source_type ) {
61 70 $attributes['livestream'] = $attributes['channel'];
62 71 }
63 72
73 + $attributes['lazyload'] = 0;
74 + if ( ! empty( $general_settings['lazyload'] ) ) {
75 + $attributes['lazyload'] = 1;
76 + }
77 +
78 + $source_url = sanitize_text_field( $attributes[ $source_type ] );
79 +
64 80 if ( isset( $args['uid'] ) && ! empty( $args['uid'] ) ) {
65 - $attributes['uid'] = $args['uid'];
81 + $attributes['uid'] = sanitize_text_field( $args['uid'] );
66 82 } else {
67 - $attributes['uid'] = md5( $source_type . sanitize_text_field( $attributes[ $source_type ] ) . sanitize_text_field( $attributes['theme'] ) );
83 + $attributes['uid'] = md5( $source_type . $source_url );
68 84 }
69 85
86 + $attributes['uid'] = apply_filters( 'ayg_gallery_id', $attributes['uid'], $args );
87 +
88 + // Deprecated since v2.5.8. Retained for backward compatibility.
89 + $deprecated_uid = md5( $source_type . $source_url . sanitize_text_field( $attributes['theme'] ) ); // Deprecated
90 + if ( isset( $args['deprecated_uid'] ) && ! empty( $args['deprecated_uid'] ) ) {
91 + $deprecated_uid = sanitize_text_field( $args['deprecated_uid'] );
92 + }
93 +
70 94 // Get Videos
71 95 $api_params = array(
96 + 'uid' => $attributes['uid'],
72 97 'type' => $source_type,
73 - 'src' => sanitize_text_field( $attributes[ $source_type ] ),
74 - 'order' => sanitize_text_field( $attributes['order'] ), // applicable only when type=search
98 + 'src' => $source_url,
99 + 'order' => sanitize_text_field( $attributes['order'] ), // Works only when type = "search".
100 + 'limit' => $attributes['limit'], // Works only when type = "search".
75 101 'maxResults' => $attributes['per_page'],
76 102 'cache' => (int) $attributes['cache']
77 103 );
78 104
@@ -92,20 +118,16 @@
92 118 $pages[] = $page_id;
93 119 update_option( 'ayg_gallery_page_ids', $pages );
94 120 }
95 121 }
96 -
97 - // Enqueue dependencies
98 - wp_enqueue_style( AYG_SLUG . '-public' );
99 - wp_enqueue_script( AYG_SLUG . '-public' );
100 122
101 123 // Gallery
102 124 $videos = array();
103 125
104 126 $gallery_id_from_url = get_query_var( 'ayg_gallery_id' );
105 - $video_id_from_url = get_query_var( 'ayg_video_id' );
127 + $video_id_from_url = get_query_var( 'ayg_video_id' );
106 128
107 - if ( $attributes['uid'] == $gallery_id_from_url ) {
129 + if ( $attributes['uid'] == $gallery_id_from_url || $deprecated_uid == $gallery_id_from_url ) {
108 130 $video = ayg_db_get_video( $video_id_from_url );
109 131
110 132 if ( $video ) {
111 133 $videos[] = $video;
@@ -143,8 +165,16 @@
143 165 $theme = 'single';
144 166 }
145 167 }
146 168
169 + // Enqueue dependencies
170 + wp_enqueue_style( AYG_SLUG . '-public' );
171 +
172 + wp_enqueue_script( AYG_SLUG . '-public' );
173 + if ( $attributes['theme'] == $theme && 'classic' == $attributes['theme'] ) {
174 + wp_enqueue_script( AYG_SLUG . '-theme-classic' );
175 + }
176 +
147 177 // Output
148 178 ob_start();
149 179 include ayg_get_template( AYG_DIR . "public/templates/theme-{$theme}.php", $attributes['theme'] );
150 180 return ob_get_clean();
@@ -153,31 +183,90 @@
153 183 }
154 184 }
155 185
156 186 /**
157 - * Create a custom database table "{$wpdb->prefix}ayg_videos"
187 + * Combine video attributes as a string.
188 + *
189 + * @since 2.5.0
190 + * @param array $atts Array of video attributes.
191 + * @param string Combined attributes string.
192 + */
193 +function ayg_combine_video_attributes( $atts ) {
194 + $attributes = array();
195 +
196 + foreach ( $atts as $key => $value ) {
197 + if ( '' === $value ) {
198 + $attributes[] = $key;
199 + } else {
200 + $attributes[] = sprintf( '%s="%s"', $key, $value );
201 + }
202 + }
203 +
204 + return implode( ' ', $attributes );
205 +}
206 +
207 +/**
208 + * Create custom database tables
158 209 *
159 210 * @since 2.1.0
160 211 */
161 -function ayg_db_create_videos_table() {
212 +function ayg_db_create_custom_tables() {
162 213 global $wpdb;
163 214
164 - $charset_collate = $wpdb->get_charset_collate();
215 + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
216 + $charset_collate = $wpdb->get_charset_collate();
217 +
218 + $videos_table = $wpdb->prefix . 'ayg_videos';
165 219
166 - $sql = "CREATE TABLE `{$wpdb->prefix}ayg_videos` (
220 + // Check if the videos table exists
221 + $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $videos_table ) );
222 +
223 + if ( $wpdb->get_var( $query ) === $videos_table ) {
224 + // Find and remove duplicate video IDs
225 + $wpdb->query(
226 + "DELETE v1 FROM $videos_table v1
227 + INNER JOIN $videos_table v2
228 + ON v1.id = v2.id AND v1.NUM > v2.NUM"
229 + );
230 + }
231 +
232 + // Create the videos table
233 + $sql = "CREATE TABLE $videos_table (
167 234 NUM bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
168 235 id varchar(100) NOT NULL,
169 236 title text NOT NULL,
170 237 description text NOT NULL,
171 - thumbnails text NOT NULL,
238 + thumbnails text NOT NULL,
172 239 duration varchar(25) NOT NULL,
173 240 status varchar(100) NOT NULL,
174 241 published_at varchar(100) NOT NULL,
175 - PRIMARY KEY (NUM)
242 + published_at_datetime datetime NULL,
243 + PRIMARY KEY (NUM),
244 + UNIQUE KEY ayg_unique_video_id (id)
176 245 ) $charset_collate;";
177 -
178 - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
246 +
179 247 dbDelta( $sql );
248 +
249 + // Add UNIQUE KEY if it is not added
250 + $existing_keys = $wpdb->get_results( "SHOW KEYS FROM $videos_table WHERE Key_name = 'ayg_unique_video_id'" );
251 +
252 + if ( empty( $existing_keys ) ) {
253 + $wpdb->query( "ALTER TABLE $videos_table ADD UNIQUE KEY ayg_unique_video_id (id)" );
254 + }
255 +
256 + // Create the galleries table
257 + $galleries_table = $wpdb->prefix . 'ayg_galleries';
258 +
259 + $sql = "CREATE TABLE $galleries_table (
260 + NUM bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
261 + video_id varchar(100) NOT NULL,
262 + gallery_id varchar(100) NOT NULL,
263 + PRIMARY KEY (NUM),
264 + UNIQUE KEY ayg_unique_video_gallery (video_id, gallery_id),
265 + INDEX ayg_idx_gallery_id (gallery_id)
266 + ) $charset_collate;";
267 +
268 + dbDelta( $sql );
180 269 }
181 270
182 271 /**
183 272 * Store videos in our custom database table "{$wpdb->prefix}ayg_videos"
@@ -182,31 +271,27 @@
182 271 /**
183 272 * Store videos in our custom database table "{$wpdb->prefix}ayg_videos"
184 273 *
185 274 * @since 2.1.0
186 - * @param object $data YouTube API response object.
275 + * @param object $data YouTube API response object.
276 + * @param array $attributes Array of user attributes.
187 277 */
188 -function ayg_db_store_videos( $data ) {
278 +function ayg_db_store_videos( $data, $attributes = array() ) {
189 279 if ( AYG_VERSION !== get_option( 'ayg_version' ) ) {
190 280 return false;
191 281 }
192 282
193 - global $wpdb, $post;
194 -
195 - $table_name = $wpdb->prefix . 'ayg_videos';
196 -
197 283 if ( isset( $data->kind ) && 'youtube#channelListResponse' == $data->kind ) {
198 284 return false;
199 285 }
200 286
201 - if ( ! isset( $data->items ) ) {
287 + if ( empty( $data->items ) || ! is_array( $data->items ) ) {
202 288 return false;
203 289 }
204 290
291 + global $wpdb;
292 +
205 293 $items = $data->items;
206 - if ( ! is_array( $items ) || 0 == count( $items ) ) {
207 - return false;
208 - }
209 294
210 295 // Store Videos
211 296 foreach ( $items as $item ) {
212 297 $row = array();
@@ -263,26 +348,51 @@
263 348
264 349 // Video publish date
265 350 $row['published_at'] = $item->snippet->publishedAt;
266 351
267 - // Store
268 - $query = $wpdb->prepare( "SELECT NUM FROM $table_name WHERE id = %s", $row['id'] );
269 - $insert_id = $wpdb->get_var( $query );
352 + $datetime = new DateTime( $item->snippet->publishedAt );
353 + $row['published_at_datetime'] = date_format( $datetime, 'Y-m-d H:i:s' );
270 354
271 - if ( empty( $insert_id ) ) {
272 - $wpdb->insert(
273 - $table_name,
274 - $row,
275 - array( '%s', '%s', '%s', '%s', '%s', '%s', '%s' )
355 + // Store the video
356 + $videos_table = $wpdb->prefix . 'ayg_videos';
357 +
358 + $query = $wpdb->prepare(
359 + "INSERT INTO $videos_table (id, title, description, thumbnails, duration, status, published_at, published_at_datetime)
360 + VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
361 + ON DUPLICATE KEY UPDATE
362 + title = VALUES(title),
363 + description = VALUES(description),
364 + thumbnails = VALUES(thumbnails),
365 + duration = VALUES(duration),
366 + status = VALUES(status),
367 + published_at = VALUES(published_at),
368 + published_at_datetime = VALUES(published_at_datetime)",
369 + $row['id'],
370 + $row['title'],
371 + $row['description'],
372 + $row['thumbnails'],
373 + $row['duration'],
374 + $row['status'],
375 + $row['published_at'],
376 + $row['published_at_datetime']
377 + );
378 +
379 + $wpdb->query( $query );
380 +
381 + // Store the gallery association
382 + $gallery_id = isset( $attributes['uid'] ) ? $attributes['uid'] : '';
383 + $source_type = isset( $attributes['type'] ) ? $attributes['type'] : 'videos';
384 +
385 + if ( ! empty( $gallery_id ) && ! in_array( $source_type, array( 'video', 'livestream' ) ) ) {
386 + $galleries_table = $wpdb->prefix . 'ayg_galleries';
387 +
388 + $query = $wpdb->prepare(
389 + "INSERT IGNORE INTO $galleries_table (video_id, gallery_id) VALUES (%s, %s)",
390 + $row['id'],
391 + $gallery_id
276 392 );
277 - } else {
278 - $wpdb->update(
279 - $table_name,
280 - $row,
281 - array( 'NUM' => $insert_id ),
282 - array( '%s', '%s', '%s', '%s', '%s', '%s', '%s' ),
283 - array( '%d' )
284 - );
393 +
394 + $wpdb->query( $query );
285 395 }
286 396 }
287 397 }
288 398
@@ -357,10 +467,18 @@
357 467 function ayg_get_default_settings() {
358 468 $defaults = array(
359 469 'ayg_general_settings' => array(
360 470 'api_key' => '',
361 - 'development_mode' => 1
471 + 'lazyload' => 0,
472 + 'development_mode' => 0
362 473 ),
474 + 'ayg_strings_settings' => array(
475 + 'more_button_label' => __( 'Load More', 'automatic-youtube-gallery' ),
476 + 'previous_button_label' => __( 'Previous', 'automatic-youtube-gallery' ),
477 + 'next_button_label' => __( 'Next', 'automatic-youtube-gallery' ),
478 + 'show_more_label' => __( 'Show More', 'automatic-youtube-gallery' ),
479 + 'show_less_label' => __( 'Show Less', 'automatic-youtube-gallery' )
480 + ),
363 481 'ayg_gallery_settings' => array(
364 482 'theme' => 'classic',
365 483 'columns' => 3,
366 484 'per_page' => 12,
@@ -370,13 +488,13 @@
370 488 'thumb_excerpt' => 1,
371 489 'thumb_excerpt_length' => 75,
372 490 'pagination' => 1,
373 491 'pagination_type' => 'more',
374 - 'more_button_label' => __( 'Load More', 'automatic-youtube-gallery' ),
375 - 'previous_button_label' => __( 'Previous', 'automatic-youtube-gallery' ),
376 - 'next_button_label' => __( 'Next', 'automatic-youtube-gallery' )
492 + 'scroll_top_offset' => 10
377 493 ),
378 494 'ayg_player_settings' => array(
495 + 'player_type' => 'youtube',
496 + 'player_color' => '#00b3ff',
379 497 'player_width' => '',
380 498 'player_ratio' => 56.25,
381 499 'player_title' => 1,
382 500 'player_description' => 1,
@@ -513,8 +631,9 @@
513 631 'label' => __( 'Cache Duration', 'automatic-youtube-gallery' ),
514 632 'description' => __( 'Specifies how frequently we should check your YouTube source for new videos/updates.', 'automatic-youtube-gallery' ),
515 633 'type' => 'select',
516 634 'options' => array(
635 + '0' => '— '. __( 'No Caching', 'automatic-youtube-gallery' ) . ' —',
517 636 '900' => __( '15 Minutes', 'automatic-youtube-gallery' ),
518 637 '1800' => __( '30 Minutes', 'automatic-youtube-gallery' ),
519 638 '3600' => __( '1 Hour', 'automatic-youtube-gallery' ),
520 639 '86400' => __( '1 Day', 'automatic-youtube-gallery' ),
@@ -532,8 +651,24 @@
532 651 ),
533 652 'player' => array(
534 653 'label' => __( 'Player (optional)', 'automatic-youtube-gallery' ),
535 654 'fields' => ayg_get_player_settings_fields()
655 + ),
656 + 'search' => array(
657 + 'label' => __( 'Search Form (optional)', 'automatic-youtube-gallery' ),
658 + 'fields' => array(
659 + array(
660 + 'name' => 'search_form',
661 + 'label' => __( 'Search Form', 'automatic-youtube-gallery' ),
662 + 'description' => sprintf(
663 + __( 'Check this option to enable the search form. Having issues? <a href="%s" target="_blank" rel="noopener noreferrer">Check here</a>.', 'automatic-youtube-gallery' ),
664 + 'https://plugins360.com/automatic-youtube-gallery/searchform/'
665 + ),
666 + 'type' => 'checkbox',
667 + 'value' => 0,
668 + 'sanitize_callback' => 'intval'
669 + )
670 + )
536 671 )
537 672 );
538 673
539 674 return apply_filters( 'ayg_editor_fields', $fields );
@@ -646,32 +781,8 @@
646 781
647 782 ),
648 783 'value' => $gallery_settings['pagination_type'],
649 784 'sanitize_callback' => 'sanitize_key'
650 - ),
651 - array(
652 - 'name' => 'more_button_label',
653 - 'label' => __( 'More Button Label', 'automatic-youtube-gallery' ),
654 - 'description' => __( 'Enter the more button label text.', 'automatic-youtube-gallery' ),
655 - 'type' => 'text',
656 - 'value' => isset( $gallery_settings['more_button_label'] ) ? $gallery_settings['more_button_label'] : __( 'Load More', 'automatic-youtube-gallery' ),
657 - 'sanitize_callback' => 'sanitize_text_field'
658 - ),
659 - array(
660 - 'name' => 'previous_button_label',
661 - 'label' => __( 'Previous Button Label', 'automatic-youtube-gallery' ),
662 - 'description' => __( 'Enter the previous button label text.', 'automatic-youtube-gallery' ),
663 - 'type' => 'text',
664 - 'value' => isset( $gallery_settings['previous_button_label'] ) ? $gallery_settings['previous_button_label'] : __( 'Previous', 'automatic-youtube-gallery' ),
665 - 'sanitize_callback' => 'sanitize_text_field'
666 - ),
667 - array(
668 - 'name' => 'next_button_label',
669 - 'label' => __( 'Next Button Label', 'automatic-youtube-gallery' ),
670 - 'description' => __( 'Enter the next button label text.', 'automatic-youtube-gallery' ),
671 - 'type' => 'text',
672 - 'value' => isset( $gallery_settings['next_button_label'] ) ? $gallery_settings['next_button_label'] : __( 'Next', 'automatic-youtube-gallery' ),
673 - 'sanitize_callback' => 'sanitize_text_field'
674 785 )
675 786 );
676 787
677 788 return apply_filters( 'ayg_gallery_settings_fields', $fields );
@@ -681,26 +792,28 @@
681 792 * Get video description to show on top of the player.
682 793 *
683 794 * @since 1.0.0
684 795 * @param stdClass $video YouTube video object.
796 + * @param array $attributes Array of user attributes.
685 797 * @param int $words_count Number of words to show by default.
686 798 * @return string Video description.
687 799 */
688 -function ayg_get_player_description( $video, $words_count = 30 ) {
800 +function ayg_get_player_description( $video, $attributes = array(), $words_count = 30 ) {
689 801 $description = $video->description;
690 802
691 803 $words_array = explode( ' ', strip_tags( $description ) );
692 804 if ( count( $words_array ) > $words_count ) {
805 + $show_more_label = ! empty( $attributes['show_more_label'] ) ? $attributes['show_more_label'] : __( 'Show More', 'automatic-youtube-gallery' );
693 806 $words_array[ $words_count ] = '<span class="ayg-player-description-dots">...</span></span><span class="ayg-player-description-more">' . $words_array[ $words_count ];
694 807
695 808 $description = '<span class="ayg-player-description-less">' . implode( ' ', $words_array ) . '</span>';
696 - $description .= '<a href="#" class="ayg-player-description-toggle-btn">[+] ' . __( 'Show More', 'automatic-youtube-gallery' ) . '</a>';
809 + $description .= '<a href="#" class="ayg-player-description-toggle-btn">' . esc_html( $show_more_label ) . '</a>';
697 810 }
698 811
699 812 $description = nl2br( $description );
700 813 $description = make_clickable( $description );
701 814
702 - return apply_filters( 'ayg_player_description', $description, $video, $words_count );
815 + return apply_filters( 'ayg_player_description', $description, $video, $attributes, $words_count );
703 816 }
704 817
705 818 /**
706 819 * Get player settings fields.
@@ -832,25 +945,9 @@
832 945 ),
833 946 'type' => 'text',
834 947 'value' => $player_settings['cc_lang_pref'],
835 948 'sanitize_callback' => 'sanitize_text_field'
836 - ),
837 - array(
838 - 'name' => 'privacy_enhanced_mode',
839 - 'label' => __( 'Privacy Enhanced Mode', 'automatic-youtube-gallery' ),
840 - 'description' => __( "Prevent YouTube from leaving tracking cookies on your visitor's browsers unless they actually play the videos. Please uncheck this option if you see errors while testing your playlist embeds or watching your videos on mobile.", 'automatic-youtube-gallery' ),
841 - 'type' => 'checkbox',
842 - 'value' => isset( $player_settings['privacy_enhanced_mode'] ) ? $player_settings['privacy_enhanced_mode'] : 0,
843 - 'sanitize_callback' => 'intval'
844 - ),
845 - array(
846 - 'name' => 'origin',
847 - 'label' => __( 'Extra Player Security', 'automatic-youtube-gallery' ),
848 - 'description' => __( 'Add site origin information with each embed code as an extra security measure. In YouTube\'s own words, checking this option "protects against malicious third-party JavaScript being injected into your page and hijacking control of your YouTube player."', 'automatic-youtube-gallery' ),
849 - 'type' => 'checkbox',
850 - 'value' => isset( $player_settings['origin'] ) ? $player_settings['origin'] : 0,
851 - 'sanitize_callback' => 'intval'
852 - ),
949 + )
853 950 );
854 951
855 952 return $fields;
856 953 }
@@ -913,8 +1010,88 @@
913 1010 return $domain;
914 1011 }
915 1012
916 1013 /**
1014 + * Get the YouTube embed URL.
1015 + *
1016 + * @since 2.5.0
1017 + * @param string $video_id YouTube video ID.
1018 + * @param array $attributes Array of user attributes.
1019 + * @return string Player embed URL.
1020 + */
1021 +function ayg_get_youtube_embed_url( $video_id, $attributes = array() ) {
1022 + $player_settings = get_option( 'ayg_player_settings' );
1023 +
1024 + $player_website = 'https://www.youtube.com';
1025 + if ( isset( $player_settings['privacy_enhanced_mode'] ) && ! empty( $player_settings['privacy_enhanced_mode'] ) ) {
1026 + $player_website = 'https://www.youtube-nocookie.com';
1027 + }
1028 +
1029 + if ( empty( $video_id ) ) {
1030 + return '';
1031 + }
1032 +
1033 + $url = $player_website . '/embed/' . $video_id . '?enablejsapi=1&playsinline=1&rel=0';
1034 +
1035 + if ( isset( $player_settings['origin'] ) && ! empty( $player_settings['origin'] ) ) {
1036 + $site_url_parts = parse_url( site_url() );
1037 + $origin = $site_url_parts['scheme'] . '://' . $site_url_parts['host'];
1038 +
1039 + $url = add_query_arg( 'origin', $origin, $url );
1040 + }
1041 +
1042 + if ( ! is_array( $attributes ) ) {
1043 + $attributes = (array) $attributes;
1044 + }
1045 +
1046 + $autoplay = isset( $attributes['autoplay'] ) ? (int) $attributes['autoplay'] : 0;
1047 + if ( 1 == $autoplay ) {
1048 + $url = add_query_arg( 'autoplay', 1, $url );
1049 + }
1050 +
1051 + $loop = isset( $attributes['loop'] ) ? (int) $attributes['loop'] : 0;
1052 + if ( 1 == $loop ) {
1053 + $url = add_query_arg( 'playlist', $video_id, $url );
1054 + $url = add_query_arg( 'loop', 1, $url );
1055 + }
1056 +
1057 + $muted = isset( $attributes['muted'] ) ? (int) $attributes['muted'] : 0;
1058 + if ( 1 == $muted ) {
1059 + $url = add_query_arg( 'mute', 1, $url );
1060 + }
1061 +
1062 + $controls = isset( $attributes['controls'] ) ? (int) $attributes['controls'] : 1;
1063 + if ( 0 == $controls ) {
1064 + $url = add_query_arg( 'controls', 0, $url );
1065 + }
1066 +
1067 + $modestbranding = isset( $attributes['modestbranding'] ) ? (int) $attributes['modestbranding'] : 0;
1068 + if ( 1 == $modestbranding ) {
1069 + $url = add_query_arg( 'modestbranding', 1, $url );
1070 + }
1071 +
1072 + $cc_load_policy = isset( $attributes['cc_load_policy'] ) ? (int) $attributes['cc_load_policy'] : 0;
1073 + if ( 1 == $cc_load_policy ) {
1074 + $url = add_query_arg( 'cc_load_policy', 1, $url );
1075 + }
1076 +
1077 + $iv_load_policy = isset( $attributes['iv_load_policy'] ) ? (int) $attributes['iv_load_policy'] : 0;
1078 + if ( 0 == $iv_load_policy ) {
1079 + $url = add_query_arg( 'iv_load_policy', 3, $url );
1080 + }
1081 +
1082 + if ( isset( $attributes['hl'] ) && ! empty( $attributes['hl'] ) ) {
1083 + $url = add_query_arg( 'hl', sanitize_text_field( $attributes['hl'] ), $url );
1084 + }
1085 +
1086 + if ( isset( $attributes['cc_lang_pref'] ) && ! empty( $attributes['cc_lang_pref'] ) ) {
1087 + $url = add_query_arg( 'cc_lang_pref', sanitize_text_field( $attributes['cc_lang_pref'] ), $url );
1088 + }
1089 +
1090 + return apply_filters( 'ayg_youtube_embed_url', $url, $video_id, $attributes );
1091 +}
1092 +
1093 +/**
917 1094 * Inserts a new associative array after another associative array key.
918 1095 *
919 1096 * @since 2.1.0
920 1097 * @param string $key The associative array key to insert after.
@@ -942,8 +1119,31 @@
942 1119 return $array;
943 1120 }
944 1121
945 1122 /**
1123 + * Detect if the client is using an iOS device (iPhone, iPad, or iPod).
1124 + *
1125 + * @return bool True if the user agent string suggests an iOS device, false otherwise.
1126 + */
1127 +function ayg_is_ios() {
1128 + if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
1129 + return false;
1130 + }
1131 +
1132 + $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1133 +
1134 + if (
1135 + strpos( $ua, 'iphone' ) !== false ||
1136 + strpos( $ua, 'ipad' ) !== false ||
1137 + strpos( $ua, 'ipod' ) !== false
1138 + ) {
1139 + return true;
1140 + }
1141 +
1142 + return false;
1143 +}
1144 +
1145 +/**
946 1146 * Sanitize the integer inputs, accepts empty values.
947 1147 *
948 1148 * @since 1.0.0
949 1149 * @param string|int $value Input value.
@@ -988,11 +1188,11 @@
988 1188
989 1189 /**
990 1190 * Gallery HTML output.
991 1191 *
992 - * @since 1.0.0
993 - * @param array $video YouTube video object.
994 - * @param array $attributes Array of user attributes.
1192 + * @since 1.0.0
1193 + * @param array $video YouTube video object.
1194 + * @param array $attributes Array of user attributes.
995 1195 */
996 1196 function the_ayg_gallery_thumbnail( $video, $attributes ) {
997 1197 include ayg_get_template( AYG_DIR . 'public/templates/thumbnail.php' );
998 1198 }
@@ -999,12 +1199,35 @@
999 1199
1000 1200 /**
1001 1201 * Pagination HTML output.
1002 1202 *
1003 - * @since 1.0.0
1004 - * @param array $attributes Array of user attributes.
1203 + * @since 1.0.0
1204 + * @param array $attributes Array of user attributes.
1005 1205 */
1006 1206 function the_ayg_pagination( $attributes ) {
1007 1207 if ( ! empty( $attributes['pagination'] ) ) {
1008 1208 include ayg_get_template( AYG_DIR . 'public/templates/pagination.php' );
1009 1209 }
1210 +}
1211 +
1212 +/**
1213 + * Search Form HTML output.
1214 + *
1215 + * @since 2.5.7
1216 + * @param array $attributes Array of user attributes.
1217 + */
1218 +function the_ayg_search_form( $attributes ) {
1219 + if ( ! empty( $attributes['search_form'] ) ) {
1220 + include ayg_get_template( AYG_DIR . 'public/templates/search-form.php' );
1221 + }
1222 +}
1223 +
1224 +/**
1225 + * Gallery HTML output.
1226 + *
1227 + * @since 2.5.0
1228 + * @param array $video YouTube video object.
1229 + * @param array $attributes Array of user attributes.
1230 + */
1231 +function the_ayg_player( $video, $attributes ) {
1232 + include ayg_get_template( AYG_DIR . 'public/templates/player.php' );
1010 1233 }