* @license PHP License * @package WB * @subpackage base */ WBClass::load('WBService' , 'WBLog' ); /** * Service VFSFile * * Deliver file * * @version 0.1.7 * @package WB * @subpackage base */ class WBService_VFSFile extends WBService { /** * decide whether to start locale tools * @var bool */ protected $useI18n = false; /** * decide whether to start WBConfig * @var bool */ protected $useConfig = false; /** * Display * * Deliver media file by URI. Typically the URI will be appended to file.php/ * or dispatcher.php/file/. Slashes are used as parameter delimiter * * file.php/Yg541/video/x-flv/movie.flv * file.php/zA542/image/jpg/picture.jpg * or * dispatcher.php/file/Yg541/video/x-flv/movie.flv * dispatcher.php/file/zA542/image/jpg/picture.jpg * * The first parameter ($this->part) is the media file's obscure id. This is * required, everything es is optional. * * The second parameter is the major mime type (video, image, text, * application, ...). If this parameter is missing, the major mime type will * be loaded from the media file's data. * * The next step loads the correesponding WBVFS_Mime-Hanlder and injects the * media file (WBVFS_File). This allows to convert WBVFS_Files of one (major) mime * tyĆ¼e to another. E.g. videos to images (to generate a title image), applications * to images (to provide graphical icons) etc. * * * @param int $status * @param mixed $data to be send * @param string $checksum * @return bool true */ public function run( &$status, &$data, &$checksum = null ) { $this->part = ''; if (!empty($this->path)) { $this->part = array_shift($this->path); } if (empty($this->part)) { $data = 'Please tell which file you want.'; $status = 400; return true; } WBParam::set('wb/response/compress', 0); $loader = WBClass::create('WBVFS_File'); /** @var $loader WBVFS_File */ $file = $loader->loadByObscureId($this->part); if (!$file->isOK()) { $data = str_replace('{FILE}', $this->part, 'File "{FILE}" does not exist.'); $status = 404; return true; } // select mime type to deliver $mimeMajor = $file->getMime(); if (!empty($this->path)) { $mimeMajor = array_shift($this->path); } $mimeMajor = strtolower($mimeMajor); $mimeMinor = null; if (!empty($this->path)) { $mimeMinor = array_shift($this->path); } // call special mime handler try{ $mimeHdl = WBClass::create('WBVFS_Mime_' . ucfirst($mimeMajor)); } catch (WBException $e) { $data = str_replace('{FILE}', $this->part, 'Unkown type convert for "{FILE}" selected.'); $status = 404; return true; } /** @var $mimeHdl WBVFS_Mime */ if (!$mimeHdl->setVirtualFile($file)) { $data = str_replace('{FILE}', $this->part, 'Cannot convert file "{FILE}" to requested type.'); $status = 404; return true; } $path = $mimeHdl->getRequestedFile($this->req, $this->res, $redirect, $mimeMinor); // redirect? if (!empty($redirect)) { $target = $this->req->protocol . '://' . $this->req->getMeta('HTTP_HOST') . $this->req->getMeta('PHP_SELF') . '?' . http_build_query($redirect['get']); // detect redirect loop $self = $this->req->protocol . '://' . $this->req->getMeta('HTTP_HOST') . $this->req->getMeta('PHP_SELF') . '?' . http_build_query($this->req->export()); if ($self == $target) { $data = str_replace('{URL}', $target, 'Redirect loop detected when redirecting to {URL}. Sorry for any invconvenience.'); $status = 404; } $this->res->addHeader('Location', $target); $data = str_replace('{URL}', $target, 'Please collect file at {URL}. Thank you.'); $status = 301; return true; } // something went wrong? if (!file_exists($path) || !is_readable($path)) { $data = str_replace('{FILE}', $this->part, 'File "{FILE}" not found.'); $status = 404; return true; } // empty file? clearstatcache(); if (!filesize($path)) { $data = str_replace('{FILE}', $this->part, 'File "{FILE}" is not there yet, This file probably is about to be converted to as suitable format - please try again later'); $status = 404; return true; } // increment view if ($file->getMime(WBVFS_File::MIME_MAJOR) == $mimeMajor && $mimeHdl->isIncrementable()) { $range = $this->req->getRange(); if (0 == $range[0]) { $file->incrementView(); } } // set header $mime = $mimeHdl->getMime(WBVFS_File::MIME_MAJOR | WBVFS_File::MIME_MINOR); $this->res->addHeader('Content-Type', $mime); $name = $file->getName(); $ext = $mimeHdl->getExtension(); if (!empty($ext)) { $name = $name . '.' . $ext; } $disposName = str_replace('"', '\\"', htmlspecialchars_decode($name)); $this->res->addHeader('Content-Disposition', 'inline; filename="' . $disposName . '"'); /* * caching time in seconds * 60 * 60 * 24 * 30 * = 3600 * 24 * 30 * = 86400 * 30 * = 2592000 */ $this->res->setMaxAge(2592000); $this->res->addHeader('Content-Length', filesize($path)); $this->res->addHeader('Accept-Ranges', 'bytes'); $checksum = md5_file($path); $data = fopen($path, 'r'); $status = 200; return true; } } ?>