Попробовав множество возможных решений, я нашел это для фотографий (и оно работает безупречно, даже если вы используете приватное ведро в AWS S3 ):
<?php
namespace App\Application\Controller;
use App\Application\Controller\Rest\RestController;
use App\Domain\Entity\BuildingMedia;
use App\Domain\Entity\PropertyPicture;
use App\Infrastructure\Command\Command\CommandBus;
use App\Infrastructure\Repository\BuildingMediaRepository;
use App\Infrastructure\Repository\PropertyPictureRepository;
use Gaufrette\Filesystem;
use JMS\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\Response;
use Swagger\Annotations as SWG;
use Nelmio\ApiDocBundle\Annotation\Operation;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpKernel\Exception\HttpException;
class MediaController extends RestController
{
/**
* @var PropertyPictureRepository
*/
private $propertyPictureRepository;
/**
* @var BuildingMediaRepository
*/
private $buildingMediaRepository;
/**
* @var Filesystem
*/
private $awsS3;
/**
* MediaController constructor.
*
* @param PropertyPictureRepository $propertyPictureRepository
* @param BuildingMediaRepository $buildingMediaRepository
* @param Filesystem $awsS3
* @param SerializerInterface $serializer
* @param CommandBus $commandBus
*/
public function __construct(
PropertyPictureRepository $propertyPictureRepository,
BuildingMediaRepository $buildingMediaRepository,
Filesystem $awsS3,
SerializerInterface $serializer,
CommandBus $commandBus
) {
$this->propertyPictureRepository = $propertyPictureRepository;
$this->buildingMediaRepository = $buildingMediaRepository;
$this->awsS3 = $awsS3;
parent::__construct($serializer, $commandBus);
}
/**
* @Operation(
* tags={"Media"},
* summary="Read a property's picture.",
* @SWG\Response(
* response="200",
* description="OK"
* ),
* @SWG\Response(
* response="400",
* description="Bad request"
* ),
* @SWG\Response(
* response="401",
* description="Unauthorized"
* ),
* @SWG\Response(
* response="403",
* description="Access denied"
* ),
* @SWG\Response(
* response="404",
* description="Entity not found"
* ),
* @SWG\Response(
* response="500",
* description="Internal server error"
* )
* )
*
* @ParamConverter("propertyPicture", converter="property_picture")
*
* @param PropertyPicture $propertyPicture
*
* @return Response
*/
public function propertyPictureReadAction(PropertyPicture $propertyPicture): Response
{
$adapter = $this->awsS3->getAdapter();
$content = $adapter->read(
'group'.DIRECTORY_SEPARATOR.
$this->getUser()->getGroupId().DIRECTORY_SEPARATOR.
'property'.DIRECTORY_SEPARATOR.
$propertyPicture->getProperty()->getIdValue().DIRECTORY_SEPARATOR.
$propertyPicture->getFilename()
);
return new Response($content, 200, array(
'Content-Type' => 'image/jpeg'
));
}
}
Метод read()
из Gaufrette
возвращает содержимое файла, а не реальный путь. Итак, я просто изменил возвращаемое значение с BinaryFileResponse
на Response
и установил вручную Content-Type
.
Следующее обновление, если у вас есть такая же обработка, это установить тип MIME в базе данных, когда Файл сохраняется и возвращает его, когда вам нужно отобразить его аналогичным образом из вашего API.