2015-08-17 17:00:26 -07:00
< ? php
namespace Drupal\system ;
use Drupal\Core\Controller\ControllerBase ;
use Symfony\Component\HttpFoundation\Request ;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException ;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException ;
use Symfony\Component\HttpFoundation\BinaryFileResponse ;
/**
* System file controller .
*/
class FileDownloadController extends ControllerBase {
/**
* Handles private file transfers .
*
* Call modules that implement hook_file_download () to find out if a file is
* accessible and what headers it should be transferred with . If one or more
* modules returned headers the download will start with the returned headers .
* If a module returns - 1 an AccessDeniedHttpException will be thrown . If the
* file exists but no modules responded an AccessDeniedHttpException will be
* thrown . If the file does not exist a NotFoundHttpException will be thrown .
*
* @ see hook_file_download ()
*
* @ param \Symfony\Component\HttpFoundation\Request $request
* The request object .
* @ param string $scheme
* The file scheme , defaults to 'private' .
*
2015-11-04 11:11:27 -08:00
* @ return \Symfony\Component\HttpFoundation\BinaryFileResponse
* The transferred file as response .
*
2015-08-17 17:00:26 -07:00
* @ throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
* Thrown when the requested file does not exist .
* @ throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
* Thrown when the user does not have access to the file .
*/
public function download ( Request $request , $scheme = 'private' ) {
$target = $request -> query -> get ( 'file' );
// Merge remaining path arguments into relative file path.
$uri = $scheme . '://' . $target ;
if ( file_stream_wrapper_valid_scheme ( $scheme ) && file_exists ( $uri )) {
// Let other modules provide headers and controls access to the file.
2017-04-13 15:53:35 +01:00
$headers = $this -> moduleHandler () -> invokeAll ( 'file_download' , [ $uri ]);
2015-08-17 17:00:26 -07:00
foreach ( $headers as $result ) {
if ( $result == - 1 ) {
throw new AccessDeniedHttpException ();
}
}
if ( count ( $headers )) {
2015-10-08 11:40:12 -07:00
// \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond()
// sets response as not cacheable if the Cache-Control header is not
// already modified. We pass in FALSE for non-private schemes for the
// $public parameter to make sure we don't change the headers.
return new BinaryFileResponse ( $uri , 200 , $headers , $scheme !== 'private' );
2015-08-17 17:00:26 -07:00
}
throw new AccessDeniedHttpException ();
}
throw new NotFoundHttpException ();
}
}