3 namespace Drupal\media_entity;
5 use Drupal\Core\Ajax\AjaxResponse;
6 use Drupal\Core\Ajax\ReplaceCommand;
7 use Drupal\Core\Entity\EntityFieldManagerInterface;
8 use Drupal\Core\Entity\EntityForm;
9 use Drupal\Core\Entity\EntityInterface;
10 use Drupal\Core\Form\FormStateInterface;
11 use Drupal\language\Entity\ContentLanguageSettings;
12 use Symfony\Component\DependencyInjection\ContainerInterface;
15 * Form controller for node type forms.
17 class MediaBundleForm extends EntityForm {
20 * The instantiated plugin instances that have configuration forms.
22 * @var \Drupal\Core\Plugin\PluginFormInterface[]
24 protected $configurableInstances = [];
27 * Manager for media entity type plugins.
29 * @var \Drupal\media_entity\MediaTypeManager
31 protected $mediaTypeManager;
34 * Entity field manager service.
36 * @var \Drupal\Core\Entity\EntityFieldManagerInterface
38 protected $entityFieldManager;
41 * Constructs a new class instance.
43 * @param \Drupal\media_entity\MediaTypeManager $media_type_manager
46 public function __construct(MediaTypeManager $media_type_manager, EntityFieldManagerInterface $entity_field_manager) {
47 $this->mediaTypeManager = $media_type_manager;
48 $this->entityFieldManager = $entity_field_manager;
54 public static function create(ContainerInterface $container) {
56 $container->get('plugin.manager.media_entity.type'),
57 $container->get('entity_field.manager')
62 * Ajax callback triggered by the type provider select element.
66 * @param \Drupal\Core\Form\FormStateInterface $form_state
69 * @return \Drupal\Core\Ajax\AjaxResponse
72 public function ajaxTypeProviderData(array $form, FormStateInterface $form_state) {
73 $response = new AjaxResponse();
74 $plugin = $this->entity->getType()->getPluginId();
76 $response->addCommand(new ReplaceCommand('#edit-type-configuration-plugin-wrapper', $form['type_configuration'][$plugin]));
77 $response->addCommand(new ReplaceCommand('#field-mapping-wrapper', $form['field_mapping']));
85 public function form(array $form, FormStateInterface $form_state) {
86 $form = parent::form($form, $form_state);
88 /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
89 $form['#entity'] = $bundle = $this->entity;
90 $form_state->set('bundle', $bundle->id());
92 if ($this->operation == 'add') {
93 $form['#title'] = $this->t('Add media bundle');
95 elseif ($this->operation == 'edit') {
96 $form['#title'] = $this->t('Edit %label media bundle', ['%label' => $bundle->label()]);
100 '#title' => $this->t('Label'),
101 '#type' => 'textfield',
102 '#default_value' => $bundle->label(),
103 '#description' => $this->t('The human-readable name of this media bundle.'),
109 // @todo: '#disabled' not always FALSE.
111 '#type' => 'machine_name',
112 '#default_value' => $bundle->id(),
114 '#disabled' => !$bundle->isNew(),
116 'exists' => ['\Drupal\media_entity\Entity\MediaBundle', 'exists'],
117 'source' => ['label'],
119 '#description' => $this->t('A unique machine-readable name for this media bundle.'),
123 $form['description'] = [
124 '#title' => $this->t('Description'),
125 '#type' => 'textarea',
126 '#default_value' => $bundle->getDescription(),
127 '#description' => $this->t('Describe this media bundle. The text will be displayed on the <em>Add new media</em> page.'),
131 $plugins = $this->mediaTypeManager->getDefinitions();
133 foreach ($plugins as $plugin => $definition) {
134 $options[$plugin] = $definition['label'];
139 '#title' => $this->t('Type provider'),
140 '#default_value' => $bundle->getType()->getPluginId(),
141 '#options' => $options,
142 '#description' => $this->t('Media type provider plugin that is responsible for additional logic related to this media.'),
145 'callback' => '::ajaxTypeProviderData',
147 'type' => 'throbber',
148 'message' => $this->t('Updating type provider configuration form.'),
153 // Media type plugin configuration.
154 $form['type_configuration'] = [
155 '#type' => 'fieldset',
156 '#title' => $this->t('Type provider configuration'),
161 /** @var \Drupal\media_entity\MediaTypeInterface $plugin */
162 if ($plugin = $bundle->getType()) {
163 $plugin_configuration = (empty($this->configurableInstances[$plugin->getPluginId()]['plugin_config'])) ? $bundle->type_configuration : $this->configurableInstances[$plugin->getPluginId()]['plugin_config'];
164 /** @var \Drupal\media_entity\MediaTypeBase $instance */
165 $instance = $this->mediaTypeManager->createInstance($plugin->getPluginId(), $plugin_configuration);
166 // Store the configuration for validate and submit handlers.
167 $this->configurableInstances[$plugin->getPluginId()]['plugin_config'] = $plugin_configuration;
169 $form['type_configuration'][$plugin->getPluginId()] = [
170 '#type' => 'container',
172 'id' => 'edit-type-configuration-plugin-wrapper',
175 $form['type_configuration'][$plugin->getPluginId()] += $instance->buildConfigurationForm([], $form_state);
178 // Field mapping configuration.
179 $form['field_mapping'] = [
180 '#type' => 'fieldset',
181 '#title' => $this->t('Field mapping'),
183 '#attributes' => ['id' => 'field-mapping-wrapper'],
185 '#type' => 'html_tag',
187 '#value' => $this->t('Media type plugins can provide metadata fields such as title, caption, size information, credits, ... Media entity can automatically save this metadata information to entity fields, which can be configured below. Information will only be mapped if the entity field is empty.'),
192 if (empty($plugin) || empty($plugin->providedFields())) {
193 $form['field_mapping']['empty_message'] = [
195 '#suffix' => '</em>',
196 '#markup' => $this->t('No metadata fields available.'),
208 'revision_timestamp',
212 $options = ['_none' => $this->t('- Skip field -')];
213 foreach ($this->entityFieldManager->getFieldDefinitions('media', $bundle->id()) as $field_name => $field) {
214 if (!in_array($field_name, $skipped_fields)) {
215 $options[$field_name] = $field->getLabel();
219 foreach ($plugin->providedFields() as $field_name => $field_label) {
220 $form['field_mapping'][$field_name] = [
222 '#title' => $field_label,
223 '#options' => $options,
224 '#default_value' => isset($bundle->field_map[$field_name]) ? $bundle->field_map[$field_name] : '_none',
229 $form['additional_settings'] = [
230 '#type' => 'vertical_tabs',
232 'library' => ['media_entity/media_bundle_form'],
237 $form['workflow'] = [
238 '#type' => 'details',
239 '#title' => $this->t('Publishing options'),
240 '#group' => 'additional_settings',
243 $workflow_options = [
244 'status' => $bundle->getStatus(),
245 'new_revision' => $bundle->shouldCreateNewRevision(),
246 'queue_thumbnail_downloads' => $bundle->getQueueThumbnailDownloads(),
248 // Prepare workflow options to be used for 'checkboxes' form element.
249 $keys = array_keys(array_filter($workflow_options));
250 $workflow_options = array_combine($keys, $keys);
251 $form['workflow']['options'] = [
252 '#type' => 'checkboxes',
253 '#title' => $this->t('Default options'),
254 '#default_value' => $workflow_options,
256 'status' => $this->t('Published'),
257 'new_revision' => $this->t('Create new revision'),
258 'queue_thumbnail_downloads' => $this->t('Queue thumbnail downloads'),
262 $form['workflow']['options']['status']['#description'] = $this->t('Entities will be automatically published when they are created.');
263 $form['workflow']['options']['new_revision']['#description'] = $this->t('Automatically create a new revision of media entities. Users with the Administer media permission will be able to override this option.');
264 $form['workflow']['options']['queue_thumbnail_downloads']['#description'] = $this->t('Download thumbnails via a queue.');
266 if ($this->moduleHandler->moduleExists('language')) {
267 $form['language'] = [
268 '#type' => 'details',
269 '#title' => $this->t('Language settings'),
270 '#group' => 'additional_settings',
273 $language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('media', $bundle->id());
275 $form['language']['language_configuration'] = [
276 '#type' => 'language_configuration',
277 '#entity_information' => [
278 'entity_type' => 'media',
279 'bundle' => $bundle->id(),
281 '#default_value' => $language_configuration,
291 public function validateForm(array &$form, FormStateInterface $form_state) {
292 parent::validateForm($form, $form_state);
294 // Let the selected plugin validate its settings.
295 $plugin = $this->entity->getType()->getPluginId();
296 $plugin_configuration = !empty($this->configurableInstances[$plugin]['plugin_config']) ? $this->configurableInstances[$plugin]['plugin_config'] : [];
297 $instance = $this->mediaTypeManager->createInstance($plugin, $plugin_configuration);
298 $instance->validateConfigurationForm($form, $form_state);
304 public function submitForm(array &$form, FormStateInterface $form_state) {
305 parent::submitForm($form, $form_state);
307 $workflow_options = ['status', 'queue_thumbnail_downloads'];
308 foreach ($workflow_options as $option) {
309 $this->entity->$option = (bool) $form_state->getValue(['options', $option]);
312 $this->entity->setNewRevision((bool) $form_state->getValue(['options', 'new_revision']));
314 // Let the selected plugin save its settings.
315 $plugin = $this->entity->getType()->getPluginId();
316 $plugin_configuration = !empty($this->configurableInstances[$plugin]['plugin_config']) ? $this->configurableInstances[$plugin]['plugin_config'] : [];
317 $instance = $this->mediaTypeManager->createInstance($plugin, $plugin_configuration);
318 $instance->submitConfigurationForm($form, $form_state);
324 protected function actions(array $form, FormStateInterface $form_state) {
325 $actions = parent::actions($form, $form_state);
326 $actions['submit']['#value'] = $this->t('Save media bundle');
327 $actions['delete']['#value'] = $this->t('Delete media bundle');
328 $actions['delete']['#access'] = $this->entity->access('delete');
335 protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
336 $configuration = $form_state->getValue('type_configuration');
338 // Store previous plugin config.
339 $plugin = $entity->getType()->getPluginId();
340 $this->configurableInstances[$plugin]['plugin_config'] = empty($configuration[$plugin]) ? [] : $configuration[$plugin];
342 /** @var \Drupal\media_entity\MediaBundleInterface $entity */
343 parent::copyFormValuesToEntity($entity, $form, $form_state);
345 // Use type configuration for the plugin that was chosen.
346 $plugin = $entity->getType()->getPluginId();
347 $plugin_configuration = empty($configuration[$plugin]) ? [] : $configuration[$plugin];
348 $entity->set('type_configuration', $plugin_configuration);
350 // Save field mapping.
351 $entity->field_map = array_filter(
352 $form_state->getValue('field_mapping', []),
353 function ($item) { return $item != '_none'; }
360 public function save(array $form, FormStateInterface $form_state) {
361 /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
362 $bundle = $this->entity;
363 $status = $bundle->save();
365 $t_args = ['%name' => $bundle->label()];
366 if ($status == SAVED_UPDATED) {
367 drupal_set_message($this->t('The media bundle %name has been updated.', $t_args));
369 elseif ($status == SAVED_NEW) {
370 drupal_set_message($this->t('The media bundle %name has been added.', $t_args));
371 $this->logger('media')->notice('Added bundle %name.', $t_args);
374 // Override the "status" base field default value, for this bundle.
375 $fields = $this->entityFieldManager->getFieldDefinitions('media', $bundle->id());
376 $media = $this->entityTypeManager->getStorage('media')->create(array('bundle' => $bundle->id()));
377 $value = (bool) $form_state->getValue(['options', 'status']);
378 if ($media->status->value != $value) {
379 $fields['status']->getConfig($bundle->id())->setDefaultValue($value)->save();
382 $form_state->setRedirectUrl($bundle->toUrl('collection'));