entity_browser-8.x-2.x-dev/src/Plugin/EntityBrowser/Widget/Upload.php
src/Plugin/EntityBrowser/Widget/Upload.php
<?php namespace Drupal\entity_browser\Plugin\EntityBrowser\Widget; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; use Drupal\entity_browser\WidgetBase; use Drupal\file\FileInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Adds an upload field browser's widget. * * @EntityBrowserWidget( * id = "upload", * label = @Translation("Upload"), * description = @Translation("Adds an upload field browser's widget."), * auto_select = FALSE * ) */ class Upload extends WidgetBase { /** * The module handler service. * * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected $moduleHandler; /** * The token service. * * @var \Drupal\Core\Utility\Token */ protected $token; /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); $instance->moduleHandler = $container->get('module_handler'); $instance->token = $container->get('token'); return $instance; } /** * {@inheritdoc} */ public function defaultConfiguration() { return array_merge(parent::defaultConfiguration(), [ 'submit_text' => $this->t('Select files'), 'upload_location' => 'public://', 'multiple' => TRUE, 'extensions' => 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp', ]); } /** * {@inheritdoc} */ public function getForm(array &$original_form, FormStateInterface $form_state, array $additional_widget_parameters) { $form = parent::getForm($original_form, $form_state, $additional_widget_parameters); $field_cardinality = $form_state->get(['entity_browser', 'validators', 'cardinality', 'cardinality']); $upload_validators = $form_state->has(['entity_browser', 'widget_context', 'upload_validators']) ? $form_state->get(['entity_browser', 'widget_context', 'upload_validators']) : []; $form['upload'] = [ '#type' => 'managed_file', '#title' => $this->t('Choose a file'), '#title_display' => 'invisible', '#upload_location' => $this->token->replace($this->configuration['upload_location']), // Multiple uploads will only be accepted if the source field allows // more than one value. '#multiple' => $field_cardinality != 1 && $this->configuration['multiple'], '#upload_validators' => array_merge([ 'FileExtension' => ['extensions' => $this->configuration['extensions']], ], $upload_validators), ]; return $form; } /** * {@inheritdoc} */ protected function prepareEntities(array $form, FormStateInterface $form_state) { $files = []; foreach ($form_state->getValue(['upload'], []) as $fid) { $files[] = $this->entityTypeManager->getStorage('file')->load($fid); } return $files; } /** * {@inheritdoc} */ public function submit(array &$element, array &$form, FormStateInterface $form_state) { if (!empty($form_state->getTriggeringElement()['#eb_widget_main_submit'])) { $files = $this->prepareEntities($form, $form_state); array_walk( $files, function (FileInterface $file) { $file->setPermanent(); $file->save(); } ); $this->selectEntities($files, $form_state); $this->clearFormValues($element, $form_state); } } /** * Clear values from upload form element. * * @param array $element * Upload form element. * @param \Drupal\Core\Form\FormStateInterface $form_state * Form state object. */ protected function clearFormValues(array &$element, FormStateInterface $form_state) { // We propagated entities to the other parts of the system. We can now remove // them from our values. $form_state->setValueForElement($element['upload']['fids'], ''); NestedArray::setValue($form_state->getUserInput(), $element['upload']['fids']['#parents'], ''); } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); $form['upload_location'] = [ '#type' => 'textfield', '#title' => $this->t('Upload location'), '#default_value' => $this->configuration['upload_location'], ]; $form['multiple'] = [ '#type' => 'checkbox', '#title' => $this->t('Accept multiple files'), '#default_value' => $this->configuration['multiple'], '#description' => $this->t('Multiple uploads will only be accepted if the source field allows more than one value.'), ]; $form['extensions'] = [ '#type' => 'textfield', '#title' => $this->t('Allowed file extensions'), '#description' => $this->t('Separate extensions with a space or comma and do not include the leading dot.'), '#default_value' => $this->configuration['extensions'], '#element_validate' => [[static::class, 'validateExtensions']], '#required' => TRUE, ]; if ($this->moduleHandler->moduleExists('token')) { $form['token_help'] = [ '#theme' => 'token_tree_link', '#token_types' => ['file'], ]; $form['upload_location']['#description'] = $this->t('You can use tokens in the upload location.'); } return $form; } /** * Validates a list of file extensions. * * @See \Drupal\file\Plugin\Field\FieldType\FileItem::validateExtensions */ public static function validateExtensions($element, FormStateInterface $form_state) { if (!empty($element['#value'])) { $extensions = preg_replace('/([, ]+\.?)/', ' ', trim(strtolower($element['#value']))); $extensions = array_filter(explode(' ', $extensions)); $extensions = implode(' ', array_unique($extensions)); if (!preg_match('/^([a-z0-9]+([.][a-z0-9])* ?)+$/', $extensions)) { $form_state->setError($element, t('The list of allowed extensions is not valid, be sure to exclude leading dots and to separate extensions with a comma or space.')); } else { $form_state->setValueForElement($element, $extensions); } } } }