file.field.inc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. /**
  3. * @file
  4. * Field module functionality for the File module.
  5. */
  6. use Drupal\Core\Field\FieldDefinitionInterface;
  7. use Drupal\Core\Field\FieldFilteredMarkup;
  8. use Drupal\Core\Render\Element;
  9. /**
  10. * Prepares variables for multi file form widget templates.
  11. *
  12. * Default template: file-widget-multiple.html.twig.
  13. *
  14. * @param array $variables
  15. * An associative array containing:
  16. * - element: A render element representing the widgets.
  17. */
  18. function template_preprocess_file_widget_multiple(&$variables) {
  19. $element = $variables['element'];
  20. // Special ID and classes for draggable tables.
  21. $weight_class = $element['#id'] . '-weight';
  22. $table_id = $element['#id'] . '-table';
  23. // Build up a table of applicable fields.
  24. $headers = [];
  25. $headers[] = t('File information');
  26. if ($element['#display_field']) {
  27. $headers[] = [
  28. 'data' => t('Display'),
  29. 'class' => ['checkbox'],
  30. ];
  31. }
  32. $headers[] = t('Weight');
  33. $headers[] = t('Operations');
  34. // Get our list of widgets in order (needed when the form comes back after
  35. // preview or failed validation).
  36. $widgets = [];
  37. foreach (Element::children($element) as $key) {
  38. $widgets[] = &$element[$key];
  39. }
  40. usort($widgets, '_field_multiple_value_form_sort_helper');
  41. $rows = [];
  42. foreach ($widgets as $key => &$widget) {
  43. // Save the uploading row for last.
  44. if (empty($widget['#files'])) {
  45. $widget['#title'] = $element['#file_upload_title'];
  46. $widget['#description'] = \Drupal::service('renderer')->renderPlain($element['#file_upload_description']);
  47. continue;
  48. }
  49. // Delay rendering of the buttons, so that they can be rendered later in the
  50. // "operations" column.
  51. $operations_elements = [];
  52. foreach (Element::children($widget) as $sub_key) {
  53. if (isset($widget[$sub_key]['#type']) && $widget[$sub_key]['#type'] == 'submit') {
  54. hide($widget[$sub_key]);
  55. $operations_elements[] = &$widget[$sub_key];
  56. }
  57. }
  58. // Delay rendering of the "Display" option and the weight selector, so that
  59. // each can be rendered later in its own column.
  60. if ($element['#display_field']) {
  61. hide($widget['display']);
  62. }
  63. hide($widget['_weight']);
  64. // Render everything else together in a column, without the normal wrappers.
  65. $widget['#theme_wrappers'] = [];
  66. $information = drupal_render($widget);
  67. $display = '';
  68. if ($element['#display_field']) {
  69. unset($widget['display']['#title']);
  70. $display = [
  71. 'data' => render($widget['display']),
  72. 'class' => ['checkbox'],
  73. ];
  74. }
  75. $widget['_weight']['#attributes']['class'] = [$weight_class];
  76. $weight = render($widget['_weight']);
  77. // Arrange the row with all of the rendered columns.
  78. $row = [];
  79. $row[] = $information;
  80. if ($element['#display_field']) {
  81. $row[] = $display;
  82. }
  83. $row[] = $weight;
  84. // Show the buttons that had previously been marked as hidden in this
  85. // preprocess function. We use show() to undo the earlier hide().
  86. foreach (Element::children($operations_elements) as $key) {
  87. show($operations_elements[$key]);
  88. }
  89. $row[] = [
  90. 'data' => $operations_elements,
  91. ];
  92. $rows[] = [
  93. 'data' => $row,
  94. 'class' => isset($widget['#attributes']['class']) ? array_merge($widget['#attributes']['class'], ['draggable']) : ['draggable'],
  95. ];
  96. }
  97. $variables['table'] = [
  98. '#type' => 'table',
  99. '#header' => $headers,
  100. '#rows' => $rows,
  101. '#attributes' => [
  102. 'id' => $table_id,
  103. ],
  104. '#tabledrag' => [
  105. [
  106. 'action' => 'order',
  107. 'relationship' => 'sibling',
  108. 'group' => $weight_class,
  109. ],
  110. ],
  111. '#access' => !empty($rows),
  112. ];
  113. $variables['element'] = $element;
  114. }
  115. /**
  116. * Prepares variables for file upload help text templates.
  117. *
  118. * Default template: file-upload-help.html.twig.
  119. *
  120. * @param array $variables
  121. * An associative array containing:
  122. * - description: The normal description for this field, specified by the
  123. * user.
  124. * - upload_validators: An array of upload validators as used in
  125. * $element['#upload_validators'].
  126. */
  127. function template_preprocess_file_upload_help(&$variables) {
  128. $description = $variables['description'];
  129. $upload_validators = $variables['upload_validators'];
  130. $cardinality = $variables['cardinality'];
  131. $descriptions = [];
  132. if (!empty($description)) {
  133. $descriptions[] = FieldFilteredMarkup::create($description);
  134. }
  135. if (isset($cardinality)) {
  136. if ($cardinality == -1) {
  137. $descriptions[] = t('Unlimited number of files can be uploaded to this field.');
  138. }
  139. else {
  140. $descriptions[] = \Drupal::translation()->formatPlural($cardinality, 'One file only.', 'Maximum @count files.');
  141. }
  142. }
  143. if (isset($upload_validators['file_validate_size'])) {
  144. $descriptions[] = t('@size limit.', ['@size' => format_size($upload_validators['file_validate_size'][0])]);
  145. }
  146. if (isset($upload_validators['file_validate_extensions'])) {
  147. $descriptions[] = t('Allowed types: @extensions.', ['@extensions' => $upload_validators['file_validate_extensions'][0]]);
  148. }
  149. if (isset($upload_validators['file_validate_image_resolution'])) {
  150. $max = $upload_validators['file_validate_image_resolution'][0];
  151. $min = $upload_validators['file_validate_image_resolution'][1];
  152. if ($min && $max && $min == $max) {
  153. $descriptions[] = t('Images must be exactly <strong>@size</strong> pixels.', ['@size' => $max]);
  154. }
  155. elseif ($min && $max) {
  156. $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]);
  157. }
  158. elseif ($min) {
  159. $descriptions[] = t('Images must be larger than <strong>@min</strong> pixels.', ['@min' => $min]);
  160. }
  161. elseif ($max) {
  162. $descriptions[] = t('Images larger than <strong>@max</strong> pixels will be resized.', ['@max' => $max]);
  163. }
  164. }
  165. $variables['descriptions'] = $descriptions;
  166. }
  167. /**
  168. * Determine whether a field references files stored in {file_managed}.
  169. *
  170. * @param \Drupal\Core\Field\FieldDefinitionInterface $field
  171. * A field definition.
  172. *
  173. * @return bool
  174. * The field column if the field references {file_managed}.fid, typically
  175. * fid, FALSE if it does not.
  176. */
  177. function file_field_find_file_reference_column(FieldDefinitionInterface $field) {
  178. $schema = $field->getFieldStorageDefinition()->getSchema();
  179. foreach ($schema['foreign keys'] as $data) {
  180. if ($data['table'] == 'file_managed') {
  181. foreach ($data['columns'] as $field_column => $column) {
  182. if ($column == 'fid') {
  183. return $field_column;
  184. }
  185. }
  186. }
  187. }
  188. return FALSE;
  189. }