<?php
namespace App\V4\Controller\Task;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use App\DataPersister\CustomerFile\CustomerFileDataPersister;
use App\Model\CustomerFile\CustomerFile;
use App\V4\Controller\AbstractDataPersisterAction;
use App\V4\DataPersister\Task\TaskDataPersister;
use App\V4\Exception\CannotRemindTaskChildQuoteException;
use App\V4\Exception\CannotRemindTaskParentQuoteException;
use App\V4\Logger\SentryLogger;
use App\V4\Model\Quote\Quote;
use App\V4\Model\Task\Task;
use Exception;
use InvalidArgumentException;
use ReflectionException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class TaskDataPersisterAction extends AbstractDataPersisterAction
{
/**
* @var CustomerFileDataPersister
*/
private $customerFileDataPersister;
/**
* @var ItemDataProviderInterface
*/
private $itemDataProvider;
/**
* @var SentryLogger
*/
private $sentryLogger;
/**
* @param TaskDataPersister $taskDataPersister
* @param CustomerFileDataPersister $customerFileDataPersister
* @param ItemDataProviderInterface $itemDataProvider
* @param SentryLogger $sentryLogger
*/
public function __construct(
TaskDataPersister $taskDataPersister,
CustomerFileDataPersister $customerFileDataPersister,
ItemDataProviderInterface $itemDataProvider,
SentryLogger $sentryLogger
) {
parent::__construct($taskDataPersister);
$this->customerFileDataPersister = $customerFileDataPersister;
$this->itemDataProvider = $itemDataProvider;
$this->sentryLogger = $sentryLogger;
}
/**
* {@inheritdoc}
*
* @throws Exception
*/
public function __invoke(Request $request, $data = null, ?string $id = null)
{
if ($request->get('quoteId')) {
try {
$quote = $this->itemDataProvider->getItem(Quote::class, $request->get('quoteId'));
if (!$quote instanceof Quote) {
throw new InvalidArgumentException('Quote not found');
}
if ($quote->isParent()) {
throw new CannotRemindTaskParentQuoteException();
}
if ($quote->isChild()) {
throw new CannotRemindTaskChildQuoteException();
}
} catch (Exception $exception) {
$this->sentryLogger->captureException(
SentryLogger::CHANNEL_DATA_PERSISTER,
$exception,
[
'catchOnClass' => self::class,
'quoteId' => $request->get('quoteId'),
]
);
return [];
}
}
/** @var Task|Response $taskOrResponse */
$taskOrResponse = parent::__invoke($request, $data, $id);
if (null === $taskOrResponse) {
return [];
}
if ($taskOrResponse instanceof Response && !$taskOrResponse->isSuccessful()) {
return $taskOrResponse;
}
$this->handleFiles($request, $taskOrResponse);
return $taskOrResponse;
}
/**
* @param Request $request
* @param Task $task
*
* @return void
*
* @throws Exception
*/
private function handleFiles(Request $request, Task $task): void
{
// Handle files: should delete current files ?
foreach ($request->request->get('customerFiles', []) as $key => $currentCustomerFile) {
if ($currentCustomerFile['shouldDelete'] ?? false) {
try {
$realCustomerFile = $task->getCustomerFiles()[$key] ?? null;
if (null !== $realCustomerFile && null !== $realCustomerFile->getId()) {
$this->customerFileDataPersister->remove($realCustomerFile);
$task->removeCustomerFile($realCustomerFile);
}
} catch (TransportExceptionInterface $e) {
$this->sentryLogger->captureException(
SentryLogger::CHANNEL_DATA_PERSISTER,
$e,
[
'catchOnClass' => self::class,
'taskId' => $task->getId(),
]
);
}
}
}
// Handle files: should upload new files
foreach ($request->files->get('customerFiles', []) as $key => $newCustomerFile) {
$customerFileData = ['taskId' => $task->getId()];
try {
$realCustomerFile = $this->customerFileDataPersister->persistCustomerFile($customerFileData, $newCustomerFile['customerFile']['file']);
$task->addCustomerFile((new CustomerFile())->importFromData($realCustomerFile));
$allCF = $task->getCustomerFiles();
unset($allCF[$key]);
$task->setCustomerFiles($allCF);
} catch (TransportExceptionInterface | ReflectionException $e) {
$this->sentryLogger->captureException(
SentryLogger::CHANNEL_DATA_PERSISTER,
$e,
[
'catchOnClass' => self::class,
'taskId' => $task->getId(),
]
);
}
}
}
}