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 +683 -371 1.6.42.6.4 View file →
@@ -17,24 +17,40 @@
17 17 /**
18 18 * Build gallery HTML output.
19 19 *
20 20 * @since 1.0.0
21 - * @param array $atts An associative array of attributes.
21 + * @param array $args An array of gallery options.
22 22 * @return mixed
23 23 */
24 -function ayg_build_gallery( $atts ) {
24 +function ayg_build_gallery( $args ) {
25 + $general_settings = get_option( 'ayg_general_settings' );
26 + $strings_settings = get_option( 'ayg_strings_settings' );
27 +
28 + global $post;
29 +
25 30 // Vars
26 - $fields = ayg_get_editor_fields();
31 + $fields = ayg_get_editor_fields();
32 + $excluded_fields = array( 'popup' ); // Fields not part of attributes
27 33 $defaults = array();
28 34
29 35 foreach ( $fields as $key => $value ) {
30 36 foreach ( $value['fields'] as $field ) {
37 + if ( in_array( $field['name'], $excluded_fields ) ) {
38 + continue;
39 + }
40 +
31 41 $defaults[ $field['name'] ] = $field['value'];
32 42 }
33 43 }
34 44
35 - $attributes = shortcode_atts( $defaults, $atts );
45 + $defaults = array_merge( $defaults, (array) $strings_settings );
46 + $attributes = shortcode_atts( $defaults, $args, 'automatic_youtube_gallery' );
36 47
48 + $attributes['post_id'] = 0;
49 + if ( isset( $post->ID ) ) {
50 + $attributes['post_id'] = (int) $post->ID;
51 + }
52 +
37 53 $attributes['columns'] = min( 12, (int) $attributes['columns'] );
38 54 if ( empty( $attributes['columns'] ) ) {
39 55 $attributes['columns'] = 3;
40 56 }
@@ -48,44 +64,94 @@
48 64 if ( empty( $attributes['per_page'] ) ) {
49 65 $attributes['per_page'] = 50;
50 66 }
51 67
52 - // Get Videos
53 68 $source_type = sanitize_text_field( $attributes['type'] );
54 -
55 69 if ( 'livestream' == $source_type ) {
56 70 $attributes['livestream'] = $attributes['channel'];
57 71 }
58 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 +
80 + if ( isset( $args['uid'] ) && ! empty( $args['uid'] ) ) {
81 + $attributes['uid'] = sanitize_text_field( $args['uid'] );
82 + } else {
83 + $attributes['uid'] = md5( $source_type . $source_url );
84 + }
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 +
94 + // Get Videos
59 95 $api_params = array(
96 + 'uid' => $attributes['uid'],
60 97 'type' => $source_type,
61 - 'id' => sanitize_text_field( $attributes[ $source_type ] ),
62 - 'order' => sanitize_text_field( $attributes['order'] ), // works 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".
63 101 'maxResults' => $attributes['per_page'],
64 102 'cache' => (int) $attributes['cache']
65 103 );
66 104
67 - $api_params = apply_filters( 'ayg_youtube_api_request_params', $api_params, $atts );
105 + $api_params = apply_filters( 'ayg_youtube_api_request_params', $api_params, $args );
68 106
69 107 $youtube_api = new AYG_YouTube_API();
70 - $response = $youtube_api->get_videos( $api_params );
108 + $response = $youtube_api->query( $api_params );
71 109
72 110 // Process output
73 111 if ( ! isset( $response->error ) ) {
74 - // Enqueue dependencies
75 - wp_enqueue_style( AYG_SLUG . '-public' );
76 - 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 + }
77 122
78 123 // Gallery
79 - $videos = array();
124 + $videos = array();
125 +
126 + $gallery_id_from_url = get_query_var( 'ayg_gallery_id' );
127 + $video_id_from_url = get_query_var( 'ayg_video_id' );
128 +
129 + if ( $attributes['uid'] == $gallery_id_from_url || $deprecated_uid == $gallery_id_from_url ) {
130 + $video = ayg_db_get_video( $video_id_from_url );
131 +
132 + if ( $video ) {
133 + $videos[] = $video;
134 + } else {
135 + $video_id_from_url = '';
136 + }
137 + }
80 138
81 139 if ( isset( $response->videos ) ) {
82 - $videos = $response->videos;
140 + if ( ! empty( $video_id_from_url ) ) {
141 + foreach ( $response->videos as $video ) {
142 + if ( $video->id != $video_id_from_url ) {
143 + $videos[] = $video;
144 + }
145 + }
146 + } else {
147 + $videos = $response->videos;
148 + }
83 149 }
84 150
85 151 // Pagination
86 152 if ( isset( $response->page_info ) ) {
87 - $attributes = array_merge( $attributes, $response->page_info, $api_params );
153 + $attributes = array_merge( $attributes, $api_params, $response->page_info );
88 154 }
89 155
90 156 // Theme
91 157 $theme = 'classic';
@@ -91,12 +157,22 @@
91 157 $theme = 'classic';
92 158
93 159 if ( 'video' == $source_type ) {
94 160 $theme = 'single';
161 + } elseif ( 'livestream' == $source_type ) {
162 + $theme = 'livestream';
163 + } else {
164 + if ( 1 == count( $videos ) ) {
165 + $theme = 'single';
166 + }
95 167 }
96 -
97 - if ( 'livestream' == $source_type ) {
98 - $theme = 'livestream';
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' );
99 175 }
100 176
101 177 // Output
102 178 ob_start();
@@ -102,13 +178,288 @@
102 178 ob_start();
103 179 include ayg_get_template( AYG_DIR . "public/templates/theme-{$theme}.php", $attributes['theme'] );
104 180 return ob_get_clean();
105 181 } else {
106 - 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 ) );
107 183 }
108 184 }
109 185
110 186 /**
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
209 + *
210 + * @since 2.1.0
211 + */
212 +function ayg_db_create_custom_tables() {
213 + global $wpdb;
214 +
215 + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
216 + $charset_collate = $wpdb->get_charset_collate();
217 +
218 + $videos_table = $wpdb->prefix . 'ayg_videos';
219 +
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 (
234 + NUM bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
235 + id varchar(100) NOT NULL,
236 + title text NOT NULL,
237 + description text NOT NULL,
238 + thumbnails text NOT NULL,
239 + duration varchar(25) NOT NULL,
240 + status varchar(100) NOT NULL,
241 + published_at varchar(100) NOT NULL,
242 + published_at_datetime datetime NULL,
243 + PRIMARY KEY (NUM),
244 + UNIQUE KEY ayg_unique_video_id (id)
245 + ) $charset_collate;";
246 +
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 );
269 +}
270 +
271 +/**
272 + * Store videos in our custom database table "{$wpdb->prefix}ayg_videos"
273 + *
274 + * @since 2.1.0
275 + * @param object $data YouTube API response object.
276 + * @param array $attributes Array of user attributes.
277 + */
278 +function ayg_db_store_videos( $data, $attributes = array() ) {
279 + if ( AYG_VERSION !== get_option( 'ayg_version' ) ) {
280 + return false;
281 + }
282 +
283 + if ( isset( $data->kind ) && 'youtube#channelListResponse' == $data->kind ) {
284 + return false;
285 + }
286 +
287 + if ( empty( $data->items ) || ! is_array( $data->items ) ) {
288 + return false;
289 + }
290 +
291 + global $wpdb;
292 +
293 + $items = $data->items;
294 +
295 + // Store Videos
296 + foreach ( $items as $item ) {
297 + $row = array();
298 +
299 + // Video ID
300 + $row['id'] = '';
301 +
302 + if ( isset( $item->snippet->resourceId ) && isset( $item->snippet->resourceId->videoId ) ) {
303 + $row['id'] = $item->snippet->resourceId->videoId;
304 + } elseif ( isset( $item->contentDetails ) && isset( $item->contentDetails->videoId ) ) {
305 + $row['id'] = $item->contentDetails->videoId;
306 + } elseif ( isset( $item->id ) && isset( $item->id->videoId ) ) {
307 + $row['id'] = $item->id->videoId;
308 + } elseif ( isset( $item->id ) ) {
309 + $row['id'] = $item->id;
310 + }
311 +
312 + if ( empty( $row['id'] ) ) {
313 + continue;
314 + }
315 +
316 + // Video title
317 + $row['title'] = $item->snippet->title;
318 +
319 + // Video description
320 + $row['description'] = $item->snippet->description;
321 +
322 + // Video thumbnails
323 + $row['thumbnails'] = '';
324 + if ( isset( $item->snippet->thumbnails ) ) {
325 + $row['thumbnails'] = serialize( $item->snippet->thumbnails );
326 + }
327 +
328 + // Video duration
329 + $row['duration'] = '';
330 + if ( isset( $item->contentDetails ) && isset( $item->contentDetails->duration ) ) {
331 + $row['duration'] = $item->contentDetails->duration;
332 + }
333 +
334 + // Video status
335 + $row['status'] = 'private';
336 +
337 + if ( isset( $item->status ) && ( 'public' == $item->status->privacyStatus || 'unlisted' == $item->status->privacyStatus ) ) {
338 + $row['status'] = 'public';
339 + }
340 +
341 + if ( isset( $item->snippet->status ) && ( 'public' == $item->snippet->status->privacyStatus || 'unlisted' == $item->snippet->status->privacyStatus ) ) {
342 + $row['status'] = 'public';
343 + }
344 +
345 + if ( 'youtube#searchResult' == $item->kind ) {
346 + $row['status'] = 'public';
347 + }
348 +
349 + // Video publish date
350 + $row['published_at'] = $item->snippet->publishedAt;
351 +
352 + $datetime = new DateTime( $item->snippet->publishedAt );
353 + $row['published_at_datetime'] = date_format( $datetime, 'Y-m-d H:i:s' );
354 +
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
392 + );
393 +
394 + $wpdb->query( $query );
395 + }
396 + }
397 +}
398 +
399 +/**
400 + * Get a single video record from our custom database table "{$wpdb->prefix}ayg_videos"
401 + *
402 + * @since 2.1.0
403 + * @param string $video_id YouTube Video ID.
404 + * @return mixed
405 + */
406 +function ayg_db_get_video( $video_id ) {
407 + global $wpdb;
408 +
409 + $cache_key = 'ayg_'. $video_id;
410 + $row = wp_cache_get( $cache_key );
411 +
412 + if ( false === $row ) {
413 + $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}ayg_videos WHERE id = %s", $video_id );
414 + $row = $wpdb->get_row( $query );
415 +
416 + if ( $row ) {
417 + if ( ! empty( $row->thumbnails ) ) {
418 + $row->thumbnails = unserialize( $row->thumbnails );
419 + }
420 +
421 + wp_cache_set( $cache_key, $row );
422 + }
423 + }
424 +
425 + return $row;
426 +}
427 +
428 +/**
429 + * Dump our plugin transients.
430 + *
431 + * @since 2.1.0
432 + */
433 +function ayg_delete_cache() {
434 + delete_option( 'ayg_gallery_page_ids' );
435 +
436 + // Get the current list of transients
437 + $transient_keys = get_option( 'ayg_transient_keys', array() );
438 +
439 + // For each key, delete that transient
440 + foreach ( $transient_keys as $key ) {
441 + delete_transient( $key );
442 + }
443 +
444 + // Reset our DB value
445 + update_option( 'ayg_transient_keys', array() );
446 +}
447 +
448 +/**
449 + * Get current address bar URL.
450 + *
451 + * @since 2.1.0
452 + * @return string Current Page URL.
453 + */
454 +function ayg_get_current_url() {
455 + global $wp;
456 + $current_url = home_url( add_query_arg( array(), $wp->request ) );
457 +
458 + return $current_url;
459 +}
460 +
461 +/**
111 462 * Get default plugin settings.
112 463 *
113 464 * @since 1.6.4
114 465 * @return array $defaults Array of plugin settings.
@@ -115,38 +466,59 @@
115 466 */
116 467 function ayg_get_default_settings() {
117 468 $defaults = array(
118 469 'ayg_general_settings' => array(
119 - 'api_key' => ''
470 + 'api_key' => '',
471 + 'lazyload' => 0,
472 + 'development_mode' => 0
120 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 + ),
121 481 'ayg_gallery_settings' => array(
122 - 'theme' => 'classic',
123 - 'columns' => 3,
124 - 'per_page' => 12,
125 - 'thumb_ratio' => 56.25,
126 - 'thumb_title' => 1,
127 - 'thumb_title_length' => 0,
128 - 'thumb_excerpt' => 1,
129 - 'thumb_excerpt_length' => 75,
130 - 'pagination' => 1,
131 - 'pagination_type' => 'load_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
132 493 ),
133 494 'ayg_player_settings' => array(
134 - 'player_ratio' => 56.25,
135 - 'player_title' => 1,
136 - 'player_description' => 1,
137 - 'autoplay' => 0,
138 - 'autoadvance' => 0,
139 - 'loop' => 0,
140 - 'controls' => 1,
141 - 'modestbranding' => 1,
142 - 'cc_load_policy' => 0,
143 - 'iv_load_policy' => 0,
144 - 'hl' => '',
145 - '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
146 513 ),
147 514 'ayg_livestream_settings' => array(
148 - 'fallback_message' => '<div style="padding: 15px; background: #eee; border-radius: 3px;"><strong>Sorry, but the channel is not currently streaming live content.</strong> Please check back later.<br /><br />Thank you!</div>'
515 + 'fallback_message' => __( 'Sorry, but the channel is not currently streaming live content. Please check back later.', 'automatic-youtube-gallery' )
516 + ),
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' )
149 521 )
150 522 );
151 523
152 524 return $defaults;
@@ -171,11 +543,11 @@
171 543 'options' => array(
172 544 'playlist' => __( 'Playlist', 'automatic-youtube-gallery' ),
173 545 'channel' => __( 'Channel', 'automatic-youtube-gallery' ),
174 546 'username' => __( 'Username', 'automatic-youtube-gallery' ),
175 - 'search' => __( 'Search Terms', 'automatic-youtube-gallery' ),
547 + 'search' => __( 'Search Keywords', 'automatic-youtube-gallery' ),
176 548 'video' => __( 'Single Video', 'automatic-youtube-gallery' ),
177 - 'livestream' => __( 'Live Stream', 'automatic-youtube-gallery' ),
549 + 'livestream' => __( 'Livestream', 'automatic-youtube-gallery' ),
178 550 'videos' => __( 'Custom Videos List', 'automatic-youtube-gallery' )
179 551 ),
180 552 'value' => 'playlist',
181 553 'sanitize_callback' => 'sanitize_key'
@@ -189,9 +561,9 @@
189 561 'sanitize_callback' => 'sanitize_text_field'
190 562 ),
191 563 array(
192 564 'name' => 'channel',
193 - 'label' => __( 'YouTube Channel ID (or) URL', 'automatic-youtube-gallery' ),
565 + 'label' => __( 'YouTube Channel ID (or) a YouTube Video URL from the Channel', 'automatic-youtube-gallery' ),
194 566 'description' => sprintf( '%s: https://www.youtube.com/channel/XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
195 567 'type' => 'url',
196 568 'value' => '',
197 569 'sanitize_callback' => 'sanitize_text_field'
@@ -205,9 +577,9 @@
205 577 'sanitize_callback' => 'sanitize_text_field'
206 578 ),
207 579 array(
208 580 'name' => 'search',
209 - 'label' => __( 'Search Terms', 'automatic-youtube-gallery' ),
581 + 'label' => __( 'Search Keywords', 'automatic-youtube-gallery' ),
210 582 'description' => sprintf( '%s: Cartoon (space:AND , -:NOT , |:OR)', __( 'Example', 'automatic-youtube-gallery' ) ),
211 583 'type' => 'text',
212 584 'value' => '',
213 585 'sanitize_callback' => 'sanitize_text_field'
@@ -255,21 +627,21 @@
255 627 'sanitize_callback' => 'intval'
256 628 ),
257 629 array(
258 630 'name' => 'cache',
259 - 'label' => __( 'Refresh the data every (Cache time)', 'automatic-youtube-gallery' ),
260 - 'description' => __( 'IMPORTANT! Specifies how frequently the plugin should check your YouTube source for any new update. We recommend keeping this value as "Page load" when you test the gallery and strongly suggest to change this value as "Day" or to a greater value before pushing the gallery live.', 'automatic-youtube-gallery' ),
631 + 'label' => __( 'Cache Duration', 'automatic-youtube-gallery' ),
632 + 'description' => __( 'Specifies how frequently we should check your YouTube source for new videos/updates.', 'automatic-youtube-gallery' ),
261 633 'type' => 'select',
262 634 'options' => array(
263 - '0' => __( 'Page load', 'automatic-youtube-gallery' ),
264 - '900' => __( '15 minutes', 'automatic-youtube-gallery' ),
265 - '1800' => __( '30 minutes', 'automatic-youtube-gallery' ),
266 - '3600' => __( 'Hour', 'automatic-youtube-gallery' ),
267 - '86400' => __( 'Day', 'automatic-youtube-gallery' ),
268 - '604800' => __( 'Week', 'automatic-youtube-gallery' ),
269 - '2419200' => __( 'Month', 'automatic-youtube-gallery' )
635 + '0' => '— '. __( 'No Caching', 'automatic-youtube-gallery' ) . ' —',
636 + '900' => __( '15 Minutes', 'automatic-youtube-gallery' ),
637 + '1800' => __( '30 Minutes', 'automatic-youtube-gallery' ),
638 + '3600' => __( '1 Hour', 'automatic-youtube-gallery' ),
639 + '86400' => __( '1 Day', 'automatic-youtube-gallery' ),
640 + '604800' => __( '1 Week', 'automatic-youtube-gallery' ),
641 + '2419200' => __( '1 Month', 'automatic-youtube-gallery' )
270 642 ),
271 - 'value' => 0,
643 + 'value' => 86400,
272 644 'sanitize_callback' => 'intval'
273 645 )
274 646 )
275 647 ),
@@ -279,8 +651,24 @@
279 651 ),
280 652 'player' => array(
281 653 'label' => __( 'Player (optional)', 'automatic-youtube-gallery' ),
282 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 + )
283 671 )
284 672 );
285 673
286 674 return apply_filters( 'ayg_editor_fields', $fields );
@@ -286,109 +674,8 @@
286 674 return apply_filters( 'ayg_editor_fields', $fields );
287 675 }
288 676
289 677 /**
290 - * Get gallery thumbnail video excerpt (short description).
291 - *
292 - * @since 1.0.0
293 - * @param stdClass $video YouTube video object.
294 - * @param array $attributes Array of user attributes.
295 - * @return string Video excerpt.
296 - */
297 -function ayg_get_gallery_thumb_excerpt( $video, $attributes ) {
298 - $char_length = (int) $attributes['thumb_excerpt_length'];
299 - $char_length++;
300 -
301 - $content = '';
302 - if ( ! empty( $attributes['thumb_excerpt'] ) ) {
303 - $content = ( $char_length > 1 ) ? wp_strip_all_tags( $video->description, true ) : nl2br( $video->description );
304 - }
305 -
306 - $excerpt = '';
307 -
308 - if ( $char_length > 1 && mb_strlen( $content ) > $char_length ) {
309 - $subex = mb_substr( $content, 0, $char_length - 5 );
310 - $exwords = explode( ' ', $subex );
311 - $excut = - ( mb_strlen( $exwords[ count( $exwords ) - 1 ] ) );
312 - if ( $excut < 0 ) {
313 - $excerpt = mb_substr( $subex, 0, $excut );
314 - } else {
315 - $excerpt = $subex;
316 - }
317 - $excerpt .= '[...]';
318 - } else {
319 - $excerpt = $content;
320 - }
321 -
322 - return apply_filters( 'ayg_gallery_thumb_excerpt', $excerpt, $video, $attributes );
323 -}
324 -
325 -/**
326 - * Get gallery thumbnail image.
327 - *
328 - * @since 1.0.0
329 - * @param stdClass $video YouTube video object.
330 - * @param array $attributes Array of user attributes.
331 - * @return string Video thumbnail image.
332 - */
333 -function ayg_get_gallery_thumb_image( $video, $attributes ) {
334 - $image = '';
335 -
336 - if ( isset( $video->thumbnails->default ) ) {
337 - $image = $video->thumbnails->default->url;
338 - }
339 -
340 - // 4:3 ( default - 120x90, high - 480x360, standard - 640x480 )
341 - if ( 75 == (int) $attributes['thumb_ratio'] ) {
342 - if ( isset( $video->thumbnails->high ) ) {
343 - $image = $video->thumbnails->high->url;
344 - }
345 - }
346 -
347 - // 16:9 ( medium - 320x180, maxres - 1280x720 )
348 - if ( 56.25 == (float) $attributes['thumb_ratio'] ) {
349 - if ( isset( $video->thumbnails->medium ) ) {
350 - $image = $video->thumbnails->medium->url;
351 - }
352 - }
353 -
354 - return apply_filters( 'ayg_gallery_thumb_image', $image, $video, $attributes );
355 -}
356 -
357 -/**
358 - * Get gallery thumbnail video title.
359 - *
360 - * @since 1.0.0
361 - * @param stdClass $video YouTube video object.
362 - * @param array $attributes Array of user attributes.
363 - * @return string Video title.
364 - */
365 -function ayg_get_gallery_thumb_title( $video, $attributes ) {
366 - $text = ! empty( $attributes['thumb_title'] ) ? $video->title : '';
367 -
368 - $char_length = (int) $attributes['thumb_title_length'];
369 - $char_length++;
370 -
371 - $title = '';
372 -
373 - if ( $char_length > 1 && mb_strlen( $text ) > $char_length ) {
374 - $subex = mb_substr( $text, 0, $char_length - 5 );
375 - $exwords = explode( ' ', $subex );
376 - $excut = - ( mb_strlen( $exwords[ count( $exwords ) - 1 ] ) );
377 - if ( $excut < 0 ) {
378 - $title = mb_substr( $subex, 0, $excut );
379 - } else {
380 - $title = $subex;
381 - }
382 - $title .= '[...]';
383 - } else {
384 - $title = $text;
385 - }
386 -
387 - return apply_filters( 'ayg_gallery_thumb_title', $title, $video, $attributes );
388 -}
389 -
390 -/**
391 678 * Get gallery settings fields.
392 679 *
393 680 * @since 1.0.0
394 681 * @return array $fields Array of fields.
@@ -398,10 +685,10 @@
398 685
399 686 $fields = array(
400 687 array(
401 688 'name' => 'theme',
402 - 'label' => __( 'Select Theme', 'automatic-youtube-gallery' ),
403 - 'description' => ( ayg_fs()->is_not_paying() ? sprintf( __( '<a href="%s">Upgrade Pro</a> for more themes (Popup, Slider, Playlister).', 'automatic-youtube-gallery' ), esc_url( ayg_fs()->get_upgrade_url() ) ) : '' ),
689 + 'label' => __( 'Select Theme (Layout)', 'automatic-youtube-gallery' ),
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() ) ) : '' ),
404 691 'type' => 'select',
405 692 'options' => array(
406 693 'classic' => __( 'Classic', 'automatic-youtube-gallery' )
407 694 ),
@@ -419,9 +706,9 @@
419 706 'sanitize_callback' => 'intval'
420 707 ),
421 708 array(
422 709 'name' => 'per_page',
423 - 'label' => __( 'Videos per page', 'automatic-youtube-gallery' ),
710 + 'label' => __( 'Videos per Page', 'automatic-youtube-gallery' ),
424 711 'description' => __( 'Enter the number of videos to show per page. Maximum of 50.', 'automatic-youtube-gallery' ),
425 712 'type' => 'number',
426 713 'min' => 0,
427 714 'max' => 50,
@@ -429,9 +716,10 @@
429 716 'sanitize_callback' => 'intval'
430 717 ),
431 718 array(
432 719 'name' => 'thumb_ratio',
433 - 'label' => __( 'Thumbnail Ratio', 'automatic-youtube-gallery' ),
720 + 'label' => __( 'Image Height (Ratio)', 'automatic-youtube-gallery' ),
721 + 'description' => __( 'Select the ratio value used to calculate the image height in the gallery thumbnails.', 'automatic-youtube-gallery' ),
434 722 'type' => 'radio',
435 723 'options' => array(
436 724 '56.25' => '16:9',
437 725 '75' => '4:3'
@@ -487,10 +775,11 @@
487 775 'name' => 'pagination_type',
488 776 'label' => __( 'Pagination Type', 'automatic-youtube-gallery' ),
489 777 'type' => 'select',
490 778 'options' => array(
491 - 'pager' => __( 'Pager', 'automatic-youtube-gallery' ),
492 - 'load_more' => __( 'Load More', 'automatic-youtube-gallery' )
779 + 'more' => __( 'More Button', 'automatic-youtube-gallery' ),
780 + 'pager' => __( 'Pager', 'automatic-youtube-gallery' )
781 +
493 782 ),
494 783 'value' => $gallery_settings['pagination_type'],
495 784 'sanitize_callback' => 'sanitize_key'
496 785 )
@@ -507,90 +796,27 @@
507 796 * @param array $attributes Array of user attributes.
508 797 * @param int $words_count Number of words to show by default.
509 798 * @return string Video description.
510 799 */
511 -function ayg_get_player_description( $video, $attributes, $words_count = 30 ) {
512 - $description = ! empty( $attributes['player_description'] ) ? $video->description : '';
800 +function ayg_get_player_description( $video, $attributes = array(), $words_count = 30 ) {
801 + $description = $video->description;
513 802
514 - $words_array = explode( ' ', strip_tags( $description ) );
515 -
803 + $words_array = explode( ' ', strip_tags( $description ) );
516 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' );
517 806 $words_array[ $words_count ] = '<span class="ayg-player-description-dots">...</span></span><span class="ayg-player-description-more">' . $words_array[ $words_count ];
518 807
519 808 $description = '<span class="ayg-player-description-less">' . implode( ' ', $words_array ) . '</span>';
520 - $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>';
521 810 }
522 811
523 - return apply_filters( 'ayg_player_description', nl2br( $description ), $video, $attributes, $words_count );
524 -}
812 + $description = nl2br( $description );
813 + $description = make_clickable( $description );
525 814
526 -/**
527 - * Get YouTube player embed URL.
528 - *
529 - * @since 1.0.0
530 - * @param stdClass $item YouTube source object.
531 - * @param array $attributes Array of user attributes.
532 - * @return string YouTube video embed URL.
533 - */
534 -function ayg_get_player_embed_url( $item, $attributes ) {
535 - if ( 'livestream' == $attributes['type'] ) {
536 - $url = "https://www.youtube-nocookie.com/embed/live_stream?channel={$item->id}";
537 - } else {
538 - $url = "https://www.youtube-nocookie.com/embed/{$item->id}";
539 - }
540 -
541 - if ( ! empty( $attributes['autoplay'] ) ) { // autoplay
542 - $url = add_query_arg( 'autoplay', 1, $url );
543 - }
544 -
545 - if ( ! empty( $attributes['loop'] ) ) { // loop
546 - $url = add_query_arg( 'loop', 1, $url );
547 - }
548 -
549 - if ( empty( $attributes['controls'] ) ) { // controls
550 - $url = add_query_arg( 'controls', 0, $url );
551 - }
552 -
553 - if ( ! empty( $attributes['modestbranding'] ) ) { // modestbranding
554 - $url = add_query_arg( 'modestbranding', 1, $url );
555 - }
556 -
557 - if ( ! empty( $attributes['cc_load_policy'] ) ) { // cc_load_policy
558 - $url = add_query_arg( 'cc_load_policy', 1, $url );
559 - }
560 -
561 - if ( empty( $attributes['iv_load_policy'] ) ) { // iv_load_policy
562 - $url = add_query_arg( 'iv_load_policy', 3, $url );
563 - }
564 -
565 - if ( ! empty( $attributes['hl'] ) ) { // hl
566 - $url = add_query_arg( 'hl', $attributes['hl'], $url );
567 - }
568 -
569 - if ( ! empty( $attributes['cc_lang_pref'] ) ) { // cc_lang_pref
570 - $url = add_query_arg( 'cc_lang_pref', $attributes['cc_lang_pref'], $url );
571 - }
572 -
573 - $url = add_query_arg( 'rel', 0, $url ); // rel
574 - $url = add_query_arg( 'playsinline', 1, $url ); // playsinline
575 - $url = add_query_arg( 'enablejsapi', 1, $url ); // enablejsapi
576 -
577 - return apply_filters( 'ayg_player_embed_url', $url, $item, $attributes );
815 + return apply_filters( 'ayg_player_description', $description, $video, $attributes, $words_count );
578 816 }
579 817
580 818 /**
581 - * Get player ratio.
582 - *
583 - * @since 1.0.0
584 - * @param array $attributes Array of user attributes.
585 - * @return string Player ratio.
586 - */
587 -function ayg_get_player_ratio( $attributes ) {
588 - $ratio = ! empty( $attributes['player_ratio'] ) ? $attributes['player_ratio'] . '%' : '56.25%';
589 - return apply_filters( 'ayg_player_ratio', $ratio, $attributes );
590 -}
591 -
592 -/**
593 819 * Get player settings fields.
594 820 *
595 821 * @since 1.0.0
596 822 * @return array $fields Array of fields.
@@ -599,10 +825,19 @@
599 825 $player_settings = get_option( 'ayg_player_settings' );
600 826
601 827 $fields = array(
602 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(
603 837 'name' => 'player_ratio',
604 - 'label' => __( 'Player Ratio', 'automatic-youtube-gallery' ),
838 + 'label' => __( 'Player Height (Ratio)', 'automatic-youtube-gallery' ),
839 + 'description' => __( 'Select the ratio value used to calculate the player height.', 'automatic-youtube-gallery' ),
605 840 'type' => 'radio',
606 841 'options' => array(
607 842 '56.25' => '16:9',
608 843 '75' => '4:3'
@@ -648,10 +883,18 @@
648 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' ),
649 884 'type' => 'checkbox',
650 885 'value' => $player_settings['loop'],
651 886 'sanitize_callback' => 'intval'
652 - ),
887 + ),
653 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(
654 897 'name' => 'controls',
655 898 'label' => __( 'Show Player Controls', 'automatic-youtube-gallery' ),
656 899 'description' => __( 'Uncheck this option to hide the video player controls.', 'automatic-youtube-gallery' ),
657 900 'type' => 'checkbox',
@@ -708,31 +951,19 @@
708 951
709 952 return $fields;
710 953 }
711 954
712 -/**
713 - * Get video title to show on bottom of the player.
714 - *
715 - * @since 1.0.0
716 - * @param stdClass $video YouTube video object.
717 - * @param array $attributes Array of user attributes.
718 - * @return string Video title.
719 - */
720 -function ayg_get_player_title( $video, $attributes ) {
721 - $title = ! empty( $attributes['player_title'] ) ? $video->title : '';
722 - return apply_filters( 'ayg_player_title', $title, $video, $attributes );
723 -}
724 955
725 956 /**
726 - * Get player width.
957 + * Get a single video page URL.
727 958 *
728 - * @since 1.0.0
729 - * @param array $attributes Array of user attributes.
730 - * @return string Player width.
959 + * @since 2.1.0
960 + * @param stdClass $video YouTube video object.
961 + * @param array $args An array of gallery options.
962 + * @return string Single video URL.
731 963 */
732 -function ayg_get_player_width( $attributes ) {
733 - $width = ! empty( $attributes['player_width'] ) ? $attributes['player_width'] . 'px' : '100%';
734 - return apply_filters( 'ayg_player_width', $width, $attributes );
964 +function ayg_get_single_video_url( $video, $attributes ) {
965 + return apply_filters( 'ayg_single_video_url', '', $video, $attributes );
735 966 }
736 967
737 968 /**
738 969 * Get filtered php template file path.
@@ -762,160 +993,241 @@
762 993 return uniqid() . ++$ayg_uniqid;
763 994 }
764 995
765 996 /**
766 - * Sanitize the integer inputs, accepts empty values.
997 + * Get YouTube domain.
767 998 *
768 - * @since 1.0.0
769 - * @param string|int $value Input value.
770 - * @return string|int Sanitized value.
999 + * @since 2.3.0
1000 + * @return string YouTube embed domain.
771 1001 */
772 -function ayg_sanitize_int( $value ) {
773 - $value = intval( $value );
774 - return ( 0 == $value ) ? '' : $value;
1002 +function ayg_get_youtube_domain() {
1003 + $player_settings = get_option( 'ayg_player_settings' );
1004 +
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';
1008 + }
1009 +
1010 + return $domain;
775 1011 }
776 1012
777 1013 /**
778 - * Gallery HTML output.
1014 + * Get the YouTube embed URL.
779 1015 *
780 - * @since 1.0.0
781 - * @param array $videos Array of YouTube video object.
782 - * @param array $attributes Array of user attributes.
783 - * @param int $active_id Current active/selected video ID in the gallery.
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.
784 1020 */
785 -function the_ayg_gallery( $videos, $attributes, $active_id = 0 ) {
786 - if ( 'video' != $attributes['type'] ) {
787 - include ayg_get_template( AYG_DIR . 'public/templates/gallery.php', $attributes['theme'] );
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';
788 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 );
789 1091 }
790 1092
791 1093 /**
792 - * Gallery HTML output.
1094 + * Inserts a new associative array after another associative array key.
793 1095 *
794 - * @since 1.0.0
795 - * @param array $video YouTube video object.
796 - * @param array $attributes Array of user attributes.
797 - * @param boolean $is_active True if active video item, false if not.
1096 + * @since 2.1.0
1097 + * @param string $key The associative array key to insert after.
1098 + * @param array $array An array to insert in to.
1099 + * @param array $new_array An array to insert.
1100 + * @return array Updated array.
798 1101 */
799 -function the_ayg_gallery_thumbnail( $video, $attributes, $is_active = false ) {
800 - include ayg_get_template( AYG_DIR . 'public/templates/gallery-thumbnail.php', $attributes['theme'] );
1102 +function ayg_insert_array_after( $key, $array, $new_array ) {
1103 + if ( array_key_exists( $key, $array ) ) {
1104 + $new = array();
1105 +
1106 + foreach ( $array as $k => $value ) {
1107 + $new[ $k ] = $value;
1108 +
1109 + if ( $k === $key ) {
1110 + foreach ( $new_array as $new_key => $new_value ) {
1111 + $new[ $new_key ] = $new_value;
1112 + }
1113 + }
1114 + }
1115 +
1116 + return $new;
1117 + }
1118 +
1119 + return $array;
801 1120 }
802 1121
803 1122 /**
804 - * Display gallery thumbnail image.
1123 + * Detect if the client is using an iOS device (iPhone, iPad, or iPod).
805 1124 *
806 - * @since 1.6.4
807 - * @param stdClass $video YouTube video object.
808 - * @param array $attributes Array of user attributes.
1125 + * @return bool True if the user agent string suggests an iOS device, false otherwise.
809 1126 */
810 -function the_ayg_gallery_thumbnail_image( $video, $attributes ) {
811 - $image = '';
812 - $src = '';
813 - $width = '';
814 - $height = '';
1127 +function ayg_is_ios() {
1128 + if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
1129 + return false;
1130 + }
815 1131
816 - if ( isset( $video->thumbnails->default ) ) {
817 - $src = $video->thumbnails->default->url;
818 - $width = $video->thumbnails->default->width;
819 - $height = $video->thumbnails->default->height;
820 - }
1132 + $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
821 1133
822 - // 4:3 ( default - 120x90, high - 480x360, standard - 640x480 )
823 - if ( 75 == (int) $attributes['thumb_ratio'] ) {
824 - if ( isset( $video->thumbnails->high ) ) {
825 - $src = $video->thumbnails->high->url;
826 - $width = $video->thumbnails->high->width;
827 - $height = $video->thumbnails->high->height;
828 - }
829 - }
1134 + if (
1135 + strpos( $ua, 'iphone' ) !== false ||
1136 + strpos( $ua, 'ipad' ) !== false ||
1137 + strpos( $ua, 'ipod' ) !== false
1138 + ) {
1139 + return true;
1140 + }
830 1141
831 - // 16:9 ( medium - 320x180, maxres - 1280x720 )
832 - if ( 56.25 == (float) $attributes['thumb_ratio'] ) {
833 - if ( isset( $video->thumbnails->medium ) ) {
834 - $src = $video->thumbnails->medium->url;
835 - $width = $video->thumbnails->medium->width;
836 - $height = $video->thumbnails->medium->height;
837 - }
838 - }
1142 + return false;
1143 +}
839 1144
840 - if ( ! empty( $src ) ) {
841 - $image = sprintf(
842 - '<img src="%s" width="%s" height="%s" class="ayg-thumbnail-image" alt="%s" />',
843 - esc_url( $src ),
844 - esc_attr( $width ),
845 - esc_attr( $height ),
846 - esc_attr( $video->title )
847 - );
848 - }
849 -
850 - echo apply_filters( 'ayg_gallery_thumbnail_image_html', $image, $video, $attributes );
1145 +/**
1146 + * Sanitize the integer inputs, accepts empty values.
1147 + *
1148 + * @since 1.0.0
1149 + * @param string|int $value Input value.
1150 + * @return string|int Sanitized value.
1151 + */
1152 +function ayg_sanitize_int( $value ) {
1153 + $value = intval( $value );
1154 + return ( 0 == $value ) ? '' : $value;
851 1155 }
852 1156
853 1157 /**
854 - * Pagination HTML output.
1158 + * Trims text to a certain number of characters.
855 1159 *
856 - * @since 1.0.0
857 - * @param array $atts Array of user attributes.
1160 + * @since 2.0.0
1161 + * @param string $text Text to trim.
1162 + * @param int $num_characters Number of characters.
1163 + * @param string $append String to append to the end of the excerpt.
1164 + * @return string Trimmed text.
858 1165 */
859 -function the_ayg_pagination( $atts ) {
860 - if ( ! empty( $atts['pagination'] ) ) {
861 - // Build attributes
862 - $attributes = array();
1166 +function ayg_trim_words( $text, $num_characters, $append = '...' ) {
1167 + $num_characters++;
863 1168
864 - $fields = ayg_get_editor_fields();
1169 + $original_text = $text;
1170 + $text = ( $num_characters > 1 ) ? wp_strip_all_tags( $original_text, true ) : nl2br( $original_text );
865 1171
866 - foreach ( $fields['gallery']['fields'] as $field ) {
867 - $field_name = $field['name'];
1172 + if ( $num_characters > 1 && mb_strlen( $text ) > $num_characters ) {
1173 + $subex = mb_substr( $text, 0, $num_characters - 5 );
1174 + $exwords = explode( ' ', $subex );
1175 + $excut = - ( mb_strlen( $exwords[ count( $exwords ) - 1 ] ) );
868 1176
869 - if ( ! in_array( $field_name, array( 'per_page', 'pagination' ) ) ) {
870 - $attributes[ $field_name ] = sanitize_text_field( $atts[ $field_name ] );
871 - }
1177 + if ( $excut < 0 ) {
1178 + $text = mb_substr( $subex, 0, $excut );
1179 + } else {
1180 + $text = $subex;
872 1181 }
873 1182
874 - $source_type = sanitize_text_field( $atts['type'] );
875 -
876 - $attributes = array_merge(
877 - $attributes,
878 - array(
879 - 'type' => $source_type,
880 - 'id' => sanitize_text_field( $atts[ $source_type ] ),
881 - 'order' => sanitize_text_field( $atts['order'] ), // works only when type=search
882 - 'per_page' => (int) $atts['per_page'],
883 - 'cache' => (int) $atts['cache'],
884 - 'player_description' => ! empty( $atts['player_description'] ) ? (int) $atts['player_description'] : 0,
885 - 'num_pages' => 1,
886 - 'paged' => ! empty( $atts['paged'] ) ? (int) $atts['paged'] : 1,
887 - 'next_page_token' => ! empty( $atts['next_page_token'] ) ? sanitize_text_field( $atts['next_page_token'] ) : '',
888 - 'prev_page_token' => ! empty( $atts['prev_page_token'] ) ? sanitize_text_field( $atts['prev_page_token'] ) : ''
889 - )
890 - );
1183 + $text .= $append;
1184 + }
891 1185
892 - // Find total number of pages
893 - $videos_found = ! empty( $atts['videos_found'] ) ? (int) $atts['videos_found'] : 0;
1186 + return apply_filters( 'ayg_trim_words', $text, $original_text, $num_characters, $append );
1187 +}
894 1188
895 - if ( $videos_found > 0 ) {
896 - if ( 'search' == $source_type ) {
897 - $limit = min( (int) $atts['limit'], $videos_found );
898 - $attributes['num_pages'] = ceil( $limit / $attributes['per_page'] );
899 - } else {
900 - $attributes['num_pages'] = ceil( $videos_found / $attributes['per_page'] );
901 - }
902 - }
1189 +/**
1190 + * Gallery HTML output.
1191 + *
1192 + * @since 1.0.0
1193 + * @param array $video YouTube video object.
1194 + * @param array $attributes Array of user attributes.
1195 + */
1196 +function the_ayg_gallery_thumbnail( $video, $attributes ) {
1197 + include ayg_get_template( AYG_DIR . 'public/templates/thumbnail.php' );
1198 +}
903 1199
904 - // Process output
905 - if ( $attributes['num_pages'] > 1 ) {
906 - $pagination_type = ( 'pager' == $atts['pagination_type'] ) ? 'pager' : 'loadmore';
907 - include ayg_get_template( AYG_DIR . 'public/templates/pagination-' . $pagination_type. '.php', $attributes['theme'] );
908 - }
1200 +/**
1201 + * Pagination HTML output.
1202 + *
1203 + * @since 1.0.0
1204 + * @param array $attributes Array of user attributes.
1205 + */
1206 +function the_ayg_pagination( $attributes ) {
1207 + if ( ! empty( $attributes['pagination'] ) ) {
1208 + include ayg_get_template( AYG_DIR . 'public/templates/pagination.php' );
909 1209 }
910 1210 }
911 1211
912 1212 /**
913 - * Player HTML output.
1213 + * Search Form HTML output.
914 1214 *
915 - * @since 1.0.0
916 - * @param stdClass $video YouTube video object.
917 - * @param array $attributes Array of user attributes.
1215 + * @since 2.5.7
1216 + * @param array $attributes Array of user attributes.
918 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 + */
919 1231 function the_ayg_player( $video, $attributes ) {
920 - include ayg_get_template( AYG_DIR . 'public/templates/player.php', $attributes['theme'] );
921 -}
1232 + include ayg_get_template( AYG_DIR . 'public/templates/player.php' );
1233 +}