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 +738 -305 1.2.02.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,46 +64,468 @@
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'] );
69 + if ( 'livestream' == $source_type ) {
70 + $attributes['livestream'] = $attributes['channel'];
71 + }
54 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
55 95 $api_params = array(
96 + 'uid' => $attributes['uid'],
56 97 'type' => $source_type,
57 - 'id' => sanitize_text_field( $attributes[ $source_type ] ),
58 - '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".
59 101 'maxResults' => $attributes['per_page'],
60 102 'cache' => (int) $attributes['cache']
61 103 );
62 104
105 + $api_params = apply_filters( 'ayg_youtube_api_request_params', $api_params, $args );
106 +
63 107 $youtube_api = new AYG_YouTube_API();
64 - $response = $youtube_api->get_videos( $api_params );
108 + $response = $youtube_api->query( $api_params );
65 109
66 110 // Process output
67 111 if ( ! isset( $response->error ) ) {
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 + }
122 +
68 123 // Gallery
69 - $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 + }
70 138
71 139 if ( isset( $response->videos ) ) {
72 - $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 + }
73 149 }
74 150
75 151 // Pagination
76 152 if ( isset( $response->page_info ) ) {
77 - $attributes = array_merge( $attributes, $response->page_info, $api_params );
153 + $attributes = array_merge( $attributes, $api_params, $response->page_info );
78 154 }
79 155
156 + // Theme
157 + $theme = 'classic';
158 +
159 + if ( 'video' == $source_type ) {
160 + $theme = 'single';
161 + } elseif ( 'livestream' == $source_type ) {
162 + $theme = 'livestream';
163 + } else {
164 + if ( 1 == count( $videos ) ) {
165 + $theme = 'single';
166 + }
167 + }
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 +
80 177 // Output
81 178 ob_start();
82 - include ayg_get_template( AYG_DIR . 'public/templates/theme-classic.php', $attributes['theme'] );
179 + include ayg_get_template( AYG_DIR . "public/templates/theme-{$theme}.php", $attributes['theme'] );
83 180 return ob_get_clean();
84 181 } else {
85 - return $response->error_message;
182 + return sprintf( '<div class="ayg ayg-error">%s</div>', wp_kses_post( $response->error_message ) );
86 183 }
87 184 }
88 185
89 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 +/**
462 + * Get default plugin settings.
463 + *
464 + * @since 1.6.4
465 + * @return array $defaults Array of plugin settings.
466 + */
467 +function ayg_get_default_settings() {
468 + $defaults = array(
469 + 'ayg_general_settings' => array(
470 + 'api_key' => '',
471 + 'lazyload' => 0,
472 + 'development_mode' => 0
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 + ),
481 + 'ayg_gallery_settings' => array(
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
493 + ),
494 + 'ayg_player_settings' => array(
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
513 + ),
514 + 'ayg_livestream_settings' => array(
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' )
521 + )
522 + );
523 +
524 + return $defaults;
525 +}
526 +
527 +/**
90 528 * Get editor fields.
91 529 *
92 530 * @since 1.0.0
93 531 * @return array Array of fields.
@@ -94,9 +532,9 @@
94 532 */
95 533 function ayg_get_editor_fields() {
96 534 $fields = array(
97 535 'source' => array(
98 - 'label' => __( 'Source', 'automatic-youtube-gallery' ),
536 + 'label' => __( 'General', 'automatic-youtube-gallery' ),
99 537 'fields' => array(
100 538 array(
101 539 'name' => 'type',
102 540 'label' => __( 'Source Type', 'automatic-youtube-gallery' ),
@@ -102,14 +540,15 @@
102 540 'label' => __( 'Source Type', 'automatic-youtube-gallery' ),
103 541 'description' => '',
104 542 'type' => 'select',
105 543 'options' => array(
106 - 'playlist' => __( 'Playlist', 'automatic-youtube-gallery' ),
107 - 'channel' => __( 'Channel', 'automatic-youtube-gallery' ),
108 - 'username' => __( 'Username', 'automatic-youtube-gallery' ),
109 - 'search' => __( 'Keyword', 'automatic-youtube-gallery' ),
110 - 'videos' => __( 'Videos', 'automatic-youtube-gallery' ),
111 - 'video' => __( 'Video', 'automatic-youtube-gallery' )
544 + 'playlist' => __( 'Playlist', 'automatic-youtube-gallery' ),
545 + 'channel' => __( 'Channel', 'automatic-youtube-gallery' ),
546 + 'username' => __( 'Username', 'automatic-youtube-gallery' ),
547 + 'search' => __( 'Search Keywords', 'automatic-youtube-gallery' ),
548 + 'video' => __( 'Single Video', 'automatic-youtube-gallery' ),
549 + 'livestream' => __( 'Livestream', 'automatic-youtube-gallery' ),
550 + 'videos' => __( 'Custom Videos List', 'automatic-youtube-gallery' )
112 551 ),
113 552 'value' => 'playlist',
114 553 'sanitize_callback' => 'sanitize_key'
115 554 ),
@@ -114,9 +553,9 @@
114 553 'sanitize_callback' => 'sanitize_key'
115 554 ),
116 555 array(
117 556 'name' => 'playlist',
118 - 'label' => __( 'YouTube Playlist URL', 'automatic-youtube-gallery' ),
557 + 'label' => __( 'YouTube Playlist ID (or) URL', 'automatic-youtube-gallery' ),
119 558 'description' => sprintf( '%s: https://www.youtube.com/playlist?list=XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
120 559 'type' => 'url',
121 560 'value' => '',
122 561 'sanitize_callback' => 'sanitize_text_field'
@@ -122,9 +561,9 @@
122 561 'sanitize_callback' => 'sanitize_text_field'
123 562 ),
124 563 array(
125 564 'name' => 'channel',
126 - 'label' => __( 'YouTube Channel URL', 'automatic-youtube-gallery' ),
565 + 'label' => __( 'YouTube Channel ID (or) a YouTube Video URL from the Channel', 'automatic-youtube-gallery' ),
127 566 'description' => sprintf( '%s: https://www.youtube.com/channel/XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
128 567 'type' => 'url',
129 568 'value' => '',
130 569 'sanitize_callback' => 'sanitize_text_field'
@@ -138,10 +577,10 @@
138 577 'sanitize_callback' => 'sanitize_text_field'
139 578 ),
140 579 array(
141 580 'name' => 'search',
142 - 'label' => __( 'Enter a Search Keyword', 'automatic-youtube-gallery' ),
143 - 'description' => sprintf( '%s: Cartoon', __( 'Example', 'automatic-youtube-gallery' ) ),
581 + 'label' => __( 'Search Keywords', 'automatic-youtube-gallery' ),
582 + 'description' => sprintf( '%s: Cartoon (space:AND , -:NOT , |:OR)', __( 'Example', 'automatic-youtube-gallery' ) ),
144 583 'type' => 'text',
145 584 'value' => '',
146 585 'sanitize_callback' => 'sanitize_text_field'
147 586 ),
@@ -146,23 +585,23 @@
146 585 'sanitize_callback' => 'sanitize_text_field'
147 586 ),
148 587 array(
149 588 'name' => 'video',
150 - 'label' => __( 'Enter a YouTube Video URL', 'automatic-youtube-gallery' ),
589 + 'label' => __( 'YouTube Video ID (or) URL', 'automatic-youtube-gallery' ),
151 590 'description' => sprintf( '%s: https://www.youtube.com/watch?v=XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
152 591 'type' => 'url',
153 592 'value' => '',
154 593 'sanitize_callback' => 'sanitize_text_field'
155 - ),
594 + ),
156 595 array(
157 596 'name' => 'videos',
158 - 'label' => __( 'YouTube Video URLs', 'automatic-youtube-gallery' ),
597 + 'label' => __( 'YouTube Video IDs (or) URLs', 'automatic-youtube-gallery' ),
159 598 'description' => sprintf( '%s: https://www.youtube.com/watch?v=XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
160 599 'type' => 'textarea',
161 600 'placeholder' => __( 'Enter one video per line', 'automatic-youtube-gallery' ),
162 601 'value' => '',
163 602 'sanitize_callback' => 'sanitize_text_field'
164 - ),
603 + ),
165 604 array(
166 605 'name' => 'order',
167 606 'label' => __( 'Order Videos by', 'automatic-youtube-gallery' ),
168 607 'description' => '',
@@ -188,21 +627,21 @@
188 627 'sanitize_callback' => 'intval'
189 628 ),
190 629 array(
191 630 'name' => 'cache',
192 - 'label' => __( 'Refresh the data every (Cache time)', 'automatic-youtube-gallery' ),
193 - 'description' => __( 'Specifies how frequently the plugin should check your YouTube source for any new update.', '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' ),
194 633 'type' => 'select',
195 634 'options' => array(
196 - '0' => __( 'Page load', 'automatic-youtube-gallery' ),
197 - '900' => __( '15 minutes', 'automatic-youtube-gallery' ),
198 - '1800' => __( '30 minutes', 'automatic-youtube-gallery' ),
199 - '3600' => __( 'Hour', 'automatic-youtube-gallery' ),
200 - '86400' => __( 'Day', 'automatic-youtube-gallery' ),
201 - '604800' => __( 'Week', 'automatic-youtube-gallery' ),
202 - '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' )
203 642 ),
204 - 'value' => 0,
643 + 'value' => 86400,
205 644 'sanitize_callback' => 'intval'
206 645 )
207 646 )
208 647 ),
@@ -212,8 +651,24 @@
212 651 ),
213 652 'player' => array(
214 653 'label' => __( 'Player (optional)', 'automatic-youtube-gallery' ),
215 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 + )
216 671 )
217 672 );
218 673
219 674 return apply_filters( 'ayg_editor_fields', $fields );
@@ -219,109 +674,8 @@
219 674 return apply_filters( 'ayg_editor_fields', $fields );
220 675 }
221 676
222 677 /**
223 - * Get gallery thumbnail video excerpt (short description).
224 - *
225 - * @since 1.0.0
226 - * @param stdClass $video YouTube video object.
227 - * @param array $attributes Array of user attributes.
228 - * @return string Video excerpt.
229 - */
230 -function ayg_get_gallery_thumb_excerpt( $video, $attributes ) {
231 - $char_length = (int) $attributes['thumb_excerpt_length'];
232 - $char_length++;
233 -
234 - $content = '';
235 - if ( ! empty( $attributes['thumb_excerpt'] ) ) {
236 - $content = ( $char_length > 1 ) ? wp_strip_all_tags( $video->description, true ) : nl2br( $video->description );
237 - }
238 -
239 - $excerpt = '';
240 -
241 - if ( $char_length > 1 && mb_strlen( $content ) > $char_length ) {
242 - $subex = mb_substr( $content, 0, $char_length - 5 );
243 - $exwords = explode( ' ', $subex );
244 - $excut = - ( mb_strlen( $exwords[ count( $exwords ) - 1 ] ) );
245 - if ( $excut < 0 ) {
246 - $excerpt = mb_substr( $subex, 0, $excut );
247 - } else {
248 - $excerpt = $subex;
249 - }
250 - $excerpt .= '[...]';
251 - } else {
252 - $excerpt = $content;
253 - }
254 -
255 - return apply_filters( 'ayg_gallery_thumb_excerpt', $excerpt, $video, $attributes );
256 -}
257 -
258 -/**
259 - * Get gallery thumbnail image.
260 - *
261 - * @since 1.0.0
262 - * @param stdClass $video YouTube video object.
263 - * @param array $attributes Array of user attributes.
264 - * @return string Video thumbnail image.
265 - */
266 -function ayg_get_gallery_thumb_image( $video, $attributes ) {
267 - $image = '';
268 -
269 - if ( isset( $video->thumbnails->default ) ) {
270 - $image = $video->thumbnails->default->url;
271 - }
272 -
273 - // 4:3 ( default - 120x90, high - 480x360, standard - 640x480 )
274 - if ( 75 == (int) $attributes['thumb_ratio'] ) {
275 - if ( isset( $video->thumbnails->high ) ) {
276 - $image = $video->thumbnails->high->url;
277 - }
278 - }
279 -
280 - // 16:9 ( medium - 320x180, maxres - 1280x720 )
281 - if ( 56.25 == (float) $attributes['thumb_ratio'] ) {
282 - if ( isset( $video->thumbnails->medium ) ) {
283 - $image = $video->thumbnails->medium->url;
284 - }
285 - }
286 -
287 - return apply_filters( 'ayg_gallery_thumb_image', $image, $video, $attributes );
288 -}
289 -
290 -/**
291 - * Get gallery thumbnail video title.
292 - *
293 - * @since 1.0.0
294 - * @param stdClass $video YouTube video object.
295 - * @param array $attributes Array of user attributes.
296 - * @return string Video title.
297 - */
298 -function ayg_get_gallery_thumb_title( $video, $attributes ) {
299 - $text = ! empty( $attributes['thumb_title'] ) ? $video->title : '';
300 -
301 - $char_length = (int) $attributes['thumb_title_length'];
302 - $char_length++;
303 -
304 - $title = '';
305 -
306 - if ( $char_length > 1 && mb_strlen( $text ) > $char_length ) {
307 - $subex = mb_substr( $text, 0, $char_length - 5 );
308 - $exwords = explode( ' ', $subex );
309 - $excut = - ( mb_strlen( $exwords[ count( $exwords ) - 1 ] ) );
310 - if ( $excut < 0 ) {
311 - $title = mb_substr( $subex, 0, $excut );
312 - } else {
313 - $title = $subex;
314 - }
315 - $title .= '[...]';
316 - } else {
317 - $title = $text;
318 - }
319 -
320 - return apply_filters( 'ayg_gallery_thumb_title', $title, $video, $attributes );
321 -}
322 -
323 -/**
324 678 * Get gallery settings fields.
325 679 *
326 680 * @since 1.0.0
327 681 * @return array $fields Array of fields.
@@ -331,10 +685,10 @@
331 685
332 686 $fields = array(
333 687 array(
334 688 'name' => 'theme',
335 - 'label' => __( 'Select Theme', 'automatic-youtube-gallery' ),
336 - '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() ) ) : '' ),
337 691 'type' => 'select',
338 692 'options' => array(
339 693 'classic' => __( 'Classic', 'automatic-youtube-gallery' )
340 694 ),
@@ -352,9 +706,9 @@
352 706 'sanitize_callback' => 'intval'
353 707 ),
354 708 array(
355 709 'name' => 'per_page',
356 - 'label' => __( 'Videos per page', 'automatic-youtube-gallery' ),
710 + 'label' => __( 'Videos per Page', 'automatic-youtube-gallery' ),
357 711 'description' => __( 'Enter the number of videos to show per page. Maximum of 50.', 'automatic-youtube-gallery' ),
358 712 'type' => 'number',
359 713 'min' => 0,
360 714 'max' => 50,
@@ -362,9 +716,10 @@
362 716 'sanitize_callback' => 'intval'
363 717 ),
364 718 array(
365 719 'name' => 'thumb_ratio',
366 - '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' ),
367 722 'type' => 'radio',
368 723 'options' => array(
369 724 '56.25' => '16:9',
370 725 '75' => '4:3'
@@ -420,10 +775,11 @@
420 775 'name' => 'pagination_type',
421 776 'label' => __( 'Pagination Type', 'automatic-youtube-gallery' ),
422 777 'type' => 'select',
423 778 'options' => array(
424 - 'pager' => __( 'Pager', 'automatic-youtube-gallery' ),
425 - 'load_more' => __( 'Load More', 'automatic-youtube-gallery' )
779 + 'more' => __( 'More Button', 'automatic-youtube-gallery' ),
780 + 'pager' => __( 'Pager', 'automatic-youtube-gallery' )
781 +
426 782 ),
427 783 'value' => $gallery_settings['pagination_type'],
428 784 'sanitize_callback' => 'sanitize_key'
429 785 )
@@ -440,86 +796,27 @@
440 796 * @param array $attributes Array of user attributes.
441 797 * @param int $words_count Number of words to show by default.
442 798 * @return string Video description.
443 799 */
444 -function ayg_get_player_description( $video, $attributes, $words_count = 30 ) {
445 - $description = ! empty( $attributes['player_description'] ) ? $video->description : '';
800 +function ayg_get_player_description( $video, $attributes = array(), $words_count = 30 ) {
801 + $description = $video->description;
446 802
447 - $words_array = explode( ' ', strip_tags( $description ) );
448 -
803 + $words_array = explode( ' ', strip_tags( $description ) );
449 804 if ( count( $words_array ) > $words_count ) {
450 - $words_array[ $words_count ] = '</span><span class="ayg-player-description-more">' . $words_array[ $words_count ];
805 + $show_more_label = ! empty( $attributes['show_more_label'] ) ? $attributes['show_more_label'] : __( 'Show More', 'automatic-youtube-gallery' );
806 + $words_array[ $words_count ] = '<span class="ayg-player-description-dots">...</span></span><span class="ayg-player-description-more">' . $words_array[ $words_count ];
451 807
452 808 $description = '<span class="ayg-player-description-less">' . implode( ' ', $words_array ) . '</span>';
453 - $description .= '<span><a class="ayg-player-description-more-less-btn">' . __( 'Show More', 'automatic-youtube-gallery' ) . '</a></span>';
809 + $description .= '<a href="#" class="ayg-player-description-toggle-btn">' . esc_html( $show_more_label ) . '</a>';
454 810 }
455 811
456 - return apply_filters( 'ayg_player_description', nl2br( $description ), $video, $attributes, $words_count );
457 -}
812 + $description = nl2br( $description );
813 + $description = make_clickable( $description );
458 814
459 -/**
460 - * Get YouTube player embed URL.
461 - *
462 - * @since 1.0.0
463 - * @param stdClass $video YouTube video object.
464 - * @param array $attributes Array of user attributes.
465 - * @return string YouTube video embed URL.
466 - */
467 -function ayg_get_player_embed_url( $video, $attributes ) {
468 - $url = "https://www.youtube-nocookie.com/embed/{$video->id}";
469 -
470 - if ( ! empty( $attributes['autoplay'] ) ) { // autoplay
471 - $url = add_query_arg( 'autoplay', 1, $url );
472 - }
473 -
474 - if ( ! empty( $attributes['loop'] ) ) { // loop
475 - $url = add_query_arg( 'loop', 1, $url );
476 - }
477 -
478 - if ( empty( $attributes['controls'] ) ) { // controls
479 - $url = add_query_arg( 'controls', 0, $url );
480 - }
481 -
482 - if ( ! empty( $attributes['modestbranding'] ) ) { // modestbranding
483 - $url = add_query_arg( 'modestbranding', 1, $url );
484 - }
485 -
486 - if ( ! empty( $attributes['cc_load_policy'] ) ) { // cc_load_policy
487 - $url = add_query_arg( 'cc_load_policy', 1, $url );
488 - }
489 -
490 - if ( empty( $attributes['iv_load_policy'] ) ) { // iv_load_policy
491 - $url = add_query_arg( 'iv_load_policy', 3, $url );
492 - }
493 -
494 - if ( ! empty( $attributes['hl'] ) ) { // hl
495 - $url = add_query_arg( 'hl', $attributes['hl'], $url );
496 - }
497 -
498 - if ( ! empty( $attributes['cc_lang_pref'] ) ) { // cc_lang_pref
499 - $url = add_query_arg( 'cc_lang_pref', $attributes['cc_lang_pref'], $url );
500 - }
501 -
502 - $url = add_query_arg( 'rel', 0, $url ); // rel
503 - $url = add_query_arg( 'playsinline', 1, $url ); // playsinline
504 - $url = add_query_arg( 'enablejsapi', 1, $url ); // enablejsapi
505 -
506 - return apply_filters( 'ayg_player_embed_url', $url, $video, $attributes );
815 + return apply_filters( 'ayg_player_description', $description, $video, $attributes, $words_count );
507 816 }
508 817
509 818 /**
510 - * Get player ratio.
511 - *
512 - * @since 1.0.0
513 - * @param array $attributes Array of user attributes.
514 - * @return string Player ratio.
515 - */
516 -function ayg_get_player_ratio( $attributes ) {
517 - $ratio = ! empty( $attributes['player_ratio'] ) ? $attributes['player_ratio'] . '%' : '56.25%';
518 - return apply_filters( 'ayg_player_ratio', $ratio, $attributes );
519 -}
520 -
521 -/**
522 819 * Get player settings fields.
523 820 *
524 821 * @since 1.0.0
525 822 * @return array $fields Array of fields.
@@ -528,10 +825,19 @@
528 825 $player_settings = get_option( 'ayg_player_settings' );
529 826
530 827 $fields = array(
531 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(
532 837 'name' => 'player_ratio',
533 - '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' ),
534 840 'type' => 'radio',
535 841 'options' => array(
536 842 '56.25' => '16:9',
537 843 '75' => '4:3'
@@ -577,10 +883,18 @@
577 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' ),
578 884 'type' => 'checkbox',
579 885 'value' => $player_settings['loop'],
580 886 'sanitize_callback' => 'intval'
581 - ),
887 + ),
582 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(
583 897 'name' => 'controls',
584 898 'label' => __( 'Show Player Controls', 'automatic-youtube-gallery' ),
585 899 'description' => __( 'Uncheck this option to hide the video player controls.', 'automatic-youtube-gallery' ),
586 900 'type' => 'checkbox',
@@ -637,31 +951,19 @@
637 951
638 952 return $fields;
639 953 }
640 954
641 -/**
642 - * Get video title to show on bottom of the player.
643 - *
644 - * @since 1.0.0
645 - * @param stdClass $video YouTube video object.
646 - * @param array $attributes Array of user attributes.
647 - * @return string Video title.
648 - */
649 -function ayg_get_player_title( $video, $attributes ) {
650 - $title = ! empty( $attributes['player_title'] ) ? $video->title : '';
651 - return apply_filters( 'ayg_player_title', $title, $video, $attributes );
652 -}
653 955
654 956 /**
655 - * Get player width.
957 + * Get a single video page URL.
656 958 *
657 - * @since 1.0.0
658 - * @param array $attributes Array of user attributes.
659 - * @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.
660 963 */
661 -function ayg_get_player_width( $attributes ) {
662 - $width = ! empty( $attributes['player_width'] ) ? $attributes['player_width'] . 'px' : '100%';
663 - 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 );
664 966 }
665 967
666 968 /**
667 969 * Get filtered php template file path.
@@ -691,8 +993,157 @@
691 993 return uniqid() . ++$ayg_uniqid;
692 994 }
693 995
694 996 /**
997 + * Get YouTube domain.
998 + *
999 + * @since 2.3.0
1000 + * @return string YouTube embed domain.
1001 + */
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;
1011 +}
1012 +
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 +/**
1094 + * Inserts a new associative array after another associative array key.
1095 + *
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.
1101 + */
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;
1120 +}
1121 +
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 +/**
695 1146 * Sanitize the integer inputs, accepts empty values.
696 1147 *
697 1148 * @since 1.0.0
698 1149 * @param string|int $value Input value.
@@ -703,98 +1154,80 @@
703 1154 return ( 0 == $value ) ? '' : $value;
704 1155 }
705 1156
706 1157 /**
707 - * Gallery HTML output.
1158 + * Trims text to a certain number of characters.
708 1159 *
709 - * @since 1.0.0
710 - * @param array $videos Array of YouTube video object.
711 - * @param array $attributes Array of user attributes.
712 - * @param int $active_id Current active/selected video ID in the gallery.
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.
713 1165 */
714 -function the_ayg_gallery( $videos, $attributes, $active_id = 0 ) {
715 - if ( 'video' != $attributes['type'] ) {
716 - include ayg_get_template( AYG_DIR . 'public/templates/gallery.php', $attributes['theme'] );
1166 +function ayg_trim_words( $text, $num_characters, $append = '...' ) {
1167 + $num_characters++;
1168 +
1169 + $original_text = $text;
1170 + $text = ( $num_characters > 1 ) ? wp_strip_all_tags( $original_text, true ) : nl2br( $original_text );
1171 +
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 ] ) );
1176 +
1177 + if ( $excut < 0 ) {
1178 + $text = mb_substr( $subex, 0, $excut );
1179 + } else {
1180 + $text = $subex;
1181 + }
1182 +
1183 + $text .= $append;
717 1184 }
1185 +
1186 + return apply_filters( 'ayg_trim_words', $text, $original_text, $num_characters, $append );
718 1187 }
719 1188
720 1189 /**
721 1190 * Gallery HTML output.
722 1191 *
723 - * @since 1.0.0
724 - * @param array $video YouTube video object.
725 - * @param array $attributes Array of user attributes.
726 - * @param boolean $is_active True if active video item, false if not.
1192 + * @since 1.0.0
1193 + * @param array $video YouTube video object.
1194 + * @param array $attributes Array of user attributes.
727 1195 */
728 -function the_ayg_gallery_thumbnail( $video, $attributes, $is_active = false ) {
729 - include ayg_get_template( AYG_DIR . 'public/templates/gallery-thumbnail.php', $attributes['theme'] );
1196 +function the_ayg_gallery_thumbnail( $video, $attributes ) {
1197 + include ayg_get_template( AYG_DIR . 'public/templates/thumbnail.php' );
730 1198 }
731 1199
732 1200 /**
733 1201 * Pagination HTML output.
734 1202 *
735 - * @since 1.0.0
736 - * @param array $atts Array of user attributes.
1203 + * @since 1.0.0
1204 + * @param array $attributes Array of user attributes.
737 1205 */
738 -function the_ayg_pagination( $atts ) {
739 - if ( ! empty( $atts['pagination'] ) ) {
740 - // Build attributes
741 - $attributes = array();
1206 +function the_ayg_pagination( $attributes ) {
1207 + if ( ! empty( $attributes['pagination'] ) ) {
1208 + include ayg_get_template( AYG_DIR . 'public/templates/pagination.php' );
1209 + }
1210 +}
742 1211
743 - $fields = ayg_get_editor_fields();
744 -
745 - foreach ( $fields['gallery']['fields'] as $field ) {
746 - $field_name = $field['name'];
747 -
748 - if ( ! in_array( $field_name, array( 'per_page', 'pagination', 'pagination_type' ) ) ) {
749 - $attributes[ $field_name ] = sanitize_text_field( $atts[ $field_name ] );
750 - }
751 - }
752 -
753 - $source_type = sanitize_text_field( $atts['type'] );
754 -
755 - $attributes = array_merge(
756 - $attributes,
757 - array(
758 - 'type' => $source_type,
759 - 'id' => sanitize_text_field( $atts[ $source_type ] ),
760 - 'order' => sanitize_text_field( $atts['order'] ), // works only when type=search
761 - 'per_page' => (int) $atts['per_page'],
762 - 'cache' => (int) $atts['cache'],
763 - 'num_pages' => 1,
764 - 'paged' => ! empty( $atts['paged'] ) ? (int) $atts['paged'] : 1,
765 - 'next_page_token' => ! empty( $atts['next_page_token'] ) ? sanitize_text_field( $atts['next_page_token'] ) : '',
766 - 'prev_page_token' => ! empty( $atts['prev_page_token'] ) ? sanitize_text_field( $atts['prev_page_token'] ) : '',
767 - 'player_description' => (int) $atts['player_description']
768 - )
769 - );
770 -
771 - // Find total number of pages
772 - $videos_found = ! empty( $atts['videos_found'] ) ? (int) $atts['videos_found'] : 0;
773 -
774 - if ( $videos_found > 0 ) {
775 - if ( 'search' == $source_type ) {
776 - $limit = min( (int) $atts['limit'], $videos_found );
777 - $attributes['num_pages'] = ceil( $limit / $attributes['per_page'] );
778 - } else {
779 - $attributes['num_pages'] = ceil( $videos_found / $attributes['per_page'] );
780 - }
781 - }
782 -
783 - // Process output
784 - if ( $attributes['num_pages'] > 1 ) {
785 - $pagination_type = ( 'pager' == $atts['pagination_type'] ) ? 'pager' : 'loadmore';
786 - include ayg_get_template( AYG_DIR . 'public/templates/pagination-' . $pagination_type. '.php', $attributes['theme'] );
787 - }
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' );
788 1221 }
789 1222 }
790 1223
791 1224 /**
792 - * Player HTML output.
1225 + * Gallery HTML output.
793 1226 *
794 - * @since 1.0.0
795 - * @param stdClass $video YouTube video object.
796 - * @param array $attributes Array of user attributes.
1227 + * @since 2.5.0
1228 + * @param array $video YouTube video object.
1229 + * @param array $attributes Array of user attributes.
797 1230 */
798 1231 function the_ayg_player( $video, $attributes ) {
799 - include ayg_get_template( AYG_DIR . 'public/templates/player.php', $attributes['theme'] );
800 -}
1232 + include ayg_get_template( AYG_DIR . 'public/templates/player.php' );
1233 +}