CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.0 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.0
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Auth
    • Core
    • Error
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
    • Network
      • Email
      • Http
    • Routing
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • Helper
  • HelperCollection
  • MediaView
  • ScaffoldView
  • ThemeView
  • View
  1: <?php
  2: /**
  3:  * Methods to display or download any type of file
  4:  *
  5:  * PHP 5
  6:  *
  7:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8:  * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9:  *
 10:  * Licensed under The MIT License
 11:  * Redistributions of files must retain the above copyright notice.
 12:  *
 13:  * @copyright     Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
 14:  * @link          http://cakephp.org CakePHP(tm) Project
 15:  * @package       Cake.View
 16:  * @since         CakePHP(tm) v 1.2.0.5714
 17:  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 18:  */
 19: 
 20: App::uses('View', 'View');
 21: App::uses('CakeRequest', 'Network');
 22: 
 23: /**
 24:  * Media View provides a custom view implementation for sending files to visitors.  Its great
 25:  * for making the response of a controller action be a file that is saved somewhere on the filesystem.
 26:  *
 27:  * An example use comes from the CakePHP internals. MediaView is used to serve plugin and theme assets,
 28:  * as they are not normally accessible from an application's webroot.  Unlike other views, MediaView
 29:  * uses several viewVars that have special meaning:
 30:  *
 31:  * - `id` The filename on the server's filesystem, including extension.
 32:  * - `name` The filename that will be sent to the user, specified without the extension.
 33:  * - `download` Set to true to set a `Content-Disposition` header.  This is ideal for file downloads.
 34:  * - `extension` The extension of the file being served.  This is used to set the mimetype
 35:  * - `path` The absolute path, including the trailing / on the server's filesystem to `id`.
 36:  * - `mimeType` The mime type of the file if CakeResponse doesn't know about it.
 37:  *
 38:  * ### Usage
 39:  *
 40:  * {{{
 41:  * class ExampleController extends AppController {
 42:  *      public function download () {
 43:  *          $this->viewClass = 'Media';
 44:  *          $params = array(
 45:  *              'id' => 'example.zip',
 46:  *              'name' => 'example',
 47:  *              'download' => true,
 48:  *              'extension' => 'zip',
 49:  *              'path' => APP . 'files' . DS
 50:  *          );
 51:  *          $this->set($params);
 52:  *      }
 53:  * }
 54:  * }}}
 55:  *
 56:  * @package       Cake.View
 57:  */
 58: class MediaView extends View {
 59: /**
 60:  * Indicates whether response gzip compression was enabled for this class
 61:  *
 62:  * @var boolean
 63:  */
 64:     protected  $_compressionEnabled = false;
 65: 
 66: /**
 67:  * Reference to the Response object responsible for sending the headers
 68:  *
 69:  * @var CakeResponse
 70:  */
 71:     public $response = null;
 72: 
 73: /**
 74:  * Constructor
 75:  *
 76:  * @param Controller $controller The controller with viewVars
 77:  */
 78:     public function __construct($controller = null) {
 79:         parent::__construct($controller);
 80:         if (is_object($controller) && isset($controller->response)) {
 81:             $this->response = $controller->response;
 82:         } else {
 83:             $this->response = new CakeResponse;
 84:         }
 85:     }
 86: 
 87: /**
 88:  * Display or download the given file
 89:  *
 90:  * @param string $view Not used
 91:  * @param string $layout Not used
 92:  * @return mixed
 93:  * @throws NotFoundException
 94:  */
 95:     public function render($view = null, $layout = null) {
 96:         $name = $download = $extension = $id = $modified = $path = $cache = $mimeType = $compress = null;
 97:         extract($this->viewVars, EXTR_OVERWRITE);
 98: 
 99:         if (is_dir($path)) {
100:             $path = $path . $id;
101:         } else {
102:             $path = APP . $path . $id;
103:         }
104: 
105:         if (!is_file($path)) {
106:             if (Configure::read('debug')) {
107:                 throw new NotFoundException(sprintf('The requested file %s was not found', $path));
108:             }
109:             throw new NotFoundException('The requested file was not found');
110:         }
111: 
112:         if (is_array($mimeType)) {
113:             $this->response->type($mimeType);
114:         }
115: 
116:         if (isset($extension) && $this->_isActive()) {
117:             $extension = strtolower($extension);
118:             $chunkSize = 8192;
119:             $buffer = '';
120:             $fileSize = @filesize($path);
121:             $handle = fopen($path, 'rb');
122: 
123:             if ($handle === false) {
124:                 return false;
125:             }
126:             if (!empty($modified) && !is_numeric($modified)) {
127:                 $modified = strtotime($modified, time());
128:             } else {
129:                 $modified = time();
130:             }
131:             if ($this->response->type($extension) === false) {
132:                 $download = true;
133:             }
134: 
135:             if ($cache) {
136:                 $this->response->cache($modified, $cache);
137:             } else {
138:                 $this->response->header(array(
139:                     'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
140:                     'Expires' => '0',
141:                     'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
142:                     'Pragma' => 'no-cache'
143:                 ));
144:             }
145: 
146:             if ($download) {
147:                 $agent = env('HTTP_USER_AGENT');
148: 
149:                 if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) {
150:                     $contentType = 'application/octetstream';
151:                 } else if (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
152:                     $contentType = 'application/force-download';
153:                 }
154: 
155:                 if (!empty($contentType)) {
156:                     $this->response->type($contentType);
157:                 }
158:                 if (is_null($name)) {
159:                     $name = $id;
160:                 }
161:                 $this->response->download($name);
162:                 $this->response->header(array('Accept-Ranges' => 'bytes'));
163: 
164:                 $httpRange = env('HTTP_RANGE');
165:                 if (isset($httpRange)) {
166:                     list($toss, $range) = explode('=', $httpRange);
167: 
168:                     $size = $fileSize - 1;
169:                     $length = $fileSize - $range;
170: 
171:                     $this->response->header(array(
172:                         'Content-Length' => $length,
173:                         'Content-Range' => 'bytes ' . $range . $size . '/' . $fileSize
174:                     ));
175: 
176:                     $this->response->statusCode(206);
177:                     fseek($handle, $range);
178:                 } else {
179:                     $this->response->header('Content-Length', $fileSize);
180:                 }
181:             } else {
182:                 $this->response->header(array(
183:                     'Content-Length' => $fileSize
184:                 ));
185:             }
186:             $this->_clearBuffer();
187:             if ($compress) {
188:                 $this->_compressionEnabled = $this->response->compress();
189:             }
190: 
191:             $this->response->send();
192:             return $this->_sendFile($handle);
193:         }
194: 
195:         return false;
196:     }
197: 
198: /**
199:  * Reads out a file handle, and echos the content to the client.
200:  *
201:  * @param resource $handle A file handle or stream
202:  * @return void
203:  */
204:     protected function _sendFile($handle) {
205:         $chunkSize = 8192;
206:         $buffer = '';
207:         while (!feof($handle)) {
208:             if (!$this->_isActive()) {
209:                 fclose($handle);
210:                 return false;
211:             }
212:             set_time_limit(0);
213:             $buffer = fread($handle, $chunkSize);
214:             echo $buffer;
215:             if (!$this->_compressionEnabled) {
216:                 $this->_flushBuffer();
217:             }
218:         }
219:         fclose($handle);
220:     }
221: 
222: /**
223:  * Returns true if connection is still active
224:  *
225:  * @return boolean
226:  */
227:     protected function _isActive() {
228:         return connection_status() == 0 && !connection_aborted();
229:     }
230: 
231: /**
232:  * Clears the contents of the topmost output buffer and discards them
233:  *
234:  * @return boolean
235:  */
236:     protected function _clearBuffer() {
237:         return @ob_end_clean();
238:     }
239: 
240: /**
241:  * Flushes the contents of the output buffer
242:  *
243:  * @return void
244:  */
245:     protected function _flushBuffer() {
246:         @flush();
247:         @ob_flush();
248:     }
249: }
250: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs