5 * Google Fonts module file.
9 * Implements hook_fontyourface_api().
11 function google_fonts_api_fontyourface_api() {
14 'name' => 'Google Fonts',
19 * Implements hook_page_attachments().
21 function google_fonts_api_page_attachments(&$page) {
22 $enabled_fonts = &drupal_static('fontyourface_fonts', []);
24 foreach ($enabled_fonts as $font) {
25 if ($font->pid->value == 'google_fonts_api') {
29 $url = google_fonts_api_generate_font_family_css($fonts);
31 $page['#attached']['html_head'][] = [
33 '#type' => 'html_tag',
36 'rel' => 'stylesheet',
40 ], 'fontyourface-google-fonts-api',
46 * Generates font family css for multiple fonts.
49 * Array of FontInterface objects.
52 * URL to load fonts on page.
54 function google_fonts_api_generate_font_family_css(array $fonts) {
57 foreach ($fonts as $font) {
58 if ($font->pid->value == 'google_fonts_api') {
59 $metadata = $font->getMetadata();
60 $path_parts = explode(':', $metadata['path']);
62 $all_subsets[$metadata['subset']] = $metadata['subset'];
64 if (!isset($paths[$path_parts[0]])) {
65 $paths[$path_parts[0]] = [];
68 if (count($path_parts) > 1) {
69 $paths[$path_parts[0]][$path_parts[1]] = $path_parts[1];
72 $paths[$path_parts[0]]['regular'] = 'regular';
77 if (count($paths) > 0) {
81 foreach ($paths as $family => $variants) {
82 $families[$family] = urlencode($family) . ':' . implode(',', $variants);
85 $base = 'http://fonts.googleapis.com/css?family=';
87 if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
88 $base = 'https://fonts.googleapis.com/css?family=';
91 $url = $base . implode('|', $families) . '&subset=' . implode(',', $all_subsets);
98 * Implements hook_fontyourface_import().
100 function google_fonts_api_fontyourface_import($font_context = []) {
101 $context = $font_context;
102 if (empty($context['sandbox'])) {
103 $context['sandbox']['fonts'] = _google_fonts_api_get_fonts_from_api();
104 $context['sandbox']['progress'] = 0;
105 $context['sandbox']['max'] = count($context['sandbox']['fonts']);
107 $font = array_pop($context['sandbox']['fonts']);
109 if (!isset($font->tags)) {
112 fontyourface_save_font($font);
113 $context['message'] = "Imported {$context['sandbox']['progress']} of {$context['sandbox']['max']}";
114 $context['sandbox']['progress'] = $context['sandbox']['max'] - count($context['sandbox']['fonts']);
115 $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
118 drupal_set_message(t('Imported @count fonts from Google Fonts', ['@count' => $context['sandbox']['progress']]));
124 * Retrieves fonts from api and parses them for consumption.
127 * List of fonts ready for ingesting as FontInterface objects.
129 function _google_fonts_api_get_fonts_from_api() {
130 // Return the JSON object with all available fonts
131 // For now, it uses the API key of BarisW (co-maintainer of this module)
132 // This key is limited to 10.000 requests per day, which should be
133 // sufficient as it is only used when selecting fonts in the admin interface.
134 // After that, the fonts are stored in Drupal.
136 $uri = 'https://www.googleapis.com/webfonts/v1/webfonts?key=AIzaSyBgeqKlFdYj3Y7VwmrEXnXzpnx5TfKXG4o';
137 $response = \Drupal::httpClient()->get($uri, ['headers' => ['Accept' => 'text/plain'], 'verify' => FALSE]);
138 $data = (string) $response->getBody();
140 catch (RequestException $e) {
141 drupal_set_message(t('The list of Google Fonts could not be fetched. Verify that your server can connect the Google Servers (https://www.googleapis.com). Error: %error', ['%error' => $response->error]), 'error');
145 $json_results = json_decode($data);
147 return _google_fonts_api_convert_api_results($json_results->items);
151 * Converts the Google Fonts API JSON results to a generic Fonts object array.
153 * @param array $json_font_list
154 * Array of Google Font objects.
157 * Array of objects compatible with Fontyourface interface.
159 function _google_fonts_api_convert_api_results(array $json_font_list) {
161 foreach ($json_font_list as $json_font) {
162 foreach ($json_font->variants as $json_font_variant) {
163 foreach ($json_font->subsets as $json_font_subset) {
165 $font_id = $json_font->family . ' ' . $json_font_variant . ' (' . $json_font_subset . ')';
167 switch ($json_font_variant) {
169 $css_style = 'normal';
170 $css_weight = 'normal';
174 $css_style = 'italic';
175 $css_weight = 'normal';
179 $css_style = 'normal';
180 $css_weight = 'bold';
184 $css_style = 'italic';
185 $css_weight = 'bold';
189 // For all other cases (eg 400 or 400italic).
190 if (is_numeric($json_font_variant)) {
191 // Variant is a number, like 400.
192 $css_style = 'normal';
193 $css_weight = $json_font_variant;
195 elseif (is_numeric(substr($json_font_variant, 0, 3))) {
196 // Variant is a combined string of number and string, like 400italic.
197 // The numeric part is always three characters long, so we can split it easily.
198 $css_style = substr($json_font_variant, 3);
199 $css_weight = substr($json_font_variant, 0, 3);
203 $fonts[$font_id] = new stdClass();
204 $fonts[$font_id]->name = $font_id;
205 $fonts[$font_id]->url = 'http://www.google.com/webfonts/family?family=' . $json_font->family . '&subset=' . $json_font_subset . '#' . $json_font_variant;
206 $fonts[$font_id]->provider = 'google_fonts_api';
207 $fonts[$font_id]->css_family = $json_font->family;
208 $fonts[$font_id]->css_style = $css_style;
209 $fonts[$font_id]->css_weight = $css_weight;
210 $fonts[$font_id]->designer = '';
211 $fonts[$font_id]->designer_url = '';
212 $fonts[$font_id]->foundry = '';
213 $fonts[$font_id]->foundry_url = '';
214 $fonts[$font_id]->license = '';
215 $fonts[$font_id]->license_url = '';
216 $fonts[$font_id]->classification = [
217 $json_font->category,
219 $fonts[$font_id]->language = [
222 $fonts[$font_id]->metadata = [
223 'path' => $json_font->family . ':' . $json_font_variant,
224 'subset' => $json_font_subset,