You are here

function filefield_sources_field_process in FileField Sources 8

Same name and namespace in other branches
  1. 6 filefield_sources.module \filefield_sources_field_process()
  2. 7 filefield_sources.module \filefield_sources_field_process()

A #process callback to extend the filefield_widget element type.

Add the central JavaScript and CSS files that allow switching between different sources. Third-party modules can also add to the list of sources by implementing hook_filefield_sources_info().

1 string reference to 'filefield_sources_field_process'
filefield_sources_element_info_alter in ./filefield_sources.module
Implements hook_element_info_alter().

File

./filefield_sources.module, line 155
Extend FileField to allow files from multiple sources.

Code

function filefield_sources_field_process(&$element, FormStateInterface $form_state, &$complete_form) {
  static $js_added;

  // Check if we are processing file field sources.
  if (!isset($element['#filefield_sources_settings'])) {
    return $element;
  }

  // Do all processing as needed by each source.
  $sources = filefield_sources_info();
  $settings = $element['#filefield_sources_settings'];
  $enabled_sources = _filefield_sources_enabled($settings);
  $context = [
    'enabled_sources' => &$enabled_sources,
    'element' => $element,
    'form_state' => $form_state,
  ];

  // Allow other modules to alter the sources.
  \Drupal::moduleHandler()
    ->alter('filefield_sources_sources', $sources, $context);
  foreach ($sources as $source_name => $source) {
    if (empty($enabled_sources[$source_name])) {
      unset($sources[$source_name]);
    }
    elseif (isset($source['class'])) {
      $callback = [
        $source['class'],
        'process',
      ];
      if (is_callable($callback)) {
        $element = call_user_func_array($callback, [
          &$element,
          $form_state,
          &$complete_form,
        ]);
      }
    }
  }
  $element['#filefield_sources'] = $sources;

  // Exit out if not adding any sources.
  if (empty($sources)) {
    return $element;
  }

  // Hide default 'upload' type?
  if (!isset($enabled_sources['upload'])) {
    foreach ([
      'upload_button',
      'upload',
    ] as $field) {
      if (isset($element[$field])) {
        $element[$field]['#access'] = FALSE;
      }
    }
  }

  // Add class to upload button.
  $element['upload_button']['#attributes']['class'][] = 'upload-button';
  $element['#attached']['library'][] = 'filefield_sources/drupal.filefield_sources';

  // Check the element for hint text that might need to be added.
  foreach (Element::children($element) as $key) {
    if (isset($element[$key]['#filefield_sources_hint_text']) && !isset($js_added[$key])) {
      $type = str_replace('filefield_', '', $key);
      $element['#attached']['drupalSettings']['fileFieldSources'][$type] = [
        'hintText' => $element[$key]['#filefield_sources_hint_text'],
      ];
      $js_added[$key] = TRUE;
    }
  }

  // Adjust the Ajax settings so that on upload and remove of any individual
  // file, the entire group of file fields is updated together.
  // Clone of Drupal\file\Plugin\Field\FieldWidget\FileWidget::process().
  if ($element['#cardinality'] != 1) {
    $parents = array_slice($element['#array_parents'], 0, -1);
    $new_options = [
      'query' => [
        'element_parents' => implode('/', $parents),
      ],
    ];
    $field_element = NestedArray::getValue($complete_form, $parents);
    $new_wrapper = $field_element['#id'] . '-ajax-wrapper';
    foreach (Element::children($element) as $key) {
      foreach (Element::children($element[$key]) as $subkey) {
        if (isset($element[$key][$subkey]['#ajax'])) {
          $element[$key][$subkey]['#ajax']['options'] = $new_options;
          $element[$key][$subkey]['#ajax']['wrapper'] = $new_wrapper;
          $element[$key][$subkey]['#limit_validation_errors'] = [
            array_slice($element['#array_parents'], 0, -2),
          ];
        }
      }
    }
    unset($element['#prefix'], $element['#suffix']);
  }

  // Add the list of sources to the element for toggling between sources.
  if (empty($element['fids']['#value'])) {
    if (count($enabled_sources) > 1) {
      $element['filefield_sources_list'] = [
        '#theme' => 'filefield_sources_list',
        '#id' => $element['#id'],
        '#sources' => $sources,
        '#weight' => -20,
      ];
    }
  }
  return $element;
}