Patched to Drupal 8.4.8 level. See https://www.drupal.org/sa-core-2018-004 and patch...
[yaffs-website] / web / modules / contrib / entity / src / Form / DeleteMultiple.php
1 <?php
2
3 namespace Drupal\entity\Form;
4
5 use Drupal\Core\Entity\EntityTypeManagerInterface;
6 use Drupal\Core\Form\ConfirmFormBase;
7 use Drupal\Core\Url;
8 use Drupal\Core\Form\FormStateInterface;
9 use Drupal\Core\Session\AccountInterface;
10 use Drupal\user\PrivateTempStoreFactory;
11 use Symfony\Component\HttpFoundation\RedirectResponse;
12 use Symfony\Component\DependencyInjection\ContainerInterface;
13
14 /**
15  * Provides an entities deletion confirmation form.
16  */
17 class DeleteMultiple extends ConfirmFormBase {
18
19   /**
20    * The current user.
21    *
22    * @var \Drupal\Core\Session\AccountInterface
23    */
24   protected $currentUser;
25
26   /**
27    * The entity type manager.
28    *
29    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
30    */
31   protected $entityTypeManager;
32
33   /**
34    * The tempstore.
35    *
36    * @var \Drupal\user\SharedTempStore
37    */
38   protected $tempStore;
39
40   /**
41    * The entity type id.
42    *
43    * @var string
44    */
45   protected $entityTypeId;
46
47   /**
48    * The selection, in the entity_id => langcodes format.
49    *
50    * @var array
51    */
52   protected $selection = [];
53
54   /**
55    * Constructs a new DeleteMultiple object.
56    *
57    * @param \Drupal\Core\Session\AccountInterface $current_user
58    *   The current user.
59    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
60    *   The entity type manager.
61    * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
62    *   The tempstore factory.
63    */
64   public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory) {
65     $this->currentUser = $current_user;
66     $this->entityTypeManager = $entity_type_manager;
67     $this->tempStore = $temp_store_factory->get('entity_delete_multiple_confirm');
68   }
69
70   /**
71    * {@inheritdoc}
72    */
73   public static function create(ContainerInterface $container) {
74     return new static(
75       $container->get('current_user'),
76       $container->get('entity_type.manager'),
77       $container->get('user.private_tempstore')
78     );
79   }
80
81   /**
82    * {@inheritdoc}
83    */
84   public function getFormId() {
85     return 'entity_delete_multiple_confirm';
86   }
87
88   /**
89    * {@inheritdoc}
90    */
91   public function getQuestion() {
92     return $this->formatPlural(count($this->selection), 'Are you sure you want to delete this item?', 'Are you sure you want to delete these items?');
93   }
94
95   /**
96    * {@inheritdoc}
97    */
98   public function getCancelUrl() {
99     return new Url('entity.' . $this->entityTypeId . '.collection');
100   }
101
102   /**
103    * {@inheritdoc}
104    */
105   public function getConfirmText() {
106     return $this->t('Delete');
107   }
108
109   /**
110    * {@inheritdoc}
111    *
112    * @param string $entity_type_id
113    *   The entity type id.
114    */
115   public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL) {
116     $this->entityTypeId = $entity_type_id;
117     $this->selection = $this->tempStore->get($this->currentUser->id());
118     if (empty($this->entityTypeId) || empty($this->selection)) {
119       return new RedirectResponse($this->getCancelUrl()->setAbsolute()->toString());
120     }
121
122     $storage = $this->entityTypeManager->getStorage($this->entityTypeId);
123     /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */
124     $entities = $storage->loadMultiple(array_keys($this->selection));
125     $items = [];
126     foreach ($this->selection as $id => $langcodes) {
127       foreach ($langcodes as $langcode) {
128         $entity = $entities[$id]->getTranslation($langcode);
129         $key = $id . ':' . $langcode;
130         $default_key = $id . ':' . $entity->getUntranslated()->language()->getId();
131
132         // If we have a translated entity we build a nested list of translations
133         // that will be deleted.
134         $languages = $entity->getTranslationLanguages();
135         if (count($languages) > 1 && $entity->isDefaultTranslation()) {
136           $names = [];
137           foreach ($languages as $translation_langcode => $language) {
138             $names[] = $language->getName();
139             unset($items[$id . ':' . $translation_langcode]);
140           }
141           $items[$default_key] = [
142             'label' => [
143               '#markup' => $this->t('@label (Original translation) - <em>The following translations will be deleted:</em>', ['@label' => $entity->label()]),
144             ],
145             'deleted_translations' => [
146               '#theme' => 'item_list',
147               '#items' => $names,
148             ],
149           ];
150         }
151         elseif (!isset($items[$default_key])) {
152           $items[$key] = $entity->label();
153         }
154       }
155     }
156
157     $form['entities'] = [
158       '#theme' => 'item_list',
159       '#items' => $items,
160     ];
161     $form = parent::buildForm($form, $form_state);
162
163     return $form;
164   }
165
166   /**
167    * {@inheritdoc}
168    */
169   public function submitForm(array &$form, FormStateInterface $form_state) {
170     $total_count = 0;
171     $delete_entities = [];
172     $delete_translations = [];
173     $storage = $this->entityTypeManager->getStorage($this->entityTypeId);
174     /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */
175     $entities = $storage->loadMultiple(array_keys($this->selection));
176
177     foreach ($this->selection as $id => $langcodes) {
178       foreach ($langcodes as $langcode) {
179         $entity = $entities[$id]->getTranslation($langcode);
180         if ($entity->isDefaultTranslation()) {
181           $delete_entities[$id] = $entity;
182           unset($delete_translations[$id]);
183           $total_count += count($entity->getTranslationLanguages());
184         }
185         elseif (!isset($delete_entities[$id])) {
186           $delete_translations[$id][] = $entity;
187         }
188       }
189     }
190
191     if ($delete_entities) {
192       $storage->delete($delete_entities);
193       $this->logger('content')->notice('Deleted @count @entity_type items.', [
194         '@count' => count($delete_entities),
195         '@entity_type' => $this->entityTypeId,
196       ]);
197     }
198
199     if ($delete_translations) {
200       $count = 0;
201       /** @var \Drupal\Core\Entity\ContentEntityInterface[][] $delete_translations */
202       foreach ($delete_translations as $id => $translations) {
203         $entity = $entities[$id]->getUntranslated();
204         foreach ($translations as $translation) {
205           $entity->removeTranslation($translation->language()->getId());
206         }
207         $entity->save();
208         $count += count($translations);
209       }
210       if ($count) {
211         $total_count += $count;
212         $this->logger('content')->notice('Deleted @count @entity_type translations.', [
213           '@count' => $count,
214           '@entity_type' => $this->entityTypeId,
215         ]);
216       }
217     }
218
219     if ($total_count) {
220       drupal_set_message($this->formatPlural($total_count, 'Deleted 1 item.', 'Deleted @count items.'));
221     }
222     $this->tempStore->delete($this->currentUser->id());
223     $form_state->setRedirectUrl($this->getCancelUrl());
224   }
225
226 }