public function FileUploadResource::post in Drupal 10
Same name and namespace in other branches
- 8 core/modules/file/src/Plugin/rest/resource/FileUploadResource.php \Drupal\file\Plugin\rest\resource\FileUploadResource::post()
- 9 core/modules/file/src/Plugin/rest/resource/FileUploadResource.php \Drupal\file\Plugin\rest\resource\FileUploadResource::post()
Creates a file from an endpoint.
Parameters
\Symfony\Component\HttpFoundation\Request $request: The current request.
string $entity_type_id: The entity type ID.
string $bundle: The entity bundle. This will be the same as $entity_type_id for entity types that don't support bundles.
string $field_name: The field name.
Return value
\Drupal\rest\ModifiedResourceResponse A 201 response, on success.
Throws
\Symfony\Component\HttpKernel\Exception\HttpException Thrown when temporary files cannot be written, a lock cannot be acquired, or when temporary files cannot be moved to their new location.
File
- core/
modules/ file/ src/ Plugin/ rest/ resource/ FileUploadResource.php, line 235
Class
- FileUploadResource
- File upload resource.
Namespace
Drupal\file\Plugin\rest\resourceCode
public function post(Request $request, $entity_type_id, $bundle, $field_name) {
$filename = $this
->validateAndParseContentDispositionHeader($request);
$field_definition = $this
->validateAndLoadFieldDefinition($entity_type_id, $bundle, $field_name);
$destination = $this
->getUploadLocation($field_definition
->getSettings());
// Check the destination file path is writable.
if (!$this->fileSystem
->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {
throw new HttpException(500, 'Destination file path is not writable');
}
$validators = $this
->getUploadValidators($field_definition);
$prepared_filename = $this
->prepareFilename($filename, $validators);
// Create the file.
$file_uri = "{$destination}/{$prepared_filename}";
$temp_file_path = $this
->streamUploadData();
$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)) {
throw new HttpException(503, sprintf('File "%s" is already locked for writing', $file_uri), NULL, [
'Retry-After' => 1,
]);
}
// Begin building file entity.
$file = File::create([]);
$file
->setOwnerId($this->currentUser
->id());
$file
->setFilename($prepared_filename);
$file
->setMimeType($this->mimeTypeGuesser
->guessMimeType($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 the file against field-level validators first while the file is
// still a temporary file. Validation is split up in 2 steps to be the same
// as in \Drupal\file\Upload\FileUploadHandler::handleFileUpload().
// For backwards compatibility this part is copied from ::validate() to
// leave that method behavior unchanged.
// @todo Improve this with a file uploader service in
// https://www.drupal.org/project/drupal/issues/2940383
$errors = file_validate($file, $validators);
if (!empty($errors)) {
$message = "Unprocessable Entity: file validation failed.\n";
$message .= implode("\n", array_map([
PlainTextOutput::class,
'renderFromHtml',
], $errors));
throw new UnprocessableEntityHttpException($message);
}
$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) {
throw new HttpException(500, 'Temporary file could not be moved to file location');
}
// Second step of the validation on the file object itself now.
$this
->resourceValidate($file);
$file
->save();
$this->lock
->release($lock_id);
// 201 Created responses return the newly created entity in the response
// body. These responses are not cacheable, so we add no cacheability
// metadata here.
return new ModifiedResourceResponse($file, 201);
}