<?php
namespace App\Service;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Mailer\MailerInterface;
use Twig\Environment;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use ImageBundle\Service\ImageService as ImageBundleImageService;
use ImageBundle\Service\TagService as ImageBundleTagService;
class VehicleImageService
{
private $params;
private $em;
private $mailer;
private $router;
private $twig;
private $hasErrors;
private $errorMessage;
private $currentUser;
private $imageService;
private $imageTagService;
public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, MailerInterface $mailer, RouterInterface $router, Environment $twig, TokenStorageInterface $tokenStorage, ImageBundleImageService $imageService, ImageBundleTagService $imageTagService)
{
$this->params = $params;
$this->em = $em;
$this->mailer = $mailer;
$this->router = $router;
$this->twig = $twig;
$this->currentUser = $tokenStorage->getToken() ? $tokenStorage->getToken()->getUser() : null;
$this->hasErrors = false;
$this->errorMessage = "";
$this->imageService = $imageService;
$this->imageTagService = $imageTagService;
}
private function decodeBase64ImageData(string $base64Content)
{
$base64Content = str_replace('data:', '', $base64Content);
$data = explode(';base64,', $base64Content);
return base64_decode($data[1]);
}
public function uploadVehicleImage($estimateId, $estimatePartnerId = null, $vehicleId, $jobId = null, $vehiclePartId = null, $imageDataList, $imageSource = 'desktop')
{
$estimate = $this->em->getRepository('App:Estimate')->find($estimateId);
if (!$estimate) {
return $this->setError('Estimate not found');
}
$vehiclePart = null;
if ($vehiclePartId) {
$vehiclePart = $this->em->getRepository('App:VehiclePart')->find($vehiclePartId);
if (!$vehiclePart) {
return $this->setError('Vehicle part not found');
}
}
$job = null;
if ($jobId) {
$job = $this->em->getRepository('App:Job')->find($jobId);
if (!$job) {
return $this->setError('Job not found');
}
}
$uploadedImagesList = [];
foreach ($imageDataList as $imageObject) {
//get mime and content from base64 data
$imageInfo = json_decode($imageObject['imageInfo'], true);
if (!in_array($imageInfo['type'], ['image/jpeg', 'image/jpg', 'image/png'])) {
return $this->setError('Invalid file image format');
}
//save temp file
$uploadedFilePath = tempnam(sys_get_temp_dir(), $imageInfo['name']);
$imageData = $this->decodeBase64ImageData($imageObject['imageBase64']);
file_put_contents($uploadedFilePath, $imageData);
try {
//imposta descrizione da parte se esiste o da label lavorazione
$description = null;
if ($vehiclePart) {
$description = $vehiclePart->getLabel();
}
if ($job) {
$description = $job->getLabel();
}
//salva immagine
$imageData = [
'title' => date('Y-m-d') . '-' . $estimate->getCode(),
'description' => $description,
'originalFilename' => md5(time() . mt_rand()) . ($imageInfo['type'] == 'image/png' ? '.png' : '.jpg'),
'mimeType' => $imageInfo['type'],
'imageType' => ($vehiclePart || $job) ? 'damage' : 'vehicle',
'imageSource' => $imageSource,
];
$imageId = $this->imageService->persistImage($imageData, $uploadedFilePath, $estimate->getDealer()->getId());
//recupera riferimenti s3 dell'immagine appena caricata
$uploadedImage = $this->imageService->getImage($imageId);
$uploadedImagesList[] = [
'id' => $uploadedImage['id'],
'urls' => $uploadedImage['urls'],
];
//aggiorna o crea il tag estimate
$tags = $this->imageTagService->getTags('estimate', [
'tagReference' => $estimate->getId(),
'includeImages' => true,
]);
if (count($tags) == 0) {
//tag non esiste, lo crea
$tagObj = [
'tagType' => 'estimate',
'tagReference' => $estimate->getId(),
'label' => $estimate->getCode(),
'images' => [['id' => $imageId]],
];
} else {
//ogni immagine ha un solo tag 'estimate', aggiunge nuova immagine in coda
$tagObj = $tags[0];
$tagObj['images'][] = ['id' => $imageId];
}
$this->imageTagService->persistTag($tagObj);
if ($estimatePartnerId != null && $this->currentUser->getPartner()) {
//l'utente รจ partner, aggiorna o crea il tag estimatePartner
$tags = $this->imageTagService->getTags('estimate-partner', [
'tagReference' => $estimatePartnerId,
'includeImages' => true,
]);
if (!$tags) {
//tag non esiste, lo crea
$tagObj = [
'tagType' => 'estimate-partner',
'tagReference' => $estimatePartnerId,
'label' => $estimatePartnerId,
'images' => [['id' => $imageId]],
];
} else {
//un solo tag per estimate partner
$tagObj = $tags[0];
//aggiunge nuova immagine in coda
$tagObj['images'][] = ['id' => $imageId];
}
$this->imageTagService->persistTag($tagObj);
}
//aggiorna o crea il tag vehicle
if ($vehicleId) {
$tags = $this->imageTagService->getTags('vehicle', [
'tagReference' => $vehicleId,
'includeImages' => true,
]);
if (!$tags) {
//tag non esiste, lo crea
$tagObj = [
'tagType' => 'vehicle',
'tagReference' => $vehicleId,
'label' => $vehicleId,
'images' => [['id' => $imageId]],
];
} else {
//un solo tag per vehicle-part
$tagObj = $tags[0];
//aggiunge nuova immagine in coda
$tagObj['images'][] = ['id' => $imageId];
}
$this->imageTagService->persistTag($tagObj);
}
//aggiorna o crea il tag vehiclePart
if ($vehiclePart) {
$tags = $this->imageTagService->getTags('vehicle-part', [
'tagReference' => $vehiclePartId,
'includeImages' => true,
]);
if (!$tags) {
//tag non esiste, lo crea
$tagObj = [
'tagType' => 'vehicle-part',
'tagReference' => $vehiclePartId,
'label' => $vehiclePart->getLabel(),
'images' => [['id' => $imageId]],
];
} else {
//un solo tag per vehicle-part
$tagObj = $tags[0];
//aggiunge nuova immagine in coda
$tagObj['images'][] = ['id' => $imageId];
}
$this->imageTagService->persistTag($tagObj);
}
//aggiorna o crea il tag job
if ($job) {
$tags = $this->imageTagService->getTags('job', [
'tagReference' => $jobId,
'includeImages' => true,
]);
if (!$tags) {
//tag non esiste, lo crea
$tagObj = [
'tagType' => 'job',
'tagReference' => $jobId,
'label' => $job->getLabel(),
'images' => [['id' => $imageId]],
];
} else {
$tagObj = $tags[0];
//aggiunge nuova immagine in coda
$tagObj['images'][] = ['id' => $imageId];
}
$this->imageTagService->persistTag($tagObj);
}
//username and surname can be empty, but $userFullName must have a value
$userFullName = trim($this->currentUser->getName() . ' ' . $this->currentUser->getSurname() . ' ' . $this->currentUser->getCompanyName());
//aggiorna o crea il tag user
$tags = $this->imageTagService->getTags('user', [
'tagReference' => $this->currentUser->getId(),
'includeImages' => true,
]);
if (!$tags) {
//tag non esiste, lo crea
$tagObj = [
'tagType' => 'user',
'tagReference' => $this->currentUser->getId(),
'label' => $userFullName != '' ? $userFullName : $this->currentUser->getId(),
'images' => [['id' => $imageId]],
];
} else {
//ogni immagine ha un solo tag 'user', aggiunge nuova immagine in coda
$tagObj = $tags[0];
$tagObj['images'][] = ['id' => $imageId];
}
$this->imageTagService->persistTag($tagObj);
//aggiorna o crea il tag company
$company = null;
if ($this->currentUser->getDealer()) {
$company = $this->currentUser->getDealer();
}
if ($this->currentUser->getPartner()) {
$company = $this->currentUser->getPartner();
}
if ($company) {
$tags = $this->imageTagService->getTags('company', [
'tagReference' => $company->getId(),
'includeImages' => true,
]);
if (!$tags) {
//tag non esiste, lo crea
$tagObj = [
'tagType' => 'company',
'tagReference' => $company->getId(),
'label' => $company->getCompanyName(),
'images' => [['id' => $imageId]],
];
} else {
//ogni immagine ha un solo tag 'company', aggiunge nuova immagine in coda
$tagObj = $tags[0];
$tagObj['images'][] = ['id' => $imageId];
}
$this->imageTagService->persistTag($tagObj);
}
} catch (\Exception $e) {
return $this->setError('Image upload failed');
}
}
return $uploadedImagesList;
}
public function getVehicleUploadedImages($estimateId, $estimatePartnerId = null)
{
$estimate = $this->em->getRepository('App:Estimate')->find($estimateId);
if (!$estimate) {
return $this->setError('Estimate not found');
}
//estrae tutti i tag collegati all'estimate
$estimateTags = $this->imageTagService->getTags('estimate', [
'tagReference' => $estimateId,
]);
$images = [];
if ($estimateTags) {
//estrae le immagini che hanno il tag id corrispondente
$estimateTagsIds = array_column($estimateTags,'id');
foreach($estimateTagsIds as $id){
$imageObj = $this->imageService->getImages([
'tagIds' => [$id],
'includeDetails' => true,
]);
if ($imageObj) {
foreach ($imageObj['images'] as $img){
$images[] = $img;
}
}
}
}
//se settato, esclude le immagini non associate al estimatePartner
foreach ($images as $k => $image) {
if ($estimatePartnerId) {
//immagine caricata da altro partner? La escludo
if (isset($image['tags']['estimate-partner']) && count($image['tags']['estimate-partner']) > 0 && $image['tags']['estimate-partner'][0]['tagReference'] != $estimatePartnerId) {
unset($images[$k]);
}
} else {
if (isset($image['tags']['estimate-partner']) && count($image['tags']['estimate-partner']) > 0) {
unset($images[$k]);
}
}
}
return $images;
}
public function deleteUploadedImage($imageId)
{
//recupera tags associati all'immagine
$image = $this->imageService->getImage($imageId);
//elimina prima i tag associati all'immagine
$imageTags = $image['tags'];
if ($imageTags && isset($imageTags['estimate'])) {
$id = $imageTags['estimate'][0]['id'];
$images = $this->imageService->getImages(['tagIds' => [$id]]);
if ($images['result_count'] == 0) {
//nessun altra immagine, elimina tutti i tags
foreach ($imageTags as $tagType => $tags) {
foreach ($tags as $tag) {
$this->imageTagService->deleteTag($tag['id']);
}
}
}
}
$this->imageService->deleteImage($imageId);
return true;
}
public function deleteJobImages($jobPriceId)
{
//estrae tutti i tag collegati all'estimate
$jobTags = $this->imageTagService->getTags('job', [
'tagReference' => $jobPriceId,
]);
$images = [];
if ($jobTags) {
//estrae le immagini che hanno il tag estimate corrispondente
$imageObj = $this->imageService->getImages([
'tagIds' => array_column($jobTags, 'id'),
'includeDetails' => true,
]);
if ($imageObj) {
$images = $imageObj['images'];
}
}
foreach ($images as $k => $image) {
$this->deleteUploadedImage($image['id']);
}
return true;
}
public function moveImagesFromExtraToParent($childEstimate, $childEstimatePartner, $parentEstimate, $parentEstimatePartner, $vehicleIds)
{
//estimate tag
$tags = $this->imageTagService->getTags('estimate', [
'tagReference' => $childEstimate->getId(),
]);
if (!isset($tags[0])) {
return $this->setError('Estimate tag not found');
}
$tagEstimate = $tags[0];
$tagEstimate['tagReference'] = $parentEstimate->getId();
$tagEstimate['label'] = $parentEstimate->getCode();
$this->imageTagService->persistTag($tagEstimate);
//estimate partner tag
$tags = $this->imageTagService->getTags('estimate-partner', [
'tagReference' => $childEstimatePartner->getId(),
]);
if (!isset($tags[0])) {
return $this->setError('Estimate Partner tag not found');
}
$tagEstimatePartner = $tags[0];
$tagEstimatePartner['tagReference'] = $parentEstimatePartner->getId();
$tagEstimatePartner['label'] = $parentEstimatePartner->getId();
$this->imageTagService->persistTag($tagEstimatePartner);
//tag vehicle
foreach ($vehicleIds as $vehicleId) {
$vehicleTags = $this->imageTagService->getTags('vehicle', [
'tagReference' => $vehicleId['child'],
]);
if(isset($vehicleTags)){
foreach($vehicleTags as $tagVehicle){
$tagVehicle['tagReference'] = $vehicleId['parent'];
$tagVehicle['label'] = $vehicleId['parent'];
$this->imageTagService->persistTag($tagVehicle);
}
}
}
return true;
}
private function setError($message)
{
$this->hasErrors = true;
$this->errorMessage = $message;
return false;
}
public function getErrorMessage()
{
return $this->errorMessage;
}
public function hasErrors()
{
return $this->hasErrors;
}
}