You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.2 KiB
99 lines
3.2 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/* For licensing terms, see /license.txt */
|
|
|
|
namespace Chamilo\CoreBundle\Controller\Api;
|
|
|
|
use Chamilo\CoreBundle\Repository\ResourceNodeRepository;
|
|
use Chamilo\CourseBundle\Entity\CDocument;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
|
use Symfony\Component\HttpKernel\KernelInterface;
|
|
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
|
|
|
class ReplaceDocumentFileAction extends BaseResourceFileAction
|
|
{
|
|
private string $uploadBasePath;
|
|
|
|
public function __construct(KernelInterface $kernel)
|
|
{
|
|
$this->uploadBasePath = $kernel->getProjectDir() . '/var/upload/resource';
|
|
}
|
|
|
|
public function __invoke(
|
|
CDocument $document,
|
|
Request $request,
|
|
ResourceNodeRepository $resourceNodeRepository,
|
|
EntityManagerInterface $em
|
|
): Response {
|
|
$uploadedFile = $request->files->get('file');
|
|
if (!$uploadedFile) {
|
|
throw new BadRequestHttpException('"file" is required.');
|
|
}
|
|
|
|
$resourceNode = $document->getResourceNode();
|
|
if (!$resourceNode) {
|
|
throw new BadRequestHttpException('ResourceNode not found.');
|
|
}
|
|
|
|
$resourceFile = $resourceNode->getFirstResourceFile();
|
|
if (!$resourceFile) {
|
|
throw new BadRequestHttpException('No file found in the resource node.');
|
|
}
|
|
|
|
$filePath = $this->uploadBasePath . $resourceNodeRepository->getFilename($resourceFile);
|
|
if (!$filePath) {
|
|
throw new BadRequestHttpException('File path could not be resolved.');
|
|
}
|
|
|
|
$this->prepareDirectory($filePath);
|
|
|
|
try {
|
|
$uploadedFile->move(dirname($filePath), basename($filePath));
|
|
} catch (FileException $e) {
|
|
throw new BadRequestHttpException(sprintf('Failed to move the file: %s', $e->getMessage()));
|
|
}
|
|
|
|
$movedFilePath = $filePath;
|
|
if (!file_exists($movedFilePath)) {
|
|
throw new \RuntimeException('The moved file does not exist at the expected location.');
|
|
}
|
|
$fileSize = filesize($movedFilePath);
|
|
$resourceFile->setSize($fileSize);
|
|
|
|
$newFileName = $uploadedFile->getClientOriginalName();
|
|
$document->setTitle($newFileName);
|
|
$resourceFile->setOriginalName($newFileName);
|
|
|
|
$resourceNode->setUpdatedAt(new \DateTime());
|
|
|
|
$em->persist($document);
|
|
$em->persist($resourceFile);
|
|
$em->flush();
|
|
|
|
return new Response('Document replaced successfully.', Response::HTTP_OK);
|
|
}
|
|
|
|
/**
|
|
* Prepares the directory to ensure it exists and is writable.
|
|
*/
|
|
protected function prepareDirectory(string $filePath): void
|
|
{
|
|
$directory = dirname($filePath);
|
|
|
|
if (!is_dir($directory)) {
|
|
if (!mkdir($directory, 0775, true) && !is_dir($directory)) {
|
|
throw new \RuntimeException(sprintf('Unable to create directory "%s".', $directory));
|
|
}
|
|
}
|
|
|
|
if (!is_writable($directory)) {
|
|
throw new \RuntimeException(sprintf('Directory "%s" is not writable.', $directory));
|
|
}
|
|
}
|
|
|
|
}
|
|
|