Yaffs site version 1.1
[yaffs-website] / web / modules / contrib / image_widget_crop / src / Plugin / Field / FieldWidget / ImageCropWidget.php
1 <?php
2
3 namespace Drupal\image_widget_crop\Plugin\Field\FieldWidget;
4
5 use Drupal\Core\Config\ConfigFactoryInterface;
6 use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
7 use Drupal\Core\Entity\EntityStorageInterface;
8 use Drupal\Core\Field\FieldDefinitionInterface;
9 use Drupal\Core\Field\FieldItemListInterface;
10 use Drupal\Core\Form\FormStateInterface;
11 use Drupal\Core\Render\ElementInfoManagerInterface;
12 use Drupal\image\Plugin\Field\FieldWidget\ImageWidget;
13 use Drupal\image_widget_crop\ImageWidgetCropInterface;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15 use Drupal\crop\Entity\CropType;
16
17 /**
18  * Plugin implementation of the 'image_widget_crop' widget.
19  *
20  * @FieldWidget(
21  *   id = "image_widget_crop",
22  *   label = @Translation("ImageWidget crop"),
23  *   field_types = {
24  *     "image"
25  *   }
26  * )
27  */
28 class ImageCropWidget extends ImageWidget {
29
30   /**
31    * Instance of ImageWidgetCropManager object.
32    *
33    * @var \Drupal\image_widget_crop\ImageWidgetCropInterface
34    */
35   protected $imageWidgetCropManager;
36
37   /**
38    * The image style storage.
39    *
40    * @var \Drupal\image\ImageStyleStorageInterface
41    */
42   protected $imageStyleStorage;
43
44   /**
45    * The crop type storage.
46    *
47    * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
48    */
49   protected $cropTypeStorage;
50
51   /**
52    * The config factory.
53    *
54    * Subclasses should use the self::config() method, which may be overridden to
55    * address specific needs when loading config, rather than this property
56    * directly. See \Drupal\Core\Form\ConfigFormBase::config() for an example of
57    * this.
58    *
59    * @var \Drupal\Core\Config\ConfigFactoryInterface
60    */
61   protected $configFactory;
62
63   /**
64    * {@inheritdoc}
65    */
66   public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, ElementInfoManagerInterface $element_info, ImageWidgetCropInterface $image_widget_crop_manager, EntityStorageInterface $image_style_storage, ConfigEntityStorageInterface $crop_type_storage, ConfigFactoryInterface $config_factory) {
67     parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings, $element_info);
68     $this->imageWidgetCropManager = $image_widget_crop_manager;
69     $this->imageStyleStorage = $image_style_storage;
70     $this->cropTypeStorage = $crop_type_storage;
71     $this->configFactory = $config_factory;
72   }
73
74   /**
75    * {@inheritdoc}
76    */
77   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
78     return new static(
79       $plugin_id,
80       $plugin_definition,
81       $configuration['field_definition'],
82       $configuration['settings'],
83       $configuration['third_party_settings'],
84       $container->get('element_info'),
85       $container->get('image_widget_crop.manager'),
86       $container->get('entity_type.manager')->getStorage('image_style'),
87       $container->get('entity_type.manager')->getStorage('crop_type'),
88       $container->get('config.factory')
89     );
90   }
91
92   /**
93    * {@inheritdoc}
94    *
95    * @return array<string,string|null|false>
96    *   The array of settings.
97    */
98   public static function defaultSettings() {
99     return [
100       'crop_preview_image_style' => 'crop_thumbnail',
101       'crop_list' => NULL,
102       'show_crop_area' => FALSE,
103       'show_default_crop' => TRUE,
104       'warn_multiple_usages' => TRUE,
105     ] + parent::defaultSettings();
106   }
107
108   /**
109    * Form API callback: Processes a crop_image field element.
110    *
111    * Expands the image_image type to include the alt and title fields.
112    *
113    * This method is assigned as a #process callback in formElement() method.
114    *
115    * @return array
116    *   The elements with parents fields.
117    */
118   public static function process($element, FormStateInterface $form_state, $form) {
119     if ($element['#files']) {
120       foreach ($element['#files'] as $file) {
121         $element['image_crop'] = [
122           '#type' => 'image_crop',
123           '#file' => $file,
124           '#crop_type_list' => $element['#crop_list'],
125           '#crop_preview_image_style' => $element['#crop_preview_image_style'],
126           '#show_default_crop' => $element['#show_default_crop'],
127           '#show_crop_area' => $element['#show_crop_area'],
128           '#warn_multiple_usages' => $element['#warn_multiple_usages'],
129         ];
130       }
131     }
132
133     return parent::process($element, $form_state, $form);
134   }
135
136   /**
137    * Verify if the element have an image file.
138    *
139    * @param array $element
140    *   A form element array containing basic properties for the widget.
141    * @param array $variables
142    *   An array with all existent variables for render.
143    *
144    * @return array<string,array>
145    *   The variables with width & height image informations.
146    */
147   public static function getFileImageVariables(array $element, array &$variables) {
148     // Determine image dimensions.
149     if (isset($element['#value']['width']) && isset($element['#value']['height'])) {
150       $variables['width'] = $element['#value']['width'];
151       $variables['height'] = $element['#value']['height'];
152     }
153     else {
154       /** @var \Drupal\Core\Image\Image $image */
155       $image = \Drupal::service('image.factory')->get($variables['uri']);
156       if ($image->isValid()) {
157         $variables['width'] = $image->getWidth();
158         $variables['height'] = $image->getHeight();
159       }
160       else {
161         $variables['width'] = $variables['height'] = NULL;
162       }
163     }
164
165     return $variables;
166   }
167
168   /**
169    * {@inheritdoc}
170    */
171   public function settingsForm(array $form, FormStateInterface $form_state) {
172     $element = parent::settingsForm($form, $form_state);
173
174     $element['crop_preview_image_style'] = [
175       '#title' => $this->t('Crop preview image style'),
176       '#type' => 'select',
177       '#options' => $this->imageWidgetCropManager->getAvailableCropImageStyle(image_style_options(FALSE)),
178       '#default_value' => $this->getSetting('crop_preview_image_style'),
179       '#description' => $this->t('The preview image will be shown while editing the content.'),
180       '#weight' => 15,
181     ];
182
183     $element['crop_list'] = [
184       '#title' => $this->t('Crop Type'),
185       '#type' => 'select',
186       '#options' => $this->imageWidgetCropManager->getAvailableCropType(CropType::getCropTypeNames()),
187       '#empty_option' => $this->t('<@no-preview>', ['@no-preview' => $this->t('no preview')]),
188       '#default_value' => $this->getSetting('crop_list'),
189       '#multiple' => TRUE,
190       '#required' => TRUE,
191       '#description' => $this->t('The type of crop to apply to your image. If your Crop Type not appear here, set an image style use your Crop Type'),
192       '#weight' => 16,
193     ];
194
195     $element['show_crop_area'] = [
196       '#title' => $this->t('Always expand crop area'),
197       '#type' => 'checkbox',
198       '#default_value' => $this->getSetting('show_crop_area'),
199     ];
200
201     $element['show_default_crop'] = [
202       '#title' => $this->t('Show default crop area'),
203       '#type' => 'checkbox',
204       '#default_value' => $this->getSetting('show_default_crop'),
205     ];
206
207     $element['warn_multiple_usages'] = [
208       '#title' => $this->t('Warn the user if the crop is used more than once.'),
209       '#type' => 'checkbox',
210       '#default_value' => $this->getSetting('warn_multiple_usages'),
211     ];
212
213     return $element;
214   }
215
216   /**
217    * {@inheritdoc}
218    *
219    * @return array<array>
220    *   A short summary of the widget settings.
221    */
222   public function settingsSummary() {
223     $preview = [];
224
225     $image_styles = image_style_options(FALSE);
226     // Unset possible 'No defined styles' option.
227     unset($image_styles['']);
228
229     // Styles could be lost because of enabled/disabled modules that defines
230     // their styles in code.
231     $image_style_setting = $this->getSetting('preview_image_style');
232     $crop_preview = $image_styles[$this->getSetting('crop_preview_image_style')];
233     $crop_list = $this->getSetting('crop_list');
234     $crop_show_button = $this->getSetting('show_crop_area');
235     $show_default_crop = $this->getSetting('show_default_crop');
236     $warn_multiple_usages = $this->getSetting('warn_multiple_usages');
237
238     $preview[] = $this->t('Always expand crop area: @bool', ['@bool' => ($crop_show_button) ? 'Yes' : 'No']);
239     $preview[] = $this->t('Show default crop area: @bool', ['@bool' => ($show_default_crop) ? 'Yes' : 'No']);
240     $preview[] = $this->t('Warn the user if the crop is used more than once: @bool', ['@bool' => ($warn_multiple_usages) ? 'Yes' : 'No']);
241
242     if (isset($image_styles[$image_style_setting])) {
243       $preview[] = $this->t('Preview image style: @style', ['@style' => $image_style_setting]);
244     }
245     else {
246       $preview[] = $this->t('No preview image style');
247     }
248
249     if (isset($crop_preview)) {
250       $preview[] = $this->t('Preview crop zone image style: @style', ['@style' => $crop_preview]);
251     }
252
253     if (!empty($crop_list)) {
254       $preview[] = $this->t('Crop Type used: @list', ['@list' => implode(", ", $crop_list)]);
255     }
256
257     return $preview;
258   }
259
260   /**
261    * {@inheritdoc}
262    *
263    * @return array<string,array>
264    *   The form elements for a single widget for this field.
265    */
266   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
267     // Add properties needed by process() method.
268     $element['#crop_list'] = $this->getSetting('crop_list');
269     $element['#crop_preview_image_style'] = $this->getSetting('crop_preview_image_style');
270     $element['#show_crop_area'] = $this->getSetting('show_crop_area');
271     $element['#show_default_crop'] = $this->getSetting('show_default_crop');
272     $element['#warn_multiple_usages'] = $this->getSetting('warn_multiple_usages');
273
274     return parent::formElement($items, $delta, $element, $form, $form_state);
275   }
276
277 }