/** * Constructor * Check if the given file is loaded and attempt to create resource * * @param string $file * @return object */ public function __construct($file) { if (!extension_loaded('gd')) { throw new Image_NoGd('PHP Extension "gd" is not loaded'); } else { if (!is_file($file)) { throw new Image_FileNoExist($file . ' does not exist or is not a readable file'); } } // Check if the image would consume too much memory. $imageInfo = getimagesize($file); if (!isset($imageInfo['channels'])) { $imageInfo['channels'] = 1; } if (isset($imageInfo['bits'])) { $memoryNeeded = round(($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $imageInfo['channels'] / 8 + pow(2, 16)) * 1.65); $memoryLimit = zula_byte_value(ini_get('memory_limit')); if (memory_get_usage() + $memoryNeeded > $memoryLimit) { throw new Image_LoadFailed('image would consume more memory than current limit'); } } /** * Create correct resource from the mime file and store other * details about the image that we may need. */ $mime = zula_get_file_mime($file); switch ($mime) { case 'image/jpeg': case 'image/jpg': $this->resource = @imagecreatefromjpeg($file); break; case 'image/png': $this->resource = @imagecreatefrompng($file); break; case 'image/gif': $this->resource = @imagecreatefromgif($file); } if (!is_resource($this->resource)) { throw new Image_LoadFailed('image is not a valid file or has invalid mime type "' . $mime . '"'); } $this->details = array_merge(pathinfo($file), array('path' => $file, 'mime' => $mime, 'originalWidth' => imagesx($this->resource), 'originalHeight' => imagesy($this->resource))); $this->details['width'] = $this->details['originalWidth']; $this->details['height'] = $this->details['originalHeight']; if (!is_resource($this->resource)) { throw new Image_LoadFailed('failed to create image resource'); } }
/** * Handles the extraction of files in a ZIP archive * * @param string $filename * @return bool */ protected function handleZip($filename) { $za = new ZipArchive(); $za->open($this->tmpName); $i = 0; $extractDir = $this->_zula->getDir('tmp') . '/uploader/' . uniqid(); while ($file = $za->statIndex($i)) { $this->fileDetails[$i + 1] = array('name' => $file['name'], 'size' => $file['size'], 'mime' => null, 'category' => null); if ($this->checkFileSize($file['size']) && $this->checkExtension($file['name'])) { // Extract file to get the mime type, will be removed if it is not valid $za->extractTo($extractDir, $file['name']); $mime = zula_get_file_mime($extractDir . '/' . $file['name']); $this->fileDetails[$i + 1]['mime'] = $mime; $this->fileDetails[$i + 1]['category'] = substr($mime, 0, strpos($mime, '/')); if ($mime !== false && $this->checkMime($mime)) { // Move the file to a uniquely named file $category = $this->fileDetails[$i + 1]['category']; if (($uploadDir = $this->makeDirectory($category)) === false) { throw new Uploader_Exception('unable to create upload directory, or not writable'); } $this->uploader->subDirectoryName(null); # Stop the same sub directory being used! $path = $uploadDir . '/' . zula_make_unique_file($uploadDir, pathinfo($file['name'], PATHINFO_EXTENSION), false); rename($extractDir . '/' . $file['name'], $path); $this->fileDetails[$i + 1]['path'] = $path; $this->fileDetails[$i + 1] = array_merge($this->fileDetails[$i + 1], pathinfo($path)); } else { unlink($uploadDir . '/' . $file['name']); } } $this->fileDetails[$i + 1]['fromArchive'] = true; ++$i; } zula_full_rmdir($extractDir); return true; }
/** * Helper function to PHP 'readfile' to set all the needed * headers to output a file via PHP. If no mimetype is * provided then it will get it its self * * @param string $file * @param string $mime * @return int|bool */ function zula_readfile($file, $mime = null) { if (!is_readable($file)) { return false; } else { if ($mime == false) { $mime = zula_get_file_mime($file); } } try { $ttl = Registry::get('config')->get('cache/ttl'); } catch (Exception $e) { $ttl = 604800; } $modified = filemtime($file); $eTag = '"' . hash('md5', $modified) . '"'; if (zula_http_header_get('If-None-Match') == $eTag) { header('HTTP/1.1 304 Not Modified'); } // Set all needed headers header('Content-Type: ' . $mime); header('Content-Length: ' . filesize($file)); header('Cache-Control: max-age=' . $ttl . ', public'); header('Pragma: '); header('Expires: ' . date(DATE_RFC1123, time() + $ttl)); header('ETag: ' . $eTag); header('Last-Modified: ' . date(DATE_RFC1123, $modified)); if (strpos(zula_http_header_get('Range'), 'bytes') !== false || strpos($mime, 'video/') === 0) { header('Accept-Ranges: bytes'); } if (ini_get('output_handler') && strpos($mime, 'image/') === 0) { // We don't want to compress images, it causes all sorts of issues ob_get_clean(); header('Content-Encoding: '); } return readfile($file); }
$module = preg_replace('#[^A-Z0-9_\\-]+#i', '', substr($assetPath, 0, $slashPos)); $path = substr($assetPath, $slashPos + 1); if ($path !== false) { /** * Build both the path and real path to the asset, comparing that to what was * provided. Basically a similar functionaility to openbase_dir I guess. */ $assetDir = Module::getDirectory() . '/' . $module . '/assets'; $assetPath = $assetDir . '/' . $path; if (strpos(realpath($assetPath), realpath($assetDir)) === 0 && is_readable($assetPath)) { // Set all of the headers needed and output the file switch (pathinfo($assetPath, PATHINFO_EXTENSION)) { case 'js': $mime = 'text/javascript; charset=utf-8'; break; case 'css': $mime = 'text/css; charset=utf-8'; break; default: $mime = zula_get_file_mime($assetPath); if ($mime === false) { $mime = 'text/plain'; } } return (bool) zula_readfile($assetPath, $mime); } } } // Will only ever occur if something goes wrong up there. header('HTTP/1.1 404 Not Found', true, 404); return false;