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