54e032f06ad813344b1dc610e4e0304b8cb54834
[yaffs-website] / web / modules / contrib / metatag / src / Form / MetatagDefaultsForm.php
1 <?php
2
3 namespace Drupal\metatag\Form;
4
5 use Drupal\Core\Entity\ContentEntityType;
6 use Drupal\Core\Entity\EntityForm;
7 use Drupal\Core\Entity\EntityTypeInterface;
8 use Drupal\Core\Form\FormStateInterface;
9 use Drupal\metatag\MetatagManager;
10
11 /**
12  * Class MetatagDefaultsForm.
13  *
14  * @package Drupal\metatag\Form
15  */
16 class MetatagDefaultsForm extends EntityForm {
17
18   /**
19    * {@inheritdoc}
20    */
21   public function form(array $form, FormStateInterface $form_state) {
22     $form = parent::form($form, $form_state);
23     $metatag_defaults = $this->entity;
24     $metatag_manager = \Drupal::service('metatag.manager');
25
26     $form['#ajax_wrapper_id'] = 'metatag-defaults-form-ajax-wrapper';
27     $ajax = [
28       'wrapper' => $form['#ajax_wrapper_id'],
29       'callback' => '::rebuildForm',
30     ];
31     $form['#prefix'] = '<div id="' . $form['#ajax_wrapper_id'] . '">';
32     $form['#suffix'] = '</div>';
33
34     $default_type = NULL;
35     if (!empty($metatag_defaults)) {
36       $default_type = $metatag_defaults->getOriginalId();
37     }
38     else {
39       $form_state->set('default_type', $default_type);
40     }
41
42     $token_types = empty($default_type) ? [] : [explode('__', $default_type)[0]];
43
44     // Add the token browser at the top.
45     $form += \Drupal::service('metatag.token')->tokenBrowser($token_types);
46
47     // If this is a new Metatag defaults, then list available bundles.
48     if ($metatag_defaults->isNew()) {
49       $options = $this->getAvailableBundles();
50       $form['id'] = [
51         '#type' => 'select',
52         '#title' => t('Type'),
53         '#description' => t('Select the type of default meta tags you would like to add.'),
54         '#options' => $options,
55         '#required' => TRUE,
56         '#default_value' => $default_type,
57         '#ajax' => $ajax + [
58           'trigger_as' => [
59             'name' => 'select_id_submit',
60           ],
61         ],
62       ];
63       $form['select_id_submit'] = [
64         '#type' => 'submit',
65         '#value' => $this->t('Submit'),
66         '#name' => 'select_id_submit',
67         '#ajax' => $ajax,
68         '#attributes' => [
69           'class' => ['js-hide'],
70         ],
71       ];
72       $values = [];
73     }
74     else {
75       $values = $metatag_defaults->get('tags');
76     }
77
78     // Add metatag form fields.
79     $form = $metatag_manager->form($values, $form);
80
81     return $form;
82   }
83
84   /**
85    * Ajax form submit handler that will return the whole rebuilt form.
86    *
87    * @param array $form
88    *   An associative array containing the structure of the form.
89    * @param \Drupal\Core\Form\FormStateInterface $form_state
90    *   The current state of the form.
91    *
92    * @return array
93    *   The form structure.
94    */
95   public function rebuildForm(array &$form, FormStateInterface $form_state) {
96     return $form;
97   }
98
99   /**
100    * {@inheritdoc}
101    */
102   protected function actions(array $form, FormStateInterface $form_state) {
103     $actions = parent::actions($form, $form_state);
104     if (isset($actions['delete'])) {
105       $actions['delete']['#access'] = $actions['delete']['#access'] && !in_array($this->entity->id(), MetatagManager::protectedDefaults());
106     }
107     return $actions;
108   }
109
110   /**
111    * {@inheritdoc}
112    */
113   public function submitForm(array &$form, FormStateInterface $form_state) {
114     if ($form_state->getTriggeringElement()['#name'] == 'select_id_submit') {
115       $form_state->set('default_type', $form_state->getValue('id'));
116       $form_state->setRebuild();
117     }
118     else {
119       parent::submitForm($form, $form_state);
120     }
121   }
122
123   /**
124    * {@inheritdoc}
125    */
126   public function save(array $form, FormStateInterface $form_state) {
127     $metatag_defaults = $this->entity;
128
129     // Set the label on new defaults.
130     if ($metatag_defaults->isNew()) {
131       $metatag_defaults_id = $form_state->getValue('id');
132
133       $type_parts = explode('__', $metatag_defaults_id);
134       $entity_type = $type_parts[0];
135       $entity_bundle = isset($type_parts[1]) ? $type_parts[1] : NULL;
136
137       // Get the entity label.
138       $entity_manager = \Drupal::service('entity_type.manager');
139       $entity_info = $entity_manager->getDefinitions();
140       $entity_label = (string) $entity_info[$entity_type]->get('label');
141
142       if (!is_null($entity_bundle)) {
143         // Get the bundle label.
144         $bundle_manager = \Drupal::service('entity_type.bundle.info');
145         $bundle_info = $bundle_manager->getBundleInfo($entity_type);
146         $entity_label .= ': ' . $bundle_info[$entity_bundle]['label'];
147       }
148
149       // Set the label to the config entity.
150       $this->entity->set('label', $entity_label);
151     }
152
153     // Set tags within the Metatag entity.
154     $tag_manager = \Drupal::service('plugin.manager.metatag.tag');
155     $tags = $tag_manager->getDefinitions();
156     $tag_values = [];
157     foreach ($tags as $tag_id => $tag_definition) {
158       if ($form_state->hasValue($tag_id)) {
159         // Some plugins need to process form input before storing it. Hence, we
160         // set it and then get it.
161         $tag = $tag_manager->createInstance($tag_id);
162         $tag->setValue($form_state->getValue($tag_id));
163         if (!empty($tag->value())) {
164           $tag_values[$tag_id] = $tag->value();
165         }
166       }
167     }
168     $metatag_defaults->set('tags', $tag_values);
169     $status = $metatag_defaults->save();
170
171     switch ($status) {
172       case SAVED_NEW:
173         drupal_set_message($this->t('Created the %label Metatag defaults.', [
174           '%label' => $metatag_defaults->label(),
175         ]));
176         break;
177
178       default:
179         drupal_set_message($this->t('Saved the %label Metatag defaults.', [
180           '%label' => $metatag_defaults->label(),
181         ]));
182     }
183
184     $form_state->setRedirectUrl($metatag_defaults->toUrl('collection'));
185   }
186
187   /**
188    * Returns an array of available bundles to override.
189    *
190    * @return array
191    *   A list of available bundles as $id => $label.
192    */
193   protected function getAvailableBundles() {
194     $options = [];
195     $entity_types = $this->getSupportedEntityTypes();
196     /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager */
197     $entity_manager = \Drupal::service('entity_type.manager');
198     /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info */
199     $bundle_info = \Drupal::service('entity_type.bundle.info');
200     $metatags_defaults_manager = $entity_manager->getStorage('metatag_defaults');
201     foreach ($entity_types as $entity_type => $entity_label) {
202       if (empty($metatags_defaults_manager->load($entity_type))) {
203         $options[$entity_label][$entity_type] = "$entity_label (Default)";
204       }
205
206       $bundles = $bundle_info->getBundleInfo($entity_type);
207       foreach ($bundles as $bundle_id => $bundle_metadata) {
208         $metatag_defaults_id = $entity_type . '__' . $bundle_id;
209
210         if (empty($metatags_defaults_manager->load($metatag_defaults_id))) {
211           $options[$entity_label][$metatag_defaults_id] = $bundle_metadata['label'];
212         }
213       }
214     }
215     return $options;
216   }
217
218   /**
219    * Returns a list of supported entity types.
220    *
221    * @return array
222    *   A list of available entity types as $machine_name => $label.
223    */
224   protected function getSupportedEntityTypes() {
225     $entity_types = [];
226
227     /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager */
228     $entity_manager = \Drupal::service('entity_type.manager');
229
230     // A list of entity types that are not supported.
231     $unsupported_types = [
232       // Custom blocks.
233       'block_content',
234       // Comments.
235       'comment',
236       // Contact messages are the messages submitted on individual contact forms
237       // so obviously shouldn't get meta tags.
238       'contact_message',
239       // Menu items.
240       'menu_link_content',
241       // Shortcut items.
242       'shortcut',
243     ];
244
245     // Make a list of supported content types.
246     foreach ($entity_manager->getDefinitions() as $entity_name => $definition) {
247       // Skip some entity types that we don't want to support.
248       if (in_array($entity_name, $unsupported_types)) {
249         continue;
250       }
251
252       // Identify supported entities.
253       if ($definition instanceof ContentEntityType) {
254         // Only work with entity types that have a list of links, i.e. publicly
255         // viewable.
256         $links = $definition->get('links');
257         if (!empty($links)) {
258           $entity_types[$entity_name] = $this->getEntityTypeLabel($definition);
259         }
260       }
261     }
262
263     return $entity_types;
264   }
265
266   /**
267    * Returns the text label for the entity type specified.
268    *
269    * @param Drupal\Core\Entity\EntityTypeInterface $entityType
270    *   The entity type to process.
271    *
272    * @return string
273    *   A label.
274    */
275   protected function getEntityTypeLabel(EntityTypeInterface $entityType) {
276     $label = $entityType->getLabel();
277
278     if (is_a($label, 'Drupal\Core\StringTranslation\TranslatableMarkup')) {
279       /** @var \Drupal\Core\StringTranslation\TranslatableMarkup $label */
280       $label = $label->render();
281     }
282
283     return $label;
284   }
285
286 }