You are here

class FilebrowserManagedFile in Filebrowser 8.2

Same name and namespace in other branches
  1. 3.x src/Element/FilebrowserManagedFile.php \Drupal\filebrowser\Element\FilebrowserManagedFile

Provides an AJAX/progress aware widget for uploading and saving a file.

Plugin annotation

@FormElement("filebrowser_managed_file");

Hierarchy

Expanded class hierarchy of FilebrowserManagedFile

1 #type use of FilebrowserManagedFile
UploadForm::buildForm in src/Form/UploadForm.php
Form constructor.

File

src/Element/FilebrowserManagedFile.php, line 21

Namespace

Drupal\filebrowser\Element
View source
class FilebrowserManagedFile extends ManagedFile {

  /**
   * @inheritDoc
   */
  public function getInfo() {
    $array = parent::getInfo();
    $array['#multiple'] = true;
    return $array;
  }
  protected static function custom_file_managed_file_save_upload($element, FormStateInterface $form_state) {
    $upload_name = implode('_', $element['#parents']);
    $all_files = \Drupal::request()->files
      ->get('files', array());
    if (empty($all_files[$upload_name])) {
      return FALSE;
    }
    $file_upload = $all_files[$upload_name];
    $destination = isset($element['#upload_location']) ? $element['#upload_location'] : NULL;
    if (isset($destination) && !\Drupal::service('file_system')
      ->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {
      \Drupal::logger('file')
        ->notice('The upload directory %directory for the file field %name could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.', array(
        '%directory' => $destination,
        '%name' => $element['#field_name'],
      ));
      $form_state
        ->setError($element, t('The file could not be uploaded.'));
      return FALSE;
    }

    // Save attached files to the database.
    $files_uploaded = $element['#multiple'] && count(array_filter($file_upload)) > 0;
    $files_uploaded |= !$element['#multiple'] && !empty($file_upload);
    if ($files_uploaded) {
      $nid = \Drupal::routeMatch()
        ->getParameter('nid');
      if (ctype_digit($nid)) {
        $node = Node::load($nid);
      }
      else {
        $node = null;
      }
      if ($node instanceof NodeInterface) {
        $config = \Drupal::config('filebrowser.settings');
        $config = $config
          ->get('filebrowser');
        $nodeValues = isset($node->filebrowser) ? $node->filebrowser : null;
        $allowOverwrite = isset($nodeValues->allowOverwrite) ? $nodeValues->allowOverwrite : $config['uploads']['allow_overwrite'];
        if ($allowOverwrite) {
          $files = file_save_upload($upload_name, $element['#upload_validators'], $destination, null, FileSystem::EXISTS_REPLACE);
        }
        else {
          $files = file_save_upload($upload_name, $element['#upload_validators'], $destination);
        }
      }
      else {
        $files = file_save_upload($upload_name, $element['#upload_validators'], $destination);
      }
      if (!$files) {
        \Drupal::logger('file')
          ->notice('The file upload failed. %upload', array(
          '%upload' => $upload_name,
        ));
        $form_state
          ->setError($element, t('Files in the @name field were unable to be uploaded.', array(
          '@name' => $element['#title'],
        )));
        return array();
      }

      // Value callback expects FIDs to be keys.
      $files = array_filter($files);
      $fids = array_map(function ($file) {
        return $file
          ->id();
      }, $files);
      return empty($files) ? array() : array_combine($fids, $files);
    }
    return array();
  }

  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {

    // Find the current value of this field.
    $fids = !empty($input['fids']) ? explode(' ', $input['fids']) : [];
    foreach ($fids as $key => $fid) {
      $fids[$key] = (int) $fid;
    }
    $force_default = FALSE;

    // Process any input and save new uploads.
    if ($input !== FALSE) {
      $input['fids'] = $fids;
      $return = $input;

      // Uploads take priority over all other values.
      if ($files = self::custom_file_managed_file_save_upload($element, $form_state)) {
        if ($element['#multiple']) {
          $fids = array_merge($fids, array_keys($files));
        }
        else {
          $fids = array_keys($files);
        }
      }
      else {

        // Check for #filefield_value_callback values.
        // Because FAPI does not allow multiple #value_callback values like it
        // does for #element_validate and #process, this fills the missing
        // functionality to allow File fields to be extended through FAPI.
        if (isset($element['#file_value_callbacks'])) {
          foreach ($element['#file_value_callbacks'] as $callback) {
            $callback($element, $input, $form_state);
          }
        }

        // Load files if the FIDs have changed to confirm they exist.
        if (!empty($input['fids'])) {
          $fids = [];
          foreach ($input['fids'] as $fid) {
            if ($file = File::load($fid)) {
              $fids[] = $file
                ->id();

              // Temporary files that belong to other users should never be
              // allowed.
              if ($file
                ->isTemporary()) {
                if ($file
                  ->getOwnerId() != \Drupal::currentUser()
                  ->id()) {
                  $force_default = TRUE;
                  break;
                }
                elseif (\Drupal::currentUser()
                  ->isAnonymous()) {
                  $token = NestedArray::getValue($form_state
                    ->getUserInput(), array_merge($element['#parents'], [
                    'file_' . $file
                      ->id(),
                    'fid_token',
                  ]));
                  if ($token !== Crypt::hmacBase64('file-' . $file
                    ->id(), \Drupal::service('private_key')
                    ->get() . Settings::getHashSalt())) {
                    $force_default = TRUE;
                    break;
                  }
                }
              }
            }
          }
          if ($force_default) {
            $fids = [];
          }
        }
      }
    }

    // If there is no input or if the default value was requested above, use the
    // default value.
    if ($input === FALSE || $force_default) {
      if ($element['#extended']) {
        $default_fids = isset($element['#default_value']['fids']) ? $element['#default_value']['fids'] : [];
        $return = isset($element['#default_value']) ? $element['#default_value'] : [
          'fids' => [],
        ];
      }
      else {
        $default_fids = isset($element['#default_value']) ? $element['#default_value'] : [];
        $return = [
          'fids' => [],
        ];
      }

      // Confirm that the file exists when used as a default value.
      if (!empty($default_fids)) {
        $fids = [];
        foreach ($default_fids as $fid) {
          if ($file = File::load($fid)) {
            $fids[] = $file
              ->id();
          }
        }
      }
    }
    $return['fids'] = $fids;
    return $return;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FilebrowserManagedFile::custom_file_managed_file_save_upload protected static function
FilebrowserManagedFile::getInfo public function @inheritDoc Overrides ManagedFile::getInfo
FilebrowserManagedFile::valueCallback public static function Determines how user input is mapped to an element's #value property. Overrides ManagedFile::valueCallback
FormElement::processAutocomplete public static function Adds autocomplete functionality to elements.
FormElement::processPattern public static function #process callback for #pattern form element property.
FormElement::validatePattern public static function #element_validate callback for #pattern form element property.
ManagedFile::fileUsage protected static function Wraps the file usage service.
ManagedFile::preRenderManagedFile public static function Render API callback: Hides display of the upload or remove controls.
ManagedFile::processManagedFile public static function Render API callback: Expands the managed_file element type.
ManagedFile::uploadAjaxCallback public static function #ajax callback for managed_file upload forms.
ManagedFile::validateManagedFile public static function Render API callback: Validates the managed_file element.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. 92
RenderElement::preRenderAjaxForm public static function Adds Ajax information about an element to communicate with JavaScript.
RenderElement::preRenderGroup public static function Adds members of this group as actual elements for rendering.
RenderElement::processAjaxForm public static function Form element processing handler for the #ajax form property. 1
RenderElement::processGroup public static function Arranges elements into groups.
RenderElement::setAttributes public static function Sets a form element's class attribute. Overrides ElementInterface::setAttributes
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.