5 * Contains fontyourface.module..
9 use Drupal\Core\Render\Element;
10 use Drupal\Core\Routing\RouteMatchInterface;
11 use Drupal\Component\Utility\Html;
12 use Drupal\taxonomy\Entity\Term;
14 use Drupal\fontyourface\FontInterface;
15 use Drupal\fontyourface\FontDisplayInterface;
16 use Drupal\fontyourface\Entity\Font;
17 use Drupal\fontyourface\Entity\FontDisplay;
20 * Implements hook_module_implements_alter().
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;
31 foreach ($list as $module_name) {
32 $group = $implementations[$module_name];
33 unset($implementations[$module_name]);
34 $implementations[$module_name] = $group;
40 * Implements hook_help().
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':
47 $output .= '<h3>' . t('About') . '</h3>';
48 $output .= '<p>' . t('Web font management tools.') . '</p>';
56 * Implements hook_library_info_build().
58 function fontyourface_library_info_build() {
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,
76 * Implements hook_theme().
78 function fontyourface_theme() {
81 'render element' => 'elements',
84 'render element' => 'elements',
87 'render element' => 'elements',
93 * Implements hook_page_attachments().
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;
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();
116 $fonts[$font->url->value] = $font;
124 * Implements hook_preprocess_HOOK().
126 * Adds body classes if certain regions have content.
128 function fontyourface_preprocess_html(&$variables) {
129 $variables['attributes']['class'][] = 'fontyourface';
133 * Implements hook_theme_suggestions_HOOK().
135 function fontyourface_theme_suggestions_font(array $variables) {
136 return ['font__' . $variables['elements']['#view_mode']];
140 * Implements hook_views_pre_render().
142 function fontyourface_views_pre_render($view) {
143 if ($view->id() == 'fontyourface_font_manager') {
144 $view->element['#attached']['library'][] = 'fontyourface/fontyourface.admin';
149 * Prepares variables for Font templates.
151 * Default template: font.html.twig.
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.
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);
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());
171 // Helpful $content variable for templates.
172 foreach (Element::children($variables['elements']) as $key) {
173 $variables['content'][$key] = $variables['elements'][$key];
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()]);
182 'id' => 'font-status-' . $font->id(),
192 $variables['attributes']['class'][] = 'disabled';
194 if ($font->isEnabled()) {
195 $url = Url::fromRoute('entity.font.disable', ['js' => 'nojs', 'font' => $font->id()], ['query' => \Drupal::destination()->getAsArray()]);
199 'id' => 'font-status-' . $font->id(),
208 $text = t('Disable');
209 $variables['attributes']['class'][] = 'enabled';
212 $url->setOption('destination', Drupal::destination());
213 $variables['operation_links'] = Drupal::l($text, $url);
217 * Prepares variables for Font templates.
219 * Default template: font--full.html.twig.
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.
226 function fontyourface_preprocess_font__full(array &$variables) {
227 fontyourface_preprocess_font($variables);
231 * Prepares variables for font teaser preview.
233 * Default template: font--teaser.html.twig.
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.
240 function fontyourface_preprocess_font__teaser(array &$variables) {
241 fontyourface_preprocess_font($variables);
245 * Saves/updates font.
247 * @param object $font_data
248 * Simple stdclass rep of font for saving.
250 * @return Drupal\fontyourface\Entity\Font
251 * Newly saved/updated font.
253 function fontyourface_save_font($font_data) {
254 $font = Font::loadByUrl($font_data->url);
256 $font = Font::create();
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'),
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'),
287 if (!empty($font_data->foundry)) {
288 $font->field_tags[] = [
289 'target_id' => _fontyourface_get_vocabulary_term($font_data->foundry, 'font_foundry'),
292 if (!empty($font_data->designer)) {
293 $font->field_tags[] = [
294 'target_id' => _fontyourface_get_vocabulary_term($font_data->designer, 'font_designer'),
297 $font->setMetadata(!empty($font_data->metadata) ? $font_data->metadata : []);
298 $font->status = FALSE;
299 if ($font->isEnabled()) {
300 $font->status = TRUE;
307 * Creates CSS with any properties set on font.
309 * @param Drupal\fontyourface\FontInterface $font
311 * @param Drupal\fontyourface\FontDisplayInterface $font_style
312 * The font display object.
313 * @param string $separator
314 * Approach to separating the resulting css.
317 * The font-family css.
319 function fontyourface_font_css(FontInterface $font, FontDisplayInterface $font_style = NULL, $separator = ' ') {
320 $css = \Drupal::moduleHandler()->invokeAll('fontyourface_font_css', [
326 return implode("\n", $css);
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;
335 $family_list = "'" . $font->css_family->value . "'";
338 if ($font_style !== NULL) {
339 if (!empty($font_style->getFallback())) {
340 $family_list .= ', ' . $font_style->getFallback();
344 $css[] = 'font-family: ' . $family_list . ';';
345 $css[] = 'font-style: ' . $font->css_style->value . ';';
346 $css[] = 'font-weight: ' . $font->css_weight->value . ';';
348 return implode($separator, $css);
352 * Deletes fonts from a specific provider.
354 * @param string $provider
355 * The providing submodule.
357 function fontyourface_delete($provider) {
359 // Delete fonts, 50 at a time.
360 @set_time_limit(3600);
362 $storage_handler = \Drupal::entityManager()->getStorage('font');
363 $fids = \Drupal::entityQuery('font')
364 ->condition('pid', $provider)
368 $fonts = $storage_handler->loadMultiple(array_keys($fids));
369 $storage_handler->delete($fonts);
378 * Logs to watchdog if logging is enabled.
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.
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);
394 * Saves and generates font file based on font display config entity data.
396 * @param Drupal\fontyourface\FontDisplayInterface $style
397 * Custom config font display entity.
400 * TRUE if files save successfully. Throw any errors otherwise.
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);
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);
415 * Retrieves a tid for use from taxonomy.
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.
423 * The found/created taxonomy term id.
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);
430 $term = Term::create([
431 'name' => $term_value,
432 'vid' => $vocabulary,