c166bb8fb03540ae015014c2485451b4eb81c671
[yaffs-website] / web / core / modules / image / src / Form / ImageStyleEditForm.php
1 <?php
2
3 namespace Drupal\image\Form;
4
5 use Drupal\Component\Utility\Unicode;
6 use Drupal\Core\Entity\EntityStorageInterface;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\Core\Url;
9 use Drupal\image\ConfigurableImageEffectInterface;
10 use Drupal\image\ImageEffectManager;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
12
13 /**
14  * Controller for image style edit form.
15  *
16  * @internal
17  */
18 class ImageStyleEditForm extends ImageStyleFormBase {
19
20   /**
21    * The image effect manager service.
22    *
23    * @var \Drupal\image\ImageEffectManager
24    */
25   protected $imageEffectManager;
26
27   /**
28    * Constructs an ImageStyleEditForm object.
29    *
30    * @param \Drupal\Core\Entity\EntityStorageInterface $image_style_storage
31    *   The storage.
32    * @param \Drupal\image\ImageEffectManager $image_effect_manager
33    *   The image effect manager service.
34    */
35   public function __construct(EntityStorageInterface $image_style_storage, ImageEffectManager $image_effect_manager) {
36     parent::__construct($image_style_storage);
37     $this->imageEffectManager = $image_effect_manager;
38   }
39
40   /**
41    * {@inheritdoc}
42    */
43   public static function create(ContainerInterface $container) {
44     return new static(
45       $container->get('entity.manager')->getStorage('image_style'),
46       $container->get('plugin.manager.image.effect')
47     );
48   }
49
50   /**
51    * {@inheritdoc}
52    */
53   public function form(array $form, FormStateInterface $form_state) {
54     $user_input = $form_state->getUserInput();
55     $form['#title'] = $this->t('Edit style %name', ['%name' => $this->entity->label()]);
56     $form['#tree'] = TRUE;
57     $form['#attached']['library'][] = 'image/admin';
58
59     // Show the thumbnail preview.
60     $preview_arguments = ['#theme' => 'image_style_preview', '#style' => $this->entity];
61     $form['preview'] = [
62       '#type' => 'item',
63       '#title' => $this->t('Preview'),
64       '#markup' => \Drupal::service('renderer')->render($preview_arguments),
65       // Render preview above parent elements.
66       '#weight' => -5,
67     ];
68
69     // Build the list of existing image effects for this image style.
70     $form['effects'] = [
71       '#type' => 'table',
72       '#header' => [
73         $this->t('Effect'),
74         $this->t('Weight'),
75         $this->t('Operations'),
76       ],
77       '#tabledrag' => [
78         [
79           'action' => 'order',
80           'relationship' => 'sibling',
81           'group' => 'image-effect-order-weight',
82         ],
83       ],
84       '#attributes' => [
85         'id' => 'image-style-effects',
86       ],
87       '#empty' => t('There are currently no effects in this style. Add one by selecting an option below.'),
88       // Render effects below parent elements.
89       '#weight' => 5,
90     ];
91     foreach ($this->entity->getEffects() as $effect) {
92       $key = $effect->getUuid();
93       $form['effects'][$key]['#attributes']['class'][] = 'draggable';
94       $form['effects'][$key]['#weight'] = isset($user_input['effects']) ? $user_input['effects'][$key]['weight'] : NULL;
95       $form['effects'][$key]['effect'] = [
96         '#tree' => FALSE,
97         'data' => [
98           'label' => [
99             '#plain_text' => $effect->label(),
100           ],
101         ],
102       ];
103
104       $summary = $effect->getSummary();
105
106       if (!empty($summary)) {
107         $summary['#prefix'] = ' ';
108         $form['effects'][$key]['effect']['data']['summary'] = $summary;
109       }
110
111       $form['effects'][$key]['weight'] = [
112         '#type' => 'weight',
113         '#title' => $this->t('Weight for @title', ['@title' => $effect->label()]),
114         '#title_display' => 'invisible',
115         '#default_value' => $effect->getWeight(),
116         '#attributes' => [
117           'class' => ['image-effect-order-weight'],
118         ],
119       ];
120
121       $links = [];
122       $is_configurable = $effect instanceof ConfigurableImageEffectInterface;
123       if ($is_configurable) {
124         $links['edit'] = [
125           'title' => $this->t('Edit'),
126           'url' => Url::fromRoute('image.effect_edit_form', [
127             'image_style' => $this->entity->id(),
128             'image_effect' => $key,
129           ]),
130         ];
131       }
132       $links['delete'] = [
133         'title' => $this->t('Delete'),
134         'url' => Url::fromRoute('image.effect_delete', [
135           'image_style' => $this->entity->id(),
136           'image_effect' => $key,
137         ]),
138       ];
139       $form['effects'][$key]['operations'] = [
140         '#type' => 'operations',
141         '#links' => $links,
142       ];
143     }
144
145     // Build the new image effect addition form and add it to the effect list.
146     $new_effect_options = [];
147     $effects = $this->imageEffectManager->getDefinitions();
148     uasort($effects, function ($a, $b) {
149       return Unicode::strcasecmp($a['label'], $b['label']);
150     });
151     foreach ($effects as $effect => $definition) {
152       $new_effect_options[$effect] = $definition['label'];
153     }
154     $form['effects']['new'] = [
155       '#tree' => FALSE,
156       '#weight' => isset($user_input['weight']) ? $user_input['weight'] : NULL,
157       '#attributes' => ['class' => ['draggable']],
158     ];
159     $form['effects']['new']['effect'] = [
160       'data' => [
161         'new' => [
162           '#type' => 'select',
163           '#title' => $this->t('Effect'),
164           '#title_display' => 'invisible',
165           '#options' => $new_effect_options,
166           '#empty_option' => $this->t('Select a new effect'),
167         ],
168         [
169           'add' => [
170             '#type' => 'submit',
171             '#value' => $this->t('Add'),
172             '#validate' => ['::effectValidate'],
173             '#submit' => ['::submitForm', '::effectSave'],
174           ],
175         ],
176       ],
177       '#prefix' => '<div class="image-style-new">',
178       '#suffix' => '</div>',
179     ];
180
181     $form['effects']['new']['weight'] = [
182       '#type' => 'weight',
183       '#title' => $this->t('Weight for new effect'),
184       '#title_display' => 'invisible',
185       '#default_value' => count($this->entity->getEffects()) + 1,
186       '#attributes' => ['class' => ['image-effect-order-weight']],
187     ];
188     $form['effects']['new']['operations'] = [
189       'data' => [],
190     ];
191
192     return parent::form($form, $form_state);
193   }
194
195   /**
196    * Validate handler for image effect.
197    */
198   public function effectValidate($form, FormStateInterface $form_state) {
199     if (!$form_state->getValue('new')) {
200       $form_state->setErrorByName('new', $this->t('Select an effect to add.'));
201     }
202   }
203
204   /**
205    * Submit handler for image effect.
206    */
207   public function effectSave($form, FormStateInterface $form_state) {
208     $this->save($form, $form_state);
209
210     // Check if this field has any configuration options.
211     $effect = $this->imageEffectManager->getDefinition($form_state->getValue('new'));
212
213     // Load the configuration form for this option.
214     if (is_subclass_of($effect['class'], '\Drupal\image\ConfigurableImageEffectInterface')) {
215       $form_state->setRedirect(
216         'image.effect_add_form',
217         [
218           'image_style' => $this->entity->id(),
219           'image_effect' => $form_state->getValue('new'),
220         ],
221         ['query' => ['weight' => $form_state->getValue('weight')]]
222       );
223     }
224     // If there's no form, immediately add the image effect.
225     else {
226       $effect = [
227         'id' => $effect['id'],
228         'data' => [],
229         'weight' => $form_state->getValue('weight'),
230       ];
231       $effect_id = $this->entity->addImageEffect($effect);
232       $this->entity->save();
233       if (!empty($effect_id)) {
234         $this->messenger()->addStatus($this->t('The image effect was successfully applied.'));
235       }
236     }
237   }
238
239   /**
240    * {@inheritdoc}
241    */
242   public function submitForm(array &$form, FormStateInterface $form_state) {
243
244     // Update image effect weights.
245     if (!$form_state->isValueEmpty('effects')) {
246       $this->updateEffectWeights($form_state->getValue('effects'));
247     }
248
249     parent::submitForm($form, $form_state);
250   }
251
252   /**
253    * {@inheritdoc}
254    */
255   public function save(array $form, FormStateInterface $form_state) {
256     parent::save($form, $form_state);
257     $this->messenger()->addStatus($this->t('Changes to the style have been saved.'));
258   }
259
260   /**
261    * Updates image effect weights.
262    *
263    * @param array $effects
264    *   Associative array with effects having effect uuid as keys and array
265    *   with effect data as values.
266    */
267   protected function updateEffectWeights(array $effects) {
268     foreach ($effects as $uuid => $effect_data) {
269       if ($this->entity->getEffects()->has($uuid)) {
270         $this->entity->getEffect($uuid)->setWeight($effect_data['weight']);
271       }
272     }
273   }
274
275 }