From ac4ed0d180f2f9cbf972b477f07d489640c6557f Mon Sep 17 00:00:00 2001 From: Shubham Date: Thu, 20 Mar 2025 09:44:38 -0400 Subject: [PATCH] Added functionality for changing file names and their URI --- ...dora_workbench_integration.permissions.yml | 4 + islandora_workbench_integration.routing.yml | 17 ++ ...rkbenchIntegrationFileRenameController.php | 181 ++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 islandora_workbench_integration.permissions.yml create mode 100644 src/Controller/IslandoraWorkbenchIntegrationFileRenameController.php diff --git a/islandora_workbench_integration.permissions.yml b/islandora_workbench_integration.permissions.yml new file mode 100644 index 0000000..8ca71b5 --- /dev/null +++ b/islandora_workbench_integration.permissions.yml @@ -0,0 +1,4 @@ +rename files: + title: 'Rename files' + description: 'Rename files.' + restrict access: true diff --git a/islandora_workbench_integration.routing.yml b/islandora_workbench_integration.routing.yml index 7ba8f53..5ff7725 100644 --- a/islandora_workbench_integration.routing.yml +++ b/islandora_workbench_integration.routing.yml @@ -24,3 +24,20 @@ islandora_workbench_integration.file_hash: _permission: 'administer site configuration' options: _auth: ['basic_auth','jwt_auth','cookie'] + + +islandora_workbench_integration.workbench_rename_file: + path: '/islandora_workbench_integration/rename/{file}' + defaults: + _controller: '\Drupal\islandora_workbench_integration\Controller\IslandoraWorkbenchIntegrationFileRenameController::main' + _title: 'Rename file' + _access: TRUE + requirements: + _permission: 'rename files' + methods: [GET, POST] + options: + _admin_route: TRUE + _auth: ['basic_auth'] + parameters: + file: + type: entity:file \ No newline at end of file diff --git a/src/Controller/IslandoraWorkbenchIntegrationFileRenameController.php b/src/Controller/IslandoraWorkbenchIntegrationFileRenameController.php new file mode 100644 index 0000000..cc2f88c --- /dev/null +++ b/src/Controller/IslandoraWorkbenchIntegrationFileRenameController.php @@ -0,0 +1,181 @@ +fileSystem = $fileSystem; + $this->eventDispatcher = $event_dispatcher; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) + { + return new static( + $container->get('file_system'), + $container->get('event_dispatcher') + ); + } + + + + /** + * Renames a file while keeping the extension unchanged. + * + * Expects a URL parameter for the file ID (fid) and a JSON payload with: + * - new_filename: The new base file name (without extension). + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The incoming request. + * @param Drupal\file\Entity\File $file + * The file ID from the URL. + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + * The JSON response. + */ + public function main(Request $request, $file) + { + // Decode JSON payload. + + $data = json_decode($request->getContent(), true); + + // Validate that new_filename is provided. + if (empty($data['new_filename'])) { + return new JsonResponse(['error' => 'Missing new_filename parameter']); + } + + + if (!$file) { + return new JsonResponse(["Error 404" => 'No file found']); + } + + + $pathinfo = pathinfo($file->getFileUri()); + $filename_new = $data['new_filename']; + $msg = $this->validate($file, $filename_new); + if ($msg != 'OK') { + return new JsonResponse(['Error' => $msg]); + } + + + + if ($filename_new != $file->getFilename()) { + $filepath_new = $this->getRenamedFilePath($file, $filename_new); + rename($file->getFileUri(), $filepath_new); + // Update file entity. + $file->setFilename($filename_new); + $file->setFileUri($filepath_new); + $status = $file->save(); + + return new JsonResponse(['message' => 'File renamed successfully', 'new_filename' => $filename_new]); + } + + } + + + /** + * Check if the file name is valid + * + * @param Drupal\file\Entity\File $file + * File that needs to be renamed + * + * @param string $new_filename + * File Name of the new file + * + * @return string + * Error Message if not valid else OK + */ + public function validate($file, $new_filename) + { + $pathinfo = pathinfo($file->getFileUri()); + $source_file_uri = $file->getFileUri(); + + if (!file_exists($source_file_uri)) { + // Show an error if no file on disc. + return 'No file exists in this'; + } + + + $new_basename = $new_filename; + + if ($new_basename !== $file->getFilename()) { + // File renamed. + if ($new_basename !== basename($new_basename) + || strpos($new_basename, '\\') !== false + ) { + // If filename contains a slash or a backslash. + return 'Value must be a filename with no path information'; + } else { + // Dispatching a event to use default filename validation. + $event = new FileUploadSanitizeNameEvent($new_basename, $pathinfo['extension']); + $this->eventDispatcher->dispatch($event); + + if ($event->isSecurityRename()) { + // If new filename contains forbidden characters. + return ('File name is invalid'); + } + } + + $new_file_path = $this->getRenamedFilePath($file, $new_basename); + if (file_exists($new_file_path)) { + // File with given name already on disc. + return ('File with this name already exists in the directory.'); + } + } + + return 'OK'; + } + + /** + * Get Renamed File Path. + * + * @param Drupal\file\Entity\File $file + * File that needs to be renamed. + * + * @param string $new_filename + * File Name of the new file + * + * @return string + * File name after rename. + */ + protected function getRenamedFilePath($file, $new_filename) + { + $pathinfo = pathinfo($file->getFileUri()); + $old_filename = $pathinfo['filename'] . '.' . $pathinfo['extension']; + // Path after renaming. + return str_replace($old_filename, $new_filename, $file->getFileUri()); + } +}