-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathAbstractResponseFactory.php
More file actions
108 lines (87 loc) · 3.21 KB
/
AbstractResponseFactory.php
File metadata and controls
108 lines (87 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
namespace Igorw\FileServeBundle\Response;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
abstract class AbstractResponseFactory
{
protected $baseDir;
protected $skipFileExists;
protected $requestStack;
protected $fullFilename;
protected $contentType;
protected $options;
public function __construct($baseDir, RequestStack $requestStack, $skipFileExists = false)
{
$this->baseDir = $baseDir;
$this->requestStack = $requestStack;
$this->skipFileExists = $skipFileExists;
}
public function create($filename, $contentType = 'application/octet-stream', $options = array())
{
$this->options = $options;
$this->fullFilename = (!empty($this->options['absolute_path'])) ? $filename : $this->baseDir.'/'.$filename;
$this->contentType = $contentType;
if (!$this->skipFileExists && !is_readable($this->fullFilename)) {
throw new \InvalidArgumentException(sprintf("Provided filename '%s' for %s is not readable.", $this->fullFilename, __METHOD__));
}
$this->parseOptions();
$response = $this->createResponse();
$this->setResponseHeaders($response);
return $response;
}
protected function parseOptions()
{
$this->options['serve_filename'] = isset($this->options['serve_filename']) ? $this->options['serve_filename'] : basename($this->fullFilename);
$this->options['inline'] = isset($this->options['inline']) ? (Bool) $this->options['inline'] : true;
}
protected function createResponse()
{
$response = new Response();
return $response;
}
protected function setResponseHeaders(Response $response)
{
$response->headers->set('Cache-Control', 'public');
$response->headers->set('Content-Type', $this->contentType);
$response->headers->set('Content-Disposition', $this->resolveDispositionHeader($this->options));
}
protected function resolveDispositionHeader(array $options)
{
$disposition = $this->options['inline'] ? 'inline' : 'attachment';
$filename = $this->options['serve_filename'];
return "$disposition; ".$this->resolveDispositionHeaderFilename($filename);
}
/**
* @param string $filename
*
* @return string
*/
protected function resolveDispositionHeaderFilename($filename)
{
if ($this->clientSupportsUtf8Filename()) {
$dispositionHeaderFilename = "filename*=UTF-8''".rawurlencode($filename);
} else {
$dispositionHeaderFilename = "filename=".rawurlencode($filename);
}
return $dispositionHeaderFilename;
}
/**
* Algorithm inspired by phpBB3
*
* @throws \LogicException
*
* @return bool
*/
private function clientSupportsUtf8Filename()
{
$request = $this->requestStack->getCurrentRequest();
if (is_null($request)) {
throw new \LogicException('Current request is not available');
}
$userAgent = $request->headers->get('User-Agent');
if (preg_match('#MSIE|Safari|Konqueror#', $userAgent)) {
return false;
}
return true;
}
}