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 +736 -311 1.6.32.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,54 +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
55 - if ( 'video' == $source_type ) {
56 - $attributes['theme'] = 'classic';
73 + $attributes['lazyload'] = 0;
74 + if ( ! empty( $general_settings['lazyload'] ) ) {
75 + $attributes['lazyload'] = 1;
57 76 }
58 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
105 + $api_params = apply_filters( 'ayg_youtube_api_request_params', $api_params, $args );
106 +
67 107 $youtube_api = new AYG_YouTube_API();
68 - $response = $youtube_api->get_videos( $api_params );
108 + $response = $youtube_api->query( $api_params );
69 109
70 110 // Process output
71 111 if ( ! isset( $response->error ) ) {
72 - // Enqueue dependencies
73 - wp_enqueue_style( AYG_SLUG . '-public' );
74 - 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 + }
75 122
76 123 // Gallery
77 - $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 + }
78 138
79 139 if ( isset( $response->videos ) ) {
80 - $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 + }
81 149 }
82 150
83 151 // Pagination
84 152 if ( isset( $response->page_info ) ) {
85 - $attributes = array_merge( $attributes, $response->page_info, $api_params );
153 + $attributes = array_merge( $attributes, $api_params, $response->page_info );
86 154 }
87 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 +
88 177 // Output
89 178 ob_start();
90 - 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'] );
91 180 return ob_get_clean();
92 181 } else {
93 - 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 ) );
94 183 }
95 184 }
96 185
97 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 +/**
98 528 * Get editor fields.
99 529 *
100 530 * @since 1.0.0
101 531 * @return array Array of fields.
@@ -110,14 +540,15 @@
110 540 'label' => __( 'Source Type', 'automatic-youtube-gallery' ),
111 541 'description' => '',
112 542 'type' => 'select',
113 543 'options' => array(
114 - 'playlist' => __( 'Playlist', 'automatic-youtube-gallery' ),
115 - 'channel' => __( 'Channel', 'automatic-youtube-gallery' ),
116 - 'username' => __( 'Username', 'automatic-youtube-gallery' ),
117 - 'search' => __( 'Search Terms', 'automatic-youtube-gallery' ),
118 - 'videos' => __( 'Custom Videos List', 'automatic-youtube-gallery' ),
119 - 'video' => __( 'Single 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' )
120 551 ),
121 552 'value' => 'playlist',
122 553 'sanitize_callback' => 'sanitize_key'
123 554 ),
@@ -130,9 +561,9 @@
130 561 'sanitize_callback' => 'sanitize_text_field'
131 562 ),
132 563 array(
133 564 'name' => 'channel',
134 - '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' ),
135 566 'description' => sprintf( '%s: https://www.youtube.com/channel/XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
136 567 'type' => 'url',
137 568 'value' => '',
138 569 'sanitize_callback' => 'sanitize_text_field'
@@ -146,13 +577,21 @@
146 577 'sanitize_callback' => 'sanitize_text_field'
147 578 ),
148 579 array(
149 580 'name' => 'search',
150 - 'label' => __( 'Search Terms', 'automatic-youtube-gallery' ),
581 + 'label' => __( 'Search Keywords', 'automatic-youtube-gallery' ),
151 582 'description' => sprintf( '%s: Cartoon (space:AND , -:NOT , |:OR)', __( 'Example', 'automatic-youtube-gallery' ) ),
152 583 'type' => 'text',
153 584 'value' => '',
154 585 'sanitize_callback' => 'sanitize_text_field'
586 + ),
587 + array(
588 + 'name' => 'video',
589 + 'label' => __( 'YouTube Video ID (or) URL', 'automatic-youtube-gallery' ),
590 + 'description' => sprintf( '%s: https://www.youtube.com/watch?v=XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
591 + 'type' => 'url',
592 + 'value' => '',
593 + 'sanitize_callback' => 'sanitize_text_field'
155 594 ),
156 595 array(
157 596 'name' => 'videos',
158 597 'label' => __( 'YouTube Video IDs (or) URLs', 'automatic-youtube-gallery' ),
@@ -160,18 +599,10 @@
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 - 'name' => 'video',
167 - 'label' => __( 'YouTube Video ID (or) URL', 'automatic-youtube-gallery' ),
168 - 'description' => sprintf( '%s: https://www.youtube.com/watch?v=XXXXXXXXXX', __( 'Example', 'automatic-youtube-gallery' ) ),
169 - 'type' => 'url',
170 - 'value' => '',
171 - 'sanitize_callback' => 'sanitize_text_field'
172 - ),
173 - array(
174 605 'name' => 'order',
175 606 'label' => __( 'Order Videos by', 'automatic-youtube-gallery' ),
176 607 'description' => '',
177 608 'type' => 'select',
@@ -196,21 +627,21 @@
196 627 'sanitize_callback' => 'intval'
197 628 ),
198 629 array(
199 630 'name' => 'cache',
200 - 'label' => __( 'Refresh the data every (Cache time)', 'automatic-youtube-gallery' ),
201 - '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' ),
202 633 'type' => 'select',
203 634 'options' => array(
204 - '0' => __( 'Page load', 'automatic-youtube-gallery' ),
205 - '900' => __( '15 minutes', 'automatic-youtube-gallery' ),
206 - '1800' => __( '30 minutes', 'automatic-youtube-gallery' ),
207 - '3600' => __( 'Hour', 'automatic-youtube-gallery' ),
208 - '86400' => __( 'Day', 'automatic-youtube-gallery' ),
209 - '604800' => __( 'Week', 'automatic-youtube-gallery' ),
210 - '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' )
211 642 ),
212 - 'value' => 0,
643 + 'value' => 86400,
213 644 'sanitize_callback' => 'intval'
214 645 )
215 646 )
216 647 ),
@@ -220,8 +651,24 @@
220 651 ),
221 652 'player' => array(
222 653 'label' => __( 'Player (optional)', 'automatic-youtube-gallery' ),
223 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 + )
224 671 )
225 672 );
226 673
227 674 return apply_filters( 'ayg_editor_fields', $fields );
@@ -227,109 +674,8 @@
227 674 return apply_filters( 'ayg_editor_fields', $fields );
228 675 }
229 676
230 677 /**
231 - * Get gallery thumbnail video excerpt (short description).
232 - *
233 - * @since 1.0.0
234 - * @param stdClass $video YouTube video object.
235 - * @param array $attributes Array of user attributes.
236 - * @return string Video excerpt.
237 - */
238 -function ayg_get_gallery_thumb_excerpt( $video, $attributes ) {
239 - $char_length = (int) $attributes['thumb_excerpt_length'];
240 - $char_length++;
241 -
242 - $content = '';
243 - if ( ! empty( $attributes['thumb_excerpt'] ) ) {
244 - $content = ( $char_length > 1 ) ? wp_strip_all_tags( $video->description, true ) : nl2br( $video->description );
245 - }
246 -
247 - $excerpt = '';
248 -
249 - if ( $char_length > 1 && mb_strlen( $content ) > $char_length ) {
250 - $subex = mb_substr( $content, 0, $char_length - 5 );
251 - $exwords = explode( ' ', $subex );
252 - $excut = - ( mb_strlen( $exwords[ count( $exwords ) - 1 ] ) );
253 - if ( $excut < 0 ) {
254 - $excerpt = mb_substr( $subex, 0, $excut );
255 - } else {
256 - $excerpt = $subex;
257 - }
258 - $excerpt .= '[...]';
259 - } else {
260 - $excerpt = $content;
261 - }
262 -
263 - return apply_filters( 'ayg_gallery_thumb_excerpt', $excerpt, $video, $attributes );
264 -}
265 -
266 -/**
267 - * Get gallery thumbnail image.
268 - *
269 - * @since 1.0.0
270 - * @param stdClass $video YouTube video object.
271 - * @param array $attributes Array of user attributes.
272 - * @return string Video thumbnail image.
273 - */
274 -function ayg_get_gallery_thumb_image( $video, $attributes ) {
275 - $image = '';
276 -
277 - if ( isset( $video->thumbnails->default ) ) {
278 - $image = $video->thumbnails->default->url;
279 - }
280 -
281 - // 4:3 ( default - 120x90, high - 480x360, standard - 640x480 )
282 - if ( 75 == (int) $attributes['thumb_ratio'] ) {
283 - if ( isset( $video->thumbnails->high ) ) {
284 - $image = $video->thumbnails->high->url;
285 - }
286 - }
287 -
288 - // 16:9 ( medium - 320x180, maxres - 1280x720 )
289 - if ( 56.25 == (float) $attributes['thumb_ratio'] ) {
290 - if ( isset( $video->thumbnails->medium ) ) {
291 - $image = $video->thumbnails->medium->url;
292 - }
293 - }
294 -
295 - return apply_filters( 'ayg_gallery_thumb_image', $image, $video, $attributes );
296 -}
297 -
298 -/**
299 - * Get gallery thumbnail video title.
300 - *
301 - * @since 1.0.0
302 - * @param stdClass $video YouTube video object.
303 - * @param array $attributes Array of user attributes.
304 - * @return string Video title.
305 - */
306 -function ayg_get_gallery_thumb_title( $video, $attributes ) {
307 - $text = ! empty( $attributes['thumb_title'] ) ? $video->title : '';
308 -
309 - $char_length = (int) $attributes['thumb_title_length'];
310 - $char_length++;
311 -
312 - $title = '';
313 -
314 - if ( $char_length > 1 && mb_strlen( $text ) > $char_length ) {
315 - $subex = mb_substr( $text, 0, $char_length - 5 );
316 - $exwords = explode( ' ', $subex );
317 - $excut = - ( mb_strlen( $exwords[ count( $exwords ) - 1 ] ) );
318 - if ( $excut < 0 ) {
319 - $title = mb_substr( $subex, 0, $excut );
320 - } else {
321 - $title = $subex;
322 - }
323 - $title .= '[...]';
324 - } else {
325 - $title = $text;
326 - }
327 -
328 - return apply_filters( 'ayg_gallery_thumb_title', $title, $video, $attributes );
329 -}
330 -
331 -/**
332 678 * Get gallery settings fields.
333 679 *
334 680 * @since 1.0.0
335 681 * @return array $fields Array of fields.
@@ -339,10 +685,10 @@
339 685
340 686 $fields = array(
341 687 array(
342 688 'name' => 'theme',
343 - 'label' => __( 'Select Theme', 'automatic-youtube-gallery' ),
344 - '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() ) ) : '' ),
345 691 'type' => 'select',
346 692 'options' => array(
347 693 'classic' => __( 'Classic', 'automatic-youtube-gallery' )
348 694 ),
@@ -360,9 +706,9 @@
360 706 'sanitize_callback' => 'intval'
361 707 ),
362 708 array(
363 709 'name' => 'per_page',
364 - 'label' => __( 'Videos per page', 'automatic-youtube-gallery' ),
710 + 'label' => __( 'Videos per Page', 'automatic-youtube-gallery' ),
365 711 'description' => __( 'Enter the number of videos to show per page. Maximum of 50.', 'automatic-youtube-gallery' ),
366 712 'type' => 'number',
367 713 'min' => 0,
368 714 'max' => 50,
@@ -370,9 +716,10 @@
370 716 'sanitize_callback' => 'intval'
371 717 ),
372 718 array(
373 719 'name' => 'thumb_ratio',
374 - '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' ),
375 722 'type' => 'radio',
376 723 'options' => array(
377 724 '56.25' => '16:9',
378 725 '75' => '4:3'
@@ -428,10 +775,11 @@
428 775 'name' => 'pagination_type',
429 776 'label' => __( 'Pagination Type', 'automatic-youtube-gallery' ),
430 777 'type' => 'select',
431 778 'options' => array(
432 - 'pager' => __( 'Pager', 'automatic-youtube-gallery' ),
433 - 'load_more' => __( 'Load More', 'automatic-youtube-gallery' )
779 + 'more' => __( 'More Button', 'automatic-youtube-gallery' ),
780 + 'pager' => __( 'Pager', 'automatic-youtube-gallery' )
781 +
434 782 ),
435 783 'value' => $gallery_settings['pagination_type'],
436 784 'sanitize_callback' => 'sanitize_key'
437 785 )
@@ -448,86 +796,27 @@
448 796 * @param array $attributes Array of user attributes.
449 797 * @param int $words_count Number of words to show by default.
450 798 * @return string Video description.
451 799 */
452 -function ayg_get_player_description( $video, $attributes, $words_count = 30 ) {
453 - $description = ! empty( $attributes['player_description'] ) ? $video->description : '';
800 +function ayg_get_player_description( $video, $attributes = array(), $words_count = 30 ) {
801 + $description = $video->description;
454 802
455 - $words_array = explode( ' ', strip_tags( $description ) );
456 -
803 + $words_array = explode( ' ', strip_tags( $description ) );
457 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' );
458 806 $words_array[ $words_count ] = '<span class="ayg-player-description-dots">...</span></span><span class="ayg-player-description-more">' . $words_array[ $words_count ];
459 807
460 808 $description = '<span class="ayg-player-description-less">' . implode( ' ', $words_array ) . '</span>';
461 - $description .= '<button type="button" class="ayg-player-description-toggle-btn">' . __( 'Show More', 'automatic-youtube-gallery' ) . '</button>';
809 + $description .= '<a href="#" class="ayg-player-description-toggle-btn">' . esc_html( $show_more_label ) . '</a>';
462 810 }
463 811
464 - return apply_filters( 'ayg_player_description', nl2br( $description ), $video, $attributes, $words_count );
465 -}
812 + $description = nl2br( $description );
813 + $description = make_clickable( $description );
466 814
467 -/**
468 - * Get YouTube player embed URL.
469 - *
470 - * @since 1.0.0
471 - * @param stdClass $video YouTube video object.
472 - * @param array $attributes Array of user attributes.
473 - * @return string YouTube video embed URL.
474 - */
475 -function ayg_get_player_embed_url( $video, $attributes ) {
476 - $url = "https://www.youtube-nocookie.com/embed/{$video->id}";
477 -
478 - if ( ! empty( $attributes['autoplay'] ) ) { // autoplay
479 - $url = add_query_arg( 'autoplay', 1, $url );
480 - }
481 -
482 - if ( ! empty( $attributes['loop'] ) ) { // loop
483 - $url = add_query_arg( 'loop', 1, $url );
484 - }
485 -
486 - if ( empty( $attributes['controls'] ) ) { // controls
487 - $url = add_query_arg( 'controls', 0, $url );
488 - }
489 -
490 - if ( ! empty( $attributes['modestbranding'] ) ) { // modestbranding
491 - $url = add_query_arg( 'modestbranding', 1, $url );
492 - }
493 -
494 - if ( ! empty( $attributes['cc_load_policy'] ) ) { // cc_load_policy
495 - $url = add_query_arg( 'cc_load_policy', 1, $url );
496 - }
497 -
498 - if ( empty( $attributes['iv_load_policy'] ) ) { // iv_load_policy
499 - $url = add_query_arg( 'iv_load_policy', 3, $url );
500 - }
501 -
502 - if ( ! empty( $attributes['hl'] ) ) { // hl
503 - $url = add_query_arg( 'hl', $attributes['hl'], $url );
504 - }
505 -
506 - if ( ! empty( $attributes['cc_lang_pref'] ) ) { // cc_lang_pref
507 - $url = add_query_arg( 'cc_lang_pref', $attributes['cc_lang_pref'], $url );
508 - }
509 -
510 - $url = add_query_arg( 'rel', 0, $url ); // rel
511 - $url = add_query_arg( 'playsinline', 1, $url ); // playsinline
512 - $url = add_query_arg( 'enablejsapi', 1, $url ); // enablejsapi
513 -
514 - return apply_filters( 'ayg_player_embed_url', $url, $video, $attributes );
815 + return apply_filters( 'ayg_player_description', $description, $video, $attributes, $words_count );
515 816 }
516 817
517 818 /**
518 - * Get player ratio.
519 - *
520 - * @since 1.0.0
521 - * @param array $attributes Array of user attributes.
522 - * @return string Player ratio.
523 - */
524 -function ayg_get_player_ratio( $attributes ) {
525 - $ratio = ! empty( $attributes['player_ratio'] ) ? $attributes['player_ratio'] . '%' : '56.25%';
526 - return apply_filters( 'ayg_player_ratio', $ratio, $attributes );
527 -}
528 -
529 -/**
530 819 * Get player settings fields.
531 820 *
532 821 * @since 1.0.0
533 822 * @return array $fields Array of fields.
@@ -536,10 +825,19 @@
536 825 $player_settings = get_option( 'ayg_player_settings' );
537 826
538 827 $fields = array(
539 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(
540 837 'name' => 'player_ratio',
541 - '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' ),
542 840 'type' => 'radio',
543 841 'options' => array(
544 842 '56.25' => '16:9',
545 843 '75' => '4:3'
@@ -585,10 +883,18 @@
585 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' ),
586 884 'type' => 'checkbox',
587 885 'value' => $player_settings['loop'],
588 886 'sanitize_callback' => 'intval'
589 - ),
887 + ),
590 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(
591 897 'name' => 'controls',
592 898 'label' => __( 'Show Player Controls', 'automatic-youtube-gallery' ),
593 899 'description' => __( 'Uncheck this option to hide the video player controls.', 'automatic-youtube-gallery' ),
594 900 'type' => 'checkbox',
@@ -645,31 +951,19 @@
645 951
646 952 return $fields;
647 953 }
648 954
649 -/**
650 - * Get video title to show on bottom of the player.
651 - *
652 - * @since 1.0.0
653 - * @param stdClass $video YouTube video object.
654 - * @param array $attributes Array of user attributes.
655 - * @return string Video title.
656 - */
657 -function ayg_get_player_title( $video, $attributes ) {
658 - $title = ! empty( $attributes['player_title'] ) ? $video->title : '';
659 - return apply_filters( 'ayg_player_title', $title, $video, $attributes );
660 -}
661 955
662 956 /**
663 - * Get player width.
957 + * Get a single video page URL.
664 958 *
665 - * @since 1.0.0
666 - * @param array $attributes Array of user attributes.
667 - * @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.
668 963 */
669 -function ayg_get_player_width( $attributes ) {
670 - $width = ! empty( $attributes['player_width'] ) ? $attributes['player_width'] . 'px' : '100%';
671 - 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 );
672 966 }
673 967
674 968 /**
675 969 * Get filtered php template file path.
@@ -699,8 +993,157 @@
699 993 return uniqid() . ++$ayg_uniqid;
700 994 }
701 995
702 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 +/**
703 1146 * Sanitize the integer inputs, accepts empty values.
704 1147 *
705 1148 * @since 1.0.0
706 1149 * @param string|int $value Input value.
@@ -711,98 +1154,80 @@
711 1154 return ( 0 == $value ) ? '' : $value;
712 1155 }
713 1156
714 1157 /**
715 - * Gallery HTML output.
1158 + * Trims text to a certain number of characters.
716 1159 *
717 - * @since 1.0.0
718 - * @param array $videos Array of YouTube video object.
719 - * @param array $attributes Array of user attributes.
720 - * @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.
721 1165 */
722 -function the_ayg_gallery( $videos, $attributes, $active_id = 0 ) {
723 - if ( 'video' != $attributes['type'] ) {
724 - 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;
725 1184 }
1185 +
1186 + return apply_filters( 'ayg_trim_words', $text, $original_text, $num_characters, $append );
726 1187 }
727 1188
728 1189 /**
729 1190 * Gallery HTML output.
730 1191 *
731 - * @since 1.0.0
732 - * @param array $video YouTube video object.
733 - * @param array $attributes Array of user attributes.
734 - * @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.
735 1195 */
736 -function the_ayg_gallery_thumbnail( $video, $attributes, $is_active = false ) {
737 - 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' );
738 1198 }
739 1199
740 1200 /**
741 1201 * Pagination HTML output.
742 1202 *
743 - * @since 1.0.0
744 - * @param array $atts Array of user attributes.
1203 + * @since 1.0.0
1204 + * @param array $attributes Array of user attributes.
745 1205 */
746 -function the_ayg_pagination( $atts ) {
747 - if ( ! empty( $atts['pagination'] ) ) {
748 - // Build attributes
749 - $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 +}
750 1211
751 - $fields = ayg_get_editor_fields();
752 -
753 - foreach ( $fields['gallery']['fields'] as $field ) {
754 - $field_name = $field['name'];
755 -
756 - if ( ! in_array( $field_name, array( 'per_page', 'pagination' ) ) ) {
757 - $attributes[ $field_name ] = sanitize_text_field( $atts[ $field_name ] );
758 - }
759 - }
760 -
761 - $source_type = sanitize_text_field( $atts['type'] );
762 -
763 - $attributes = array_merge(
764 - $attributes,
765 - array(
766 - 'type' => $source_type,
767 - 'id' => sanitize_text_field( $atts[ $source_type ] ),
768 - 'order' => sanitize_text_field( $atts['order'] ), // works only when type=search
769 - 'per_page' => (int) $atts['per_page'],
770 - 'cache' => (int) $atts['cache'],
771 - 'player_description' => ! empty( $atts['player_description'] ) ? (int) $atts['player_description'] : 0,
772 - 'num_pages' => 1,
773 - 'paged' => ! empty( $atts['paged'] ) ? (int) $atts['paged'] : 1,
774 - 'next_page_token' => ! empty( $atts['next_page_token'] ) ? sanitize_text_field( $atts['next_page_token'] ) : '',
775 - 'prev_page_token' => ! empty( $atts['prev_page_token'] ) ? sanitize_text_field( $atts['prev_page_token'] ) : ''
776 - )
777 - );
778 -
779 - // Find total number of pages
780 - $videos_found = ! empty( $atts['videos_found'] ) ? (int) $atts['videos_found'] : 0;
781 -
782 - if ( $videos_found > 0 ) {
783 - if ( 'search' == $source_type ) {
784 - $limit = min( (int) $atts['limit'], $videos_found );
785 - $attributes['num_pages'] = ceil( $limit / $attributes['per_page'] );
786 - } else {
787 - $attributes['num_pages'] = ceil( $videos_found / $attributes['per_page'] );
788 - }
789 - }
790 -
791 - // Process output
792 - if ( $attributes['num_pages'] > 1 ) {
793 - $pagination_type = ( 'pager' == $atts['pagination_type'] ) ? 'pager' : 'loadmore';
794 - include ayg_get_template( AYG_DIR . 'public/templates/pagination-' . $pagination_type. '.php', $attributes['theme'] );
795 - }
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' );
796 1221 }
797 1222 }
798 1223
799 1224 /**
800 - * Player HTML output.
1225 + * Gallery HTML output.
801 1226 *
802 - * @since 1.0.0
803 - * @param stdClass $video YouTube video object.
804 - * @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.
805 1230 */
806 1231 function the_ayg_player( $video, $attributes ) {
807 - include ayg_get_template( AYG_DIR . 'public/templates/player.php', $attributes['theme'] );
808 -}
1232 + include ayg_get_template( AYG_DIR . 'public/templates/player.php' );
1233 +}