<?php /* * This file is part of Anis Server. * * (c) Laboratoire d'Astrophysique de Marseille / CNRS * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ declare(strict_types=1); namespace App\Action; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; use Doctrine\ORM\EntityManagerInterface; use Slim\Exception\HttpNotFoundException; use Nyholm\Psr7\Factory\Psr17Factory; /** * @author François Agneray <francois.agneray@lam.fr> * @package App\Action */ final class DownloadFileAction extends AbstractAction { /** * Contains anis-server data path * * @var string */ private $dataPath; /** * Contains settings to handle Json Web Token * * @var array */ private $settings; /** * Create the classe before call __invoke to execute the action * * @param EntityManagerInterface $em Doctrine Entity Manager Interface * @param string $dataPath Contains anis-server data path * @param array $settings Settings about token */ public function __construct(EntityManagerInterface $em, string $dataPath, array $settings) { parent::__construct($em); $this->dataPath = $dataPath; $this->settings = $settings; } /** * `GET` Returns the file found * * @param ServerRequestInterface $request PSR-7 This object represents the HTTP request * @param ResponseInterface $response PSR-7 This object represents the HTTP response * @param string[] $args This table contains information transmitted in the URL (see routes.php) * * @return ResponseInterface */ public function __invoke(Request $request, Response $response, array $args): Response { if ($request->getMethod() === OPTIONS) { return $response->withHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); } // Search the correct dataset with primary key $datasetName = $args['dname']; $dataset = $this->em->find('App\Entity\Dataset', $datasetName); // If dataset is not found 404 if (is_null($dataset)) { throw new HttpNotFoundException( $request, 'Dataset with name ' . $datasetName . ' is not found' ); } // If dataset is private and authorization enabled if (!$dataset->getPublic() && boolval($this->settings['enabled'])) { $this->verifyDatasetAuthorization($request, $dataset->getName(), $this->settings['admin_role']); } // Search the file $filePath = $this->dataPath . $dataset->getFullDataPath() . DIRECTORY_SEPARATOR . $args['fpath']; // If the file not found 404 if (!file_exists($filePath)) { throw new HttpNotFoundException( $request, 'File with path ' . $args['fpath'] . ' is not found for the dataset ' . $datasetName ); } // If the file found so stream it $psr17Factory = new Psr17Factory(); $stream = $psr17Factory->createStreamFromFile($filePath, 'r'); return $response->withBody($stream) ->withHeader('Content-Disposition', 'attachment; filename=' . basename($filePath) . ';') ->withHeader('Content-Type', mime_content_type($filePath)) ->withHeader('Content-Length', filesize($filePath)); } }