1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
25: class FileResponse extends Object implements IPresenterResponse
26: {
27:
28: private $file;
29:
30:
31: private $contentType;
32:
33:
34: private $name;
35:
36:
37: public $resuming = TRUE;
38:
39:
40: 41: 42: 43: 44:
45: public function __construct($file, $name = NULL, $contentType = NULL)
46: {
47: if (!is_file($file)) {
48: throw new BadRequestException("File '$file' doesn't exist.");
49: }
50:
51: $this->file = $file;
52: $this->name = $name ? $name : basename($file);
53: $this->contentType = $contentType ? $contentType : 'application/octet-stream';
54: }
55:
56:
57: 58: 59: 60:
61: final public function getFile()
62: {
63: return $this->file;
64: }
65:
66:
67: 68: 69: 70:
71: final public function getName()
72: {
73: return $this->name;
74: }
75:
76:
77: 78: 79: 80:
81: final public function getContentType()
82: {
83: return $this->contentType;
84: }
85:
86:
87: 88: 89: 90:
91: public function send(IHttpRequest $httpRequest, IHttpResponse $httpResponse)
92: {
93: $httpResponse->setContentType($this->contentType);
94: $httpResponse->setHeader('Content-Disposition', 'attachment; filename="' . $this->name . '"');
95:
96: $filesize = $length = filesize($this->file);
97: $handle = fopen($this->file, 'r');
98:
99: if ($this->resuming) {
100: $httpResponse->setHeader('Accept-Ranges', 'bytes');
101: if (preg_match('#^bytes=(\d*)-(\d*)\z#', $httpRequest->getHeader('Range'), $matches)) {
102: list(, $start, $end) = $matches;
103: if ($start === '') {
104: $start = max(0, $filesize - $end);
105: $end = $filesize - 1;
106:
107: } elseif ($end === '' || $end > $filesize - 1) {
108: $end = $filesize - 1;
109: }
110: if ($end < $start) {
111: $httpResponse->setCode(416);
112: return;
113: }
114:
115: $httpResponse->setCode(206);
116: $httpResponse->setHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $filesize);
117: $length = $end - $start + 1;
118: fseek($handle, $start);
119:
120: } else {
121: $httpResponse->setHeader('Content-Range', 'bytes 0-' . ($filesize - 1) . '/' . $filesize);
122: }
123: }
124:
125: $httpResponse->setHeader('Content-Length', $length);
126: while (!feof($handle) && $length > 0) {
127: echo $s = fread($handle, min(4e6, $length));
128: $length -= strlen($s);
129: }
130: fclose($handle);
131: }
132:
133: }
134: