diff --git a/modules/api/php/endpoints/candidate/visit/image/format.class.inc b/modules/api/php/endpoints/candidate/visit/image/format.class.inc index d211146fb25..781df707249 100644 --- a/modules/api/php/endpoints/candidate/visit/image/format.class.inc +++ b/modules/api/php/endpoints/candidate/visit/image/format.class.inc @@ -90,7 +90,11 @@ class Format extends Endpoint $handler = new Format\Brainbrowser($this->_image); break; case 'thumbnail': - $handler = new Format\Thumbnail($this->_image); + case 'nifti': + case 'bval': + case 'bvec': + case 'bidsjson': + $handler = new Format\DownloadFile($this->_image, $format); break; default: return new \LORIS\Http\Response\JSON\UnsupportedMediaType(); diff --git a/modules/api/php/endpoints/candidate/visit/image/format/thumbnail.class.inc b/modules/api/php/endpoints/candidate/visit/image/format/downloadfile.class.inc similarity index 57% rename from modules/api/php/endpoints/candidate/visit/image/format/thumbnail.class.inc rename to modules/api/php/endpoints/candidate/visit/image/format/downloadfile.class.inc index 3bc3e122447..3ebd104d33a 100644 --- a/modules/api/php/endpoints/candidate/visit/image/format/thumbnail.class.inc +++ b/modules/api/php/endpoints/candidate/visit/image/format/downloadfile.class.inc @@ -23,24 +23,50 @@ use \LORIS\api\Endpoint; * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 * @link https://github.com/aces/Loris */ -class Thumbnail extends Endpoint implements \LORIS\Middleware\ETagCalculator +class DownloadFile extends Endpoint implements \LORIS\Middleware\ETagCalculator { - - /** - * The requested Image - * - * @var \LORIS\Image - */ - private $_image; + private $_format; + private $_info; + private $_file_type; + private $_content_type; /** * Contructor * - * @param \LORIS\Image $image The requested image + * @param \LORIS\Image $image The requested image + * @param string $format The format user wishes to download */ - public function __construct(\LORIS\Image $image) + public function __construct(\LORIS\Image $image, string $format) { - $this->_image = $image; + $this->_format = $format; + + switch ($this->_format) { + case 'thumbnail': + $this->_info = $image->getThumbnailFileInfo(); + $this->_file_type = "Thumbnail"; + $this->_content_type = 'image/jpeg'; + break; + case 'nifti': + $this->_info = $image->getNiiFileInfo(); + $this->_file_type = "NIfTI"; + $this->_content_type = 'application/octet-stream'; + break; + case 'bval': + $this->_info = $image->getBvalFileInfo(); + $this->_file_type = "NIfTI BVAL"; + $this->_content_type = 'application/text'; + break; + case 'bvec': + $this->_info = $image->getBvecFileInfo(); + $this->_file_type = "NIfTI BVEC"; + $this->_content_type = 'application/text'; + break; + case 'bidsjson': + $this->_info = $image->getBidsJsonFileInfo(); + $this->_file_type = "BIDS JSON"; + $this->_content_type = 'application/json'; + break; + } } /** @@ -100,23 +126,22 @@ class Thumbnail extends Endpoint implements \LORIS\Middleware\ETagCalculator */ private function _handleGET(): ResponseInterface { - $info = $this->_image->getThumbnailFileInfo(); - - if (!$info->isFile()) { - error_log('Thumbnail not found'); + if (!$this->_info->isFile()) { + $this->logger->error("$this->_file_type file not found"); return new \LORIS\Http\Response\JSON\NotFound(); } - if (!$info->isReadable()) { - error_log('Thumbnail exists but is not readable by webserver'); + if (!$this->_info->isReadable()) { + $this->logger->error( + "$this->_file_type file exists but is not readable by webserver" + ); return new \LORIS\Http\Response\JSON\NotFound(); } - $filename = $info->getFilename(); - - $realpath = $info->getRealPath(); + $filename = $this->_info->getFilename(); + $realpath = $this->_info->getRealPath(); if ($realpath === false) { - $realpath = $info->getPath() . "/" . $info->getFilename(); + $realpath = $this->_info->getPath() . "/" . $this->_info->getFilename(); } $body = new \LORIS\Http\FileStream($realpath, 'r'); @@ -125,7 +150,7 @@ class Thumbnail extends Endpoint implements \LORIS\Middleware\ETagCalculator $body, 200, [ - 'Content-Type' => 'image/jpeg', + 'Content-Type' => $this->_content_type, 'Content-Disposition' => 'attachment; filename=' . $filename, ] ); @@ -140,16 +165,15 @@ class Thumbnail extends Endpoint implements \LORIS\Middleware\ETagCalculator */ public function ETag(ServerRequestInterface $request) : string { - $info = $this->_image->getThumbnailFileInfo(); - if (!$info->isFile() || !$info->isReadable()) { + if (!$this->_info->isFile() || !$this->_info->isReadable()) { return ''; } $signature = [ - 'filename' => $info->getFilename(), - 'size' => $info->getSize(), - 'mtime' => $info->getMTime(), + 'filename' => $this->_info->getFilename(), + 'size' => $this->_info->getSize(), + 'mtime' => $this->_info->getMTime(), ]; return md5(json_encode($signature)); diff --git a/modules/imaging_browser/jsx/ImagePanel.js b/modules/imaging_browser/jsx/ImagePanel.js index ba47d4430e0..43b1d865f2f 100644 --- a/modules/imaging_browser/jsx/ImagePanel.js +++ b/modules/imaging_browser/jsx/ImagePanel.js @@ -671,6 +671,7 @@ DownloadButton.propTypes = { FileName: PropTypes.string, BaseURL: PropTypes.string, Label: PropTypes.string, + URL: PropTypes.string, }; @@ -826,22 +827,30 @@ class ImageDownloadButtons extends Component { BaseURL={this.props.BaseURL} Label="Download NRRD" /> - - - - + { this.props.NiiFile ? + : + null + } + {this.props.BvalFile ? + : + null + } + {this.props.BvecFile ? + : + null + } + {this.props.JsonFile ? + : + null + } $OtherTimepoints, 'CaveatViolationsResolvedID' => $caveatViolationsResolvedID, ]; + $this->tpl_data['files'][] = $file; } } diff --git a/php/libraries/Image.class.inc b/php/libraries/Image.class.inc index 7c6b128edea..0c564144281 100644 --- a/php/libraries/Image.class.inc +++ b/php/libraries/Image.class.inc @@ -38,6 +38,7 @@ class Image private \CenterID $_centerid; private $_entitytype; + /** * Constructor * @@ -58,7 +59,7 @@ class Image s.CenterID as centerid, c.Entity_type as entitytype FROM - files f + files f LEFT JOIN session s ON (f.SessionID = s.ID) LEFT JOIN candidate c @@ -80,7 +81,6 @@ class Image $this->_filetype = $dbrow['filetype']; $this->_centerid = new \CenterID($dbrow['centerid']); $this->_entitytype = $dbrow['entitytype']; - } } @@ -100,7 +100,7 @@ class Image SELECT Value FROM - parameter_file pf + parameter_file pf JOIN parameter_type pt USING (ParameterTypeID) JOIN files f @@ -132,7 +132,7 @@ class Image pt.Name as name, pf.Value as value FROM - parameter_file pf + parameter_file pf JOIN parameter_type pt USING (ParameterTypeID) JOIN files f @@ -253,6 +253,46 @@ class Image return $this->_getFullPath($this->_filelocation); } + /** + * Return a SPLFileInfo object based on this images's properties. + * + * @return \SplFileInfo + */ + public function getNiiFileInfo(): \SplFileInfo + { + return $this->_getFullPath($this->getHeader('check_nii_filename')); + } + + /** + * Return a SPLFileInfo object based on this images's properties. + * + * @return \SplFileInfo + */ + public function getBvalFileInfo(): \SplFileInfo + { + return $this->_getFullPath($this->getHeader('check_bval_filename')); + } + + /** + * Return a SPLFileInfo object based on this images's properties. + * + * @return \SplFileInfo + */ + public function getBvecFileInfo(): \SplFileInfo + { + return $this->_getFullPath($this->getHeader('check_bvec_filename')); + } + + /** + * Return a SPLFileInfo object based on this images's properties. + * + * @return \SplFileInfo + */ + public function getBidsJsonFileInfo(): \SplFileInfo + { + return $this->_getFullPath($this->getHeader('bids_json_file')); + } + /** * Return a SPLFileInfo object based on this images's thumbnail properties. * diff --git a/src/Http/Endpoint.php b/src/Http/Endpoint.php index b0c61682422..856256daa2f 100644 --- a/src/Http/Endpoint.php +++ b/src/Http/Endpoint.php @@ -28,6 +28,8 @@ */ abstract class Endpoint implements RequestHandlerInterface { + use \PSR\Log\LoggerAwareTrait; + /** * An Endpoint overrides the default LORIS middleware to remove the * PageDecorationMiddleware. @@ -41,6 +43,13 @@ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { + $loris = $request->getAttribute('loris'); + $loglevel = $loris->getConfiguration() + ->getLogSettings() + ->getRequestLogLevel(); + + $this->logger = new \LORIS\Log\ErrorLogLogger($loglevel); + $interfaces = class_implements($handler); if (in_array('LORIS\Middleware\ETagCalculator', $interfaces)) { return (new \LORIS\Middleware\ETag())->process($request, $handler);