Upgraded imagemagick and manually altered pdf to image module to handle changes....
[yaffs-website] / web / modules / contrib / entity / src / Form / DeleteMultipleForm.php
1 <?php
2
3 namespace Drupal\entity\Form;
4
5 use Drupal\Core\Entity\EntityTypeManagerInterface;
6 use Drupal\Core\Form\BaseFormIdInterface;
7 use Drupal\Core\Form\ConfirmFormBase;
8 use Drupal\Core\Messenger\MessengerInterface;
9 use Drupal\Core\TypedData\TranslatableInterface;
10 use Drupal\Core\Url;
11 use Drupal\Core\Form\FormStateInterface;
12 use Drupal\Core\Session\AccountInterface;
13 use Drupal\Core\TempStore\PrivateTempStoreFactory;
14 use Symfony\Component\HttpFoundation\RedirectResponse;
15 use Symfony\Component\DependencyInjection\ContainerInterface;
16
17 /**
18  * Provides an entities deletion confirmation form.
19  */
20 class DeleteMultipleForm extends ConfirmFormBase implements BaseFormIdInterface {
21
22   /**
23    * The current user.
24    *
25    * @var \Drupal\Core\Session\AccountInterface
26    */
27   protected $currentUser;
28
29   /**
30    * The entity type manager.
31    *
32    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
33    */
34   protected $entityTypeManager;
35
36   /**
37    * The tempstore.
38    *
39    * @var \Drupal\Core\TempStore\SharedTempStore
40    */
41   protected $tempStore;
42
43   /**
44    * The messenger service.
45    *
46    * @var \Drupal\Core\Messenger\MessengerInterface
47    */
48   protected $messenger;
49
50   /**
51    * The entity type ID.
52    *
53    * @var string
54    */
55   protected $entityTypeId;
56
57   /**
58    * The selection, in the entity_id => langcodes format.
59    *
60    * @var array
61    */
62   protected $selection = [];
63
64   /**
65    * The entity type definition.
66    *
67    * @var \Drupal\Core\Entity\EntityTypeInterface
68    */
69   protected $entityType;
70
71   /**
72    * Constructs a new DeleteMultiple object.
73    *
74    * @param \Drupal\Core\Session\AccountInterface $current_user
75    *   The current user.
76    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
77    *   The entity type manager.
78    * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
79    *   The tempstore factory.
80    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
81    *   The messenger service.
82    */
83   public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory, MessengerInterface $messenger) {
84     $this->currentUser = $current_user;
85     $this->entityTypeManager = $entity_type_manager;
86     $this->tempStore = $temp_store_factory->get('entity_delete_multiple_confirm');
87     $this->messenger = $messenger;
88   }
89
90   /**
91    * {@inheritdoc}
92    */
93   public static function create(ContainerInterface $container) {
94     return new static(
95       $container->get('current_user'),
96       $container->get('entity_type.manager'),
97       $container->get('tempstore.private'),
98       $container->get('messenger')
99     );
100   }
101
102   /**
103    * {@inheritdoc}
104    */
105   public function getBaseFormId() {
106     return 'entity_delete_multiple_confirm_form';
107   }
108
109   /**
110    * {@inheritdoc}
111    */
112   public function getFormId() {
113     // Get entity type ID from the route because ::buildForm has not yet been
114     // called.
115     $entity_type_id = $this->getRouteMatch()->getParameter('entity_type_id');
116     return $entity_type_id . '_delete_multiple_confirm_form';
117   }
118
119   /**
120    * {@inheritdoc}
121    */
122   public function getQuestion() {
123     return $this->formatPlural(count($this->selection), 'Are you sure you want to delete this @item?', 'Are you sure you want to delete these @items?', [
124       '@item' => $this->entityType->getSingularLabel(),
125       '@items' => $this->entityType->getPluralLabel(),
126     ]);
127   }
128
129   /**
130    * {@inheritdoc}
131    */
132   public function getCancelUrl() {
133     if ($this->entityType->hasLinkTemplate('collection')) {
134       return new Url('entity.' . $this->entityTypeId . '.collection');
135     }
136     else {
137       return new Url('<front>');
138     }
139   }
140
141   /**
142    * {@inheritdoc}
143    */
144   public function getConfirmText() {
145     return $this->t('Delete');
146   }
147
148   /**
149    * {@inheritdoc}
150    */
151   public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL) {
152     $this->entityTypeId = $entity_type_id;
153     $this->entityType = $this->entityTypeManager->getDefinition($this->entityTypeId);
154     $this->selection = $this->tempStore->get($this->currentUser->id() . ':' . $entity_type_id);
155     if (empty($this->entityTypeId) || empty($this->selection)) {
156       return new RedirectResponse($this->getCancelUrl()
157         ->setAbsolute()
158         ->toString());
159     }
160
161     $items = [];
162     $entities = $this->entityTypeManager->getStorage($entity_type_id)->loadMultiple(array_keys($this->selection));
163     foreach ($this->selection as $id => $selected_langcodes) {
164       $entity = $entities[$id];
165       foreach ($selected_langcodes as $langcode) {
166         $key = $id . ':' . $langcode;
167         if ($entity instanceof TranslatableInterface) {
168           $entity = $entity->getTranslation($langcode);
169           $default_key = $id . ':' . $entity->getUntranslated()->language()->getId();
170
171           // Build a nested list of translations that will be deleted if the
172           // entity has multiple translations.
173           $entity_languages = $entity->getTranslationLanguages();
174           if (count($entity_languages) > 1 && $entity->isDefaultTranslation()) {
175             $names = [];
176             foreach ($entity_languages as $translation_langcode => $language) {
177               $names[] = $language->getName();
178               unset($items[$id . ':' . $translation_langcode]);
179             }
180             $items[$default_key] = [
181               'label' => [
182                 '#markup' => $this->t('@label (Original translation) - <em>The following @entity_type translations will be deleted:</em>',
183                   [
184                     '@label' => $entity->label(),
185                     '@entity_type' => $this->entityType->getSingularLabel(),
186                   ]),
187               ],
188               'deleted_translations' => [
189                 '#theme' => 'item_list',
190                 '#items' => $names,
191               ],
192             ];
193           }
194           elseif (!isset($items[$default_key])) {
195             $items[$key] = $entity->label();
196           }
197         }
198         elseif (!isset($items[$key])) {
199           $items[$key] = $entity->label();
200         }
201       }
202     }
203
204     $form['entities'] = [
205       '#theme' => 'item_list',
206       '#items' => $items,
207     ];
208     $form = parent::buildForm($form, $form_state);
209
210     return $form;
211   }
212
213   /**
214    * {@inheritdoc}
215    */
216   public function submitForm(array &$form, FormStateInterface $form_state) {
217     $total_count = 0;
218     $delete_entities = [];
219     $delete_translations = [];
220     $inaccessible_entities = [];
221     $storage = $this->entityTypeManager->getStorage($this->entityTypeId);
222
223     $entities = $storage->loadMultiple(array_keys($this->selection));
224     foreach ($this->selection as $id => $selected_langcodes) {
225       $entity = $entities[$id];
226       if (!$entity->access('delete', $this->currentUser)) {
227         $inaccessible_entities[] = $entity;
228         continue;
229       }
230       foreach ($selected_langcodes as $langcode) {
231         if ($entity instanceof TranslatableInterface) {
232           $entity = $entity->getTranslation($langcode);
233           // If the entity is the default translation then deleting it will
234           // delete all the translations.
235           if ($entity->isDefaultTranslation()) {
236             $delete_entities[$id] = $entity;
237             // If there are translations already marked for deletion then remove
238             // them as they will be deleted anyway.
239             unset($delete_translations[$id]);
240             // Update the total count. Since a single delete will delete all
241             // translations, we need to add the number of translations to the
242             // count.
243             $total_count += count($entity->getTranslationLanguages());
244           }
245           // Add the translation to the list of translations to be deleted
246           // unless the default translation is being deleted.
247           elseif (!isset($delete_entities[$id])) {
248             $delete_translations[$id][] = $entity;
249           }
250         }
251         elseif (!isset($delete_entities[$id])) {
252           $delete_entities[$id] = $entity;
253           $total_count++;
254         }
255       }
256     }
257
258     if ($delete_entities) {
259       $storage->delete($delete_entities);
260       foreach ($delete_entities as $entity) {
261         $this->logger($entity->getEntityType()->getProvider())->notice('The @entity-type %label has been deleted.', [
262           '@entity-type' => $entity->getEntityType()->getLowercaseLabel(),
263           '%label' => $entity->label(),
264         ]);
265       }
266     }
267
268     if ($delete_translations) {
269       /** @var \Drupal\Core\Entity\TranslatableInterface[][] $delete_translations */
270       foreach ($delete_translations as $id => $translations) {
271         $entity = $entities[$id]->getUntranslated();
272         foreach ($translations as $translation) {
273           $entity->removeTranslation($translation->language()->getId());
274         }
275         $entity->save();
276         foreach ($translations as $translation) {
277           $this->logger($entity->getEntityType()->getProvider())->notice('The @entity-type %label @language translation has been deleted.', [
278             '@entity-type' => $entity->getEntityType()->getLowercaseLabel(),
279             '%label'       => $entity->label(),
280             '@language'    => $translation->language()->getName(),
281           ]);
282         }
283         $total_count += count($translations);
284       }
285     }
286
287     if ($total_count) {
288       $this->messenger->addStatus($this->getDeletedMessage($total_count));
289     }
290     if ($inaccessible_entities) {
291       $this->messenger->addWarning($this->getInaccessibleMessage(count($inaccessible_entities)));
292     }
293     $this->tempStore->delete($this->currentUser->id());
294     $form_state->setRedirectUrl($this->getCancelUrl());
295   }
296
297   /**
298    * Returns the message to show the user after an item was deleted.
299    *
300    * @param int $count
301    *   Count of deleted translations.
302    *
303    * @return \Drupal\Core\StringTranslation\TranslatableMarkup
304    *   The item deleted message.
305    */
306   protected function getDeletedMessage($count) {
307     return $this->formatPlural($count, 'Deleted @count item.', 'Deleted @count items.');
308   }
309
310   /**
311    * Returns the message to show the user when an item has not been deleted.
312    *
313    * @param int $count
314    *   Count of deleted translations.
315    *
316    * @return \Drupal\Core\StringTranslation\TranslatableMarkup
317    *   The item inaccessible message.
318    */
319   protected function getInaccessibleMessage($count) {
320     return $this->formatPlural($count, "@count item has not been deleted because you do not have the necessary permissions.", "@count items have not been deleted because you do not have the necessary permissions.");
321   }
322
323 }