Pathologic was missing because of a .git folder inside.
[yaffs-website] / web / modules / contrib / bootstrap_layouts / bootstrap_layouts.module
1 <?php
2
3 /**
4  * @file
5  * Contains bootstrap_layouts.module.
6  */
7
8 use Drupal\bootstrap_layouts\BootstrapLayout;
9 use Drupal\Component\Utility\Html;
10 use Drupal\Component\Utility\NestedArray;
11 use Drupal\Core\Render\Element;
12 use Drupal\Core\Template\Attribute;
13 use Drupal\layout_plugin\Layout;
14
15 /**
16  * Implements hook_theme_registry_alter().
17  */
18 function bootstrap_layouts_theme_registry_alter(&$theme_registry) {
19   // Find all Bootstrap Layouts.
20   $layouts = Layout::layoutPluginManager()->getDefinitions();
21   $layout_theme_hooks = [];
22   foreach ($layouts as $info) {
23     if ($info['class'] === '\Drupal\bootstrap_layouts\Plugin\Layout\BootstrapLayoutsBase') {
24       $layout_theme_hooks[] = $info['theme'];
25     }
26   }
27
28   // Add a special internal preprocess function.
29   foreach ($theme_registry as $theme_hook => $info) {
30     if (in_array($theme_hook, $layout_theme_hooks) || (!empty($info['base hook']) && in_array($info['base hook'], $layout_theme_hooks))) {
31       $theme_registry[$theme_hook]['preprocess functions'][] = '_bootstrap_layouts_preprocess_layout';
32     }
33   }
34 }
35
36 /**
37  * Parses an attribute string saved in the UI.
38  *
39  * @param string $string
40  *   The attribute string to parse.
41  * @param array $tokens
42  *   An associative array of token data to use.
43  *
44  * @return array
45  *   A parsed attributes array.
46  */
47 function _bootstrap_layouts_parse_attributes($string = NULL, array $tokens = []) {
48   static $token;
49   if (!isset($token)) {
50     /** @var \Drupal\Core\Utility\Token $token */
51     $token = \Drupal::service('token');
52   }
53   $attributes = [];
54   if (!empty($string)) {
55     $parts = explode(',', $string);
56     foreach ($parts as $attribute) {
57       if (strpos($attribute, '|') !== FALSE) {
58         list($key, $value) = explode('|', $token->replace($attribute, $tokens, ['clear' => TRUE]));
59         $attributes[$key] = $value;
60       }
61     }
62   }
63   return $attributes;
64 }
65
66 /**
67  * Internal preprocess callback.
68  *
69  * This is used to determine standardize variables to use in Bootstrap Layouts
70  * templates based on whatever implementation is used (i.e. Display Suite or
71  * Panels, etc.).
72  *
73  * @param array $variables
74  *   Variables array, passed by reference.
75  */
76 function _bootstrap_layouts_preprocess_layout(array &$variables) {
77   // Utilize the BootstrapLayout utility class to normalize DX readability here.
78   $layout = new BootstrapLayout($variables['layout']['id'], [], $variables['settings']);
79
80
81   // Determine the entity, entity type and bundle.
82   /** @var \Drupal\Core\Entity\EntityInterface $entity */
83   $entity = isset($variables['content']['#entity']) ? $variables['content']['#entity'] : FALSE;
84   $entity_type = isset($variables['content']['#entity_type']) ? $variables['content']['#entity_type'] : FALSE;
85   $bundle = isset($variables['content']['#bundle']) ? $variables['content']['#bundle'] : FALSE;
86   $view_mode = isset($variables['content']['#view_mode']) ? $variables['content']['#view_mode'] : FALSE;
87
88   $tokens = [];
89   if ($entity_type && $entity) {
90     $tokens[$entity_type] = $entity;
91
92     // Copy entity to top level to improve theme experience.
93     $variables[$entity_type] = $entity;
94   }
95
96   // Add a layout wrapper and its attributes.
97   $variables['wrapper'] = $layout->getSetting('layout.wrapper', 'div');
98   $layout_attributes = isset($variables['attributes']) ? $variables['attributes'] : [];
99   $layout_attributes = NestedArray::mergeDeep(_bootstrap_layouts_parse_attributes($layout->getSetting('layout.attributes'), $tokens), $layout_attributes);
100
101   $attributes = new Attribute($layout_attributes);
102   $attributes->addClass(array_keys($layout->getSetting('layout.classes', [])));
103   if ($layout->getSetting('layout.add_layout_class')) {
104     $attributes->addClass(Html::cleanCssIdentifier($layout->getId()));
105   }
106
107   // Unfortunately since Display Suite doesn't abstract this bit of code, it
108   // must be duplicated in this module to support it from the UI.
109   if ($entity_type && isset($variables['content']['#ds_configuration'])) {
110     // Add theming-classes to template.
111     $entity_classes = !empty($variables['content']['#ds_configuration']['layout']['entity_classes']) ? $variables['content']['#ds_configuration']['layout']['entity_classes'] : 'old_view_mode';
112     if ($entity_classes !== 'no_classes') {
113       if ($entity_classes === 'all_classes') {
114         $entity_type_class = Html::cleanCssIdentifier($entity_type);
115         $entity_classes = [$entity_type_class];
116         if ($bundle) {
117           $entity_classes[] = "$entity_type_class--type-" . Html::cleanCssIdentifier($bundle);
118         }
119         if ($view_mode) {
120           $entity_classes[] = "$entity_type_class--view-mode-" . Html::cleanCssIdentifier($view_mode);
121         }
122         $attributes->addClass($entity_classes);
123       }
124       // Add (old style, non cleaned) view-mode-{name} to classes.
125       elseif ($entity_classes === 'old_view_mode' && $view_mode && !$attributes->hasClass("view-mode-$view_mode")) {
126         $attributes->addClass("view-mode-$view_mode");
127       }
128     }
129
130     // Let other modules know we have rendered.
131     $variables['rendered_by_ds'] = TRUE;
132
133     // Let other modules alter the ds array before rendering.
134     $context = [
135       'entity' => $entity,
136       'entity_type' => $entity_type,
137       'bundle' => $bundle,
138       'view_mode' => $view_mode,
139     ];
140     \Drupal::moduleHandler()->alter('ds_pre_render', $variables['content'], $context, $variables);
141   }
142
143   // Set the attributes variable.
144   $variables['attributes'] = $attributes;
145
146   // Create region variables based on the layout settings.
147   foreach ($layout->getSetting('regions') as $region => $region_settings) {
148     $region_attributes = new Attribute(_bootstrap_layouts_parse_attributes($region_settings['attributes'], $tokens));
149     $region_attributes->addClass(array_keys($region_settings['classes']));
150     if (!empty($region_settings['add_region_classes'])) {
151       $region_attributes->addClass(['bs-region', Html::cleanCssIdentifier("bs-region--$region")]);
152     }
153     unset($region_settings['classes']);
154     $region_settings['attributes'] = $region_attributes;
155     $region_settings['content'] = isset($variables['content'][$region]) && !Element::isEmpty($variables['content'][$region]) ? $variables['content'][$region] : NULL;
156     $variables[$region] = $region_settings;
157   }
158 }