Pathologic was missing because of a .git folder inside.
[yaffs-website] / web / modules / contrib / fontyourface / fontyourface.module
1 <?php
2
3 /**
4  * @file
5  * Contains fontyourface.module..
6  */
7
8 use Drupal\Core\Url;
9 use Drupal\Core\Render\Element;
10 use Drupal\Core\Routing\RouteMatchInterface;
11 use Drupal\Component\Utility\Html;
12 use Drupal\taxonomy\Entity\Term;
13
14 use Drupal\fontyourface\FontInterface;
15 use Drupal\fontyourface\FontDisplayInterface;
16 use Drupal\fontyourface\Entity\Font;
17 use Drupal\fontyourface\Entity\FontDisplay;
18
19 /**
20  * Implements hook_module_implements_alter().
21  */
22 function fontyourface_module_implements_alter(&$implementations, $hook) {
23   if ($hook == 'page_attachments') {
24     // Move the fontyourface and submodules to be among the last to build on page.
25     $list = ['fontyourface'];
26     foreach (\Drupal::moduleHandler()->getImplementations('fontyourface_api') as $module_name) {
27       if (isset($implementations[$module_name])) {
28         $list[] = $module_name;
29       }
30     }
31     foreach ($list as $module_name) {
32       $group = $implementations[$module_name];
33       unset($implementations[$module_name]);
34       $implementations[$module_name] = $group;
35     }
36   }
37 }
38
39 /**
40  * Implements hook_help().
41  */
42 function fontyourface_help($route_name, RouteMatchInterface $route_match) {
43   switch ($route_name) {
44     // Main module help for the fontyourface module.
45     case 'help.page.fontyourface':
46       $output = '';
47       $output .= '<h3>' . t('About') . '</h3>';
48       $output .= '<p>' . t('Web font management tools.') . '</p>';
49       return $output;
50
51     default:
52   }
53 }
54
55 /**
56  * Implements hook_library_info_build().
57  */
58 function fontyourface_library_info_build() {
59   $libraries = [];
60   $drupal_themes = \Drupal::service('theme_handler')->listInfo();
61   foreach ($drupal_themes as $key => $theme) {
62     $styles = FontDisplay::loadByTheme($key);
63     if (!empty($styles)) {
64       foreach ($styles as $style) {
65         $file_url = file_build_uri('fontyourface/font_display/' . $style->id() . '.css');
66         $libraries['font_display_' . $key]['css']['base'][$file_url] = [
67           'basename' => $file_url,
68         ];
69       }
70     }
71   }
72   return $libraries;
73 }
74
75 /**
76  * Implements hook_theme().
77  */
78 function fontyourface_theme() {
79   return [
80     'font' => [
81       'render element' => 'elements',
82     ],
83     'font__full' => [
84       'render element' => 'elements',
85     ],
86     'font__teaser' => [
87       'render element' => 'elements',
88     ],
89   ];
90 }
91
92 /**
93  * Implements hook_page_attachments().
94  */
95 function fontyourface_page_attachments(&$page) {
96   $config = \Drupal::config('fontyourface.settings');
97   $fonts = &drupal_static('fontyourface_fonts', []);
98   // Load all enabled fonts regardless of theme if setting allows it.
99   if ($config->get('load_all_enabled_fonts')) {
100     foreach (Font::loadEnabledFonts() as $font) {
101       $fonts[$font->url->value] = $font;
102     }
103   }
104
105   $font_preview = &drupal_static('fontyourface_font_preview');
106   // On a font preview page, ONLY show the preview font and other base theme font.
107   if (empty($font_preview)) {
108     // We are dealing with a regular page.
109     $theme = \Drupal::theme()->getActiveTheme()->getName();
110     $styles = FontDisplay::loadByTheme($theme);
111     if (!empty($styles)) {
112       $page['#attached']['library'][] = 'fontyourface/font_display_' . $theme;
113       foreach ($styles as $style) {
114         $font = $style->getFont();
115         if (!empty($font)) {
116           $fonts[$font->url->value] = $font;
117         }
118       }
119     }
120   }
121 }
122
123 /**
124  * Implements hook_preprocess_HOOK().
125  *
126  * Adds body classes if certain regions have content.
127  */
128 function fontyourface_preprocess_html(&$variables) {
129   $variables['attributes']['class'][] = 'fontyourface';
130 }
131
132 /**
133  * Implements hook_theme_suggestions_HOOK().
134  */
135 function fontyourface_theme_suggestions_font(array $variables) {
136   return ['font__' . $variables['elements']['#view_mode']];
137 }
138
139 /**
140  * Implements hook_views_pre_render().
141  */
142 function fontyourface_views_pre_render($view) {
143   if ($view->id() == 'fontyourface_font_manager') {
144     $view->element['#attached']['library'][] = 'fontyourface/fontyourface.admin';
145   }
146 }
147
148 /**
149  * Prepares variables for Font templates.
150  *
151  * Default template: font.html.twig.
152  *
153  * @param array $variables
154  *   An associative array containing:
155  *   - elements: An associative array containing the user information and any
156  *   - attributes: HTML attributes for the containing element.
157  */
158 function fontyourface_preprocess_font(array &$variables) {
159   // Fetch Font Entity Object.
160   $font = $variables['elements']['#font'];
161   $fonts = &drupal_static('fontyourface_fonts');
162   $fonts[$font->url->value] = $font;
163   $font_preview = &drupal_static('fontyourface_font_preview');
164   $font_preview = TRUE;
165   $title = Html::escape($font->name->value);
166
167   $variables['font_style'] = fontyourface_font_css($font, NULL, "\n");
168   $variables['font_style_inline'] = fontyourface_font_css($font);
169   $variables['font_title'] = \Drupal::l($title, $font->urlInfo());
170
171   // Helpful $content variable for templates.
172   foreach (Element::children($variables['elements']) as $key) {
173     $variables['content'][$key] = $variables['elements'][$key];
174   }
175
176   $variables['attributes']['class'] = ['font'];
177   if ($font->isDisabled()) {
178     $url = Url::fromRoute('entity.font.enable', ['js' => 'nojs', 'font' => $font->id()], ['query' => \Drupal::destination()->getAsArray()]);
179     $url->setOptions(
180       [
181         'attributes' => [
182           'id' => 'font-status-' . $font->id(),
183           'class' => [
184             'font-status',
185             'disabled',
186             'use-ajax',
187           ],
188         ],
189       ]
190     );
191     $text = t('Enable');
192     $variables['attributes']['class'][] = 'disabled';
193   }
194   if ($font->isEnabled()) {
195     $url = Url::fromRoute('entity.font.disable', ['js' => 'nojs', 'font' => $font->id()], ['query' => \Drupal::destination()->getAsArray()]);
196     $url->setOptions(
197       [
198         'attributes' => [
199           'id' => 'font-status-' . $font->id(),
200           'class' => [
201             'font-status',
202             'enabled',
203             'use-ajax',
204           ],
205         ],
206       ]
207     );
208     $text = t('Disable');
209     $variables['attributes']['class'][] = 'enabled';
210   }
211
212   $url->setOption('destination', Drupal::destination());
213   $variables['operation_links'] = Drupal::l($text, $url);
214 }
215
216 /**
217  * Prepares variables for Font templates.
218  *
219  * Default template: font--full.html.twig.
220  *
221  * @param array $variables
222  *   An associative array containing:
223  *   - elements: An associative array containing the user information and any
224  *   - attributes: HTML attributes for the containing element.
225  */
226 function fontyourface_preprocess_font__full(array &$variables) {
227   fontyourface_preprocess_font($variables);
228 }
229
230 /**
231  * Prepares variables for font teaser preview.
232  *
233  * Default template: font--teaser.html.twig.
234  *
235  * @param array $variables
236  *   An associative array containing:
237  *   - elements: An associative array containing the user information and any
238  *   - attributes: HTML attributes for the containing element.
239  */
240 function fontyourface_preprocess_font__teaser(array &$variables) {
241   fontyourface_preprocess_font($variables);
242 }
243
244 /**
245  * Saves/updates font.
246  *
247  * @param object $font_data
248  *   Simple stdclass rep of font for saving.
249  *
250  * @return Drupal\fontyourface\Entity\Font
251  *   Newly saved/updated font.
252  */
253 function fontyourface_save_font($font_data) {
254   $font = Font::loadByUrl($font_data->url);
255   if (empty($font)) {
256     $font = Font::create();
257   }
258   $font->pid = $font_data->provider;
259   $font->url = $font_data->url;
260   $font->name = $font_data->name;
261   $font->css_family = !empty($font_data->css_family) ? $font_data->css_family : '';
262   $font->css_style = !empty($font_data->css_style) ? $font_data->css_style : '';
263   $font->css_weight = !empty($font_data->css_weight) ? $font_data->css_weight : '';
264   $font->foundry = !empty($font_data->foundry) ? $font_data->foundry : '';
265   $font->foundry_url = !empty($font_data->foundry_url) ? $font_data->foundry_url : '';
266   $font->license = !empty($font_data->license) ? $font_data->license : '';
267   $font->license_url = !empty($font_data->license_url) ? $font_data->license_url : '';
268   $font->designer = !empty($font_data->designer) ? $font_data->designer : '';
269   $font->designer_url = !empty($font_data->designer_url) ? $font_data->designer_url : '';
270   if (!empty($font_data->classification)) {
271     $font->field_classification = [];
272     foreach ($font_data->classification as $classification) {
273       $font->field_classification[] = [
274         'target_id' => _fontyourface_get_vocabulary_term($classification, 'font_classification'),
275       ];
276     }
277   }
278   if (!empty($font_data->language)) {
279     $font->field_supported_languages = [];
280     foreach ($font_data->language as $language) {
281       $font->field_supported_languages[] = [
282         'target_id' => _fontyourface_get_vocabulary_term($language, 'languages_supported'),
283       ];
284     }
285   }
286   $font->tags = [];
287   if (!empty($font_data->foundry)) {
288     $font->field_tags[] = [
289       'target_id' => _fontyourface_get_vocabulary_term($font_data->foundry, 'font_foundry'),
290     ];
291   }
292   if (!empty($font_data->designer)) {
293     $font->field_tags[] = [
294       'target_id' => _fontyourface_get_vocabulary_term($font_data->designer, 'font_designer'),
295     ];
296   }
297   $font->setMetadata(!empty($font_data->metadata) ? $font_data->metadata : []);
298   $font->status = FALSE;
299   if ($font->isEnabled()) {
300     $font->status = TRUE;
301   }
302   $font->save();
303   return $font;
304 }
305
306 /**
307  * Creates CSS with any properties set on font.
308  *
309  * @param Drupal\fontyourface\FontInterface $font
310  *   The font object.
311  * @param Drupal\fontyourface\FontDisplayInterface $font_style
312  *   The font display object.
313  * @param string $separator
314  *   Approach to separating the resulting css.
315  *
316  * @return string
317  *   The font-family css.
318  */
319 function fontyourface_font_css(FontInterface $font, FontDisplayInterface $font_style = NULL, $separator = ' ') {
320   $css = \Drupal::moduleHandler()->invokeAll('fontyourface_font_css', [
321     $font,
322     $font_style,
323     $separator,
324   ]);
325   if (!empty($css)) {
326     return implode("\n", $css);
327   }
328   $css = [];
329
330   // Enclose font family definition in single quotes if not already enclosed.
331   if ($font->css_family->value[0] === "'") {
332     $family_list = $font->css_family->value;
333   }
334   else {
335     $family_list = "'" . $font->css_family->value . "'";
336   }
337
338   if ($font_style !== NULL) {
339     if (!empty($font_style->getFallback())) {
340       $family_list .= ', ' . $font_style->getFallback();
341     }
342   }
343
344   $css[] = 'font-family: ' . $family_list . ';';
345   $css[] = 'font-style: ' . $font->css_style->value . ';';
346   $css[] = 'font-weight: ' . $font->css_weight->value . ';';
347
348   return implode($separator, $css);
349 }
350
351 /**
352  * Deletes fonts from a specific provider.
353  *
354  * @param string $provider
355  *   The providing submodule.
356  */
357 function fontyourface_delete($provider) {
358
359   // Delete fonts, 50 at a time.
360   @set_time_limit(3600);
361   while (TRUE) {
362     $storage_handler = \Drupal::entityManager()->getStorage('font');
363     $fids = \Drupal::entityQuery('font')
364       ->condition('pid', $provider)
365       ->range(0, 50)
366       ->execute();
367     if (!empty($fids)) {
368       $fonts = $storage_handler->loadMultiple(array_keys($fids));
369       $storage_handler->delete($fonts);
370     }
371     else {
372       break;
373     }
374   }
375 }
376
377 /**
378  * Logs to watchdog if logging is enabled.
379  *
380  * @param string $message
381  *   Log message. This should be a literal string; see
382  *   http://drupal.org/node/323101 for more details.
383  * @param array $arguments
384  *   Arguments to replace placeholders, if there are any, in $message.
385  */
386 function fontyourface_log($message, array $arguments) {
387   $config = \Drupal::config('fontyourface.settings');
388   if ($config->get('fontyourface_detailed_logging')) {
389     watchdog('@font-your-face', $message, $arguments, WATCHDOG_INFO);
390   }
391 }
392
393 /**
394  * Saves and generates font file based on font display config entity data.
395  *
396  * @param Drupal\fontyourface\FontDisplayInterface $style
397  *   Custom config font display entity.
398  *
399  * @return bool
400  *   TRUE if files save successfully. Throw any errors otherwise.
401  */
402 function fontyourface_save_and_generate_font_display_css(FontDisplayInterface $style) {
403   $directory = file_build_uri('fontyourface/font_display');
404   file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
405
406   $font = $style->getFont();
407   $css_file = $directory . '/' . $style->id() . '.css';
408   $css_file_data = $style->getSelectors() . ' { ' . fontyourface_font_css($font, $style) . ' }';
409   file_unmanaged_save_data($css_file_data, $css_file, FILE_EXISTS_REPLACE);
410
411   return TRUE;
412 }
413
414 /**
415  * Retrieves a tid for use from taxonomy.
416  *
417  * @param string $term_value
418  *   The taxonomy term string.
419  * @param string $vocabulary
420  *   The machine name of the vocabulary the term belongs to.
421  *
422  * @return int
423  *   The found/created taxonomy term id.
424  */
425 function _fontyourface_get_vocabulary_term($term_value, $vocabulary) {
426   if ($terms = taxonomy_term_load_multiple_by_name($term_value, $vocabulary)) {
427     $term = reset($terms);
428   }
429   else {
430     $term = Term::create([
431       'name' => $term_value,
432       'vid' => $vocabulary,
433     ]);
434     $term->save();
435   }
436   return $term->id();
437 }