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