diff --git a/assets/css/ot-admin.css b/assets/css/ot-admin.css index 74cfc9f8..a701a05f 100755 --- a/assets/css/ot-admin.css +++ b/assets/css/ot-admin.css @@ -2659,6 +2659,19 @@ ul.ot-gallery-list li img { margin-bottom: 0px; } +/* -------------------------------------------------- + :: Google Fonts + ---------------------------------------------------*/ +#option-tree-settings-api .option-tree-google-font-subsets-wrapper { + display: block; + clear: both; +} +#option-tree-settings-api .option-tree-google-font-subsets-wrapper p { + margin: 0.3em 0 !important; + float: left; + width: 100%; +} + /* -------------------------------------------------- :: On/Off Switch ---------------------------------------------------*/ @@ -3698,4 +3711,4 @@ a.ui-datepicker-next { .ot-metabox-tabs.ui-tabs .ot-metabox-panel { clear: both; } -} \ No newline at end of file +} diff --git a/assets/js/ot-admin.js b/assets/js/ot-admin.js index 608bcb63..a66e3cfc 100755 --- a/assets/js/ot-admin.js +++ b/assets/js/ot-admin.js @@ -24,6 +24,7 @@ this.init_tabs(); this.init_radio_image_select(); this.init_select_wrapper(); + this.init_google_fonts(); this.fix_upload_parent(); this.fix_textarea(); this.replicate_ajax(); @@ -555,19 +556,86 @@ }); }, init_select_wrapper: function() { - $('.option-tree-ui-select').each(function () { + $('.option-tree-ui-select').each(function() { if ( ! $(this).parent().hasClass('select-wrapper') ) { $(this).wrap('
'); $(this).parent('.select-wrapper').prepend('' + $(this).find('option:selected').text() + ''); } }); - $(document).on('change', '.option-tree-ui-select', function () { + $(document).on('change', '.option-tree-ui-select', function() { $(this).prev('span').replaceWith('' + $(this).find('option:selected').text() + ''); - }) + }); $(document).on($.browser.msie ? 'click' : 'change', '.option-tree-ui-select', function(event) { $(this).prev('span').replaceWith('' + $(this).find('option:selected').text() + ''); }); }, + init_google_fonts: function() { + if( ! option_tree.google_fonts ) { + return; + } + + var update_variants = function(input, variants) { + var variantsUI = input.closest('.format-settings').find('.option-tree-google-font-variants'); + if(variantsUI.length) { + variantsUI.children('option').not(':first').remove(); + variantsUI.append($.map(variants, function(variant){ + var option = document.createElement('option'); + option.innerHTML = option.value = variant; + return option; + })).trigger('change'); + } + }, update_subsets = function(input, subsets) { + var subsetsUI = input.closest('.format-settings').find('.option-tree-google-font-subsets-wrapper'); + if( subsetsUI.length ) { + subsetsUI.empty(); + subsetsUI.append($.map(subsets, function(subset) { + var input = document.createElement('input'),label = document.createElement('label'); + input.type = 'checkbox'; + input.id = ( subsetsUI.data('field-id-prefix') || '' ) + subset; + input.name = ( subsetsUI.data('field-name') || '' ); + label.innerHTML = subset; + $( label ).attr( 'for', input.id ); + return $( document.createElement('p') ).append([input, label]); + })); + } + }; + + if( 'js' == option_tree.google_fonts.method && option_tree.google_fonts.fonts ) { + var fonts = option_tree.google_fonts.fonts || {}; + $(document).on('change', '.option-tree-google-font-family', function() { + var input = $(this), family = input.val(); + if( fonts.hasOwnProperty( family ) ) { + if( fonts[family].hasOwnProperty('variants') ) { + update_variants(input,fonts[family].variants); + } + if( fonts[family].hasOwnProperty('subsets') ) { + update_subsets(input,fonts[family].subsets); + } + } + }); + } else { + $(document).on('change', '.option-tree-google-font-family', function() { + var input = $(this); + $.ajax({ + url: option_tree.ajax, + type: 'POST', + dataType: 'json', + data: { + action: 'ot_google_font', + family: input.val(), + field_id: input.attr('id').replace( /-google-font-family$/, '' ) + } + }).done(function(response) { + if( response.hasOwnProperty('variants') ) { + update_variants(input,response.variants); + } + if( response.hasOwnProperty('subsets') ) { + update_subsets(input,response.subsets); + } + }); + }); + } + }, bind_colorpicker: function(field_id) { $('#'+field_id).wpColorPicker(); }, @@ -1108,4 +1176,4 @@ }) }) -}(window.jQuery); \ No newline at end of file +}(window.jQuery); diff --git a/includes/ot-functions-admin.php b/includes/ot-functions-admin.php index 27b626a1..3f95d06b 100755 --- a/includes/ot-functions-admin.php +++ b/includes/ot-functions-admin.php @@ -645,10 +645,21 @@ function ot_admin_scripts() { /* load all the required scripts */ wp_enqueue_script( 'ot-admin-js', OT_URL . 'assets/js/ot-admin.js', array( 'jquery', 'jquery-ui-tabs', 'jquery-ui-sortable', 'jquery-ui-slider', 'wp-color-picker', 'ace-editor', 'jquery-ui-datepicker', 'jquery-ui-timepicker' ), OT_VERSION ); + + /* prepare google font settings */ + $google_font = array( + 'method' => apply_filters('ot_google_font_method','ajax') + ); + + /* The js method does not filter font variants and subsets */ + if ( 'js' == $google_font['method'] ) { + $google_font['fonts'] = ot_fetch_google_fonts(); + } /* create localized JS array */ $localized_array = array( 'ajax' => admin_url( 'admin-ajax.php' ), + 'google_fonts' => $google_font, 'upload_text' => apply_filters( 'ot_upload_text', __( 'Send to OptionTree', 'option-tree' ) ), 'remove_media_text' => __( 'Remove Media', 'option-tree' ), 'reset_agree' => __( 'Are you sure you want to reset back to the defaults?', 'option-tree' ), @@ -2210,6 +2221,7 @@ function ot_option_types_array() { 'date-picker' => __('Date Picker', 'option-tree'), 'date-time-picker' => __('Date Time Picker', 'option-tree'), 'gallery' => __('Gallery', 'option-tree'), + 'google-font' => __('Google Font', 'option-tree'), 'list-item' => __('List Item', 'option-tree'), 'measurement' => __('Measurement', 'option-tree'), 'numeric-slider' => __('Numeric Slider', 'option-tree'), @@ -4520,6 +4532,152 @@ function ot_filter_std_value( $value = '', $std = '' ) { } +function ot_fetch_google_fonts( $normalize = true ) { + + /* Google Fonts cache key */ + $ot_google_fonts_cache_key = apply_filters( 'ot_google_fonts_cache_key', 'ot_google_fonts_cache' ); + + /* get the fonts from cache */ + $ot_google_fonts = apply_filters( 'ot_google_fonts_cache', get_transient( $ot_google_fonts_cache_key ) ); + + if ( ! is_array( $ot_google_fonts ) || empty( $ot_google_fonts ) ) { + + $ot_google_fonts = array(); + + /* API url and key */ + $ot_google_fonts_api_url = apply_filters( 'ot_google_fonts_api_url', 'https://www.googleapis.com/webfonts/v1/webfonts' ); + $ot_google_fonts_api_key = apply_filters( 'ot_google_fonts_api_key', 'AIzaSyC-0ipgZdTRp2jeOct8w9GuPqjBX5LDDHE' ); + + /* API arguments */ + $ot_google_fonts_fields = apply_filters( 'ot_google_fonts_fields', array( 'family', 'variants', 'subsets' ) ); + $ot_google_fonts_sort = apply_filters( 'ot_google_fonts_sort', 'alpha' ); + + /* Initiate API request */ + $ot_google_fonts_query_args = array( + 'key' => $ot_google_fonts_api_key, + 'fields' => 'items(' . implode( ',', $ot_google_fonts_fields ) . ')', + 'sort' => $ot_google_fonts_sort + ); + + /* Build and make the request */ + $ot_google_fonts_query = add_query_arg( $ot_google_fonts_query_args, $ot_google_fonts_api_url ); + $ot_google_fonts_response = wp_safe_remote_get( $ot_google_fonts_query, array( 'sslverify' => false, 'timeout' => 15 ) ); + + /* continue if we got a valid response */ + if ( 200 == wp_remote_retrieve_response_code( $ot_google_fonts_response ) ) { + + if ( $response_body = wp_remote_retrieve_body( $ot_google_fonts_response ) ) { + + /* JSON decode the response body and cache the result */ + $ot_google_fonts_data = json_decode( trim( $response_body ), true ); + + if ( is_array( $ot_google_fonts_data ) && isset( $ot_google_fonts_data['items'] ) ) { + + $ot_google_fonts = $ot_google_fonts_data['items']; + set_transient( $ot_google_fonts_cache_key, $ot_google_fonts, WEEK_IN_SECONDS ); + + } + + } + + } + + } + + return $normalize ? ot_normalize_google_fonts( $ot_google_fonts ) : $ot_google_fonts; + +} + +function ot_normalize_google_fonts( $google_fonts ) { + + $ot_normalized_google_fonts = array(); + + if ( is_array( $google_fonts ) && ! empty( $google_fonts ) ) { + + foreach( $google_fonts as $google_font ) { + + if( isset( $google_font['family'] ) ) { + + $id = ot_google_font_id( $google_font['family'] ); + + $ot_normalized_google_fonts[ $id ] = array( + 'family' => $google_font['family'] + ); + + if( isset( $google_font['variants'] ) ) { + + $ot_normalized_google_fonts[ $id ]['variants'] = $google_font['variants']; + + } + + if( isset( $google_font['subsets'] ) ) { + + $ot_normalized_google_fonts[ $id ]['subsets'] = $google_font['subsets']; + + } + + } + + } + + } + + return $ot_normalized_google_fonts; + +} + +function ot_available_google_font_variants( $family, $field_id ) { + + $ot_google_fonts = ot_fetch_google_fonts(); + + if( isset( $ot_google_fonts[ $family ], $ot_google_fonts[ $family ]['variants'] ) ) { + + return apply_filters( 'ot_recognized_google_font_variants', $ot_google_fonts[ $family ]['variants'], $field_id ); + + } + + return array(); + +} + +function ot_available_google_font_subsets( $family, $field_id ) { + + $ot_google_fonts = ot_fetch_google_fonts(); + + if( isset( $ot_google_fonts[ $family ], $ot_google_fonts[ $family ]['subsets'] ) ) { + + return apply_filters( 'ot_recognized_google_font_subsets', $ot_google_fonts[ $family ]['subsets'], $field_id ); + + } + + return array(); + +} + +function ot_recognized_google_font_families( $field_id ) { + + $google_fonts = array(); + + foreach( ot_fetch_google_fonts() as $id => $google_font ) { + + if ( isset( $google_font['family'] ) ) { + + $google_fonts[ $id ] = $google_font['family']; + + } + + } + + return apply_filters( 'ot_recognized_google_font_families', $google_fonts, $field_id ); + +} + +function ot_google_font_id( $family ) { + + return str_replace( ' ', '+', $family ); + +} + /** * Helper function to register a WPML string * @@ -4913,4 +5071,4 @@ function ot_get_option_type_by_id( $option_id, $settings_id = '' ) { } /* End of file ot-functions-admin.php */ -/* Location: ./includes/ot-functions-admin.php */ \ No newline at end of file +/* Location: ./includes/ot-functions-admin.php */ diff --git a/includes/ot-functions-option-types.php b/includes/ot-functions-option-types.php index e2b68112..3432609f 100755 --- a/includes/ot-functions-option-types.php +++ b/includes/ot-functions-option-types.php @@ -830,6 +830,83 @@ function ot_type_gallery( $args = array() ) { } +/** + * Google Font option type. + * + * See @ot_display_by_type to see the full list of available arguments. + * + * @param array An array of arguments. + * @return string + * + * @access public + * @since @version + */ +if ( ! function_exists( 'ot_type_google_font' ) ) { + + function ot_type_google_font( $args = array() ) { + + /* turns arguments array into variables */ + extract( $args ); + + /* verify a description */ + $has_desc = $field_desc ? true : false; + + /* format setting outer wrapper */ + echo '
'; + + /* description */ + echo $has_desc ? '
' . htmlspecialchars_decode( $field_desc ) . '
' : ''; + + /* format setting inner wrapper */ + echo '
'; + + /* allow fields to be filtered */ + $ot_recognized_google_fonts_fields = apply_filters( 'ot_recognized_google_font_fields', array( + 'font-variant', + 'font-subsets' + ), $field_id ); + + /* build font family */ + $font_family = isset( $field_value['font-family'] ) ? $field_value['font-family'] : ''; + echo ''; + + /* build font variant */ + if ( in_array( 'font-variant', $ot_recognized_google_fonts_fields ) ) { + $font_variant = isset( $field_value['font-variant'] ) ? esc_attr( $field_value['font-variant'] ) : ''; + echo ''; + } + + /* build font subsets */ + if ( in_array( 'font-subsets', $ot_recognized_google_fonts_fields ) ) { + $font_subsets = isset( $field_value['font-subsets'] ) ? $field_value['font-subsets'] : array(); + echo '
'; + foreach ( ot_available_google_font_subsets( $font_family, $field_id ) as $subset ) { + echo '

'; + echo ''; + echo ''; + echo '

'; + } + echo '
'; + } + + echo '
'; + + echo '
'; + + } + +} + /** * List Item option type. * @@ -2465,4 +2542,4 @@ function ot_type_upload( $args = array() ) { } /* End of file ot-functions-option-types.php */ -/* Location: ./includes/ot-functions-option-types.php */ \ No newline at end of file +/* Location: ./includes/ot-functions-option-types.php */ diff --git a/ot-loader.php b/ot-loader.php index 46b9e186..06323663 100755 --- a/ot-loader.php +++ b/ot-loader.php @@ -516,6 +516,9 @@ private function hooks() { /* AJAX call to create a new social link */ add_action( 'wp_ajax_add_social_links', array( $this, 'add_social_links' ) ); + + /* AJAX call to retrieve Google Font data */ + add_action( 'wp_ajax_ot_google_font', array( $this, 'retrieve_google_font' ) ); // Adds the temporary hacktastic shortcode add_filter( 'media_view_settings', array( $this, 'shortcode' ), 10, 2 ); @@ -725,6 +728,23 @@ public function ajax_gallery_update() { } } + + public function retrieve_google_font() { + + if ( isset( $_POST['family'], $_POST['field_id'] ) ) { + + $ot_google_font_variants = ot_available_google_font_variants( $_POST['family'], $_POST['field_id'] ); + $ot_google_font_subsets = ot_available_google_font_subsets( $_POST['family'], $_POST['field_id'] ); + + echo json_encode( array( + 'variants' => $ot_google_font_variants, + 'subsets' => $ot_google_font_subsets + ) ); + exit(); + + } + + } /** * Filters the media uploader button. @@ -762,4 +782,4 @@ public function change_image_button( $translation, $text, $domain ) { } /* End of file ot-loader.php */ -/* Location: ./ot-loader.php */ \ No newline at end of file +/* Location: ./ot-loader.php */