Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / modules / contrib / fontyourface / modules / fontsquirrel_api / fontsquirrel_api.module
1 <?php
2
3 /**
4  * @file
5  * Font Squirrel API module file.
6  */
7
8 use Drupal\Core\Entity\EntityInterface;
9 use Drupal\Core\Link;
10 use Drupal\fontyourface\Entity\Font;
11
12 /**
13  * Implements hook_fontyourface_api().
14  */
15 function fontsquirrel_api_fontyourface_api() {
16   return [
17     'version' => '3',
18     'name' => 'Font Squirrel',
19   ];
20 }
21
22 /**
23  * Implements hook_modules_installed().
24  *
25  * Use this hook instead of hook_install, because the route "font.settings" is
26  * not defined otherwise.
27  */
28 function fontsquirrel_api_modules_installed($modules) {
29   if (in_array('fontsquirrel_api', $modules)) {
30     drupal_set_message(t('Due to the number of fonts, automated import from install for Font Squirrel is disabled. Please use @link to import Font Squirrel Fonts.', ['@link' => Link::createFromRoute('@font-your-face settings', 'font.settings')->toString()]));
31   }
32 }
33
34 /**
35  * Implements hook_entity_presave().
36  */
37 function fontsquirrel_api_entity_presave(EntityInterface $entity) {
38   if ($entity instanceof Font) {
39     if ($entity->pid->value == 'fontsquirrel_api' && $entity->isActivated()) {
40       $metadata = $entity->getMetadata();
41       $directory_location = _fontsquirrel_api_get_font_directory_location($entity);
42       file_prepare_directory($directory_location, FILE_CREATE_DIRECTORY);
43       $zip_location = file_build_uri('fontyourface/fontsquirrel/' . $metadata['path'] . '-fontfacekit.zip');
44       // Throw an exception; make it hard if this fails.
45       $uri = 'https://www.fontsquirrel.com/fontfacekit/' . $metadata['path'];
46       $response = \Drupal::httpClient()->get($uri, ['headers' => ['Accept' => 'text/plain']]);
47       if (!file_exists(drupal_realpath($zip_location))) {
48         file_unmanaged_save_data($response->getBody(), $zip_location);
49       }
50       $files = [];
51       $font_pathinfo = pathinfo($metadata['font_filename']);
52       if ($zip = zip_open(drupal_realpath($zip_location))) {
53         while ($entry = zip_read($zip)) {
54           $entry_name = zip_entry_name($entry);
55           $path_info = pathinfo($entry_name);
56           if (strpos($path_info['filename'], $font_pathinfo['filename'] . '-webfont') !== FALSE &&
57               in_array($path_info['extension'], ['eot', 'ttf', 'woff', 'svg'])) {
58             $files[$path_info['extension']] = $path_info['filename'] . '.' . $path_info['extension'];
59             $data = zip_entry_read($entry, zip_entry_filesize($entry));
60             file_unmanaged_save_data($data, $directory_location . '/' . $path_info['filename'] . '.' . $path_info['extension'], FILE_EXISTS_REPLACE);
61           }
62           zip_entry_close($entry);
63         }
64         zip_close($zip);
65       }
66       if (!empty($files)) {
67         $css_file = _fontsquirrel_api_generate_fontfamily_css_stylesheet($entity->css_family->value, $files);
68         file_unmanaged_save_data($css_file, $directory_location . '/fontyourface-stylesheet.css', FILE_EXISTS_REPLACE);
69       }
70     }
71   }
72 }
73
74 /**
75  * Implements hook_page_attachments().
76  */
77 function fontsquirrel_api_page_attachments(&$page) {
78   $enabled_fonts = &drupal_static('fontyourface_fonts', []);
79   foreach ($enabled_fonts as $font) {
80     if ($font->pid->value == 'fontsquirrel_api' && $font->isActivated()) {
81       $directory_location = _fontsquirrel_api_get_font_directory_location($font);
82       $page['#attached']['html_head'][] = [
83         [
84           '#type' => 'html_tag',
85           '#tag' => 'link',
86           '#attributes' => [
87             'rel' => 'stylesheet',
88             'href' => file_create_url($directory_location . '/fontyourface-stylesheet.css'),
89             'media' => 'all',
90           ],
91         ], 'fontsquirrel-api-' . $font->id(),
92       ];
93     }
94   }
95 }
96
97 /**
98  * Prepares variables for Font templates.
99  *
100  * Default template: font.html.twig.
101  *
102  * @param array $variables
103  *   An associative array containing:
104  *   - elements: An associative array containing the user information and any
105  *   - attributes: HTML attributes for the containing element.
106  */
107 function fontsquirrel_api_preprocess_font(array &$variables) {
108   $font = $variables['elements']['#font'];
109   $metadata = $font->getMetadata();
110   if ($font->pid->value == 'fontsquirrel_api' && $font->isDeactivated()) {
111     $variables['font_preview']['#markup'] = '<img style=\'max-width:100%;\' src="' . $metadata['preview_image'] . '" />';
112   }
113 }
114
115 /**
116  * Prepares variables for full font template preview.
117  *
118  * Default template: font--full.html.twig.
119  *
120  * @param array $variables
121  *   An associative array containing:
122  *   - elements: An associative array containing the user information and any
123  *   - attributes: HTML attributes for the containing element.
124  */
125 function fontsquirrel_api_preprocess_font__full(array &$variables) {
126   fontsquirrel_api_preprocess_font($variables);
127 }
128
129 /**
130  * Prepares variables for font teaser preview.
131  *
132  * Default template: font--teaser.html.twig.
133  *
134  * @param array $variables
135  *   An associative array containing:
136  *   - elements: An associative array containing the user information and any
137  *   - attributes: HTML attributes for the containing element.
138  */
139 function fontsquirrel_api_preprocess_font__teaser(array &$variables) {
140   $font = $variables['elements']['#font'];
141   $metadata = $font->getMetadata();
142   if ($font->pid->value == 'fontsquirrel_api' && $font->isDeactivated()) {
143     $variables['font_preview']['#markup'] = '<img width="160px" src="https://www.fontsquirrel.com/widgets/test_drive/' . $metadata['checksum'] . '?s=144&t=AaGg" />';
144   }
145 }
146
147 /**
148  * Implements hook_fontyourface_import().
149  */
150 function fontsquirrel_api_fontyourface_import($font_context = []) {
151   // Individual font could take a lot of time.
152   @set_time_limit(3600);
153   $context = $font_context;
154
155   if (empty($context['sandbox'])) {
156     $context['sandbox']['fonts'] = _fontsquirrel_api_get_fonts_from_api();
157     $context['sandbox']['progress'] = 0;
158     $context['sandbox']['max'] = count($context['sandbox']['fonts']);
159   }
160
161   $font_import = array_pop($context['sandbox']['fonts']);
162   if (!empty($font_import)) {
163     $metadata = [
164       'id' => $font_import->id,
165       'path' => $font_import->family_urlname,
166       'font_filename' => $font_import->font_filename,
167     ];
168     $font = new stdClass();
169     $font->name = $font_import->family_name;
170     $font->url = 'https://www.fontsquirrel.com/fonts/' . $font_import->family_urlname;
171     $font->provider = 'fontsquirrel_api';
172     $font->css_family = $font_import->family_urlname . 'regular';
173     // Font Squirrel fonts have no concept of normal/bold/light/italics fonts.
174     $font->css_weight = 400;
175     $font->css_style = 'normal';
176     $font->foundry = $font_import->foundry_name;
177     $font->foundry_url = 'https://www.fontsquirrel.com/foundry/' . $font_import->foundry_urlname;
178     $font->license = 'See Font Squirrel license page';
179     $font->license_url = $font->url . '#eula';
180     $font->classification = [
181       str_replace(' ', '-', strtolower($font_import->classification)),
182     ];
183     $font->language = [
184       'English',
185     ];
186     $font->metadata = $metadata;
187     $variants = fontsquirrel_api_get_font_family_info($font_import);
188     foreach ($variants as $variant) {
189       $variant_metadata = $metadata;
190       $variant_metadata['font_filename'] = $variant->filename;
191       $variant_metadata['checksum'] = $variant->checksum;
192       $variant_metadata['preview_image'] = str_replace('\\', '', $variant->sample_image);
193       $variant_font = clone $font;
194       $variant_font->name = $variant->family_name . ' ' . $variant->style_name;
195       $variant_font->url = $font->url . '#' . $variant->fontface_name;
196       $variant_font->css_family = $variant->fontface_name;
197       $variant_font->metadata = $variant_metadata;
198       fontyourface_save_font($variant_font);
199     }
200     $context['message'] = "Imported {$context['sandbox']['progress']} (plus variants) of {$context['sandbox']['max']}";
201     $context['sandbox']['progress'] = $context['sandbox']['max'] - count($context['sandbox']['fonts']);
202     $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
203   }
204   else {
205     drupal_set_message(t('Imported @count Font Squirrel fonts (and variants).', ['@count' => $context['sandbox']['max']]));
206   }
207   return $context;
208 }
209
210 /**
211  * Retrieves fonts from api and parses them for consumption.
212  *
213  * @return array
214  *   List of fonts ready for ingesting as FontInterface objects.
215  */
216 function _fontsquirrel_api_get_fonts_from_api() {
217   try {
218     $uri = 'https://www.fontsquirrel.com/api/fontlist/all';
219     $response = \Drupal::httpClient()->get($uri, ['headers' => ['Accept' => 'text/plain']]);
220     $data = json_decode($response->getBody());
221   }
222   catch (RequestException $e) {
223     drupal_set_message(t('There was an error downloading font list from Font Squirrel.'), 'error');
224     fontyourface_log('Invalid drupal_http_request response: @response', ['@response' => $e->getMessage()]);
225     return FALSE;
226   }
227   return $data;
228 }
229
230 /**
231  * Get font family information from Font Squirrel.
232  *
233  * @param object $font_import
234  *   Initial font package data from Font Squirrel.
235  *
236  * @return object
237  *   Font family information from Font Squirrel.
238  */
239 function fontsquirrel_api_get_font_family_info($font_import) {
240   try {
241     $uri = 'https://www.fontsquirrel.com/api/familyinfo/' . $font_import->family_urlname;
242     $response = \Drupal::httpClient()->get($uri, ['headers' => ['Accept' => 'text/plain']]);
243     $data = json_decode($response->getBody());
244   }
245   catch (RequestException $e) {
246     drupal_set_message(t('There was an error downloading font list from Font Squirrel.'), 'error');
247     fontyourface_log('Invalid drupal_http_request response: @response', ['@response' => $e->getMessage()]);
248     return FALSE;
249   }
250   return $data;
251 }
252
253 /**
254  * Returns directory location of font package from Font Squirrel.
255  *
256  * @param Drupal\fontyourface\Entity\Font $font
257  *   Font entity with downloaded package.
258  *
259  * @return string
260  *   File stream location to font package.
261  */
262 function _fontsquirrel_api_get_font_directory_location(Font $font) {
263   return file_build_uri('fontyourface/fontsquirrel/' . _fontsquirrel_api_get_sanitized_css_family($font->css_family->value) . '-fontfacekit');
264 }
265
266 /**
267  * Returns sanitized css family text.
268  *
269  * @param string $css_family
270  *   Unsanitized version of css family string.
271  *
272  * @return string
273  *   Sanitized css family string.
274  */
275 function _fontsquirrel_api_get_sanitized_css_family($css_family) {
276   return preg_replace("/[^A-Za-z0-9\-]/", '', $css_family);
277 }
278
279 /**
280  * Generates CSS to load font.
281  *
282  * @param string $css_family
283  *   Font entity with downloaded package.
284  * @param array $files
285  *   Font files keyed by file type.
286  *
287  * @return string
288  *   CSS Definition for @font-face.
289  */
290 function _fontsquirrel_api_generate_fontfamily_css_stylesheet($css_family, array $files) {
291   $data = "@font-face {\n";
292   $data .= "font-family: '{$css_family}';\n";
293   $lines = [];
294
295   if ($files['eot']) {
296     $data .= "src: url('{$files['eot']}');\n";
297     $lines[] = "url('{$files['eot']}?#iefix') format('embedded-opentype')";
298   }
299   if ($files['ttf']) {
300     $lines[] = "url('{$files['ttf']}') format('truetype')";
301   }
302   if ($files['woff']) {
303     $lines[] = "url('{$files['woff']}') format('woff')";
304   }
305   if ($files['svg']) {
306     $lines[] = "url('{$files['svg']}#{$css_family}') format('svg')";
307   }
308
309   $data .= 'src: ' . implode(', ', $lines) . ";\n";
310   $data .= "font-weight: normal;\n";
311   $data .= "font-style: normal;\n";
312   return $data . "}\n";
313 }