file.field.inc 6.72 KB
Newer Older
1 2 3 4 5 6 7
<?php

/**
 * @file
 * Field module functionality for the File module.
 */

8
use Drupal\Core\Field\FieldDefinitionInterface;
9
use Drupal\Core\Field\FieldFilteredMarkup;
10
use Drupal\Core\Render\Element;
11

12
/**
13 14 15
 * Prepares variables for multi file form widget templates.
 *
 * Default template: file-widget-multiple.html.twig.
16
 *
17
 * @param array $variables
18 19
 *   An associative array containing:
 *   - element: A render element representing the widgets.
20
 */
21
function template_preprocess_file_widget_multiple(&$variables) {
22 23
  $element = $variables['element'];

24 25 26 27 28 29 30
  // Special ID and classes for draggable tables.
  $weight_class = $element['#id'] . '-weight';
  $table_id = $element['#id'] . '-table';

  // Build up a table of applicable fields.
  $headers = array();
  $headers[] = t('File information');
31
  if ($element['#display_field']) {
32 33 34 35 36 37 38 39
    $headers[] = array(
      'data' => t('Display'),
      'class' => array('checkbox'),
    );
  }
  $headers[] = t('Weight');
  $headers[] = t('Operations');

40 41 42
  // Get our list of widgets in order (needed when the form comes back after
  // preview or failed validation).
  $widgets = array();
43
  foreach (Element::children($element) as $key) {
44 45
    $widgets[] = &$element[$key];
  }
46
  usort($widgets, '_field_multiple_value_form_sort_helper');
47

48
  $rows = array();
49
  foreach ($widgets as $key => &$widget) {
50
    // Save the uploading row for last.
51
    if (empty($widget['#files'])) {
52
      $widget['#title'] = $element['#file_upload_title'];
53
      $widget['#description'] = \Drupal::service('renderer')->renderPlain($element['#file_upload_description']);
54 55 56
      continue;
    }

57 58 59
    // Delay rendering of the buttons, so that they can be rendered later in the
    // "operations" column.
    $operations_elements = array();
60
    foreach (Element::children($widget) as $sub_key) {
61 62 63
      if (isset($widget[$sub_key]['#type']) && $widget[$sub_key]['#type'] == 'submit') {
        hide($widget[$sub_key]);
        $operations_elements[] = &$widget[$sub_key];
64 65 66
      }
    }

67 68 69
    // Delay rendering of the "Display" option and the weight selector, so that
    // each can be rendered later in its own column.
    if ($element['#display_field']) {
70
      hide($widget['display']);
71
    }
72
    hide($widget['_weight']);
73 74

    // Render everything else together in a column, without the normal wrappers.
75
    $widget['#theme_wrappers'] = array();
76
    $information = \Drupal::service('renderer')->render($widget);
77
    $display = '';
78
    if ($element['#display_field']) {
79
      unset($widget['display']['#title']);
80
      $display = array(
81
        'data' => render($widget['display']),
82 83 84
        'class' => array('checkbox'),
      );
    }
85 86
    $widget['_weight']['#attributes']['class'] = array($weight_class);
    $weight = render($widget['_weight']);
87

88
    // Arrange the row with all of the rendered columns.
89 90
    $row = array();
    $row[] = $information;
91
    if ($element['#display_field']) {
92 93 94
      $row[] = $display;
    }
    $row[] = $weight;
95 96 97 98 99 100 101 102 103

    // Show the buttons that had previously been marked as hidden in this
    // preprocess function. We use show() to undo the earlier hide().
    foreach (Element::children($operations_elements) as $key) {
      show($operations_elements[$key]);
    }
    $row[] = array(
      'data' => $operations_elements,
    );
104 105
    $rows[] = array(
      'data' => $row,
106
      'class' => isset($widget['#attributes']['class']) ? array_merge($widget['#attributes']['class'], array('draggable')) : array('draggable'),
107 108 109
    );
  }

110
  $variables['table'] = array(
111
    '#type' => 'table',
112 113 114 115 116
    '#header' => $headers,
    '#rows' => $rows,
    '#attributes' => array(
      'id' => $table_id,
    ),
117 118 119 120 121 122 123
    '#tabledrag' => array(
      array(
        'action' => 'order',
        'relationship' => 'sibling',
        'group' => $weight_class,
      ),
    ),
124
    '#access' => !empty($rows),
125 126
  );

127
  $variables['element'] = $element;
128 129 130
}

/**
131
 * Prepares variables for file upload help text templates.
132
 *
133 134 135
 * Default template: file-upload-help.html.twig.
 *
 * @param array $variables
136 137 138 139 140
 *   An associative array containing:
 *   - description: The normal description for this field, specified by the
 *     user.
 *   - upload_validators: An array of upload validators as used in
 *     $element['#upload_validators'].
141
 */
142
function template_preprocess_file_upload_help(&$variables) {
143 144
  $description = $variables['description'];
  $upload_validators = $variables['upload_validators'];
145
  $cardinality = $variables['cardinality'];
146

147 148
  $descriptions = array();

149
  if (!empty($description)) {
150
    $descriptions[] = FieldFilteredMarkup::create($description);
151
  }
152 153 154 155 156
  if (isset($cardinality)) {
    if ($cardinality == -1) {
      $descriptions[] = t('Unlimited number of files can be uploaded to this field.');
    }
    else {
157
      $descriptions[] = \Drupal::translation()->formatPlural($cardinality, 'One file only.', 'Maximum @count files.');
158 159
    }
  }
160
  if (isset($upload_validators['file_validate_size'])) {
161
    $descriptions[] = t('@size limit.', array('@size' => format_size($upload_validators['file_validate_size'][0])));
162 163
  }
  if (isset($upload_validators['file_validate_extensions'])) {
164
    $descriptions[] = t('Allowed types: @extensions.', array('@extensions' => $upload_validators['file_validate_extensions'][0]));
165 166
  }

167 168 169 170
  if (isset($upload_validators['file_validate_image_resolution'])) {
    $max = $upload_validators['file_validate_image_resolution'][0];
    $min = $upload_validators['file_validate_image_resolution'][1];
    if ($min && $max && $min == $max) {
171
      $descriptions[] = t('Images must be exactly <strong>@size</strong> pixels.', array('@size' => $max));
172 173
    }
    elseif ($min && $max) {
174
      $descriptions[] = t('Images must be larger than <strong>@min</strong> pixels. Images larger than <strong>@max</strong> pixels will be resized.', array('@min' => $min, '@max' => $max));
175 176
    }
    elseif ($min) {
177
      $descriptions[] = t('Images must be larger than <strong>@min</strong> pixels.', array('@min' => $min));
178 179
    }
    elseif ($max) {
180
      $descriptions[] = t('Images larger than <strong>@max</strong> pixels will be resized.', array('@max' => $max));
181 182 183
    }
  }

184
  $variables['descriptions'] = $descriptions;
185 186
}

187 188 189
/**
 * Determine whether a field references files stored in {file_managed}.
 *
190
 * @param \Drupal\Core\Field\FieldDefinitionInterface $field
191
 *   A field definition.
192
 *
193
 * @return bool
194
 *   The field column if the field references {file_managed}.fid, typically
195
 *   fid, FALSE if it does not.
196
 */
197
function file_field_find_file_reference_column(FieldDefinitionInterface $field) {
198
  $schema = $field->getFieldStorageDefinition()->getSchema();
199
  foreach ($schema['foreign keys'] as $data) {
200 201 202 203 204 205 206 207 208 209
    if ($data['table'] == 'file_managed') {
      foreach ($data['columns'] as $field_column => $column) {
        if ($column == 'fid') {
          return $field_column;
        }
      }
    }
  }
  return FALSE;
}