diff --git a/modules/api/php/endpoints/candidate/visit/electrophysiology/recording.class.inc b/modules/api/php/endpoints/candidate/visit/electrophysiology/recording.class.inc index 8a157798ed..d8ccd61c81 100644 --- a/modules/api/php/endpoints/candidate/visit/electrophysiology/recording.class.inc +++ b/modules/api/php/endpoints/candidate/visit/electrophysiology/recording.class.inc @@ -170,12 +170,10 @@ class Recording extends Endpoint implements \LORIS\Middleware\ETagCalculator return new \LORIS\Http\Response\JSON\NotFound($e->getMessage()); } - $mimetype = substr($recording->getMetadata('header'), 0, 4) === 'hdf5' ? - 'application/x.minc2' : 'application/octet-stream'; - $info = $recording->getFileInfo(); + $filepath = $info->getRealPath(); - if (!$info->isFile()) { + if (!$info->isFile() && !$info->isDir()) { error_log('file in database but not in file system'); return new \LORIS\Http\Response\JSON\NotFound(); } @@ -185,13 +183,25 @@ class Recording extends Endpoint implements \LORIS\Middleware\ETagCalculator return new \LORIS\Http\Response\JSON\NotFound(); } - $body = new \LORIS\Http\FileStream($info->getRealPath(), 'r'); + // Tar the acquisition file if it is actually a directory (such as for MEG + // CTF acquisitions). + if ($info->isDir()) { + $filename = $this->_filename . '.tar'; + $mimetype = 'application/x-tar'; + $body = new \LORIS\Http\ArchiveStream($filepath); + } else { + $filename = $this->_filename; + $mimetype = substr($recording->getMetadata('header'), 0, 4) === 'hdf5' + ? 'application/x.minc2' + : 'application/octet-stream'; + $body = new \LORIS\Http\FileStream($filepath, 'r'); + } return (new \LORIS\Http\Response()) ->withHeader('Content-Type', $mimetype) ->withHeader( 'Content-Disposition', - 'attachment; filename=' . $this->_filename + 'attachment; filename=' . $filename ) ->withBody($body); } diff --git a/modules/electrophysiology_browser/jsx/components/DownloadPanel.js b/modules/electrophysiology_browser/jsx/components/DownloadPanel.js index a2d60828d9..4a76a8373e 100644 --- a/modules/electrophysiology_browser/jsx/components/DownloadPanel.js +++ b/modules/electrophysiology_browser/jsx/components/DownloadPanel.js @@ -33,7 +33,7 @@ class DownloadPanel extends Component { * @return {JSX} - React markup for the component */ render() { - const {t} = this.props; + const {t, dccid, visit, physioFileName} = this.props; return ( { const disabled = (download.file === ''); + let recordingFileUrl = `/api/v0.0.3/candidates/${dccid}/` + + `${visit}/recordings/${physioFileName}`; + + switch (type) { + case 'physiological_event_files': + recordingFileUrl += '/bidsfiles/events'; + break; + case 'all_files': + recordingFileUrl += '/bidsfiles/archive'; + break; + case 'physiological_channel_file': + recordingFileUrl += '/bidsfiles/channels'; + break; + case 'physiological_electrode_file': + recordingFileUrl += '/bidsfiles/electrodes'; + break; + } + // Ignore physiological_coord_system_file return type !== 'physiological_coord_system_file' ? ( @@ -93,13 +111,13 @@ class DownloadPanel extends Component { : diff --git a/src/Http/ArchiveStream.php b/src/Http/ArchiveStream.php new file mode 100644 index 0000000000..723460e5a9 --- /dev/null +++ b/src/Http/ArchiveStream.php @@ -0,0 +1,66 @@ +archivePath = sys_get_temp_dir() . '/' . uniqid() . '.tar'; + + $phar = new \PharData($this->archivePath); + $phar->buildFromDirectory($directoryPath); + + parent::__construct($this->archivePath, 'r'); + } + + /** + * {@inheritdoc} + */ + public function close(): void + { + parent::close(); + + if (file_exists($this->archivePath)) { + unlink($this->archivePath); + } + } +}