Overview

Namespaces

  • Composer
    • Autoload
  • Guzzle
    • Common
      • Exception
    • Http
      • Curl
      • Exception
      • Message
        • Header
      • QueryAggregator
    • Parser
      • Cookie
      • Message
      • UriTemplate
      • Url
    • Plugin
      • Mock
    • Stream
  • Mockery
    • Adapter
      • Phpunit
    • CountValidator
    • Exception
    • Generator
      • StringManipulation
        • Pass
    • Loader
    • Matcher
  • None
  • Omnipay
    • Common
      • Exception
      • Message
    • Dummy
      • Message
    • Fatzebra
      • Message
  • PHP
  • Symfony
    • Component
      • EventDispatcher
        • Debug
        • DependencyInjection
        • Tests
          • Debug
          • DependencyInjection
      • HttpFoundation
        • File
          • Exception
          • MimeType
        • Session
          • Attribute
          • Flash
          • Storage
            • Handler
            • Proxy
        • Tests
          • File
            • MimeType
          • Session
            • Attribute
            • Flash
            • Storage
              • Handler
              • Proxy
      • Yaml
        • Exception
        • Tests

Classes

  • Symfony\Component\Yaml\Tests\A
  • Symfony\Component\Yaml\Tests\B
  • Symfony\Component\Yaml\Tests\DumperTest
  • Symfony\Component\Yaml\Tests\InlineTest
  • Symfony\Component\Yaml\Tests\ParseExceptionTest
  • Symfony\Component\Yaml\Tests\ParserTest
  • Symfony\Component\Yaml\Tests\YamlTest
  • Overview
  • Namespace
  • Function
  • Tree
  1: <?php
  2: 
  3: /*
  4:  * This file is part of the Symfony package.
  5:  *
  6:  * (c) Fabien Potencier <fabien@symfony.com>
  7:  *
  8:  * For the full copyright and license information, please view the LICENSE
  9:  * file that was distributed with this source code.
 10:  */
 11: 
 12: namespace Symfony\Component\HttpFoundation;
 13: 
 14: use Symfony\Component\HttpFoundation\File\File;
 15: use Symfony\Component\HttpFoundation\File\Exception\FileException;
 16: 
 17: /**
 18:  * BinaryFileResponse represents an HTTP response delivering a file.
 19:  *
 20:  * @author Niklas Fiekas <niklas.fiekas@tu-clausthal.de>
 21:  * @author stealth35 <stealth35-php@live.fr>
 22:  * @author Igor Wiedler <igor@wiedler.ch>
 23:  * @author Jordan Alliot <jordan.alliot@gmail.com>
 24:  * @author Sergey Linnik <linniksa@gmail.com>
 25:  */
 26: class BinaryFileResponse extends Response
 27: {
 28:     protected static $trustXSendfileTypeHeader = false;
 29: 
 30:     protected $file;
 31:     protected $offset;
 32:     protected $maxlen;
 33:     protected $deleteFileAfterSend = false;
 34: 
 35:     /**
 36:      * Constructor.
 37:      *
 38:      * @param \SplFileInfo|string $file               The file to stream
 39:      * @param int                 $status             The response status code
 40:      * @param array               $headers            An array of response headers
 41:      * @param bool                $public             Files are public by default
 42:      * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename
 43:      * @param bool                $autoEtag           Whether the ETag header should be automatically set
 44:      * @param bool                $autoLastModified   Whether the Last-Modified header should be automatically set
 45:      */
 46:     public function __construct($file, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
 47:     {
 48:         parent::__construct(null, $status, $headers);
 49: 
 50:         $this->setFile($file, $contentDisposition, $autoEtag, $autoLastModified);
 51: 
 52:         if ($public) {
 53:             $this->setPublic();
 54:         }
 55:     }
 56: 
 57:     /**
 58:      * @param \SplFileInfo|string $file               The file to stream
 59:      * @param int                 $status             The response status code
 60:      * @param array               $headers            An array of response headers
 61:      * @param bool                $public             Files are public by default
 62:      * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename
 63:      * @param bool                $autoEtag           Whether the ETag header should be automatically set
 64:      * @param bool                $autoLastModified   Whether the Last-Modified header should be automatically set
 65:      *
 66:      * @return BinaryFileResponse The created response
 67:      */
 68:     public static function create($file = null, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
 69:     {
 70:         return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified);
 71:     }
 72: 
 73:     /**
 74:      * Sets the file to stream.
 75:      *
 76:      * @param \SplFileInfo|string $file               The file to stream
 77:      * @param string              $contentDisposition
 78:      * @param bool                $autoEtag
 79:      * @param bool                $autoLastModified
 80:      *
 81:      * @return BinaryFileResponse
 82:      *
 83:      * @throws FileException
 84:      */
 85:     public function setFile($file, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
 86:     {
 87:         if (!$file instanceof File) {
 88:             if ($file instanceof \SplFileInfo) {
 89:                 $file = new File($file->getPathname());
 90:             } else {
 91:                 $file = new File((string) $file);
 92:             }
 93:         }
 94: 
 95:         if (!$file->isReadable()) {
 96:             throw new FileException('File must be readable.');
 97:         }
 98: 
 99:         $this->file = $file;
100: 
101:         if ($autoEtag) {
102:             $this->setAutoEtag();
103:         }
104: 
105:         if ($autoLastModified) {
106:             $this->setAutoLastModified();
107:         }
108: 
109:         if ($contentDisposition) {
110:             $this->setContentDisposition($contentDisposition);
111:         }
112: 
113:         return $this;
114:     }
115: 
116:     /**
117:      * Gets the file.
118:      *
119:      * @return File The file to stream
120:      */
121:     public function getFile()
122:     {
123:         return $this->file;
124:     }
125: 
126:     /**
127:      * Automatically sets the Last-Modified header according the file modification date.
128:      */
129:     public function setAutoLastModified()
130:     {
131:         $this->setLastModified(\DateTime::createFromFormat('U', $this->file->getMTime()));
132: 
133:         return $this;
134:     }
135: 
136:     /**
137:      * Automatically sets the ETag header according to the checksum of the file.
138:      */
139:     public function setAutoEtag()
140:     {
141:         $this->setEtag(sha1_file($this->file->getPathname()));
142: 
143:         return $this;
144:     }
145: 
146:     /**
147:      * Sets the Content-Disposition header with the given filename.
148:      *
149:      * @param string $disposition      ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT
150:      * @param string $filename         Optionally use this filename instead of the real name of the file
151:      * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename
152:      *
153:      * @return BinaryFileResponse
154:      */
155:     public function setContentDisposition($disposition, $filename = '', $filenameFallback = '')
156:     {
157:         if ($filename === '') {
158:             $filename = $this->file->getFilename();
159:         }
160: 
161:         $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback);
162:         $this->headers->set('Content-Disposition', $dispositionHeader);
163: 
164:         return $this;
165:     }
166: 
167:     /**
168:      * {@inheritdoc}
169:      */
170:     public function prepare(Request $request)
171:     {
172:         $this->headers->set('Content-Length', $this->file->getSize());
173: 
174:         if (!$this->headers->has('Accept-Ranges')) {
175:             // Only accept ranges on safe HTTP methods
176:             $this->headers->set('Accept-Ranges', $request->isMethodSafe() ? 'bytes' : 'none');
177:         }
178: 
179:         if (!$this->headers->has('Content-Type')) {
180:             $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
181:         }
182: 
183:         if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
184:             $this->setProtocolVersion('1.1');
185:         }
186: 
187:         $this->ensureIEOverSSLCompatibility($request);
188: 
189:         $this->offset = 0;
190:         $this->maxlen = -1;
191: 
192:         if (self::$trustXSendfileTypeHeader && $request->headers->has('X-Sendfile-Type')) {
193:             // Use X-Sendfile, do not send any content.
194:             $type = $request->headers->get('X-Sendfile-Type');
195:             $path = $this->file->getRealPath();
196:             if (strtolower($type) == 'x-accel-redirect') {
197:                 // Do X-Accel-Mapping substitutions.
198:                 foreach (explode(',', $request->headers->get('X-Accel-Mapping', '')) as $mapping) {
199:                     $mapping = explode('=', $mapping, 2);
200: 
201:                     if (2 == count($mapping)) {
202:                         $location = trim($mapping[0]);
203:                         $pathPrefix = trim($mapping[1]);
204: 
205:                         if (substr($path, 0, strlen($pathPrefix)) == $pathPrefix) {
206:                             $path = $location.substr($path, strlen($pathPrefix));
207:                             break;
208:                         }
209:                     }
210:                 }
211:             }
212:             $this->headers->set($type, $path);
213:             $this->maxlen = 0;
214:         } elseif ($request->headers->has('Range')) {
215:             // Process the range headers.
216:             if (!$request->headers->has('If-Range') || $this->getEtag() == $request->headers->get('If-Range')) {
217:                 $range = $request->headers->get('Range');
218:                 $fileSize = $this->file->getSize();
219: 
220:                 list($start, $end) = explode('-', substr($range, 6), 2) + array(0);
221: 
222:                 $end = ('' === $end) ? $fileSize - 1 : (int) $end;
223: 
224:                 if ('' === $start) {
225:                     $start = $fileSize - $end;
226:                     $end = $fileSize - 1;
227:                 } else {
228:                     $start = (int) $start;
229:                 }
230: 
231:                 if ($start <= $end) {
232:                     if ($start < 0 || $end > $fileSize - 1) {
233:                         $this->setStatusCode(416);
234:                     } elseif ($start !== 0 || $end !== $fileSize - 1) {
235:                         $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
236:                         $this->offset = $start;
237: 
238:                         $this->setStatusCode(206);
239:                         $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize));
240:                         $this->headers->set('Content-Length', $end - $start + 1);
241:                     }
242:                 }
243:             }
244:         }
245: 
246:         return $this;
247:     }
248: 
249:     /**
250:      * Sends the file.
251:      */
252:     public function sendContent()
253:     {
254:         if (!$this->isSuccessful()) {
255:             parent::sendContent();
256: 
257:             return;
258:         }
259: 
260:         if (0 === $this->maxlen) {
261:             return;
262:         }
263: 
264:         $out = fopen('php://output', 'wb');
265:         $file = fopen($this->file->getPathname(), 'rb');
266: 
267:         stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);
268: 
269:         fclose($out);
270:         fclose($file);
271: 
272:         if ($this->deleteFileAfterSend) {
273:             unlink($this->file->getPathname());
274:         }
275:     }
276: 
277:     /**
278:      * {@inheritdoc}
279:      *
280:      * @throws \LogicException when the content is not null
281:      */
282:     public function setContent($content)
283:     {
284:         if (null !== $content) {
285:             throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.');
286:         }
287:     }
288: 
289:     /**
290:      * {@inheritdoc}
291:      *
292:      * @return false
293:      */
294:     public function getContent()
295:     {
296:         return false;
297:     }
298: 
299:     /**
300:      * Trust X-Sendfile-Type header.
301:      */
302:     public static function trustXSendfileTypeHeader()
303:     {
304:         self::$trustXSendfileTypeHeader = true;
305:     }
306: 
307:     /**
308:      * If this is set to true, the file will be unlinked after the request is send
309:      * Note: If the X-Sendfile header is used, the deleteFileAfterSend setting will not be used.
310:      * @param bool $shouldDelete
311:      *
312:      * @return BinaryFileResponse
313:      */
314:     public function deleteFileAfterSend($shouldDelete)
315:     {
316:         $this->deleteFileAfterSend = $shouldDelete;
317: 
318:         return $this;
319:     }
320: }
321: 
Omnipay Fat Zebra / Paystream Gateway Module API Documentation API documentation generated by ApiGen