reverted: --- b/core/modules/media/config/optional/core.entity_form_mode.media.add_inline.yml +++ /dev/null @@ -1,9 +0,0 @@ -langcode: en -status: true -dependencies: - module: - - media -id: media.add_inline -label: 'File Upload' -targetEntityType: media -cache: true reverted: --- b/core/modules/media/src/Element/MediaManagedFile.php +++ /dev/null @@ -1,90 +0,0 @@ -getSource()->getConfiguration()['source_field']; - $media_source_values = $media_entity->get($media_source_field)->getValue(); - foreach ($media_source_values as $media_source_value) { - $value['fids'][] = $media_source_value['target_id']; - } - } - $element = parent::processManagedFile($element, $form_state, $complete_form); - - // We don't want to show the file-upload field for values that already have - // a file. - if (!empty($element['#files'])) { - $element['upload']['#access'] = FALSE; - } - - // $value['mids'] would have been set in MediaFileWidget::value() in the - // cases that a) the user has just uploaded a file or files, or b) they are - // viewing a form where a media item had been previously uploaded. - // @see Drupal\media\Plugin\Field\FieldWidget\MediaFileWidget::value() - $mids = isset($value['mids']) ? $value['mids'] : []; - $element['mids'] = [ - '#type' => 'hidden', - '#value' => $mids, - ]; - - return $element; - } - - /** - * Validates the media form using our custom form handler. - * - * @param array $entity_form - * The entity form. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The current state of the form. - */ - public static function validateEntityForm(array &$entity_form, FormStateInterface $form_state) { - \Drupal::entityTypeManager()->getHandler('media', 'add_inline') - ->entityFormValidate($entity_form, $form_state); - } - -} diff -u b/core/modules/media/src/Form/MediaInlineForm.php b/core/modules/media/src/Form/MediaInlineForm.php --- b/core/modules/media/src/Form/MediaInlineForm.php +++ b/core/modules/media/src/Form/MediaInlineForm.php @@ -4,11 +4,8 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\Entity\EntityFormDisplay; -use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -20,21 +17,7 @@ */ class MediaInlineForm implements EntityHandlerInterface { - /** - * The entity field manager. - * - * @var \Drupal\Core\Entity\EntityFieldManagerInterface - */ - protected $entityFieldManager; - - /** - * The entity type manager. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** + /** * The entity type managed by this handler. * * @var \Drupal\Core\Entity\EntityTypeInterface @@ -42,28 +25,12 @@ protected $entityType; /** - * Module handler service. - * - * @var \Drupal\Core\Extension\ModuleHandlerInterface - */ - protected $moduleHandler; - - /** * Constructs the inline entity form controller. * - * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager - * The entity field manager. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager. - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler. * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. */ - public function __construct(EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, EntityTypeInterface $entity_type) { - $this->entityFieldManager = $entity_field_manager; - $this->entityTypeManager = $entity_type_manager; - $this->moduleHandler = $module_handler; + public function __construct(EntityTypeInterface $entity_type) { $this->entityType = $entity_type; } @@ -71,12 +38,7 @@ * {@inheritdoc} */ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { - return new static( - $container->get('entity_field.manager'), - $container->get('entity_type.manager'), - $container->get('module_handler'), - $entity_type - ); + return new static($entity_type); } /** @@ -101,26 +63,28 @@ $entity = $entity_form['#entity']; $form_display = EntityFormDisplay::collectRenderDisplay($entity, $entity_form['#form_mode']); $form_display->buildForm($entity, $entity_form, $form_state); - $entity_form['#weight'] = 100; // In the service of keeping this form as user-friendly as possible in the // context of a parent entity form, only show required fields. /** @var \Drupal\Core\Field\BaseFieldDefinition $field_definition */ foreach ($entity->getFieldDefinitions() as $field_definition) { $field_name = $field_definition->getName(); - if (!$field_definition->isRequired()) { - $entity_form[$field_name]['#access'] = FALSE; - } - elseif (!empty($entity_form[$field_name])) { - // Elements with "#required" key set will always be validated, even if - // 'limit_validation_errors' is set. Disable their validation here, we - // will enforce validation happens inside the real submit handler. - $entity_form[$field_name] = $this->disableElementChildrenValidation($entity_form[$field_name]); + if (isset($entity_form[$field_name])) { + $entity_form[$field_name]['#access'] = $field_definition->isRequired(); + + if ($field_definition->isRequired()) { + // Elements with "#required" key set will always be validated, even if + // '#limit_validation_errors' is set. Disable their validation here, + // we will enforce validation happens inside the real submit handler. + $entity_form[$field_name] = $this->disableElementChildrenValidation($entity_form[$field_name]); + } } } - // The media name will be automatically populated by the source plugin, we + // The media name will be automatically populated by the source plugin. We // are OK with the default name in this case. - $entity_form['name']['#access'] = FALSE; + if (isset($entity_form['name'])) { + $entity_form['name']['#access'] = FALSE; + } // By this point it is expected that the source field has already been // populated, so hide it too. An example for the file widget can be found in @@ -132,19 +96,18 @@ // If this is an image media entity, and the image field on that entity has // either "Alt field required" or "Title field required", we take care of - // that in + // that in MediaImageWidget::process(). // @see \Drupal\media\Plugin\Field\FieldWidget\MediaImageWidget::process(). foreach (['#alt_field_required', '#title_field_required'] as $extra_image_field_attribute) { - if (!empty($entity_form[$source_field]['widget'][0][$extra_image_field_attribute])) { - $entity_form[$source_field]['widget'][0][$extra_image_field_attribute] = FALSE; + if (isset($entity_form[$source_field]['widget'][0][$extra_image_field_attribute])) { + $entity_form[$source_field]['widget'][0][$extra_image_field_attribute]['#access'] = FALSE; } } // Inline entities inherit the parent language, so hide translation-related // fields as well. - $langcode_key = $this->entityType->getKey('langcode'); - if ($langcode_key && isset($entity_form[$langcode_key])) { - $entity_form[$langcode_key]['#access'] = FALSE; + if (isset($entity_form['langcode'])) { + $entity_form['langcode']['#access'] = FALSE; } return $entity_form; @@ -159,46 +122,46 @@ * The form state of the parent form. */ public function entityFormValidate(array &$entity_form, FormStateInterface $form_state) { - $triggering_element = $form_state->getTriggeringElement(); // Perform entity validation only if the inline form was submitted, // skipping other requests such as file uploads. if (!$this->hostFormSubmitted($form_state)) { return; } $mids = []; - $form_mids = $form_state->getValue($entity_form['#field_name']); - if (!empty($form_mids)) { - foreach ($form_mids as $form_mid) { - if (!empty($form_mid['mids'][0])) { - $mids[] = $form_mid['mids'][0]; + // @todo use #parents if possible. + $field_values = $form_state->getValue($entity_form['#field_name']); + if ($field_values) { + foreach ($field_values as $field_value) { + if (!empty($field_value['mids'])) { + $mids[] = reset($field_value['mids']); } } } foreach ($mids as $mid) { $media_form_key = 'media_' . $mid; - if (empty($entity_form[$media_form_key]['media_form']['form'])) { + // @todo throw error in this case instead of quietly continuing. + if (empty($entity_form[$media_form_key]['form_wrapper']['form'])) { continue; } - $media_form = $entity_form[$media_form_key]['media_form']['form']; + $media_form = $entity_form[$media_form_key]['form_wrapper']['form']; /** @var \Drupal\media\MediaInterface $entity */ $entity = $media_form['#entity']; - if ($entity instanceof ContentEntityInterface) { - $this->buildEntity($media_form, $entity, $form_state); - $form_display = EntityFormDisplay::collectRenderDisplay($entity, $media_form['#form_mode']); - $form_display->validateFormValues($entity, $media_form, $form_state); - $entity->setValidationRequired(FALSE); - - foreach ($form_state->getErrors() as $name => $message) { - // $name may be unknown in $form_state and - // $form_state->setErrorByName($name, $message) may suppress the error - // message. - $form_state->setError($triggering_element, $message); - } - - // If no validation errors are present, set the media back to Published. - if (empty($form_state->getErrors())) { - $entity->setPublished()->save(); - } + $triggering_element = $form_state->getTriggeringElement(); + $this->buildEntity($media_form, $entity, $form_state); + $form_display = EntityFormDisplay::collectRenderDisplay($entity, $media_form['#form_mode']); + $form_display->validateFormValues($entity, $media_form, $form_state); + $entity->setValidationRequired(FALSE); + + foreach ($form_state->getErrors() as $name => $message) { + // $name may be unknown in $form_state and + // $form_state->setErrorByName($name, $message) may suppress the error + // message. + $form_state->setError($triggering_element, $message); + } + + // If no validation errors are present, set the media back to Published. + if (empty($form_state->getErrors())) { + $entity->setPublished()->save(); } } } @@ -227,7 +190,6 @@ return $element; } - /** * Builds an updated entity object based upon the submitted form values. * diff -u b/core/modules/media/src/Plugin/Field/FieldWidget/MediaFileWidget.php b/core/modules/media/src/Plugin/Field/FieldWidget/MediaFileWidget.php --- b/core/modules/media/src/Plugin/Field/FieldWidget/MediaFileWidget.php +++ b/core/modules/media/src/Plugin/Field/FieldWidget/MediaFileWidget.php @@ -2,20 +2,18 @@ namespace Drupal\media\Plugin\Field\FieldWidget; -use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\EntityFormInterface; +use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\ElementInfoManagerInterface; -use Drupal\Core\Render\RendererInterface; -use Drupal\file\Plugin\Field\FieldWidget; use Drupal\file\Plugin\Field\FieldWidget\FileWidget; -use Drupal\Core\Field\TypedData\FieldItemDataDefinition; -use Drupal\file\Plugin\Field\FieldType\FileItem; use Drupal\media\Entity\Media; use Drupal\media\Entity\MediaType; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Link; +use Drupal\media\Plugin\media\Source\File; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -32,18 +30,10 @@ class MediaFileWidget extends FileWidget { /** - * The renderer. - * - * @var \Drupal\Core\Render\RendererInterface - */ - protected $renderer; - - /** * {@inheritdoc} */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, ElementInfoManagerInterface $element_info, RendererInterface $renderer) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, ElementInfoManagerInterface $element_info) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings, $element_info); - $this->renderer = $renderer; } /** @@ -56,12 +46,23 @@ $configuration['field_definition'], $configuration['settings'], $configuration['third_party_settings'], - $container->get('element_info'), - $container->get('renderer') + $container->get('element_info') ); } /** + * Gets the default value structure this widget expects. + * + * @return array + */ + protected static function getDefaultValues() { + return [ + 'mids' => [], + 'fids' => [], + ]; + } + + /** * {@inheritdoc} * * Uses nearly the same code that FileWidget does here, except that we have to @@ -69,77 +70,51 @@ * location and upload validators. */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { - $field_settings = $this->getFieldSettings(); - - // The field settings include defaults for the field type. However, this - // widget is a base class for other widgets (e.g., ImageWidget) that may act - // on field types without these expected settings. - $field_settings += [ - 'display_default' => NULL, - 'display_field' => NULL, - 'description_field' => NULL, - ]; - - $defaults = [ - 'mids' => [], - 'fids' => [], - 'display' => (bool) $field_settings['display_default'], - 'description' => '', - ]; - - $target_bundle = array_shift($this->fieldDefinition->getSetting('handler_settings')['target_bundles']); + // We've ensured that there's only one target bundle. Get an instance of + // that bundle in order to get its source field. + // @see \Drupal\media\Plugin\Field\FieldWidget\MediaFileWidget::isApplicable() + $target_bundle = reset($this->fieldDefinition->getSetting('handler_settings')['target_bundles']); /** @var \Drupal\media\Entity\MediaType $media_type */ $media_type = MediaType::load($target_bundle); - $source = $media_type->getSource(); - $source_data_definition = FieldItemDataDefinition::create($source->getSourceFieldDefinition($media_type)); - $file_item = new FileItem($source_data_definition); - - $element_info = $this->elementInfo->getInfo('media_managed_file'); - $cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality(); + /** @var \Drupal\media\MediaInterface $media_item */ + $media_item = Media::create(['bundle' => $target_bundle]); + $source_field_definition = $media_item->getSource()->getSourceFieldDefinition($media_type); + $source_field_items = $media_item->get($source_field_definition->getName()); + $source_field_items->appendItem(); + + // Temporarily use the source field's fieldDefinition, so that + // FileWidget::formElement() returns a usable $element array. + // @see \Drupal\file\Plugin\Field\FieldWidget\FileWidget\FileWidget::formElement() + $real_field_definition = $this->fieldDefinition; + $this->fieldDefinition = $source_field_definition; + $element = parent::formElement($source_field_items, 0, $element, $form, $form_state); + $this->fieldDefinition = $real_field_definition; - $element += [ - '#type' => 'media_managed_file', - '#upload_location' => $file_item->getUploadLocation(), - '#upload_validators' => $file_item->getUploadValidators(), - '#value_callback' => [get_class($this), 'value'], - '#process' => array_merge($element_info['#process'], [[get_class($this), 'process']]), - '#progress_indicator' => $this->getSetting('progress_indicator'), - // Allows this field to return an array instead of a single value. - '#extended' => TRUE, - // Add properties needed by value() and process() methods. - '#field_name' => $this->fieldDefinition->getName(), - // This is actually talking about the entity type ON WHICH this field is - // placed, not the entity type TO WHICH it can refer. In fact, it seems - // only to be used, unnecessarily, on FileWidget::validateMultipleCount(). - '#entity_type' => $items->getEntity()->getEntityTypeId(), - '#display_field' => (bool) $field_settings['display_field'], - '#display_default' => $field_settings['display_default'], - '#description_field' => $field_settings['description_field'], - '#cardinality' => $cardinality, + // Now modify $element to account for the fact that it was originally built + // to reference file entities, whereas we are going to reference media + // entities. + $element['#element_validate'] = [ + [static::class, 'validateEntityForm'], ]; - + $element['#progress_indicator'] = $this->getSetting('progress_indicator'); + $element['#field_name'] = $this->fieldDefinition->getName(); $element['#weight'] = $delta; + // Accommodate multiple uploads, if field settings require it. + $cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality(); + $element['#cardinality'] = $cardinality; + $element['#multiple'] = $cardinality != 1 ? TRUE : FALSE; + if ($cardinality != 1 && $cardinality != -1) { + $element['#element_validate'][] = [static::class, 'validateMultipleCount']; + } + // Save mid, the target_id value that this field ultimately cares about. if (!isset($items[$delta]->mids) && isset($items[$delta]->target_id)) { $items[$delta]->mids = [$items[$delta]->target_id]; } - $element['#default_value'] = $items[$delta]->getValue() + $defaults; - $default_fids = $element['#extended'] ? $element['#default_value']['fids'] : $element['#default_value']; - if (empty($default_fids)) { - $file_upload_help = [ - '#theme' => 'file_upload_help', - '#description' => $element['#description'], - '#upload_validators' => $element['#upload_validators'], - '#cardinality' => $cardinality, - ]; - $element['#description'] = $this->renderer->renderPlain($file_upload_help); - $element['#multiple'] = $cardinality != 1 ? TRUE : FALSE; - if ($cardinality != 1 && $cardinality != -1) { - $element['#element_validate'][] = [get_class($this), 'validateMultipleCount']; - } - } + // Finally, fill in any needed defaults that haven't already been set. + $element['#default_value'] = $items[$delta]->getValue() + static::getDefaultValues(); return $element; } @@ -151,7 +126,7 @@ // Override FileWidget::massageFormValues() in order to reference Media // entities instead of files. $new_values = []; - foreach ($values as &$value) { + foreach ($values as $value) { $value['mids'] = !empty($value['mids']) ? $value['mids'] : []; foreach ($value['mids'] as $mid) { $new_value = $value; @@ -165,29 +140,48 @@ } /** - * Retrieves the value for the element. + * {@inheritdoc} */ public static function value($element, $input, FormStateInterface $form_state) { $return = parent::value($element, $input, $form_state); - if (empty($return['mids'])) { - $return['mids'] = []; + + $form_object = $form_state->getFormObject(); + if (!$form_object instanceOf EntityFormInterface) { + throw new \LogicException('We are in bat country.'); + } + + // Although this method is mainly used as a value callback for real user- + // entered values, it is also called when site builders are configuring the + // field. In that case, $host_entity won't be a FieldableEntityInterface; + // just return the default value structure. + $host_entity = $form_object->getEntity(); + if (!$host_entity instanceof FieldableEntityInterface) { + return static::getDefaultValues(); + } + // We're only allowing this widget to be used when there's a single target + // bundle. That means there's only one item in + // $handler_settings['target_bundles']. + // @see \Drupal\media\Plugin\Field\FieldWidget\MediaFileWidget::isApplicable() + $handler_settings = $host_entity->getFieldDefinitions()[$element['#field_name']]->getSetting('handler_settings'); + $media_type = reset($handler_settings['target_bundles']); + + // This widget target media references. Our element (managed_file) needs + // file ids, so load the file id for it to use. + $get_fid = isset($return['target_id']) && empty($return['fids']); + + // The user has just uploaded file(s); create media accordingly. + $create_media = $input && empty($element['#default_value']['mids']) && !empty($return['fids']); + + // The host form is now being saved with newly-created media entities. They + // might have required field values to save, so save those. + $resave_media = !empty($input['mids']); + + if ($get_fid) { + $media_entity = Media::load($element['#default_value']['target_id']); + $return['fids'][] = $media_entity->getSource()->getSourceFieldValue($media_entity); } - $media_type = FALSE; - $host_entity = $form_state->getFormObject()->getEntity(); - if ($host_entity && $host_entity instanceof ContentEntityInterface) { - $handler_settings = $host_entity->getFieldDefinitions()[$element['#field_name']]->getSetting('handler_settings'); - // If this field happens to point to multiple media types (bundles), just - // use the first one that implements a file source. - $media_type = !empty($handler_settings['target_bundles']) ? self::getFileMediaTypeFromSet($handler_settings['target_bundles']) : FALSE; - } - - // When the form has just been submitted with file(s) being uploaded, - // $input['mids'] should be empty. FileWidget::value() calls - // ManagedFile::valueCallback(), which populates $return['fids']. If there's - // info in there AND we're not doing the subsequent form rebuild, it's time - // to make the media. - if (empty($input['mids']) && !empty($return['fids']) && !$form_state->isRebuilding() && $media_type) { + if ($create_media) { foreach ($return['fids'] as $fid) { /** @var \Drupal\media\MediaInterface $media_entity */ $media_entity = Media::create([ @@ -208,7 +202,8 @@ $return['mids'][] = $media_entity->id(); } } - elseif (!empty($input['mids'])) { + + if ($resave_media) { $mid = $input['mids']; $media_fields_key = 'media_' . $mid; @@ -234,50 +229,75 @@ */ public static function process($element, FormStateInterface $form_state, $form) { $element = parent::process($element, $form_state, $form); + + // For readability, working with $value rather than $element['#value']. For + // how $element['#value'] gets set, see massageFormValues() in our related + // classes. + // * @see \Drupal\media\Plugin\Field\FieldWidget\MediaFileWidget::massageFormValues() + // * @see \Drupal\file\Plugin\Field\FieldWidget\FileWidget::massageFormValues() + $value = isset($element['#value']) ? $element['#value'] : []; + + // $value['mids'] would have been set in MediaFileWidget::value() in the + // cases that a) the user has just uploaded a file or files, or b) they are + // viewing a form where a media item had been previously uploaded. + // @see \Drupal\media\Plugin\Field\FieldWidget\MediaFileWidget::value() + $mids = isset($value['mids']) ? $value['mids'] : []; + $element['mids'] = [ + '#type' => 'hidden', + '#value' => $mids, + ]; + $mid = FALSE; $show_form = FALSE; - if (!empty($element['#value']['target_id'])) { - // This is an existing entity ref and we're loading the edit page the - // first time. Just show the icon and name. - $mid = $element['#value']['target_id']; + if (!empty($value['target_id'])) { + // When a media entity reference value was previously saved, then loaded + // again on this host entity form, it has this 'target_id' key. So we know + // this is an existing entity ref; just show the icon and name. + $mid = $value['target_id']; } - elseif (!empty($element['#value']['mids']) && count($element['#value']['mids']) === 1) { + elseif (!empty($value['mids']) && count($value['mids']) === 1) { // If $element['mids']['#value'] has multiple values, that means this is // the first pass after someone uploaded several files; ignore. If it has // only ONE, then this media entity was just created and we want to force // the user to fill out all the new entity's required fields. I.e., show // the form, as well as the standard icon and name. - $mid = $element['#value']['mids'][0]; + $mid = reset($value['mids']); - if (empty($element['#value']['media_already_saved'])) { + if (empty($value['media_already_saved'])) { $show_form = TRUE; } } + // $mid can be false here, in the event that this value is the final one + // for the media_managed_file element. That value becomes the upload button. if ($mid) { - // First, get rid of the file link that FileManaged has created, and - // replace with a media-entity link. - $fid = $element['#value']['fids'][0]; + // First, get rid of the file link that FileManaged has created. + $fid = reset($value['fids']); unset($element['file_' . $fid]); + // Under some circumstances this button said "remove selected," but since // we just removed the checkbox this button should instead always just say // "remove." $element['remove_button']['#value'] = t('Remove'); + // Also hide the upload button. + $element['upload']['#access'] = FALSE; // Now show the media icon and name. $form_element_name = 'media_' . $mid; $form_element_parents = array_merge($element['#parents'], [$form_element_name]); $media_entity = Media::load($mid); - $element[$form_element_name]['media_icon'] = [ + // @todo: entity query to be sure whether or not thumbnail image style + // actually exists. If not stick the user with the "original" image style. + $element[$form_element_name]['icon'] = [ '#theme' => 'image_style', '#style_name' => 'thumbnail', '#uri' => $media_entity->getSource()->getMetadata($media_entity, 'thumbnail_uri'), '#weight' => -20, ]; $link_build = Link::createFromRoute($media_entity->getName(), 'entity.media.canonical', ['media' => $mid])->toRenderable(); - $element[$form_element_name]['media_name'] = $link_build + ['#weight' => -10]; + $element[$form_element_name]['link'] = $link_build + ['#weight' => -10]; if ($show_form) { // Create and add the media entity form. @@ -290,7 +310,7 @@ $inline_form_handler = \Drupal::entityTypeManager() ->getHandler('media', $form_mode); $media_form = $inline_form_handler->entityForm($media_form, $form_state); - $element[$form_element_name]['media_form'] = [ + $element[$form_element_name]['form_wrapper'] = [ '#type' => 'container', 'form' => $media_form, ]; @@ -301,6 +321,19 @@ } /** + * Validates the media form using our custom form handler. + * + * @param array $entity_form + * The entity form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + */ + public static function validateEntityForm(array &$entity_form, FormStateInterface $form_state) { + \Drupal::entityTypeManager()->getHandler('media', 'add_inline') + ->entityFormValidate($entity_form, $form_state); + } + + /** * Form submission handler for upload/remove button of formElement(). * * Overrides FileWidget::submit(), performing the exact same functionality, @@ -360,7 +393,7 @@ /** * {@inheritdoc} */ - public static function isApplicable(FieldDefinitionInterface $field_definition) { + public static final function isApplicable(FieldDefinitionInterface $field_definition) { // This widget is restricted to entity_reference fields pointing to media // entities. if ($field_definition->getSetting('target_type') !== 'media') { @@ -377,7 +410,7 @@ $media_type = MediaType::load($type_name); if ($media_type) { $source = $media_type->getSource(); - if (is_a($source, '\Drupal\media\Plugin\media\Source\File')) { + if ($source instanceof File) { return TRUE; } } @@ -387,30 +420,2 @@ - /** - * Given a set of media types, fetch the first one with a File source. - * - * @param array $types - * An array where the values are media type IDs. - * - * @return bool|string - * The ID of the first type found (from the set passed in) with a source - * plugin that implements - * \Drupal\media\Plugin\media\Source\File, or FALSE if none found. - */ - public static function getFileMediaTypeFromSet(array $types) { - $media_types = MediaType::loadMultiple($types); - if (!$media_types) { - return FALSE; - } - - foreach ($media_types as $media_type) { - /** @var \Drupal\media\MediaTypeInterface $media_type */ - $source = $media_type->getSource(); - if (is_a($source, '\Drupal\media\Plugin\media\Source\File')) { - return $media_type->id(); - } - } - - return FALSE; - } - } only in patch2: unchanged: --- /dev/null +++ b/core/modules/media/config/install/core.entity_form_mode.media.add_inline.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: + module: + - media +id: media.add_inline +label: 'File Upload' +targetEntityType: media +cache: true