<?php
namespace App\Controller;
use App\Entity\User;
use App\Helper\ImageHelper;
use App\Service\ImageService;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
class ImageController extends BaseController
{
private ImageService $imageService;
public function __construct(
ImageService $imageService
) {
$this->imageService = $imageService;
}
public function getAction(Request $request): BinaryFileResponse|JsonResponse
{
/** @var User $user */
$user = $this->getUser();
$imageId = $request->get('imageId');
$width = $request->get('w');
if ($imageId === 'placeholder') {
// return placeholder image
return new BinaryFileResponse(__DIR__ . '/../../data/placeholder_images/crop.jpg');
}
$image = $this->imageService->getImage($imageId);
if (empty($image)) {
return new JsonResponse(['error' => 'bad_request'], 400);
}
// allow crop images that are shared or belong to user without access token
// because we need this for the library at our website;
// also allow profile garden images
if ($image->isRestricted() && $image->getType() !== ImageService::TYPE_CROP && $user === null) {
return new JsonResponse(['error' => 'forbidden'], 403);
}
// todo: check if crop is shared -> then allow image
$allowed = $this->imageService->checkAllowed($user, $image);
if (!$allowed) {
return new JsonResponse(['error' => 'bad_request'], 400);
}
$path = $image->getPath();
if ($width !== null) {
$width = (int)$width;
if (!is_numeric($width)) {
return new JsonResponse(['error' => 'bad_request'], 400);
}
// if width is given check if resized version exists and if not create one
$ext = substr($image->getPath(), -4, 4);
$resizedPath = substr($image->getPath(), 0, -4) . '-w' . $width . $ext;
if (!file_exists($resizedPath)) {
$img = imagecreatefromstring(file_get_contents($image->getPath()));
$type = mime_content_type($image->getPath());
$originalWidth = imagesx($img);
$originalHeight = imagesy($img);
$height = $width * ($originalHeight / $originalWidth);
if ($width < $originalWidth && $height < $originalHeight) {
$resizedImg = ImageHelper::resize($img, $width, $height, true, true);
if ($type === 'image/jpeg') {
imagejpeg($resizedImg, $resizedPath, 80);
} else {
imagepng($resizedImg, $resizedPath);
}
}
}
if (file_exists($resizedPath)) {
$path = $resizedPath;
}
}
if($path === null || !file_exists($path)) {
return new JsonResponse(['error' => 'bad_request'], 400);
}
return $this->file($path);
}
public function deleteAction(Request $request): JsonResponse
{
/** @var User $user */
$user = $this->getUser();
if (empty($user)) {
return new JsonResponse(['error' => 'forbidden'], 403);
}
$imageId = $request->get('imageId');
$result = $this->imageService->deleteImage($user, $imageId);
if ($result === false) {
return new JsonResponse(['error' => 'bad_request'], 400);
}
return new JsonResponse(['success' => $result]);
}
public function saveAction(Request $request): JsonResponse
{
/** @var User $user */
$user = $this->getUser();
if (empty($user)) {
return new JsonResponse(['error' => 'forbidden'], 403);
}
$data = json_decode($request->getContent(), true);
$type = $data['type'];
$base64 = $data['base64'];
$referenceId = $data['referenceId'];
$types = ['crop', 'package'];
if (!in_array($type, $types)) {
return new JsonResponse(['error' => 'bad_request', 'details' => 'type not allowed'], 400);
}
$result = $this->imageService->save($base64, $user, $referenceId, $type);
if ($result === false) {
return new JsonResponse(['error' => 'bad_request', 'details' => 'save not allowed'], 400);
}
return new JsonResponse(['image' => ['id' => $result->getId()]]);
}
}