refactor: Update ChillWopiBundle - Work in progress.

This commit is contained in:
Pol Dellaiera 2021-08-17 14:33:28 +02:00 committed by Marc Ducobu
parent f358f1af8d
commit cefc4096c5
3 changed files with 46 additions and 65 deletions

View File

@ -9,8 +9,6 @@ declare(strict_types=1);
namespace Symfony\Component\DependencyInjection\Loader\Configurator; namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use OpenStack\OpenStack;
return static function (ContainerConfigurator $container) { return static function (ContainerConfigurator $container) {
$services = $container $services = $container
->services(); ->services();

View File

@ -7,6 +7,7 @@ namespace Chill\WopiBundle\Service\OpenStack;
use OpenStack\OpenStack; use OpenStack\OpenStack;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
// TODO: Remove extends - Ugly.
final class Client extends OpenStack implements OpenStackClientInterface final class Client extends OpenStack implements OpenStackClientInterface
{ {
private ParameterBagInterface $parameterBag; private ParameterBagInterface $parameterBag;

View File

@ -7,36 +7,42 @@
declare(strict_types=1); declare(strict_types=1);
namespace Chill\WopiBundle\Service; namespace Chill\WopiBundle\Service\Wopi;
use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface;
use ChampsLibres\WopiLib\Discovery\WopiDiscoveryInterface; use ChampsLibres\WopiLib\Discovery\WopiDiscoveryInterface;
use ChampsLibres\WopiLib\WopiInterface; use ChampsLibres\WopiLib\WopiInterface;
use Chill\DocStoreBundle\Repository\StoredObjectRepository;
use Exception;
use loophp\psr17\Psr17Interface; use loophp\psr17\Psr17Interface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\KernelInterface;
final class OpenstackWopi implements WopiInterface final class ChillWopi implements WopiInterface
{ {
private string $filesRepository;
private Filesystem $fs;
private KernelInterface $kernel;
private Psr17Interface $psr17; private Psr17Interface $psr17;
private WopiDiscoveryInterface $wopiDiscovery; private WopiDiscoveryInterface $wopiDiscovery;
public function __construct(Psr17Interface $psr17, KernelInterface $kernel, WopiDiscoveryInterface $wopiDiscovery) private StoredObjectRepository $storedObjectRepository;
{
$this->kernel = $kernel; private ClientInterface $httpClient;
private TempUrlGeneratorInterface $tempUrlGeneratorInterface;
public function __construct(
Psr17Interface $psr17,
WopiDiscoveryInterface $wopiDiscovery,
StoredObjectRepository $storedObjectRepository,
ClientInterface $httpClient,
TempUrlGeneratorInterface $tempUrlGeneratorInterface
) {
$this->psr17 = $psr17; $this->psr17 = $psr17;
$this->wopiDiscovery = $wopiDiscovery; $this->wopiDiscovery = $wopiDiscovery;
$this->fs = new Filesystem(); $this->storedObjectRepository = $storedObjectRepository;
$this->filesRepository = sprintf('%s/files', $this->kernel->getCacheDir()); $this->httpClient = $httpClient;
$this->fs->mkdir($this->filesRepository); $this->tempUrlGeneratorInterface = $tempUrlGeneratorInterface;
} }
public function checkFileInfo( public function checkFileInfo(
@ -44,19 +50,10 @@ final class OpenstackWopi implements WopiInterface
?string $accessToken, ?string $accessToken,
RequestInterface $request RequestInterface $request
): ResponseInterface { ): ResponseInterface {
$filepath = sprintf( $storedObject = $this->storedObjectRepository->findOneBy(['filename' => $fileId]);
'%s/%s', $mimeType = $storedObject->getType();
$this->filesRepository,
$fileId
);
if (!$this->fs->exists($filepath)) { if (false !== current($this->wopiDiscovery->discoverMimeType($mimeType))) {
$this->fs->touch($filepath);
}
$filepathInfo = pathinfo($filepath);
if (false !== current($this->wopiDiscovery->discoverExtension($filepathInfo['extension']))) {
// TODO Exception. // TODO Exception.
} }
@ -66,9 +63,9 @@ final class OpenstackWopi implements WopiInterface
->withHeader('Content-Type', 'application/json') ->withHeader('Content-Type', 'application/json')
->withBody($this->psr17->createStream((string) json_encode( ->withBody($this->psr17->createStream((string) json_encode(
[ [
'BaseFileName' => $filepathInfo['basename'], 'BaseFileName' => $storedObject->getFilename(),
'OwnerId' => uniqid(), 'OwnerId' => uniqid(),
'Size' => filesize($filepath), 'Size' => 0,
'UserId' => uniqid(), 'UserId' => uniqid(),
'Version' => 'v' . uniqid(), 'Version' => 'v' . uniqid(),
'ReadOnly' => false, 'ReadOnly' => false,
@ -77,7 +74,7 @@ final class OpenstackWopi implements WopiInterface
'SupportsLocks' => true, 'SupportsLocks' => true,
'UserFriendlyName' => 'User Name ' . uniqid(), 'UserFriendlyName' => 'User Name ' . uniqid(),
'UserExtraInfo' => [], 'UserExtraInfo' => [],
'LastModifiedTime' => date('Y-m-d\TH:i:s.u\Z', filemtime($filepath)), 'LastModifiedTime' => date('Y-m-d\TH:i:s.u\Z', $storedObject->getCreationDate()),
'CloseButtonClosesWindow' => true, 'CloseButtonClosesWindow' => true,
'EnableInsertRemoteImage' => true, 'EnableInsertRemoteImage' => true,
'EnableShare' => true, 'EnableShare' => true,
@ -105,11 +102,13 @@ final class OpenstackWopi implements WopiInterface
public function getFile(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface public function getFile(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface
{ {
$filepath = sprintf( $storedObject = $this->storedObjectRepository->findOneBy(['filename' => $fileId]);
'%s/%s',
$this->filesRepository, // TODO: Add strict typing in champs-libres/async-uploader-bundle
$fileId /** @var StdClass $object */
); $object = $this->tempUrlGeneratorInterface->generate('GET', $storedObject->getFilename());
$response = $this->httpClient->sendRequest($this->psr17->createRequest('GET', $object->url));
return $this return $this
->psr17 ->psr17
@ -120,9 +119,9 @@ final class OpenstackWopi implements WopiInterface
) )
->withHeader( ->withHeader(
'Content-Disposition', 'Content-Disposition',
sprintf('attachment; filename=%s', basename($filepath)) sprintf('attachment; filename=%s', $storedObject->getFilename())
) )
->withBody($this->psr17->createStreamFromFile($filepath)); ->withBody($response->getBody());
} }
public function getLock(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface public function getLock(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface
@ -196,34 +195,17 @@ final class OpenstackWopi implements WopiInterface
string $xWopiEditors, string $xWopiEditors,
RequestInterface $request RequestInterface $request
): ResponseInterface { ): ResponseInterface {
$filepath = sprintf( $storedObject = $this->storedObjectRepository->findOneBy(['filename' => $fileId]);
'%s/%s',
$this->filesRepository,
$fileId
);
$lockFilepath = $this->getLockFilepath($fileId); // TODO: Add strict typing in champs-libres/async-uploader-bundle
/** @var StdClass $object */
$object = $this->tempUrlGeneratorInterface->generate('PUT', $storedObject->getFilename());
if ($this->fs->exists($lockFilepath)) { $response = $this->httpClient->sendRequest($this->psr17->createRequest('PUT', $object->url)->withBody($request->getBody()));
$previousLockData = json_decode(file_get_contents($lockFilepath));
if ($previousLockData->lock !== $xWopiLock) { if (200 !== $response->getStatusCode())
return $this {
->psr17 throw new Exception('Error in response.');
->createResponse(409)
->withAddedHeader('X-WOPI-Lock', $previousLockData->lock);
}
}
$return = file_put_contents(
$filepath,
(string) $request->getBody()
);
if (false === $return) {
return $this
->psr17
->createResponse(500);
} }
return $this return $this