google_fonts_api.module in @font-your-face 8.3
Google Fonts module file.
File
modules/google_fonts_api/google_fonts_api.moduleView source
<?php
/**
* @file
* Google Fonts module file.
*/
use Drupal\Core\Link;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_fontyourface_api().
*/
function google_fonts_api_fontyourface_api() {
return [
'version' => '3',
'name' => 'Google Fonts',
];
}
/**
* Implements hook_modules_installed().
*
* Use this hook instead of hook_install, because the route "font.settings" is
* not defined otherwise.
*/
function google_fonts_api_modules_installed($modules) {
if (in_array('google_fonts_api', $modules)) {
Drupal::messenger()
->addMessage(t('Due to the number of fonts, automated import from install for Google Fonts is disabled. Please use @link to import Google Fonts.', [
'@link' => Link::createFromRoute('@font-your-face settings', 'font.settings')
->toString(),
]));
}
}
/**
* Implements hook_page_attachments().
*/
function google_fonts_api_page_attachments(&$page) {
$enabled_fonts =& drupal_static('fontyourface_fonts', []);
$fonts = [];
foreach ($enabled_fonts as $font) {
if ($font->pid->value == 'google_fonts_api') {
$fonts[] = $font;
}
}
$url = google_fonts_api_generate_font_family_css($fonts);
if (!empty($url)) {
$page['#attached']['html_head'][] = [
[
'#type' => 'html_tag',
'#tag' => 'link',
'#attributes' => [
'rel' => 'stylesheet',
'href' => $url,
'media' => 'all',
],
],
'fontyourface-google-fonts-api',
];
}
}
/**
* Generates font family css for multiple fonts.
*
* @param array $fonts
* Array of FontInterface objects.
*
* @return string
* URL to load fonts on page.
*/
function google_fonts_api_generate_font_family_css(array $fonts) {
$url = '';
$paths = [];
foreach ($fonts as $font) {
if ($font->pid->value == 'google_fonts_api') {
$metadata = $font
->getMetadata();
$path_parts = explode(':', $metadata['path']);
$all_subsets[$metadata['subset']] = $metadata['subset'];
if (!isset($paths[$path_parts[0]])) {
$paths[$path_parts[0]] = [];
}
if (count($path_parts) > 1) {
$paths[$path_parts[0]][$path_parts[1]] = $path_parts[1];
}
else {
$paths[$path_parts[0]]['regular'] = 'regular';
}
}
}
if (count($paths) > 0) {
$families = [];
foreach ($paths as $family => $variants) {
$families[$family] = urlencode($family) . ':' . implode(',', $variants);
}
$base = 'https://fonts.googleapis.com/css?family=';
$url = $base . implode('|', $families) . '&subset=' . implode(',', $all_subsets);
}
return $url;
}
/**
* Implements hook_fontyourface_import().
*/
function google_fonts_api_fontyourface_import($font_context = []) {
$context = $font_context;
if (empty($context['sandbox'])) {
$context['sandbox']['fonts'] = _google_fonts_api_get_fonts_from_api();
$context['sandbox']['progress'] = 0;
$all = _google_fonts_api_convert_api_results($context['sandbox']['fonts']);
$context['sandbox']['max'] = count($all);
}
$fonts = _google_fonts_api_convert_api_results($context['sandbox']['fonts']);
$index = $context['sandbox']['progress'];
$font = $fonts[$index];
if (!empty($font)) {
if (!isset($font->tags)) {
$font->tags = [];
}
fontyourface_save_font($font);
$context['message'] = "Imported {$context['sandbox']['progress']} of {$context['sandbox']['max']}";
$context['sandbox']['progress']++;
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
else {
Drupal::messenger()
->addMessage(t('Imported @count fonts from Google Fonts', [
'@count' => $context['sandbox']['progress'],
]));
}
return $context;
}
/**
* Retrieves fonts from api and parses them for consumption.
*
* @param string $temp_key
* An API key to use for testing.
*
* @return array
* List of fonts ready for ingesting as FontInterface objects.
*/
function _google_fonts_api_get_fonts_from_api($temp_key = '') {
// Return the JSON object with all available fonts.
$google_api_key = $temp_key ?: \Drupal::config('google_fonts_api.settings')
->get('google_api_key');
try {
$uri = 'https://www.googleapis.com/webfonts/v1/webfonts?key=' . $google_api_key;
$response = \Drupal::httpClient()
->get($uri, [
'headers' => [
'Accept' => 'text/plain',
],
'verify' => FALSE,
]);
if ($response
->getStatusCode() == 200) {
$data = (string) $response
->getBody();
$json_results = json_decode($data);
return $json_results->items;
}
else {
// Connection was successful but Google responded with an error code.
throw new \Exception();
}
} catch (Exception $e) {
Drupal::messenger()
->addMessage(t('The list of Google Fonts could not be fetched. Verify that your server can connect to the Google servers (https://www.googleapis.com). Error: %error', [
'%error' => $e
->getMessage(),
]), 'error');
return FALSE;
}
}
/**
* Converts the Google Fonts API JSON results to a generic Fonts object array.
*
* @param array $json_font_list
* Array of Google Font objects.
*
* @return array
* Array of objects compatible with Fontyourface interface.
*/
function _google_fonts_api_convert_api_results(array $json_font_list) {
$fonts = [];
foreach ($json_font_list as $json_font) {
foreach ($json_font->variants as $json_font_variant) {
foreach ($json_font->subsets as $json_font_subset) {
$font_id = $json_font->family . ' ' . $json_font_variant . ' (' . $json_font_subset . ')';
switch ($json_font_variant) {
case 'regular':
$css_style = 'normal';
$css_weight = 'normal';
break;
case 'italic':
$css_style = 'italic';
$css_weight = 'normal';
break;
case 'bold':
$css_style = 'normal';
$css_weight = 'bold';
break;
case 'bolditalic':
$css_style = 'italic';
$css_weight = 'bold';
break;
default:
// For all other cases (eg 400 or 400italic).
if (is_numeric($json_font_variant)) {
// Variant is a number, like 400.
$css_style = 'normal';
$css_weight = $json_font_variant;
}
elseif (is_numeric(substr($json_font_variant, 0, 3))) {
// Variant is a combined string of number and string, like
// 400italic.
// The numeric part is always three characters long, so we can
// split it easily.
$css_style = substr($json_font_variant, 3);
$css_weight = substr($json_font_variant, 0, 3);
}
}
$font = new stdClass();
$font->name = $font_id;
$font->url = 'https://www.google.com/webfonts/family?family=' . $json_font->family . '&subset=' . $json_font_subset . '#' . $json_font_variant;
$font->provider = 'google_fonts_api';
$font->css_family = $json_font->family;
$font->css_style = $css_style;
$font->css_weight = $css_weight;
$font->designer = '';
$font->designer_url = '';
$font->foundry = '';
$font->foundry_url = '';
$font->license = '';
$font->license_url = '';
$font->classification = [
$json_font->category,
];
$font->language = [
$json_font_subset,
];
$font->metadata = [
'path' => $json_font->family . ':' . $json_font_variant,
'subset' => $json_font_subset,
];
$fonts[] = $font;
}
}
}
return $fonts;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function google_fonts_api_form_font_settings_alter(&$form, FormStateInterface $form_state) {
$config = \Drupal::config('google_fonts_api.settings');
$form['google_fonts_api'] = [
'#type' => 'fieldset',
'#title' => t('Google Fonts Settings'),
];
$form['google_fonts_api']['google_api_key'] = [
'#type' => 'textfield',
'#title' => t('Google API Key'),
'#description' => t('Add your Google API key to import fonts. Available at <a target="_blank" href=":url">:url</a>.', [
':url' => 'https://developers.google.com/fonts/docs/developer_api#APIKey',
]),
'#default_value' => $config
->get('google_api_key'),
];
$form['imports']['import_google_fonts_api']['#disabled'] = !(bool) $config
->get('google_api_key');
$form['#validate'][] = 'google_fonts_api_form_font_settings_validate';
$form['#submit'][] = 'google_fonts_api_form_font_settings_submit';
}
/**
* Form validation handler for Google Font settings.
*/
function google_fonts_api_form_font_settings_validate(&$form, FormStateInterface $form_state) {
$google_api_key = trim($form_state
->getValue('google_api_key'));
if ($google_api_key) {
$connection_works = _google_fonts_api_get_fonts_from_api($google_api_key);
if (!$connection_works) {
// The _google_fonts_api_get_fonts_from_api() will output a more
// thorough error message.
$form_state
->setError($form['google_fonts_api']['google_api_key'], '');
}
}
}
/**
* Form submit handler for Google Font settings.
*/
function google_fonts_api_form_font_settings_submit(&$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
$config = \Drupal::configFactory()
->getEditable('google_fonts_api.settings');
$config
->set('google_api_key', $values['google_api_key'])
->save();
}
Functions
Name | Description |
---|---|
google_fonts_api_fontyourface_api | Implements hook_fontyourface_api(). |
google_fonts_api_fontyourface_import | Implements hook_fontyourface_import(). |
google_fonts_api_form_font_settings_alter | Implements hook_form_FORM_ID_alter(). |
google_fonts_api_form_font_settings_submit | Form submit handler for Google Font settings. |
google_fonts_api_form_font_settings_validate | Form validation handler for Google Font settings. |
google_fonts_api_generate_font_family_css | Generates font family css for multiple fonts. |
google_fonts_api_modules_installed | Implements hook_modules_installed(). |
google_fonts_api_page_attachments | Implements hook_page_attachments(). |
_google_fonts_api_convert_api_results | Converts the Google Fonts API JSON results to a generic Fonts object array. |
_google_fonts_api_get_fonts_from_api | Retrieves fonts from api and parses them for consumption. |