ba8267fde785629a50abec12b0115f2f33834081
[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\Component\Utility\Unicode;
7
8 /**
9  * A base for field formatter admin to have re-usable methods in one place.
10  */
11 abstract class BlazyAdminFormatterBase extends BlazyAdminBase {
12
13   /**
14    * Returns re-usable image formatter form elements.
15    */
16   public function imageStyleForm(array &$form, $definition = []) {
17     $is_responsive = function_exists('responsive_image_get_image_dimensions');
18
19     if (empty($definition['no_image_style'])) {
20       $form['image_style'] = $this->baseForm($definition)['image_style'];
21     }
22
23     if (!empty($definition['thumbnail_style'])) {
24       $form['thumbnail_style'] = $this->baseForm($definition)['thumbnail_style'];
25     }
26
27     if ($is_responsive && !empty($definition['responsive_image'])) {
28       $url = Url::fromRoute('entity.responsive_image_style.collection')->toString();
29       $form['responsive_image_style'] = [
30         '#type'        => 'select',
31         '#title'       => $this->t('Responsive image'),
32         '#options'     => $this->getResponsiveImageOptions(),
33         '#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. <a href=":url" target="_blank">Manage responsive image styles</a>.', [':url' => $url]),
34         '#access'      => $this->getResponsiveImageOptions(),
35         '#weight'      => -100,
36       ];
37
38       if (!empty($definition['background'])) {
39         $form['background']['#states'] = $this->getState(static::STATE_RESPONSIVE_IMAGE_STYLE_DISABLED, $definition);
40       }
41     }
42
43     if (!empty($definition['thumbnail_effect'])) {
44       $form['thumbnail_effect'] = [
45         '#type'    => 'select',
46         '#title'   => $this->t('Thumbnail effect'),
47         '#options' => isset($definition['thumbnail_effect']) ? $definition['thumbnail_effect'] : [],
48         '#weight'  => -100,
49       ];
50     }
51   }
52
53   /**
54    * Return the field formatter settings summary.
55    *
56    * @deprecated: To remove for self::getSettingsSummary() post full release so
57    * to avoid unpredictable settings, and complication with form elements.
58    */
59   public function settingsSummary($plugin, $definition = []) {
60     $definition = isset($definition) ? $definition : $plugin->getScopedFormElements();
61     $definition['settings'] = isset($definition['settings']) ? $definition['settings'] : $plugin->getSettings();
62
63     return $this->getSettingsSummary($definition);
64   }
65
66   /**
67    * Return the field formatter settings summary.
68    */
69   public function getSettingsSummary($definition = []) {
70     $summary = [];
71
72     if (empty($definition['settings'])) {
73       return $summary;
74     }
75
76     $this->getExcludedSettingsSummary($definition);
77
78     $enforced = [
79       'optionset',
80       'cache',
81       'skin',
82       'view_mode',
83       'override',
84       'overridables',
85       'style',
86       'vanilla',
87     ];
88
89     $enforced    = isset($definition['enforced']) ? $definition['enforced'] : $enforced;
90     $settings    = array_filter($definition['settings']);
91     $breakpoints = isset($settings['breakpoints']) && is_array($settings['breakpoints']) ? array_filter($settings['breakpoints']) : [];
92
93     foreach ($definition['settings'] as $key => $setting) {
94       $title   = Unicode::ucfirst(str_replace('_', ' ', $key));
95       $vanilla = !empty($settings['vanilla']);
96
97       if ($key == 'breakpoints') {
98         $widths = [];
99         if ($breakpoints) {
100           foreach ($breakpoints as $id => $breakpoint) {
101             if (!empty($breakpoint['width'])) {
102               $widths[] = $breakpoint['width'];
103             }
104           }
105         }
106
107         $title   = 'Breakpoints';
108         $setting = $widths ? implode(', ', $widths) : 'none';
109       }
110       else {
111         if ($vanilla && !in_array($key, $enforced)) {
112           continue;
113         }
114
115         if ($key == 'override' && empty($setting)) {
116           unset($settings['overridables']);
117         }
118
119         if (is_bool($setting) && $setting) {
120           $setting = 'yes';
121         }
122         elseif (is_array($setting)) {
123           $setting = array_filter($setting);
124           if (!empty($setting)) {
125             $setting = implode(', ', $setting);
126           }
127         }
128
129         if ($key == 'cache') {
130           $setting = $this->getCacheOptions()[$setting];
131         }
132       }
133
134       if (empty($setting)) {
135         continue;
136       }
137
138       if (isset($settings[$key]) && is_string($setting)) {
139         $summary[] = $this->t('@title: <strong>@setting</strong>', [
140           '@title'   => $title,
141           '@setting' => $setting,
142         ]);
143       }
144     }
145     return $summary;
146   }
147
148   /**
149    * Exclude the field formatter settings summary as required.
150    */
151   public function getExcludedSettingsSummary(array &$definition = []) {
152     $settings     = &$definition['settings'];
153     $excludes     = empty($definition['excludes']) ? [] : $definition['excludes'];
154     $plugin_id    = isset($definition['plugin_id']) ? $definition['plugin_id'] : '';
155     $blazy        = $plugin_id && strpos($plugin_id, 'blazy') !== FALSE;
156     $image_styles = function_exists('image_style_options') ? image_style_options(TRUE) : [];
157     $media_switch = empty($settings['media_switch']) ? '' : $settings['media_switch'];
158
159     unset($image_styles['']);
160
161     $excludes['current_view_mode'] = TRUE;
162
163     if ($blazy) {
164       $excludes['optionset'] = TRUE;
165     }
166
167     if ($media_switch != 'media') {
168       $excludes['iframe_lazy'] = TRUE;
169     }
170
171     if (!empty($settings['responsive_image_style'])) {
172       foreach (['ratio', 'breakpoints', 'background', 'sizes'] as $key) {
173         $excludes[$key] = TRUE;
174       }
175     }
176
177     if (empty($settings['grid'])) {
178       foreach (['grid', 'grid_medium', 'grid_small', 'visible_items'] as $key) {
179         $excludes[$key] = TRUE;
180       }
181     }
182
183     // Remove exluded settings.
184     foreach ($excludes as $key => $value) {
185       if (isset($settings[$key])) {
186         unset($settings[$key]);
187       }
188     }
189
190     foreach ($settings as $key => $setting) {
191       if ($key == 'style' || $key == 'responsive_image_style' || empty($settings[$key])) {
192         continue;
193       }
194       if (strpos($key, 'style') !== FALSE && isset($image_styles[$settings[$key]])) {
195         $settings[$key] = $image_styles[$settings[$key]];
196       }
197     }
198   }
199
200   /**
201    * Returns available fields for select options.
202    */
203   public function getFieldOptions($target_bundles = [], $allowed_field_types = [], $entity_type = 'media', $target_type = '') {
204     $options = [];
205     $storage = $this->blazyManager()->getEntityTypeManager()->getStorage('field_config');
206
207     // Fix for Views UI not recognizing Media bundles, unlike Formatters.
208     if (empty($target_bundles)) {
209       $bundle_service = \Drupal::service('entity_type.bundle.info');
210       $target_bundles = $bundle_service->getBundleInfo($entity_type);
211     }
212
213     // Declutters options from less relevant options.
214     $excludes = $this->getExcludedFieldOptions();
215
216     foreach ($target_bundles as $bundle => $label) {
217       if ($fields = $storage->loadByProperties(['entity_type' => $entity_type, 'bundle' => $bundle])) {
218         foreach ((array) $fields as $field_name => $field) {
219           if (in_array($field->getName(), $excludes)) {
220             continue;
221           }
222           if (empty($allowed_field_types)) {
223             $options[$field->getName()] = $field->getLabel();
224           }
225           elseif (in_array($field->getType(), $allowed_field_types)) {
226             $options[$field->getName()] = $field->getLabel();
227           }
228
229           if (!empty($target_type) && ($field->getSetting('target_type') == $target_type)) {
230             $options[$field->getName()] = $field->getLabel();
231           }
232         }
233       }
234     }
235
236     return $options;
237   }
238
239   /**
240    * Declutters options from less relevant options.
241    */
242   public function getExcludedFieldOptions() {
243     $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';
244     $excludes = explode(' ', $excludes);
245     $excludes = array_combine($excludes, $excludes);
246
247     $this->blazyManager->getModuleHandler()->alter('blazy_excluded_field_options', $excludes);
248     return $excludes;
249   }
250
251   /**
252    * Returns Responsive image for select options.
253    */
254   public function getResponsiveImageOptions() {
255     $options = [];
256     if ($this->blazyManager()->getModuleHandler()->moduleExists('responsive_image')) {
257       $image_styles = $this->blazyManager()->entityLoadMultiple('responsive_image_style');
258       if (!empty($image_styles)) {
259         foreach ($image_styles as $name => $image_style) {
260           if ($image_style->hasImageStyleMappings()) {
261             $options[$name] = strip_tags($image_style->label());
262           }
263         }
264       }
265     }
266     return $options;
267   }
268
269 }