/** * beforeRender callback function * * @param Controller $controller * @return array contents for panel */ public function beforeRender(Controller $controller) { $data = array(); $dir = new Folder(LOGS); $files = $dir->find(); foreach ($files as $log) { $file = new File(LOGS . $log); $name = $file->name(); $data[$name] = array(); if (!$file->readable()) { $data[$name]['content'] = __('This log file is unreadable.'); continue; } $data[$name]['lastChange'] = date('Y-m-d H:i:s', $file->lastChange()); if ($file->size() > $this->readBytes) { $file->offset(-$this->readBytes, SEEK_END); } $data[$name]['content'] = $file->read($this->readBytes); } return $data; }
/** * Setup for display or download the given file * * @param string $path Path to file * @param array $options Options * ### Options keys * - name: Alternate download name * - download: If `true` sets download header and forces file to be downloaded rather than displayed in browser * @return void * @throws NotFoundException */ public function file($path, $options = array()) { $options += array('name' => null, 'download' => null); if (!is_file($path)) { $path = APP . $path; } $file = new File($path); if (!$file->exists() || !$file->readable()) { if (Configure::read('debug')) { throw new NotFoundException(__d('cake_dev', 'The requested file %s was not found or not readable', $path)); } throw new NotFoundException(__d('cake', 'The requested file was not found')); } $extension = strtolower($file->ext()); $download = $options['download']; if ((!$extension || $this->type($extension) === false) && is_null($download)) { $download = true; } $fileSize = $file->size(); if ($download) { $agent = env('HTTP_USER_AGENT'); if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) { $contentType = 'application/octetstream'; } elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { $contentType = 'application/force-download'; } if (!empty($contentType)) { $this->type($contentType); } if (is_null($options['name'])) { $name = $file->name; } else { $name = $options['name']; } $this->download($name); $this->header('Accept-Ranges', 'bytes'); $httpRange = env('HTTP_RANGE'); if (isset($httpRange)) { list(, $range) = explode('=', $httpRange); $size = $fileSize - 1; $length = $fileSize - $range; $this->header(array('Content-Length' => $length, 'Content-Range' => 'bytes ' . $range . $size . '/' . $fileSize)); $this->statusCode(206); $file->open('rb', true); $file->offset($range); } else { $this->header('Content-Length', $fileSize); } } else { $this->header('Content-Length', $fileSize); } $this->_clearBuffer(); $this->_file = $file; }
/** * Creates a file with contents from base64 encoded string. * * TestData::getFile('image-png.png'); * TestData::getFile(array('image-png.png' => TMP . 'other-name.png')); * TestData::getFile(array('image-png.png' => 'other-name.png')); * TestData::getFile('file.txt', 'I am the content'); * * @param mixed $key * @param string $string * @return string Absolute path to the created file */ public function getFile($key = null, $string = '') { if (is_array($key)) { $file = current($key); $key = key($key); if (!Folder::isAbsolute($file)) { $file = $this->settings['base'] . $file; } $alias = $file; } else { $alias = $key; $file = $this->settings['base'] . $key; } if ($string === '') { $string = $this->getString($key); } $File = new File($file); if ($File->exists()) { $File->delete(); } $File->write($string); $File->offset(0); $File->close(); $this->Files[$alias] =& $File; return $File->pwd(); }
/** * Will load a file from various sources * * Supported formats: * - Freedesktop Shared MIME-info Database * - Apache Module mod_mime_magic * - PHP file containing variables formatted like: $data[0] = array(item, item, item, ...) * * @param mixed $file An absolute path to a magic file in apache, freedesktop * or a filename (without .php) of a file in the configs/ dir in CakePHP format * @return mixed A format string or null if format could not be determined * @access private * @link http://httpd.apache.org/docs/2.2/en/mod/mod_mime_magic.html * @link http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.13.html */ function __read($db) { $format = MimeMagic::format($db); if ($format === 'Array') { foreach ($db as $item) { $this->register($item); } } elseif ($format === 'PHP') { include $db; foreach ($data as $item) { $this->register($item); } } elseif ($format === 'Freedesktop Shared MIME-info Database') { $sectionRegex = '^\\[(\\d{1,3}):([-\\w.\\+]+\\/[-\\w.\\+]+)\\]$'; $itemRegex = '^(\\d*)\\>+(\\d+)=+([^&~\\+]{2})([^&~\\+]+)&?([^~\\+]*)~?(\\d*)\\+?(\\d*).*$'; $File = new File($db); $File->open('rb'); $File->offset(12); while (!feof($File->handle)) { $line = ''; if (!isset($chars)) { $chars = array(0 => $File->read(1), 1 => $File->read(1)); } else { $chars = array(0 => $chars[1], 1 => null); } while (!feof($File->handle) && !($chars[0] === "\n" && (ctype_digit($chars[1]) || $chars[1] === '>' || $chars[1] === '['))) { $line .= $chars[0]; $chars = array(0 => $chars[1], 1 => $File->read(1)); } if (preg_match('/' . $sectionRegex . '/', $line, $matches)) { $section = array('priority' => $matches[1], 'mime_type' => $matches[2]); } elseif (preg_match('/' . $itemRegex . '/', $line, $matches)) { $indent = empty($matches[1]) ? 0 : intval($matches[1]); $wordSize = empty($matches[6]) ? 1 : intval($matches[6]); $item = array('offset' => intval($matches[2]), 'value_length' => current(unpack('n', $matches[3])), 'value' => $this->__formatValue($matches[4], $wordSize), 'mask' => empty($matches[5]) ? null : $this->__formatValue($matches[5], $wordSize), 'range_length' => empty($matches[7]) ? 1 : intval($matches[7]), 'mime_type' => $section['mime_type']); $this->register($item, $indent, $section['priority']); } } } elseif ($format === 'Apache Module mod_mime_magic') { $itemRegex = '^(\\>*)(\\d+)\\t+(\\S+)\\t+([\\S^\\040]+)\\t*([-\\w.\\+]+\\/[-\\w.\\+]+)*\\t*(\\S*)$'; $File = new File($db); $File->open('rb'); while (!feof($File->handle)) { $line = trim(fgets($File->handle)); if (empty($line) || $line[0] === '#') { continue; } $line = preg_replace('/(?!\\B)\\040+/', "\t", $line); if (!preg_match('/' . $itemRegex . '/', $line, $matches)) { continue; } $item = array('offset' => intval($matches[2]), 'value' => $this->__formatValue($matches[4], $matches[3], true), 'mask' => null, 'range_length' => 0, 'mime_type' => empty($matches[5]) ? null : $matches[5], 'encoding' => empty($matches[6]) ? null : $matches[6]); $item['value_length'] = strlen($item['value']); $this->register($item, strlen($matches[1]), 80); } } else { trigger_error('MimeGlob::read - Unknown db format', E_USER_WARNING); } }
/** * Reads out a file, and echos the content to the client. * * @param File $file File object * @param array $range The range to read out of the file. * @return bool True is whole file is echoed successfully or false if client connection is lost in between */ protected function _sendFile($file, $range) { $compress = $this->outputCompressed(); $file->open('rb'); $end = $start = false; if ($range) { list($start, $end) = $range; } if ($start !== false) { $file->offset($start); } $bufferSize = 8192; set_time_limit(0); session_write_close(); while (!feof($file->handle)) { if (!$this->_isActive()) { $file->close(); return false; } $offset = $file->offset(); if ($end && $offset >= $end) { break; } if ($end && $offset + $bufferSize >= $end) { $bufferSize = $end - $offset + 1; } echo fread($file->handle, $bufferSize); if (!$compress) { $this->_flushBuffer(); } } $file->close(); return true; }