public function FileUpload::saveFileUpload in GraphQL 8.4
Validates an uploaded file, saves it and returns a file upload response.
Based on several file upload handlers, see _file_save_upload_single() \Drupal\file\Plugin\Field\FieldType\FileItem \Drupal\file\Plugin\rest\resource\FileUploadResource.
Parameters
\Symfony\Component\HttpFoundation\File\UploadedFile $uploaded_file: The file entity to upload.
array $settings: File settings as specified in regular file field config. Contains keys:
- file_directory: Where to upload the file
- uri_scheme: Uri scheme to upload the file to (eg public://, private://)
- file_extensions: List of valid file extensions (eg [xml, pdf])
- max_filesize: Maximum allowed size of uploaded file.
Return value
\Drupal\graphql\GraphQL\Response\FileUploadResponse The file upload response containing file entity or list of violations.
Throws
\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
\Drupal\Component\Plugin\Exception\PluginNotFoundException
\RuntimeException
1 call to FileUpload::saveFileUpload()
- FileUpload::saveMultipleFileUploads in src/
GraphQL/ Utility/ FileUpload.php - Validates uploaded files, saves them and returns a file upload response.
File
- src/
GraphQL/ Utility/ FileUpload.php, line 166
Class
- FileUpload
- Service to manage file uploads within GraphQL mutations.
Namespace
Drupal\graphql\GraphQL\UtilityCode
public function saveFileUpload(UploadedFile $uploaded_file, array $settings) : FileUploadResponse {
$response = new FileUploadResponse();
// Check for file upload errors and return FALSE for this file if a lower
// level system error occurred.
// @see http://php.net/manual/features.file-upload.errors.php.
switch ($uploaded_file
->getError()) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
$maxUploadSize = format_size($this
->getMaxUploadSize($settings));
$response
->addViolation($this
->t('The file @file could not be saved because it exceeds @maxsize, the maximum allowed size for uploads.', [
'@file' => $uploaded_file
->getClientOriginalName(),
'@maxsize' => $maxUploadSize,
]));
return $response;
case UPLOAD_ERR_PARTIAL:
case UPLOAD_ERR_NO_FILE:
$response
->addViolation($this
->t('The file "@file" could not be saved because the upload did not complete.', [
'@file' => $uploaded_file
->getClientOriginalName(),
]));
return $response;
case UPLOAD_ERR_OK:
// Final check that this is a valid upload, if it isn't, use the
// default error handler.
if ($uploaded_file
->isValid()) {
break;
}
default:
$response
->addViolation($this
->t('Unknown error while uploading the file "@file".', [
'@file' => $uploaded_file
->getClientOriginalName(),
]));
$this->logger
->error('Error while uploading the file "@file" with an error code "@code".', [
'@file' => $uploaded_file
->getFilename(),
'@code' => $uploaded_file
->getError(),
]);
return $response;
}
if (empty($settings['uri_scheme']) || empty($settings['file_directory'])) {
throw new \RuntimeException('uri_scheme or file_directory missing in settings');
}
$destination = $this
->getUploadLocation($settings);
// Check the destination file path is writable.
if (!$this->fileSystem
->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {
$response
->addViolation($this
->t('Unknown error while uploading the file "@file".', [
'@file' => $uploaded_file
->getClientOriginalName(),
]));
$this->logger
->error('Could not create directory "@upload_directory".', [
"@upload_directory" => $destination,
]);
return $response;
}
$validators = $this
->getUploadValidators($settings);
$prepared_filename = $this
->prepareFilename($uploaded_file
->getClientOriginalName(), $validators);
// Create the file.
$file_uri = "{$destination}/{$prepared_filename}";
$temp_file_path = $uploaded_file
->getRealPath();
$file_uri = $this->fileSystem
->getDestinationFilename($file_uri, FileSystemInterface::EXISTS_RENAME);
// Lock based on the prepared file URI.
$lock_id = $this
->generateLockIdFromFileUri($file_uri);
if (!$this->lock
->acquire($lock_id)) {
$response
->addViolation($this
->t('Unknown error while uploading the file "@file".', [
'@file' => $uploaded_file
->getClientOriginalName(),
]));
return $response;
}
try {
// Begin building file entity.
/** @var \Drupal\file\FileInterface $file */
$file = $this->fileStorage
->create([]);
$file
->setOwnerId($this->currentUser
->id());
$file
->setFilename($prepared_filename);
$file
->setMimeType($this->mimeTypeGuesser
->guess($prepared_filename));
$file
->setFileUri($temp_file_path);
// Set the size. This is done in File::preSave() but we validate the file
// before it is saved.
$file
->setSize(@filesize($temp_file_path));
// Validate against file_validate() first with the temporary path.
$errors = file_validate($file, $validators);
if (!empty($errors)) {
$response
->addViolations($errors);
return $response;
}
$file
->setFileUri($file_uri);
// Move the file to the correct location after validation. Use
// FileSystemInterface::EXISTS_ERROR as the file location has already been
// determined above in FileSystem::getDestinationFilename().
try {
$this->fileSystem
->move($temp_file_path, $file_uri, FileSystemInterface::EXISTS_ERROR);
} catch (FileException $e) {
$response
->addViolation($this
->t('Unknown error while uploading the file "@file".', [
'@file' => $uploaded_file
->getClientOriginalName(),
]));
$this->logger
->error('Unable to move file from "@file" to "@destination".', [
'@file' => $uploaded_file
->getRealPath(),
'@destination' => $file
->getFileUri(),
]);
return $response;
}
// Validate the file entity against entity-level validation now after the
// file has moved.
if (!$this
->validate($file, $validators, $response)) {
return $response;
}
$file
->save();
$response
->setFileEntity($file);
return $response;
} finally {
// This will always be executed before any return statement or exception
// in the try {} block.
$this->lock
->release($lock_id);
}
}