5 * 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;
13 * Prepares variables for multi file form widget templates.
15 * Default template: file-widget-multiple.html.twig.
17 * @param array $variables
18 * An associative array containing:
19 * - element: A render element representing the widgets.
21 function template_preprocess_file_widget_multiple(&$variables) {
22 $element = $variables['element'];
24 // Special ID and classes for draggable tables.
25 $weight_class = $element['#id'] . '-weight';
26 $table_id = $element['#id'] . '-table';
28 // Build up a table of applicable fields.
30 $headers[] = t('File information');
31 if ($element['#display_field']) {
33 'data' => t('Display'),
34 'class' => ['checkbox'],
37 $headers[] = t('Weight');
38 $headers[] = t('Operations');
40 // Get our list of widgets in order (needed when the form comes back after
41 // preview or failed validation).
43 foreach (Element::children($element) as $key) {
44 $widgets[] = &$element[$key];
46 usort($widgets, '_field_multiple_value_form_sort_helper');
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']);
57 // Delay rendering of the buttons, so that they can be rendered later in the
58 // "operations" column.
59 $operations_elements = [];
60 foreach (Element::children($widget) as $sub_key) {
61 if (isset($widget[$sub_key]['#type']) && $widget[$sub_key]['#type'] == 'submit') {
62 hide($widget[$sub_key]);
63 $operations_elements[] = &$widget[$sub_key];
67 // Delay rendering of the "Display" option and the weight selector, so that
68 // each can be rendered later in its own column.
69 if ($element['#display_field']) {
70 hide($widget['display']);
72 hide($widget['_weight']);
74 // Render everything else together in a column, without the normal wrappers.
75 $widget['#theme_wrappers'] = [];
76 $information = \Drupal::service('renderer')->render($widget);
78 if ($element['#display_field']) {
79 unset($widget['display']['#title']);
81 'data' => render($widget['display']),
82 'class' => ['checkbox'],
85 $widget['_weight']['#attributes']['class'] = [$weight_class];
86 $weight = render($widget['_weight']);
88 // Arrange the row with all of the rendered columns.
90 $row[] = $information;
91 if ($element['#display_field']) {
96 // Show the buttons that had previously been marked as hidden in this
97 // preprocess function. We use show() to undo the earlier hide().
98 foreach (Element::children($operations_elements) as $key) {
99 show($operations_elements[$key]);
102 'data' => $operations_elements,
106 'class' => isset($widget['#attributes']['class']) ? array_merge($widget['#attributes']['class'], ['draggable']) : ['draggable'],
110 $variables['table'] = [
112 '#header' => $headers,
120 'relationship' => 'sibling',
121 'group' => $weight_class,
124 '#access' => !empty($rows),
127 $variables['element'] = $element;
131 * Prepares variables for file upload help text templates.
133 * Default template: file-upload-help.html.twig.
135 * @param array $variables
136 * An associative array containing:
137 * - description: The normal description for this field, specified by the
139 * - upload_validators: An array of upload validators as used in
140 * $element['#upload_validators'].
142 function template_preprocess_file_upload_help(&$variables) {
143 $description = $variables['description'];
144 $upload_validators = $variables['upload_validators'];
145 $cardinality = $variables['cardinality'];
149 if (!empty($description)) {
150 $descriptions[] = FieldFilteredMarkup::create($description);
152 if (isset($cardinality)) {
153 if ($cardinality == -1) {
154 $descriptions[] = t('Unlimited number of files can be uploaded to this field.');
157 $descriptions[] = \Drupal::translation()->formatPlural($cardinality, 'One file only.', 'Maximum @count files.');
160 if (isset($upload_validators['file_validate_size'])) {
161 $descriptions[] = t('@size limit.', ['@size' => format_size($upload_validators['file_validate_size'][0])]);
163 if (isset($upload_validators['file_validate_extensions'])) {
164 $descriptions[] = t('Allowed types: @extensions.', ['@extensions' => $upload_validators['file_validate_extensions'][0]]);
167 if (isset($upload_validators['file_validate_image_resolution'])) {
168 $max = $upload_validators['file_validate_image_resolution'][0];
169 $min = $upload_validators['file_validate_image_resolution'][1];
170 if ($min && $max && $min == $max) {
171 $descriptions[] = t('Images must be exactly <strong>@size</strong> pixels.', ['@size' => $max]);
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.', ['@min' => $min, '@max' => $max]);
177 $descriptions[] = t('Images must be larger than <strong>@min</strong> pixels.', ['@min' => $min]);
180 $descriptions[] = t('Images larger than <strong>@max</strong> pixels will be resized.', ['@max' => $max]);
184 $variables['descriptions'] = $descriptions;
188 * Determine whether a field references files stored in {file_managed}.
190 * @param \Drupal\Core\Field\FieldDefinitionInterface $field
191 * A field definition.
194 * The field column if the field references {file_managed}.fid, typically
195 * fid, FALSE if it does not.
197 function file_field_find_file_reference_column(FieldDefinitionInterface $field) {
198 $schema = $field->getFieldStorageDefinition()->getSchema();
199 foreach ($schema['foreign keys'] as $data) {
200 if ($data['table'] == 'file_managed') {
201 foreach ($data['columns'] as $field_column => $column) {
202 if ($column == 'fid') {
203 return $field_column;