Skip to content

Commit

Permalink
119. handle file upload
Browse files Browse the repository at this point in the history
  • Loading branch information
teebbstudios committed Aug 2, 2021
1 parent 4ae1b6b commit 3f1fec8
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 1 deletion.
41 changes: 41 additions & 0 deletions src/Controller/ApiFileController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php


namespace App\Controller;


use App\Entity\FileManaged;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

class ApiFileController extends AbstractController
{
public function __invoke(Request $request, EntityManagerInterface $em, string $projectDir)
{
/**@var UploadedFile $uploadedFile * */
$uploadedFile = $request->files->get('file');
if (!$uploadedFile) {
throw new BadRequestHttpException('"file" is required');
}

$newFileName = $uploadedFile->getClientOriginalName() . '_' .
substr(hash('sha1', $uploadedFile->getClientOriginalName()), 0, 8) .
'.' . $uploadedFile->getClientOriginalExtension();
$file = new FileManaged();
$file->setMimeType($uploadedFile->getMimeType());
$file->setOriginName($uploadedFile->getClientOriginalName());
$file->setFileName($newFileName);
$file->setFileSize($uploadedFile->getSize());
$file->setPath('/uploads/images/' . $newFileName);

$em->persist($file);
$em->flush();

$uploadedFile->move($projectDir . '/public/uploads/images', $newFileName);

return $file;
}
}
52 changes: 51 additions & 1 deletion src/Entity/FileManaged.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,44 @@
namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Controller\ApiFileController;
use App\Repository\FileManagedRepository;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass=FileManagedRepository::class)
* @ORM\Table(name="file")
*/
#[ApiResource]
#[ApiResource(
collectionOperations: [
'get',
'post' => [
'controller' => ApiFileController::class,
'method' => 'post',
'deserialize' => false,
'openapi_context' => [
'requestBody' => [
'content' => [
'multipart/form-data' => [
'schema' => [
'type' => 'object',
'properties' => [
'file' => [
'type' => 'string',
'format' => 'binary',
],
],
],
],
],
],
],
]
],
itemOperations: [
'get'
]
)]
class FileManaged
{
/**
Expand Down Expand Up @@ -45,6 +75,8 @@ class FileManaged
*/
private $path;

private $fileUrl;

public function getId(): ?int
{
return $this->id;
Expand Down Expand Up @@ -109,4 +141,22 @@ public function setPath(string $path): self

return $this;
}

/**
* @return mixed
*/
public function getFileUrl()
{
return $this->fileUrl;
}

/**
* @param mixed $fileUrl
*/
public function setFileUrl($fileUrl): void
{
$this->fileUrl = $fileUrl;
}


}
56 changes: 56 additions & 0 deletions src/Serializer/Normalizer/FileAwareNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php


namespace App\Serializer\Normalizer;


use App\Entity\FileManaged;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;

class FileAwareNormalizer implements NormalizerAwareInterface, ContextAwareNormalizerInterface
{
use NormalizerAwareTrait;

/**
* @var RequestStack
*/
private RequestStack $requestStack;

public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}

private const FILE_NORMALIZER_ALREADY_CALLED = 'file_normalizer_already_called';

public function supportsNormalization($data, string $format = null, array $context = [])
{
if (isset($context[self::FILE_NORMALIZER_ALREADY_CALLED]))
{
return false;
}
return $data instanceof FileManaged;
}

/**
* @param FileManaged $object
* @param string|null $format
* @param array $context
* @return array|\ArrayObject|bool|float|int|string|null
* @throws ExceptionInterface
*/
public function normalize($object, string $format = null, array $context = [])
{
$context[self::FILE_NORMALIZER_ALREADY_CALLED] = true;

$object->setFileUrl($this->requestStack->getCurrentRequest()->getSchemeAndHttpHost() . $object->getPath());
return $this->normalizer->normalize($object, $format, $context);
}
}

0 comments on commit 3f1fec8

Please sign in to comment.