From 82c59f849986d71456b966890376bc798a0449b9 Mon Sep 17 00:00:00 2001 From: Lee Rowlands <lee.rowlands@previousnext.com.au> Date: Mon, 13 Nov 2023 14:35:58 +1000 Subject: [PATCH] Issue #3389447 by kim.pepper, smustgrave, quietone: Provide a trait to create file upload validators from file field settings --- .../src/Plugin/Field/FieldType/FileItem.php | 22 ++------ .../rest/resource/FileUploadResource.php | 48 ++--------------- .../Validation/FileValidatorSettingsTrait.php | 51 +++++++++++++++++++ .../TemporaryJsonapiFileFieldUploader.php | 46 ++--------------- 4 files changed, 62 insertions(+), 105 deletions(-) create mode 100644 core/modules/file/src/Validation/FileValidatorSettingsTrait.php diff --git a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php index d61822ceb04d..d9fe46ec600c 100644 --- a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php +++ b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php @@ -15,6 +15,7 @@ use Drupal\Core\StringTranslation\ByteSizeMarkup; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\TypedData\DataDefinition; +use Drupal\file\Validation\FileValidatorSettingsTrait; /** * Plugin implementation of the 'file' field type. @@ -35,6 +36,8 @@ */ class FileItem extends EntityReferenceItem { + use FileValidatorSettingsTrait; + /** * {@inheritdoc} */ @@ -327,24 +330,7 @@ protected static function doGetUploadLocation(array $settings, $data = []) { * element's '#upload_validators' property. */ public function getUploadValidators() { - $validators = []; - $settings = $this->getSettings(); - - // Cap the upload size according to the PHP limit. - $max_filesize = Bytes::toNumber(Environment::getUploadMaxSize()); - if (!empty($settings['max_filesize'])) { - $max_filesize = min($max_filesize, Bytes::toNumber($settings['max_filesize'])); - } - - // There is always a file size limit due to the PHP server limit. - $validators['FileSizeLimit'] = ['fileLimit' => $max_filesize]; - - // Add the extension check if necessary. - if (!empty($settings['file_extensions'])) { - $validators['FileExtension'] = ['extensions' => $settings['file_extensions']]; - } - - return $validators; + return $this->getFileUploadValidators($this->getSettings()); } /** diff --git a/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php b/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php index 8abc3cc29f13..607f258c509f 100644 --- a/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php +++ b/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php @@ -3,13 +3,10 @@ namespace Drupal\file\Plugin\rest\resource; use Drupal\Component\Render\PlainTextOutput; -use Drupal\Component\Utility\Bytes; use Drupal\Component\Utility\Crypt; -use Drupal\Component\Utility\Environment; use Drupal\Core\Config\Config; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\File\Event\FileUploadSanitizeNameEvent; use Drupal\Core\File\Exception\FileException; use Drupal\Core\File\FileSystemInterface; @@ -20,6 +17,7 @@ use Drupal\file\Upload\ContentDispositionFilenameParser; use Drupal\file\Upload\InputStreamFileWriterInterface; use Drupal\file\Validation\FileValidatorInterface; +use Drupal\file\Validation\FileValidatorSettingsTrait; use Drupal\rest\ModifiedResourceResponse; use Drupal\rest\Plugin\ResourceBase; use Drupal\rest\Plugin\rest\resource\EntityResourceValidationTrait; @@ -59,6 +57,7 @@ */ class FileUploadResource extends ResourceBase { + use FileValidatorSettingsTrait; use EntityResourceValidationTrait { validate as resourceValidate; } @@ -282,7 +281,7 @@ public function post(Request $request, $entity_type_id, $bundle, $field_name) { throw new HttpException(500, 'Destination file path is not writable'); } - $validators = $this->getUploadValidators($field_definition); + $validators = $this->getFileUploadValidators($field_definition->getSettings()); $prepared_filename = $this->prepareFilename($filename, $validators); @@ -488,47 +487,6 @@ protected function getUploadLocation(array $settings) { return $settings['uri_scheme'] . '://' . $destination; } - /** - * Retrieves the upload validators for a field definition. - * - * This is copied from \Drupal\file\Plugin\Field\FieldType\FileItem as there - * is no entity instance available here that a FileItem would exist for. - * - * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition - * The field definition for which to get validators. - * - * @return array - * An array suitable for passing to file_save_upload() or the file field - * element's '#upload_validators' property. - */ - protected function getUploadValidators(FieldDefinitionInterface $field_definition) { - $validators = [ - // Add in our check of the file name length. - 'FileNameLength' => [], - ]; - $settings = $field_definition->getSettings(); - - // Cap the upload size according to the PHP limit. - $max_filesize = Bytes::toNumber(Environment::getUploadMaxSize()); - if (!empty($settings['max_filesize'])) { - $max_filesize = min($max_filesize, Bytes::toNumber($settings['max_filesize'])); - } - - // There is always a file size limit due to the PHP server limit. - $validators['FileSizeLimit'] = [ - 'fileLimit' => $max_filesize, - ]; - - // Add the extension check if necessary. - if (!empty($settings['file_extensions'])) { - $validators['FileExtension'] = [ - 'extensions' => $settings['file_extensions'], - ]; - } - - return $validators; - } - /** * {@inheritdoc} */ diff --git a/core/modules/file/src/Validation/FileValidatorSettingsTrait.php b/core/modules/file/src/Validation/FileValidatorSettingsTrait.php new file mode 100644 index 000000000000..26e36498b37c --- /dev/null +++ b/core/modules/file/src/Validation/FileValidatorSettingsTrait.php @@ -0,0 +1,51 @@ +<?php + +namespace Drupal\file\Validation; + +use Drupal\Component\Utility\Bytes; +use Drupal\Component\Utility\Environment; + +/** + * Provides a trait to create validators from settings. + */ +trait FileValidatorSettingsTrait { + + /** + * Gets the upload validators for the specified settings. + * + * @param array $settings + * An associative array of settings. The following keys are supported: + * - max_filesize: The maximum file size in bytes. Defaults to the PHP max + * upload size. + * - file_extensions: A space-separated list of allowed file extensions. + * + * @return array + * An array suitable for passing to file_save_upload() or the file field + * element's '#upload_validators' property. + */ + public function getFileUploadValidators(array $settings): array { + $validators = [ + // Add in our check of the file name length. + 'FileNameLength' => [], + ]; + + // Cap the upload size according to the PHP limit. + $maxFilesize = Bytes::toNumber(Environment::getUploadMaxSize()); + if (!empty($settings['max_filesize'])) { + $maxFilesize = min($maxFilesize, Bytes::toNumber($settings['max_filesize'])); + } + + // There is always a file size limit due to the PHP server limit. + $validators['FileSizeLimit'] = ['fileLimit' => $maxFilesize]; + + // Add the extension check if necessary. + if (!empty($settings['file_extensions'])) { + $validators['FileExtension'] = [ + 'extensions' => $settings['file_extensions'], + ]; + } + + return $validators; + } + +} diff --git a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php index b897ed5dfb2b..0e469ff18f44 100644 --- a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php +++ b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php @@ -3,9 +3,7 @@ namespace Drupal\jsonapi\Controller; use Drupal\Component\Render\PlainTextOutput; -use Drupal\Component\Utility\Bytes; use Drupal\Component\Utility\Crypt; -use Drupal\Component\Utility\Environment; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; @@ -22,6 +20,7 @@ use Drupal\file\Upload\ContentDispositionFilenameParser; use Drupal\file\Upload\InputStreamFileWriterInterface; use Drupal\file\Validation\FileValidatorInterface; +use Drupal\file\Validation\FileValidatorSettingsTrait; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\File\Exception\CannotWriteFileException; use Symfony\Component\HttpFoundation\File\Exception\NoFileException; @@ -45,6 +44,8 @@ */ class TemporaryJsonapiFileFieldUploader { + use FileValidatorSettingsTrait; + /** * The regex used to extract the filename from the content disposition header. * @@ -200,7 +201,7 @@ public function handleFileUploadForField(FieldDefinitionInterface $field_definit throw new HttpException(500, 'Destination file path is not writable'); } - $validators = $this->getUploadValidators($field_definition); + $validators = $this->getFileUploadValidators($field_definition->getSettings()); $prepared_filename = $this->prepareFilename($filename, $validators); @@ -423,45 +424,6 @@ protected function getUploadLocation(array $settings) { return $settings['uri_scheme'] . '://' . $destination; } - /** - * Retrieves the upload validators for a field definition. - * - * This is copied from \Drupal\file\Plugin\Field\FieldType\FileItem as there - * is no entity instance available here that a FileItem would exist for. - * - * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition - * The field definition for which to get validators. - * - * @return array - * An array suitable for passing to file_save_upload() or the file field - * element's '#upload_validators' property. - */ - protected function getUploadValidators(FieldDefinitionInterface $field_definition) { - $validators = [ - // Add in our check of the file name length. - 'FileNameLength' => [], - ]; - $settings = $field_definition->getSettings(); - - // Cap the upload size according to the PHP limit. - $max_filesize = Bytes::toNumber(Environment::getUploadMaxSize()); - if (!empty($settings['max_filesize'])) { - $max_filesize = min($max_filesize, Bytes::toNumber($settings['max_filesize'])); - } - - // There is always a file size limit due to the PHP server limit. - $validators['FileSizeLimit'] = ['fileLimit' => $max_filesize]; - - // Add the extension check if necessary. - if (!empty($settings['file_extensions'])) { - $validators['FileExtension'] = [ - 'extensions' => $settings['file_extensions'], - ]; - } - - return $validators; - } - /** * Generates a lock ID based on the file URI. * -- GitLab