<?php
namespace App\Tus\EventListener;
use App\Entity\UserUpload;
use App\Tus\Service\FileCollectorService;
use Doctrine\ORM\EntityManagerInterface;
use Roothirsch\CoreBundle\Behaviors\Attributable\MappedSuperclass\AbstractAttributable;
use Roothirsch\CoreBundle\Behaviors\Attributable\MappedSuperclass\AbstractAttributeValue;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\RouterInterface;
use TusPhp\Events\UploadComplete;
use TusPhp\Events\UploadCreated;
use TusPhp\Events\UploadProgress;
use TusPhp\File;
class TusListener implements EventSubscriberInterface
{
public function __construct(
private KernelInterface $kernel,
private RouterInterface $router,
private FileCollectorService $collectorService,
private EntityManagerInterface $entityManager,
private ?File $file = null
){}
public static function getSubscribedEvents()
{
return [
UploadComplete::NAME => ['onComplete'],
];
}
public function onComplete(UploadComplete $event){
$this->file = $event->getFile();
if(!$this->hasRequiredMetaData(['entity_id', 'entity_fqcn', 'property_name'])){
return;
}
$metaData = $this->getMetaData();
$entity = $this->entityManager->getRepository($metaData['entity_fqcn'])->find($metaData['entity_id']);
$fileCollector = $this->collectorService->findCollectorSupports($metaData['entity_fqcn']);
$fileCollector->setProperty($metaData['property_name']);
$fileCollector->setEntity($entity);
$file = $fileCollector->relocate($event->getFile());
$hash = $fileCollector->hashFile($file);
$event->getResponse()->setHeaders([
'x-file-download' => $this->router->generate('tus_file_action', [
'hash' => $hash ,
"action" => 'download'
], 0),
'x-file-delete' => $this->router->generate('tus_file_action', [
'hash' => $hash ,
"action" => 'delete'
], 0),
'x-file-id' => $hash,
'x-file-public' => str_replace($this->kernel->getProjectDir().'/public/', "", $file->getRealPath())
]);
}
private function getTargetDir(){
return $this->getUploadsDir().'/' .$this->getEntityDir();
}
private function getEntityDir()
{
return static::getEntityDirFromMeta(
$this->getMetaData('entity_fqcn'),
$this->getMetaData('property_name'),
$this->getMetaData('entity_id')
);
}
public static function getEntityDirFromMeta($class, $prop, $entityId){
if(!$class && !$prop && !$entityId) {return ''; }
return sprintf("%s/%s/%s",
strtolower((new \ReflectionClass($class))->getShortName()), // class
md5($entityId), // id
$prop
);
}
private function getUploadsDir()
{
return $this->kernel->getProjectDir().'/public/uploads';
}
private function getMetaData($key=null)
{
$meta = $this->file->details()['metadata'];
if($key === null) {
return $meta;
}
if(array_key_exists($key, $meta)){
return $meta[$key];
}
return null;
}
private function hasRequiredMetaData(array $keys){
$exists = array_filter($keys, function($key) {
return !!$this->getMetaData($key);
});
return count($keys) === count($exists);
}
}