| @@ -21,21 +21,30 @@ | ||
| 21 | 21 | * @param array $args An array of gallery options. |
| 22 | 22 | * @return mixed |
| 23 | 23 | */ |
| 24 | 24 | function ayg_build_gallery( $args ) { |
| 25 | + $general_settings = get_option( 'ayg_general_settings' ); | |
| 26 | + $strings_settings = get_option( 'ayg_strings_settings' ); | |
| 27 | + | |
| 25 | 28 | global $post; |
| 26 | 29 | |
| 27 | 30 | // Vars |
| 28 | - $fields = ayg_get_editor_fields(); | |
| 31 | + $fields = ayg_get_editor_fields(); | |
| 32 | + $excluded_fields = array( 'popup' ); // Fields not part of attributes | |
| 29 | 33 | $defaults = array(); |
| 30 | 34 | |
| 31 | 35 | foreach ( $fields as $key => $value ) { |
| 32 | 36 | foreach ( $value['fields'] as $field ) { |
| 37 | + if ( in_array( $field['name'], $excluded_fields ) ) { | |
| 38 | + continue; | |
| 39 | + } | |
| 40 | + | |
| 33 | 41 | $defaults[ $field['name'] ] = $field['value']; |
| 34 | 42 | } |
| 35 | 43 | } |
| 36 | 44 | |
| 37 | - $attributes = shortcode_atts( $defaults, $args ); | |
| 45 | + $defaults = array_merge( $defaults, (array) $strings_settings ); | |
| 46 | + $attributes = shortcode_atts( $defaults, $args, 'automatic_youtube_gallery' ); | |
| 38 | 47 | |
| 39 | 48 | $attributes['post_id'] = 0; |
| 40 | 49 | if ( isset( $post->ID ) ) { |
| 41 | 50 | $attributes['post_id'] = (int) $post->ID; |
| @@ -60,19 +69,36 @@ | ||
| 60 | 69 | if ( 'livestream' == $source_type ) { |
| 61 | 70 | $attributes['livestream'] = $attributes['channel']; |
| 62 | 71 | } |
| 63 | 72 | |
| 73 | + $attributes['lazyload'] = 0; | |
| 74 | + if ( ! empty( $general_settings['lazyload'] ) ) { | |
| 75 | + $attributes['lazyload'] = 1; | |
| 76 | + } | |
| 77 | + | |
| 78 | + $source_url = sanitize_text_field( $attributes[ $source_type ] ); | |
| 79 | + | |
| 64 | 80 | if ( isset( $args['uid'] ) && ! empty( $args['uid'] ) ) { |
| 65 | - $attributes['uid'] = $args['uid']; | |
| 81 | + $attributes['uid'] = sanitize_text_field( $args['uid'] ); | |
| 66 | 82 | } else { |
| 67 | - $attributes['uid'] = md5( $source_type . sanitize_text_field( $attributes[ $source_type ] ) . sanitize_text_field( $attributes['theme'] ) ); | |
| 83 | + $attributes['uid'] = md5( $source_type . $source_url ); | |
| 68 | 84 | } |
| 69 | 85 | |
| 86 | + $attributes['uid'] = apply_filters( 'ayg_gallery_id', $attributes['uid'], $args ); | |
| 87 | + | |
| 88 | + // Deprecated since v2.5.8. Retained for backward compatibility. | |
| 89 | + $deprecated_uid = md5( $source_type . $source_url . sanitize_text_field( $attributes['theme'] ) ); // Deprecated | |
| 90 | + if ( isset( $args['deprecated_uid'] ) && ! empty( $args['deprecated_uid'] ) ) { | |
| 91 | + $deprecated_uid = sanitize_text_field( $args['deprecated_uid'] ); | |
| 92 | + } | |
| 93 | + | |
| 70 | 94 | // Get Videos |
| 71 | 95 | $api_params = array( |
| 96 | + 'uid' => $attributes['uid'], | |
| 72 | 97 | 'type' => $source_type, |
| 73 | - 'src' => sanitize_text_field( $attributes[ $source_type ] ), | |
| 74 | - 'order' => sanitize_text_field( $attributes['order'] ), // applicable only when type=search | |
| 98 | + 'src' => $source_url, | |
| 99 | + 'order' => sanitize_text_field( $attributes['order'] ), // Works only when type = "search". | |
| 100 | + 'limit' => $attributes['limit'], // Works only when type = "search". | |
| 75 | 101 | 'maxResults' => $attributes['per_page'], |
| 76 | 102 | 'cache' => (int) $attributes['cache'] |
| 77 | 103 | ); |
| 78 | 104 | |
| @@ -92,20 +118,16 @@ | ||
| 92 | 118 | $pages[] = $page_id; |
| 93 | 119 | update_option( 'ayg_gallery_page_ids', $pages ); |
| 94 | 120 | } |
| 95 | 121 | } |
| 96 | - | |
| 97 | - // Enqueue dependencies | |
| 98 | - wp_enqueue_style( AYG_SLUG . '-public' ); | |
| 99 | - wp_enqueue_script( AYG_SLUG . '-public' ); | |
| 100 | 122 | |
| 101 | 123 | // Gallery |
| 102 | 124 | $videos = array(); |
| 103 | 125 | |
| 104 | - $gallery_id_from_url = get_query_var( 'ayg_gallery' ); | |
| 105 | - $video_id_from_url = get_query_var( 'ayg_video' ); | |
| 126 | + $gallery_id_from_url = get_query_var( 'ayg_gallery_id' ); | |
| 127 | + $video_id_from_url = get_query_var( 'ayg_video_id' ); | |
| 106 | 128 | |
| 107 | - if ( $attributes['uid'] == $gallery_id_from_url ) { | |
| 129 | + if ( $attributes['uid'] == $gallery_id_from_url || $deprecated_uid == $gallery_id_from_url ) { | |
| 108 | 130 | $video = ayg_db_get_video( $video_id_from_url ); |
| 109 | 131 | |
| 110 | 132 | if ( $video ) { |
| 111 | 133 | $videos[] = $video; |
| @@ -143,41 +165,108 @@ | ||
| 143 | 165 | $theme = 'single'; |
| 144 | 166 | } |
| 145 | 167 | } |
| 146 | 168 | |
| 169 | + // Enqueue dependencies | |
| 170 | + wp_enqueue_style( AYG_SLUG . '-public' ); | |
| 171 | + | |
| 172 | + wp_enqueue_script( AYG_SLUG . '-public' ); | |
| 173 | + if ( $attributes['theme'] == $theme && 'classic' == $attributes['theme'] ) { | |
| 174 | + wp_enqueue_script( AYG_SLUG . '-theme-classic' ); | |
| 175 | + } | |
| 176 | + | |
| 147 | 177 | // Output |
| 148 | 178 | ob_start(); |
| 149 | 179 | include ayg_get_template( AYG_DIR . "public/templates/theme-{$theme}.php", $attributes['theme'] ); |
| 150 | 180 | return ob_get_clean(); |
| 151 | 181 | } else { |
| 152 | - 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 ) ); | |
| 153 | 183 | } |
| 154 | 184 | } |
| 155 | 185 | |
| 156 | 186 | /** |
| 157 | - * Create a custom database table "{$wpdb->prefix}ayg_videos" | |
| 187 | + * Combine video attributes as a string. | |
| 188 | + * | |
| 189 | + * @since 2.5.0 | |
| 190 | + * @param array $atts Array of video attributes. | |
| 191 | + * @param string Combined attributes string. | |
| 192 | + */ | |
| 193 | +function ayg_combine_video_attributes( $atts ) { | |
| 194 | + $attributes = array(); | |
| 195 | + | |
| 196 | + foreach ( $atts as $key => $value ) { | |
| 197 | + if ( '' === $value ) { | |
| 198 | + $attributes[] = $key; | |
| 199 | + } else { | |
| 200 | + $attributes[] = sprintf( '%s="%s"', $key, $value ); | |
| 201 | + } | |
| 202 | + } | |
| 203 | + | |
| 204 | + return implode( ' ', $attributes ); | |
| 205 | +} | |
| 206 | + | |
| 207 | +/** | |
| 208 | + * Create custom database tables | |
| 158 | 209 | * |
| 159 | 210 | * @since 2.1.0 |
| 160 | 211 | */ |
| 161 | -function ayg_db_create_videos_table() { | |
| 212 | +function ayg_db_create_custom_tables() { | |
| 162 | 213 | global $wpdb; |
| 163 | 214 | |
| 164 | - $charset_collate = $wpdb->get_charset_collate(); | |
| 215 | + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); | |
| 216 | + $charset_collate = $wpdb->get_charset_collate(); | |
| 217 | + | |
| 218 | + $videos_table = $wpdb->prefix . 'ayg_videos'; | |
| 165 | 219 | |
| 166 | - $sql = "CREATE TABLE `{$wpdb->prefix}ayg_videos` ( | |
| 220 | + // Check if the videos table exists | |
| 221 | + $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $videos_table ) ); | |
| 222 | + | |
| 223 | + if ( $wpdb->get_var( $query ) === $videos_table ) { | |
| 224 | + // Find and remove duplicate video IDs | |
| 225 | + $wpdb->query( | |
| 226 | + "DELETE v1 FROM $videos_table v1 | |
| 227 | + INNER JOIN $videos_table v2 | |
| 228 | + ON v1.id = v2.id AND v1.NUM > v2.NUM" | |
| 229 | + ); | |
| 230 | + } | |
| 231 | + | |
| 232 | + // Create the videos table | |
| 233 | + $sql = "CREATE TABLE $videos_table ( | |
| 167 | 234 | NUM bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
| 168 | 235 | id varchar(100) NOT NULL, |
| 169 | 236 | title text NOT NULL, |
| 170 | 237 | description text NOT NULL, |
| 171 | - thumbnails text NOT NULL, | |
| 238 | + thumbnails text NOT NULL, | |
| 172 | 239 | duration varchar(25) NOT NULL, |
| 173 | 240 | status varchar(100) NOT NULL, |
| 174 | 241 | published_at varchar(100) NOT NULL, |
| 175 | - PRIMARY KEY (NUM) | |
| 242 | + published_at_datetime datetime NULL, | |
| 243 | + PRIMARY KEY (NUM), | |
| 244 | + UNIQUE KEY ayg_unique_video_id (id) | |
| 176 | 245 | ) $charset_collate;"; |
| 177 | - | |
| 178 | - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); | |
| 246 | + | |
| 179 | 247 | dbDelta( $sql ); |
| 248 | + | |
| 249 | + // Add UNIQUE KEY if it is not added | |
| 250 | + $existing_keys = $wpdb->get_results( "SHOW KEYS FROM $videos_table WHERE Key_name = 'ayg_unique_video_id'" ); | |
| 251 | + | |
| 252 | + if ( empty( $existing_keys ) ) { | |
| 253 | + $wpdb->query( "ALTER TABLE $videos_table ADD UNIQUE KEY ayg_unique_video_id (id)" ); | |
| 254 | + } | |
| 255 | + | |
| 256 | + // Create the galleries table | |
| 257 | + $galleries_table = $wpdb->prefix . 'ayg_galleries'; | |
| 258 | + | |
| 259 | + $sql = "CREATE TABLE $galleries_table ( | |
| 260 | + NUM bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, | |
| 261 | + video_id varchar(100) NOT NULL, | |
| 262 | + gallery_id varchar(100) NOT NULL, | |
| 263 | + PRIMARY KEY (NUM), | |
| 264 | + UNIQUE KEY ayg_unique_video_gallery (video_id, gallery_id), | |
| 265 | + INDEX ayg_idx_gallery_id (gallery_id) | |
| 266 | + ) $charset_collate;"; | |
| 267 | + | |
| 268 | + dbDelta( $sql ); | |
| 180 | 269 | } |
| 181 | 270 | |
| 182 | 271 | /** |
| 183 | 272 | * Store videos in our custom database table "{$wpdb->prefix}ayg_videos" |
| @@ -182,31 +271,27 @@ | ||
| 182 | 271 | /** |
| 183 | 272 | * Store videos in our custom database table "{$wpdb->prefix}ayg_videos" |
| 184 | 273 | * |
| 185 | 274 | * @since 2.1.0 |
| 186 | - * @param object $data YouTube API response object. | |
| 275 | + * @param object $data YouTube API response object. | |
| 276 | + * @param array $attributes Array of user attributes. | |
| 187 | 277 | */ |
| 188 | -function ayg_db_store_videos( $data ) { | |
| 278 | +function ayg_db_store_videos( $data, $attributes = array() ) { | |
| 189 | 279 | if ( AYG_VERSION !== get_option( 'ayg_version' ) ) { |
| 190 | 280 | return false; |
| 191 | 281 | } |
| 192 | 282 | |
| 193 | - global $wpdb, $post; | |
| 194 | - | |
| 195 | - $table_name = $wpdb->prefix . 'ayg_videos'; | |
| 196 | - | |
| 197 | 283 | if ( isset( $data->kind ) && 'youtube#channelListResponse' == $data->kind ) { |
| 198 | 284 | return false; |
| 199 | 285 | } |
| 200 | 286 | |
| 201 | - if ( ! isset( $data->items ) ) { | |
| 287 | + if ( empty( $data->items ) || ! is_array( $data->items ) ) { | |
| 202 | 288 | return false; |
| 203 | 289 | } |
| 204 | 290 | |
| 291 | + global $wpdb; | |
| 292 | + | |
| 205 | 293 | $items = $data->items; |
| 206 | - if ( ! is_array( $items ) || 0 == count( $items ) ) { | |
| 207 | - return false; | |
| 208 | - } | |
| 209 | 294 | |
| 210 | 295 | // Store Videos |
| 211 | 296 | foreach ( $items as $item ) { |
| 212 | 297 | $row = array(); |
| @@ -263,26 +348,51 @@ | ||
| 263 | 348 | |
| 264 | 349 | // Video publish date |
| 265 | 350 | $row['published_at'] = $item->snippet->publishedAt; |
| 266 | 351 | |
| 267 | - // Store | |
| 268 | - $query = $wpdb->prepare( "SELECT NUM FROM $table_name WHERE id = %s", $row['id'] ); | |
| 269 | - $insert_id = $wpdb->get_var( $query ); | |
| 352 | + $datetime = new DateTime( $item->snippet->publishedAt ); | |
| 353 | + $row['published_at_datetime'] = date_format( $datetime, 'Y-m-d H:i:s' ); | |
| 270 | 354 | |
| 271 | - if ( empty( $insert_id ) ) { | |
| 272 | - $wpdb->insert( | |
| 273 | - $table_name, | |
| 274 | - $row, | |
| 275 | - array( '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) | |
| 355 | + // Store the video | |
| 356 | + $videos_table = $wpdb->prefix . 'ayg_videos'; | |
| 357 | + | |
| 358 | + $query = $wpdb->prepare( | |
| 359 | + "INSERT INTO $videos_table (id, title, description, thumbnails, duration, status, published_at, published_at_datetime) | |
| 360 | + VALUES (%s, %s, %s, %s, %s, %s, %s, %s) | |
| 361 | + ON DUPLICATE KEY UPDATE | |
| 362 | + title = VALUES(title), | |
| 363 | + description = VALUES(description), | |
| 364 | + thumbnails = VALUES(thumbnails), | |
| 365 | + duration = VALUES(duration), | |
| 366 | + status = VALUES(status), | |
| 367 | + published_at = VALUES(published_at), | |
| 368 | + published_at_datetime = VALUES(published_at_datetime)", | |
| 369 | + $row['id'], | |
| 370 | + $row['title'], | |
| 371 | + $row['description'], | |
| 372 | + $row['thumbnails'], | |
| 373 | + $row['duration'], | |
| 374 | + $row['status'], | |
| 375 | + $row['published_at'], | |
| 376 | + $row['published_at_datetime'] | |
| 377 | + ); | |
| 378 | + | |
| 379 | + $wpdb->query( $query ); | |
| 380 | + | |
| 381 | + // Store the gallery association | |
| 382 | + $gallery_id = isset( $attributes['uid'] ) ? $attributes['uid'] : ''; | |
| 383 | + $source_type = isset( $attributes['type'] ) ? $attributes['type'] : 'videos'; | |
| 384 | + | |
| 385 | + if ( ! empty( $gallery_id ) && ! in_array( $source_type, array( 'video', 'livestream' ) ) ) { | |
| 386 | + $galleries_table = $wpdb->prefix . 'ayg_galleries'; | |
| 387 | + | |
| 388 | + $query = $wpdb->prepare( | |
| 389 | + "INSERT IGNORE INTO $galleries_table (video_id, gallery_id) VALUES (%s, %s)", | |
| 390 | + $row['id'], | |
| 391 | + $gallery_id | |
| 276 | 392 | ); |
| 277 | - } else { | |
| 278 | - $wpdb->update( | |
| 279 | - $table_name, | |
| 280 | - $row, | |
| 281 | - array( 'NUM' => $insert_id ), | |
| 282 | - array( '%s', '%s', '%s', '%s', '%s', '%s', '%s' ), | |
| 283 | - array( '%d' ) | |
| 284 | - ); | |
| 393 | + | |
| 394 | + $wpdb->query( $query ); | |
| 285 | 395 | } |
| 286 | 396 | } |
| 287 | 397 | } |
| 288 | 398 | |
| @@ -357,43 +467,58 @@ | ||
| 357 | 467 | function ayg_get_default_settings() { |
| 358 | 468 | $defaults = array( |
| 359 | 469 | 'ayg_general_settings' => array( |
| 360 | 470 | 'api_key' => '', |
| 361 | - 'development_mode' => 1 | |
| 471 | + 'lazyload' => 0, | |
| 472 | + 'development_mode' => 0 | |
| 362 | 473 | ), |
| 474 | + 'ayg_strings_settings' => array( | |
| 475 | + 'more_button_label' => __( 'Load More', 'automatic-youtube-gallery' ), | |
| 476 | + 'previous_button_label' => __( 'Previous', 'automatic-youtube-gallery' ), | |
| 477 | + 'next_button_label' => __( 'Next', 'automatic-youtube-gallery' ), | |
| 478 | + 'show_more_label' => __( 'Show More', 'automatic-youtube-gallery' ), | |
| 479 | + 'show_less_label' => __( 'Show Less', 'automatic-youtube-gallery' ) | |
| 480 | + ), | |
| 363 | 481 | 'ayg_gallery_settings' => array( |
| 364 | - 'theme' => 'classic', | |
| 365 | - 'columns' => 3, | |
| 366 | - 'per_page' => 12, | |
| 367 | - 'thumb_ratio' => 56.25, | |
| 368 | - 'thumb_title' => 1, | |
| 369 | - 'thumb_title_length' => 0, | |
| 370 | - 'thumb_excerpt' => 1, | |
| 371 | - 'thumb_excerpt_length' => 75, | |
| 372 | - 'pagination' => 1, | |
| 373 | - 'pagination_type' => 'more' | |
| 482 | + 'theme' => 'classic', | |
| 483 | + 'columns' => 3, | |
| 484 | + 'per_page' => 12, | |
| 485 | + 'thumb_ratio' => 56.25, | |
| 486 | + 'thumb_title' => 1, | |
| 487 | + 'thumb_title_length' => 0, | |
| 488 | + 'thumb_excerpt' => 1, | |
| 489 | + 'thumb_excerpt_length' => 75, | |
| 490 | + 'pagination' => 1, | |
| 491 | + 'pagination_type' => 'more', | |
| 492 | + 'scroll_top_offset' => 10 | |
| 374 | 493 | ), |
| 375 | 494 | 'ayg_player_settings' => array( |
| 376 | - 'player_ratio' => 56.25, | |
| 377 | - 'player_title' => 1, | |
| 378 | - 'player_description' => 1, | |
| 379 | - 'autoplay' => 0, | |
| 380 | - 'autoadvance' => 1, | |
| 381 | - 'loop' => 0, | |
| 382 | - 'controls' => 1, | |
| 383 | - 'modestbranding' => 1, | |
| 384 | - 'cc_load_policy' => 0, | |
| 385 | - 'iv_load_policy' => 0, | |
| 386 | - 'hl' => '', | |
| 387 | - 'cc_lang_pref' => '' | |
| 495 | + 'player_type' => 'youtube', | |
| 496 | + 'player_color' => '#00b3ff', | |
| 497 | + 'player_width' => '', | |
| 498 | + 'player_ratio' => 56.25, | |
| 499 | + 'player_title' => 1, | |
| 500 | + 'player_description' => 1, | |
| 501 | + 'autoplay' => 0, | |
| 502 | + 'autoadvance' => 1, | |
| 503 | + 'loop' => 0, | |
| 504 | + 'muted' => 0, | |
| 505 | + 'controls' => 1, | |
| 506 | + 'modestbranding' => 1, | |
| 507 | + 'cc_load_policy' => 0, | |
| 508 | + 'iv_load_policy' => 0, | |
| 509 | + 'hl' => '', | |
| 510 | + 'cc_lang_pref' => '', | |
| 511 | + 'privacy_enhanced_mode' => 0, | |
| 512 | + 'origin' => 0 | |
| 388 | 513 | ), |
| 389 | 514 | 'ayg_livestream_settings' => array( |
| 390 | 515 | 'fallback_message' => __( 'Sorry, but the channel is not currently streaming live content. Please check back later.', 'automatic-youtube-gallery' ) |
| 391 | 516 | ), |
| 392 | - 'ayg_privacy_settings' => array( | |
| 393 | - 'cookie_consent' => 0, | |
| 394 | - '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' ), | |
| 395 | - 'button_label' => __( 'Accept', 'automatic-youtube-gallery' ) | |
| 517 | + 'ayg_privacy_settings' => array( | |
| 518 | + 'cookie_consent' => 0, | |
| 519 | + 'consent_message' => __( 'Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.', 'automatic-youtube-gallery' ), | |
| 520 | + 'button_label' => __( 'Accept', 'automatic-youtube-gallery' ) | |
| 396 | 521 | ) |
| 397 | 522 | ); |
| 398 | 523 | |
| 399 | 524 | return $defaults; |
| @@ -506,14 +631,15 @@ | ||
| 506 | 631 | 'label' => __( 'Cache Duration', 'automatic-youtube-gallery' ), |
| 507 | 632 | 'description' => __( 'Specifies how frequently we should check your YouTube source for new videos/updates.', 'automatic-youtube-gallery' ), |
| 508 | 633 | 'type' => 'select', |
| 509 | 634 | 'options' => array( |
| 510 | - '900' => __( '15 minutes', 'automatic-youtube-gallery' ), | |
| 511 | - '1800' => __( '30 minutes', 'automatic-youtube-gallery' ), | |
| 635 | + '0' => '— '. __( 'No Caching', 'automatic-youtube-gallery' ) . ' —', | |
| 636 | + '900' => __( '15 Minutes', 'automatic-youtube-gallery' ), | |
| 637 | + '1800' => __( '30 Minutes', 'automatic-youtube-gallery' ), | |
| 512 | 638 | '3600' => __( '1 Hour', 'automatic-youtube-gallery' ), |
| 513 | 639 | '86400' => __( '1 Day', 'automatic-youtube-gallery' ), |
| 514 | 640 | '604800' => __( '1 Week', 'automatic-youtube-gallery' ), |
| 515 | - '2419200' => __( ' 1Month', 'automatic-youtube-gallery' ) | |
| 641 | + '2419200' => __( '1 Month', 'automatic-youtube-gallery' ) | |
| 516 | 642 | ), |
| 517 | 643 | 'value' => 86400, |
| 518 | 644 | 'sanitize_callback' => 'intval' |
| 519 | 645 | ) |
| @@ -525,8 +651,24 @@ | ||
| 525 | 651 | ), |
| 526 | 652 | 'player' => array( |
| 527 | 653 | 'label' => __( 'Player (optional)', 'automatic-youtube-gallery' ), |
| 528 | 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 | + ) | |
| 529 | 671 | ) |
| 530 | 672 | ); |
| 531 | 673 | |
| 532 | 674 | return apply_filters( 'ayg_editor_fields', $fields ); |
| @@ -544,9 +686,9 @@ | ||
| 544 | 686 | $fields = array( |
| 545 | 687 | array( |
| 546 | 688 | 'name' => 'theme', |
| 547 | 689 | 'label' => __( 'Select Theme (Layout)', 'automatic-youtube-gallery' ), |
| 548 | - 'description' => ( ayg_fs()->is_not_paying() ? sprintf( __( '<a href="%s">Upgrade Pro</a> for more themes (Inline, Popup, Slider, Playlist).', 'automatic-youtube-gallery' ), esc_url( ayg_fs()->get_upgrade_url() ) ) : '' ), | |
| 690 | + 'description' => ( ayg_fs()->is_not_paying() ? sprintf( __( '<a href="%s">Upgrade Pro</a> for more themes (Popup, Inline, Slider, Playlist).', 'automatic-youtube-gallery' ), esc_url( ayg_fs()->get_upgrade_url() ) ) : '' ), | |
| 549 | 691 | 'type' => 'select', |
| 550 | 692 | 'options' => array( |
| 551 | 693 | 'classic' => __( 'Classic', 'automatic-youtube-gallery' ) |
| 552 | 694 | ), |
| @@ -650,26 +792,28 @@ | ||
| 650 | 792 | * Get video description to show on top of the player. |
| 651 | 793 | * |
| 652 | 794 | * @since 1.0.0 |
| 653 | 795 | * @param stdClass $video YouTube video object. |
| 796 | + * @param array $attributes Array of user attributes. | |
| 654 | 797 | * @param int $words_count Number of words to show by default. |
| 655 | 798 | * @return string Video description. |
| 656 | 799 | */ |
| 657 | -function ayg_get_player_description( $video, $words_count = 30 ) { | |
| 800 | +function ayg_get_player_description( $video, $attributes = array(), $words_count = 30 ) { | |
| 658 | 801 | $description = $video->description; |
| 659 | 802 | |
| 660 | 803 | $words_array = explode( ' ', strip_tags( $description ) ); |
| 661 | 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' ); | |
| 662 | 806 | $words_array[ $words_count ] = '<span class="ayg-player-description-dots">...</span></span><span class="ayg-player-description-more">' . $words_array[ $words_count ]; |
| 663 | 807 | |
| 664 | 808 | $description = '<span class="ayg-player-description-less">' . implode( ' ', $words_array ) . '</span>'; |
| 665 | - $description .= '<a href="javascript:void(0);" class="ayg-player-description-toggle-btn">[+] ' . __( 'Show More', 'automatic-youtube-gallery' ) . '</a>'; | |
| 809 | + $description .= '<a href="#" class="ayg-player-description-toggle-btn">' . esc_html( $show_more_label ) . '</a>'; | |
| 666 | 810 | } |
| 667 | 811 | |
| 668 | 812 | $description = nl2br( $description ); |
| 669 | 813 | $description = make_clickable( $description ); |
| 670 | 814 | |
| 671 | - return apply_filters( 'ayg_player_description', $description, $video, $words_count ); | |
| 815 | + return apply_filters( 'ayg_player_description', $description, $video, $attributes, $words_count ); | |
| 672 | 816 | } |
| 673 | 817 | |
| 674 | 818 | /** |
| 675 | 819 | * Get player settings fields. |
| @@ -681,8 +825,16 @@ | ||
| 681 | 825 | $player_settings = get_option( 'ayg_player_settings' ); |
| 682 | 826 | |
| 683 | 827 | $fields = array( |
| 684 | 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( | |
| 685 | 837 | 'name' => 'player_ratio', |
| 686 | 838 | 'label' => __( 'Player Height (Ratio)', 'automatic-youtube-gallery' ), |
| 687 | 839 | 'description' => __( 'Select the ratio value used to calculate the player height.', 'automatic-youtube-gallery' ), |
| 688 | 840 | 'type' => 'radio', |
| @@ -731,10 +883,18 @@ | ||
| 731 | 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' ), |
| 732 | 884 | 'type' => 'checkbox', |
| 733 | 885 | 'value' => $player_settings['loop'], |
| 734 | 886 | 'sanitize_callback' => 'intval' |
| 735 | - ), | |
| 887 | + ), | |
| 736 | 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( | |
| 737 | 897 | 'name' => 'controls', |
| 738 | 898 | 'label' => __( 'Show Player Controls', 'automatic-youtube-gallery' ), |
| 739 | 899 | 'description' => __( 'Uncheck this option to hide the video player controls.', 'automatic-youtube-gallery' ), |
| 740 | 900 | 'type' => 'checkbox', |
| @@ -796,14 +956,14 @@ | ||
| 796 | 956 | /** |
| 797 | 957 | * Get a single video page URL. |
| 798 | 958 | * |
| 799 | 959 | * @since 2.1.0 |
| 800 | - * @param string $video_id YouTube Video ID. | |
| 801 | - * @param array $args An array of gallery options. | |
| 802 | - * @return string Single video URL. | |
| 960 | + * @param stdClass $video YouTube video object. | |
| 961 | + * @param array $args An array of gallery options. | |
| 962 | + * @return string Single video URL. | |
| 803 | 963 | */ |
| 804 | -function ayg_get_single_video_url( $video_id, $attributes ) { | |
| 805 | - return apply_filters( 'ayg_single_video_url', '', $video_id, $attributes ); | |
| 964 | +function ayg_get_single_video_url( $video, $attributes ) { | |
| 965 | + return apply_filters( 'ayg_single_video_url', '', $video, $attributes ); | |
| 806 | 966 | } |
| 807 | 967 | |
| 808 | 968 | /** |
| 809 | 969 | * Get filtered php template file path. |
| @@ -833,25 +993,105 @@ | ||
| 833 | 993 | return uniqid() . ++$ayg_uniqid; |
| 834 | 994 | } |
| 835 | 995 | |
| 836 | 996 | /** |
| 837 | - * Check if Yoast SEO plugin is active. | |
| 997 | + * Get YouTube domain. | |
| 838 | 998 | * |
| 839 | - * @since 2.1.0 | |
| 840 | - * @return bool $has_yoast True if the Yoast plugin is installed and active, false if not. | |
| 999 | + * @since 2.3.0 | |
| 1000 | + * @return string YouTube embed domain. | |
| 841 | 1001 | */ |
| 842 | -function ayg_has_yoast() { | |
| 843 | - $has_yoast = false; | |
| 1002 | +function ayg_get_youtube_domain() { | |
| 1003 | + $player_settings = get_option( 'ayg_player_settings' ); | |
| 844 | 1004 | |
| 845 | - $active_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) ); | |
| 846 | - if ( in_array( 'wordpress-seo/wp-seo.php', $active_plugins ) || in_array( 'wordpress-seo-premium/wp-seo-premium.php', $active_plugins ) ) { | |
| 847 | - $has_yoast = true; | |
| 1005 | + $domain = 'https://www.youtube.com'; | |
| 1006 | + if ( isset( $player_settings['privacy_enhanced_mode'] ) && ! empty( $player_settings['privacy_enhanced_mode'] ) ) { | |
| 1007 | + $domain = 'https://www.youtube-nocookie.com'; | |
| 848 | 1008 | } |
| 849 | 1009 | |
| 850 | - return $has_yoast; | |
| 1010 | + return $domain; | |
| 851 | 1011 | } |
| 852 | 1012 | |
| 853 | 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 | +/** | |
| 854 | 1094 | * Inserts a new associative array after another associative array key. |
| 855 | 1095 | * |
| 856 | 1096 | * @since 2.1.0 |
| 857 | 1097 | * @param string $key The associative array key to insert after. |
| @@ -879,8 +1119,31 @@ | ||
| 879 | 1119 | return $array; |
| 880 | 1120 | } |
| 881 | 1121 | |
| 882 | 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 | +/** | |
| 883 | 1146 | * Sanitize the integer inputs, accepts empty values. |
| 884 | 1147 | * |
| 885 | 1148 | * @since 1.0.0 |
| 886 | 1149 | * @param string|int $value Input value. |
| @@ -925,11 +1188,11 @@ | ||
| 925 | 1188 | |
| 926 | 1189 | /** |
| 927 | 1190 | * Gallery HTML output. |
| 928 | 1191 | * |
| 929 | - * @since 1.0.0 | |
| 930 | - * @param array $video YouTube video object. | |
| 931 | - * @param array $attributes Array of user attributes. | |
| 1192 | + * @since 1.0.0 | |
| 1193 | + * @param array $video YouTube video object. | |
| 1194 | + * @param array $attributes Array of user attributes. | |
| 932 | 1195 | */ |
| 933 | 1196 | function the_ayg_gallery_thumbnail( $video, $attributes ) { |
| 934 | 1197 | include ayg_get_template( AYG_DIR . 'public/templates/thumbnail.php' ); |
| 935 | 1198 | } |
| @@ -936,12 +1199,35 @@ | ||
| 936 | 1199 | |
| 937 | 1200 | /** |
| 938 | 1201 | * Pagination HTML output. |
| 939 | 1202 | * |
| 940 | - * @since 1.0.0 | |
| 941 | - * @param array $attributes Array of user attributes. | |
| 1203 | + * @since 1.0.0 | |
| 1204 | + * @param array $attributes Array of user attributes. | |
| 942 | 1205 | */ |
| 943 | 1206 | function the_ayg_pagination( $attributes ) { |
| 944 | 1207 | if ( ! empty( $attributes['pagination'] ) ) { |
| 945 | 1208 | include ayg_get_template( AYG_DIR . 'public/templates/pagination.php' ); |
| 946 | 1209 | } |
| 1210 | +} | |
| 1211 | + | |
| 1212 | +/** | |
| 1213 | + * Search Form HTML output. | |
| 1214 | + * | |
| 1215 | + * @since 2.5.7 | |
| 1216 | + * @param array $attributes Array of user attributes. | |
| 1217 | + */ | |
| 1218 | +function the_ayg_search_form( $attributes ) { | |
| 1219 | + if ( ! empty( $attributes['search_form'] ) ) { | |
| 1220 | + include ayg_get_template( AYG_DIR . 'public/templates/search-form.php' ); | |
| 1221 | + } | |
| 1222 | +} | |
| 1223 | + | |
| 1224 | +/** | |
| 1225 | + * Gallery HTML output. | |
| 1226 | + * | |
| 1227 | + * @since 2.5.0 | |
| 1228 | + * @param array $video YouTube video object. | |
| 1229 | + * @param array $attributes Array of user attributes. | |
| 1230 | + */ | |
| 1231 | +function the_ayg_player( $video, $attributes ) { | |
| 1232 | + include ayg_get_template( AYG_DIR . 'public/templates/player.php' ); | |
| 947 | 1233 | } |