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 +401 -112 2.1.02.6.4 View file →
@@ -21,25 +21,34 @@
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 - $attributes['post_id'] = $post->ID;
50 + $attributes['post_id'] = (int) $post->ID;
42 51 }
43 52
44 53 $attributes['columns'] = min( 12, (int) $attributes['columns'] );
45 54 if ( empty( $attributes['columns'] ) ) {
@@ -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
@@ -82,19 +108,26 @@
82 108 $response = $youtube_api->query( $api_params );
83 109
84 110 // Process output
85 111 if ( ! isset( $response->error ) ) {
86 - // Enqueue dependencies
87 - wp_enqueue_style( AYG_SLUG . '-public' );
88 - wp_enqueue_script( AYG_SLUG . '-public' );
112 + // Store Gallery ID
113 + if ( $attributes['post_id'] > 0 && isset( $attributes['deeplinking'] ) && 1 == $attributes['deeplinking'] ) {
114 + $pages = get_option( 'ayg_gallery_page_ids', array() );
115 + $page_id = $attributes['post_id'];
116 +
117 + if ( ! in_array( $page_id, $pages ) ) {
118 + $pages[] = $page_id;
119 + update_option( 'ayg_gallery_page_ids', $pages );
120 + }
121 + }
89 122
90 123 // Gallery
91 124 $videos = array();
92 125
93 - $gallery_id_from_url = get_query_var( 'ayg_gallery' );
94 - $video_id_from_url = get_query_var( 'ayg_video' );
126 + $gallery_id_from_url = get_query_var( 'ayg_gallery_id' );
127 + $video_id_from_url = get_query_var( 'ayg_video_id' );
95 128
96 - if ( $attributes['uid'] == $gallery_id_from_url ) {
129 + if ( $attributes['uid'] == $gallery_id_from_url || $deprecated_uid == $gallery_id_from_url ) {
97 130 $video = ayg_db_get_video( $video_id_from_url );
98 131
99 132 if ( $video ) {
100 133 $videos[] = $video;
@@ -132,41 +165,108 @@
132 165 $theme = 'single';
133 166 }
134 167 }
135 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 +
136 177 // Output
137 178 ob_start();
138 179 include ayg_get_template( AYG_DIR . "public/templates/theme-{$theme}.php", $attributes['theme'] );
139 180 return ob_get_clean();
140 181 } else {
141 - return '<p class="ayg-error">' . $response->error_message . '</p>';
182 + return sprintf( '<div class="ayg ayg-error">%s</div>', wp_kses_post( $response->error_message ) );
142 183 }
143 184 }
144 185
145 186 /**
146 - * 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
147 209 *
148 210 * @since 2.1.0
149 211 */
150 -function ayg_db_create_videos_table() {
212 +function ayg_db_create_custom_tables() {
151 213 global $wpdb;
152 214
153 - $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';
154 219
155 - $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 (
156 234 NUM bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
157 235 id varchar(100) NOT NULL,
158 236 title text NOT NULL,
159 237 description text NOT NULL,
160 - thumbnails text NOT NULL,
238 + thumbnails text NOT NULL,
161 239 duration varchar(25) NOT NULL,
162 240 status varchar(100) NOT NULL,
163 241 published_at varchar(100) NOT NULL,
164 - PRIMARY KEY (NUM)
242 + published_at_datetime datetime NULL,
243 + PRIMARY KEY (NUM),
244 + UNIQUE KEY ayg_unique_video_id (id)
165 245 ) $charset_collate;";
166 -
167 - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
246 +
168 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 );
169 269 }
170 270
171 271 /**
172 272 * Store videos in our custom database table "{$wpdb->prefix}ayg_videos"
@@ -171,31 +271,27 @@
171 271 /**
172 272 * Store videos in our custom database table "{$wpdb->prefix}ayg_videos"
173 273 *
174 274 * @since 2.1.0
175 - * @param object $data YouTube API response object.
275 + * @param object $data YouTube API response object.
276 + * @param array $attributes Array of user attributes.
176 277 */
177 -function ayg_db_store_videos( $data ) {
278 +function ayg_db_store_videos( $data, $attributes = array() ) {
178 279 if ( AYG_VERSION !== get_option( 'ayg_version' ) ) {
179 280 return false;
180 281 }
181 282
182 - global $wpdb, $post;
183 -
184 - $table_name = $wpdb->prefix . 'ayg_videos';
185 -
186 283 if ( isset( $data->kind ) && 'youtube#channelListResponse' == $data->kind ) {
187 284 return false;
188 285 }
189 286
190 - if ( ! isset( $data->items ) ) {
287 + if ( empty( $data->items ) || ! is_array( $data->items ) ) {
191 288 return false;
192 289 }
193 290
291 + global $wpdb;
292 +
194 293 $items = $data->items;
195 - if ( ! is_array( $items ) || 0 == count( $items ) ) {
196 - return false;
197 - }
198 294
199 295 // Store Videos
200 296 foreach ( $items as $item ) {
201 297 $row = array();
@@ -252,38 +348,53 @@
252 348
253 349 // Video publish date
254 350 $row['published_at'] = $item->snippet->publishedAt;
255 351
256 - // Store
257 - $query = $wpdb->prepare( "SELECT NUM FROM $table_name WHERE id = %s", $row['id'] );
258 - $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' );
259 354
260 - if ( empty( $insert_id ) ) {
261 - $wpdb->insert(
262 - $table_name,
263 - $row,
264 - 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
265 392 );
266 - } else {
267 - $wpdb->update(
268 - $table_name,
269 - $row,
270 - array( 'NUM' => $insert_id ),
271 - array( '%s', '%s', '%s', '%s', '%s', '%s', '%s' ),
272 - array( '%d' )
273 - );
393 +
394 + $wpdb->query( $query );
274 395 }
275 396 }
276 -
277 - // Store Page ID
278 - if ( ! is_admin() ) {
279 - if ( isset( $post->ID ) ) {
280 - $page_ids = get_option( 'ayg_gallery_page_ids', array() );
281 - $page_ids[] = (int) $post->ID;
282 -
283 - update_option( 'ayg_gallery_page_ids', array_unique( $page_ids ) );
284 - }
285 - }
286 397 }
287 398
288 399 /**
289 400 * Get a single video record from our custom database table "{$wpdb->prefix}ayg_videos"
@@ -319,8 +430,10 @@
319 430 *
320 431 * @since 2.1.0
321 432 */
322 433 function ayg_delete_cache() {
434 + delete_option( 'ayg_gallery_page_ids' );
435 +
323 436 // Get the current list of transients
324 437 $transient_keys = get_option( 'ayg_transient_keys', array() );
325 438
326 439 // For each key, delete that transient
@@ -354,43 +467,58 @@
354 467 function ayg_get_default_settings() {
355 468 $defaults = array(
356 469 'ayg_general_settings' => array(
357 470 'api_key' => '',
358 - 'development_mode' => 1
471 + 'lazyload' => 0,
472 + 'development_mode' => 0
359 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 + ),
360 481 'ayg_gallery_settings' => array(
361 - 'theme' => 'classic',
362 - 'columns' => 3,
363 - 'per_page' => 12,
364 - 'thumb_ratio' => 56.25,
365 - 'thumb_title' => 1,
366 - 'thumb_title_length' => 0,
367 - 'thumb_excerpt' => 1,
368 - 'thumb_excerpt_length' => 75,
369 - 'pagination' => 1,
370 - 'pagination_type' => 'more'
482 + 'theme' => 'classic',
483 + 'columns' => 3,
484 + 'per_page' => 12,
485 + 'thumb_ratio' => 56.25,
486 + 'thumb_title' => 1,
487 + 'thumb_title_length' => 0,
488 + 'thumb_excerpt' => 1,
489 + 'thumb_excerpt_length' => 75,
490 + 'pagination' => 1,
491 + 'pagination_type' => 'more',
492 + 'scroll_top_offset' => 10
371 493 ),
372 494 'ayg_player_settings' => array(
373 - 'player_ratio' => 56.25,
374 - 'player_title' => 1,
375 - 'player_description' => 1,
376 - 'autoplay' => 0,
377 - 'autoadvance' => 1,
378 - 'loop' => 0,
379 - 'controls' => 1,
380 - 'modestbranding' => 1,
381 - 'cc_load_policy' => 0,
382 - 'iv_load_policy' => 0,
383 - 'hl' => '',
384 - 'cc_lang_pref' => ''
495 + 'player_type' => 'youtube',
496 + 'player_color' => '#00b3ff',
497 + 'player_width' => '',
498 + 'player_ratio' => 56.25,
499 + 'player_title' => 1,
500 + 'player_description' => 1,
501 + 'autoplay' => 0,
502 + 'autoadvance' => 1,
503 + 'loop' => 0,
504 + 'muted' => 0,
505 + 'controls' => 1,
506 + 'modestbranding' => 1,
507 + 'cc_load_policy' => 0,
508 + 'iv_load_policy' => 0,
509 + 'hl' => '',
510 + 'cc_lang_pref' => '',
511 + 'privacy_enhanced_mode' => 0,
512 + 'origin' => 0
385 513 ),
386 514 'ayg_livestream_settings' => array(
387 515 'fallback_message' => __( 'Sorry, but the channel is not currently streaming live content. Please check back later.', 'automatic-youtube-gallery' )
388 516 ),
389 - 'ayg_privacy_settings' => array(
390 - 'cookie_consent' => 0,
391 - 'consent_message' => __( 'Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.', 'automatic-youtube-gallery' ),
392 - 'button_label' => __( 'Accept', 'automatic-youtube-gallery' )
517 + 'ayg_privacy_settings' => array(
518 + 'cookie_consent' => 0,
519 + 'consent_message' => __( 'Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.', 'automatic-youtube-gallery' ),
520 + 'button_label' => __( 'Accept', 'automatic-youtube-gallery' )
393 521 )
394 522 );
395 523
396 524 return $defaults;
@@ -503,14 +631,15 @@
503 631 'label' => __( 'Cache Duration', 'automatic-youtube-gallery' ),
504 632 'description' => __( 'Specifies how frequently we should check your YouTube source for new videos/updates.', 'automatic-youtube-gallery' ),
505 633 'type' => 'select',
506 634 'options' => array(
507 - '900' => __( '15 minutes', 'automatic-youtube-gallery' ),
508 - '1800' => __( '30 minutes', 'automatic-youtube-gallery' ),
635 + '0' => '— '. __( 'No Caching', 'automatic-youtube-gallery' ) . ' —',
636 + '900' => __( '15 Minutes', 'automatic-youtube-gallery' ),
637 + '1800' => __( '30 Minutes', 'automatic-youtube-gallery' ),
509 638 '3600' => __( '1 Hour', 'automatic-youtube-gallery' ),
510 639 '86400' => __( '1 Day', 'automatic-youtube-gallery' ),
511 640 '604800' => __( '1 Week', 'automatic-youtube-gallery' ),
512 - '2419200' => __( ' 1Month', 'automatic-youtube-gallery' )
641 + '2419200' => __( '1 Month', 'automatic-youtube-gallery' )
513 642 ),
514 643 'value' => 86400,
515 644 'sanitize_callback' => 'intval'
516 645 )
@@ -522,8 +651,24 @@
522 651 ),
523 652 'player' => array(
524 653 'label' => __( 'Player (optional)', 'automatic-youtube-gallery' ),
525 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 + )
526 671 )
527 672 );
528 673
529 674 return apply_filters( 'ayg_editor_fields', $fields );
@@ -541,9 +686,9 @@
541 686 $fields = array(
542 687 array(
543 688 'name' => 'theme',
544 689 'label' => __( 'Select Theme (Layout)', 'automatic-youtube-gallery' ),
545 - 'description' => ( ayg_fs()->is_not_paying() ? sprintf( __( '<a href="%s">Upgrade Pro</a> for more themes (Inline, Popup, Slider, Playlist).', 'automatic-youtube-gallery' ), esc_url( ayg_fs()->get_upgrade_url() ) ) : '' ),
690 + 'description' => ( ayg_fs()->is_not_paying() ? sprintf( __( '<a href="%s">Upgrade Pro</a> for more themes (Popup, Inline, Slider, Playlist).', 'automatic-youtube-gallery' ), esc_url( ayg_fs()->get_upgrade_url() ) ) : '' ),
546 691 'type' => 'select',
547 692 'options' => array(
548 693 'classic' => __( 'Classic', 'automatic-youtube-gallery' )
549 694 ),
@@ -647,26 +792,28 @@
647 792 * Get video description to show on top of the player.
648 793 *
649 794 * @since 1.0.0
650 795 * @param stdClass $video YouTube video object.
796 + * @param array $attributes Array of user attributes.
651 797 * @param int $words_count Number of words to show by default.
652 798 * @return string Video description.
653 799 */
654 -function ayg_get_player_description( $video, $words_count = 30 ) {
800 +function ayg_get_player_description( $video, $attributes = array(), $words_count = 30 ) {
655 801 $description = $video->description;
656 802
657 803 $words_array = explode( ' ', strip_tags( $description ) );
658 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' );
659 806 $words_array[ $words_count ] = '<span class="ayg-player-description-dots">...</span></span><span class="ayg-player-description-more">' . $words_array[ $words_count ];
660 807
661 808 $description = '<span class="ayg-player-description-less">' . implode( ' ', $words_array ) . '</span>';
662 - $description .= '<a href="javascript:void(0);" 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>';
663 810 }
664 811
665 812 $description = nl2br( $description );
666 813 $description = make_clickable( $description );
667 814
668 - return apply_filters( 'ayg_player_description', $description, $video, $words_count );
815 + return apply_filters( 'ayg_player_description', $description, $video, $attributes, $words_count );
669 816 }
670 817
671 818 /**
672 819 * Get player settings fields.
@@ -678,8 +825,16 @@
678 825 $player_settings = get_option( 'ayg_player_settings' );
679 826
680 827 $fields = array(
681 828 array(
829 + 'name' => 'player_width',
830 + 'label' => __( 'Player Width', 'automatic-youtube-gallery' ),
831 + 'description' => __( 'In pixels. Maximum width of the player. Leave this field empty to scale 100% of its enclosing container/html element.', 'automatic-youtube-gallery' ),
832 + 'type' => 'text',
833 + 'value' => isset( $player_settings['player_width'] ) ? $player_settings['player_width'] : '',
834 + 'sanitize_callback' => 'ayg_sanitize_int'
835 + ),
836 + array(
682 837 'name' => 'player_ratio',
683 838 'label' => __( 'Player Height (Ratio)', 'automatic-youtube-gallery' ),
684 839 'description' => __( 'Select the ratio value used to calculate the player height.', 'automatic-youtube-gallery' ),
685 840 'type' => 'radio',
@@ -728,10 +883,18 @@
728 883 'description' => __( 'In the case of a single video player, plays the initial video again and again. In the case of a gallery, plays the entire list in the gallery and then starts again at the first video.', 'automatic-youtube-gallery' ),
729 884 'type' => 'checkbox',
730 885 'value' => $player_settings['loop'],
731 886 'sanitize_callback' => 'intval'
732 - ),
887 + ),
733 888 array(
889 + 'name' => 'muted',
890 + 'label' => __( 'Muted', 'automatic-youtube-gallery' ),
891 + 'description' => __( 'Check this option to turn OFF the audio output of the video by default.', 'automatic-youtube-gallery' ),
892 + 'type' => 'checkbox',
893 + 'value' => isset( $player_settings['muted'] ) ? $player_settings['muted'] : 0,
894 + 'sanitize_callback' => 'intval'
895 + ),
896 + array(
734 897 'name' => 'controls',
735 898 'label' => __( 'Show Player Controls', 'automatic-youtube-gallery' ),
736 899 'description' => __( 'Uncheck this option to hide the video player controls.', 'automatic-youtube-gallery' ),
737 900 'type' => 'checkbox',
@@ -793,14 +956,14 @@
793 956 /**
794 957 * Get a single video page URL.
795 958 *
796 959 * @since 2.1.0
797 - * @param string $video_id YouTube Video ID.
798 - * @param array $args An array of gallery options.
799 - * @return string Single video URL.
960 + * @param stdClass $video YouTube video object.
961 + * @param array $args An array of gallery options.
962 + * @return string Single video URL.
800 963 */
801 -function ayg_get_single_video_url( $video_id, $attributes ) {
802 - return apply_filters( 'ayg_single_video_url', '', $video_id, $attributes );
964 +function ayg_get_single_video_url( $video, $attributes ) {
965 + return apply_filters( 'ayg_single_video_url', '', $video, $attributes );
803 966 }
804 967
805 968 /**
806 969 * Get filtered php template file path.
@@ -830,25 +993,105 @@
830 993 return uniqid() . ++$ayg_uniqid;
831 994 }
832 995
833 996 /**
834 - * Check if Yoast SEO plugin is active.
997 + * Get YouTube domain.
835 998 *
836 - * @since 2.1.0
837 - * @return bool $has_yoast True if the Yoast plugin is installed and active, false if not.
999 + * @since 2.3.0
1000 + * @return string YouTube embed domain.
838 1001 */
839 -function ayg_has_yoast() {
840 - $has_yoast = false;
1002 +function ayg_get_youtube_domain() {
1003 + $player_settings = get_option( 'ayg_player_settings' );
841 1004
842 - $active_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) );
843 - if ( in_array( 'wordpress-seo/wp-seo.php', $active_plugins ) || in_array( 'wordpress-seo-premium/wp-seo-premium.php', $active_plugins ) ) {
844 - $has_yoast = true;
1005 + $domain = 'https://www.youtube.com';
1006 + if ( isset( $player_settings['privacy_enhanced_mode'] ) && ! empty( $player_settings['privacy_enhanced_mode'] ) ) {
1007 + $domain = 'https://www.youtube-nocookie.com';
845 1008 }
846 1009
847 - return $has_yoast;
1010 + return $domain;
848 1011 }
849 1012
850 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 +/**
851 1094 * Inserts a new associative array after another associative array key.
852 1095 *
853 1096 * @since 2.1.0
854 1097 * @param string $key The associative array key to insert after.
@@ -876,8 +1119,31 @@
876 1119 return $array;
877 1120 }
878 1121
879 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 +/**
880 1146 * Sanitize the integer inputs, accepts empty values.
881 1147 *
882 1148 * @since 1.0.0
883 1149 * @param string|int $value Input value.
@@ -922,11 +1188,11 @@
922 1188
923 1189 /**
924 1190 * Gallery HTML output.
925 1191 *
926 - * @since 1.0.0
927 - * @param array $video YouTube video object.
928 - * @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.
929 1195 */
930 1196 function the_ayg_gallery_thumbnail( $video, $attributes ) {
931 1197 include ayg_get_template( AYG_DIR . 'public/templates/thumbnail.php' );
932 1198 }
@@ -933,12 +1199,35 @@
933 1199
934 1200 /**
935 1201 * Pagination HTML output.
936 1202 *
937 - * @since 1.0.0
938 - * @param array $attributes Array of user attributes.
1203 + * @since 1.0.0
1204 + * @param array $attributes Array of user attributes.
939 1205 */
940 1206 function the_ayg_pagination( $attributes ) {
941 1207 if ( ! empty( $attributes['pagination'] ) ) {
942 1208 include ayg_get_template( AYG_DIR . 'public/templates/pagination.php' );
943 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' );
944 1233 }