Files
chill-bundles/src/Bundle/ChillWopiBundle/src/Controller/Convert.php

98 lines
3.7 KiB
PHP

<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\WopiBundle\Controller;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Service\StoredObjectManager;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Chill\MainBundle\Entity\User;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\Multipart\FormDataPart;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
class Convert
{
private const LOG_PREFIX = '[convert] ';
private string $collaboraDomain;
/**
* @param StoredObjectManager $storedObjectManager
*/
public function __construct(
private HttpClientInterface $httpClient,
private RequestStack $requestStack,
private Security $security,
private StoredObjectManagerInterface $storedObjectManager,
private LoggerInterface $logger,
ParameterBagInterface $parameters
) {
$this->collaboraDomain = $parameters->get('wopi')['server'];
}
public function __invoke(StoredObject $storedObject): Response
{
if (!$this->security->getUser() instanceof User) {
throw new AccessDeniedHttpException('User must be authenticated');
}
$content = $this->storedObjectManager->read($storedObject);
$query = [];
if (null !== $request = $this->requestStack->getCurrentRequest()) {
$query['lang'] = $request->getLocale();
}
try {
$url = sprintf('%s/cool/convert-to/pdf', $this->collaboraDomain);
$form = new FormDataPart([
'data' => new DataPart($content, $storedObject->getUuid()->toString(), $storedObject->getType()),
]);
$response = $this->httpClient->request('POST', $url, [
'headers' => $form->getPreparedHeaders()->toArray(),
'query' => $query,
'body' => $form->bodyToString(),
'timeout' => 10,
]);
return new Response($response->getContent(), Response::HTTP_OK, [
'Content-Type' => 'application/pdf',
]);
} catch (ClientExceptionInterface|TransportExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface $exception) {
return $this->onConversionFailed($url, $exception->getResponse());
}
}
private function onConversionFailed(string $url, ResponseInterface $response): JsonResponse
{
$this->logger->error(self::LOG_PREFIX . ' could not convert document', [
'response_status' => $response->getStatusCode(),
'message' => $response->getContent(false),
'server' => $this->collaboraDomain,
'url' => $url,
]);
return new JsonResponse(['message' => 'conversion failed : ' . $response->getContent(false)], Response::HTTP_SERVICE_UNAVAILABLE);
}
}