Version 1
[yaffs-website] / web / modules / contrib / blazy / src / Form / BlazyAdminFormatterBase.php
1 <?php
2
3 namespace Drupal\blazy\Form;
4
5 use Drupal\Core\Url;
6 use Drupal\Core\Form\FormState;
7 use Drupal\Component\Utility\Unicode;
8
9 /**
10  * A base for field formatter admin to have re-usable methods in one place.
11  */
12 abstract class BlazyAdminFormatterBase extends BlazyAdminBase {
13
14   /**
15    * Returns re-usable image formatter form elements.
16    */
17   public function imageStyleForm(array &$form, $definition = []) {
18     $image_styles  = image_style_options(FALSE);
19     $is_responsive = function_exists('responsive_image_get_image_dimensions');
20
21     if (empty($definition['no_image_style'])) {
22       $form['image_style'] = $this->baseForm($definition)['image_style'];
23     }
24
25     if (!empty($definition['thumbnail_style'])) {
26       $form['thumbnail_style'] = $this->baseForm($definition)['thumbnail_style'];
27     }
28
29     if ($is_responsive && !empty($definition['responsive_image'])) {
30       $form['responsive_image_style'] = [
31         '#type'        => 'select',
32         '#title'       => $this->t('Responsive image'),
33         '#options'     => $this->getResponsiveImageOptions(),
34         '#description' => $this->t('Responsive image style for the main stage image is more reasonable for large images. Works with multi-serving IMG, or PICTURE element. Not compatible with breakpoints and aspect ratio, yet. Leave empty to disable.'),
35         '#access'      => $this->getResponsiveImageOptions(),
36         '#weight'      => -100,
37       ];
38
39       if (!empty($definition['background'])) {
40         $form['background']['#states'] = $this->getState(static::STATE_RESPONSIVE_IMAGE_STYLE_DISABLED, $definition);
41       }
42     }
43
44     if (!empty($definition['thumbnail_effect'])) {
45       $form['thumbnail_effect'] = [
46         '#type'    => 'select',
47         '#title'   => $this->t('Thumbnail effect'),
48         '#options' => isset($definition['thumbnail_effect']) ? $definition['thumbnail_effect'] : [],
49         '#weight'  => -100,
50       ];
51     }
52
53     if ($is_responsive && isset($form['responsive_image_style'])) {
54       $url = Url::fromRoute('entity.responsive_image_style.collection')->toString();
55       $form['responsive_image_style']['#description'] .= ' ' . $this->t('<a href=":url" target="_blank">Manage responsive image styles</a>.', [':url' => $url]);
56     }
57   }
58
59   /**
60    * Return the field formatter settings summary.
61    */
62   public function settingsSummary($plugin, $definition = []) {
63     $form         = [];
64     $summary      = [];
65     $form_state   = new FormState();
66     $settings     = isset($definition['settings']) ? $definition['settings'] : $plugin->getSettings();
67     $elements     = $plugin->settingsForm($form, $form_state);
68     $image_styles = image_style_options(TRUE);
69     $breakpoints  = isset($settings['breakpoints']) ? array_filter($settings['breakpoints']) : [];
70     $excludes     = empty($definition['excludes']) ? $definition : $definition['excludes'];
71
72     unset($image_styles['']);
73
74     $extras = ['details', 'fieldset', 'hidden', 'markup', 'item', 'table'];
75     foreach ($settings as $key => $setting) {
76       $type = isset($elements[$key]['#type']) ? $elements[$key]['#type'] : '';
77
78       if (!empty($excludes) && in_array($key, $excludes)) {
79         continue;
80       }
81
82       if (in_array($type, $extras) || empty($type)) {
83         continue;
84       }
85
86       $access   = isset($elements[$key]['#access']) ? $elements[$key]['#access'] : TRUE;
87       $title    = !isset($elements[$key]) && isset($settings[$key]) ? Unicode::ucfirst(str_replace('_', ' ', $key)) : '';
88       $title    = isset($elements[$key]['#title']) ? $elements[$key]['#title'] : $title;
89       $options  = isset($elements[$key]['#options']) ? $elements[$key]['#options'] : [];
90       $vanilla  = !empty($settings['vanilla']) && !isset($elements[$key]['#enforced']);
91       $multiple = isset($elements[$key]['#multiple']) && $elements[$key]['#multiple'];
92
93       if ($key == 'breakpoints') {
94         $widths = [];
95         if ($breakpoints) {
96           foreach ($breakpoints as $id => $breakpoint) {
97             if (!empty($breakpoint['width'])) {
98               $widths[] = $breakpoint['width'];
99             }
100           }
101         }
102
103         $title   = $this->t('Breakpoints');
104         $setting = $widths ? implode(', ', $widths) : $this->t('None');
105       }
106       else {
107         if (empty($title) || $vanilla || !$access) {
108           continue;
109         }
110
111         if ($key == 'override' && empty($setting)) {
112           unset($settings['overridables']);
113         }
114
115         if (is_bool($setting) && $setting) {
116           $setting = $this->t('Yes');
117         }
118         elseif (is_string($setting) && $key != 'cache') {
119           // The value is based on select options.
120           if (!$multiple && $type == 'select' && isset($options[$setting])) {
121             $setting = is_object($options[$setting]) ? $options[$setting]->render() : $options[$setting];
122           }
123         }
124         elseif (is_array($setting)) {
125           $values = array_filter($setting);
126
127           if (!empty($values)) {
128             // Combine possible multi-value select, or checkboxes.
129             $multiple_values = array_combine($values, $values);
130
131             foreach ($multiple_values as $i => $value) {
132               if (isset($options[$i])) {
133                 $multiple_values[$i] = is_object($options[$i]) ? $options[$i]->render() : $options[$i];
134               }
135             }
136
137             $setting = implode(', ', $multiple_values);
138           }
139
140           if (is_array($setting)) {
141             $setting = array_filter($setting);
142             if (!empty($setting)) {
143               $setting = implode(', ', $setting);
144             }
145           }
146         }
147
148         if ($key == 'cache') {
149           $setting = $this->getCacheOptions()[$setting];
150         }
151       }
152
153       if (empty($setting)) {
154         continue;
155       }
156
157       if (isset($settings[$key])) {
158         $summary[] = $this->t('@title: <strong>@setting</strong>', [
159           '@title'   => $title,
160           '@setting' => $setting,
161         ]);
162       }
163     }
164     return $summary;
165   }
166
167   /**
168    * Returns available fields for select options.
169    */
170   public function getFieldOptions($target_bundles = [], $allowed_field_types = [], $entity_type = 'media', $target_type = '') {
171     $options = [];
172     $storage = $this->blazyManager()->getEntityTypeManager()->getStorage('field_config');
173
174     // Fix for Views UI not recognizing Media bundles, unlike Formatters.
175     if (empty($target_bundles)) {
176       $bundle_service = \Drupal::service('entity_type.bundle.info');
177       $target_bundles = $bundle_service->getBundleInfo($entity_type);
178     }
179
180     // Declutters options from less relevant options.
181     $excludes = $this->getExcludedFieldOptions();
182
183     foreach ($target_bundles as $bundle => $label) {
184       if ($fields = $storage->loadByProperties(['entity_type' => $entity_type, 'bundle' => $bundle])) {
185         foreach ((array) $fields as $field_name => $field) {
186           if (in_array($field->getName(), $excludes)) {
187             continue;
188           }
189           if (empty($allowed_field_types)) {
190             $options[$field->getName()] = $field->getLabel();
191           }
192           elseif (in_array($field->getType(), $allowed_field_types)) {
193             $options[$field->getName()] = $field->getLabel();
194           }
195
196           if (!empty($target_type) && ($field->getSetting('target_type') == $target_type)) {
197             $options[$field->getName()] = $field->getLabel();
198           }
199         }
200       }
201     }
202
203     return $options;
204   }
205
206   /**
207    * Declutters options from less relevant options.
208    */
209   public function getExcludedFieldOptions() {
210     $excludes = 'field_document_size field_id field_media_in_library field_mime_type field_source field_tweet_author field_tweet_id field_tweet_url field_media_video_embed_field field_instagram_shortcode field_instagram_url';
211     $excludes = explode(' ', $excludes);
212     $excludes = array_combine($excludes, $excludes);
213
214     $this->blazyManager->getModuleHandler()->alter('blazy_excluded_field_options', $excludes);
215     return $excludes;
216   }
217
218   /**
219    * Returns Responsive image for select options.
220    */
221   public function getResponsiveImageOptions() {
222     $options = [];
223     if ($this->blazyManager()->getModuleHandler()->moduleExists('responsive_image')) {
224       $image_styles = $this->blazyManager()->entityLoadMultiple('responsive_image_style');
225       if (!empty($image_styles)) {
226         foreach ($image_styles as $name => $image_style) {
227           if ($image_style->hasImageStyleMappings()) {
228             $options[$name] = strip_tags($image_style->label());
229           }
230         }
231       }
232     }
233     return $options;
234   }
235
236 }