public function sendFile() { if (!is_file($this->source) or !is_readable($this->source)) { $this->sendError(404, 'could not find this attachment.'); } // Пытаемся открыть файл на чтение. Сработает только если файл является картинкой. $img = ImageMagick::getInstance(); $rc = $img->open($this->source, $this->node->filetype); // Если не удалось открыть, значит файл не является картинкой. Отдаём его в режиме скачивания. if ($rc === false) { return $this->sendFileDownload($img); } if (!is_file($this->output) or filemtime($this->source) > filemtime($this->output)) { // Если файл существует -- обязательно его удаляем, иначе есть // шанс запороть оригинал, попытавшись перезаписать симлинк (по // причине кривой обработки параметров, или по другой -- не важно, // всякое бывает). // Масштабируем картинку, если это нужно. if ($this->options !== null) { $this->processImage($img); } if (is_link($this->output) and !unlink($this->output)) { $this->sendError(500, 'could not remove the file from cache. Overwriting that file would cause the original data to be lost.'); } } // Бывают ситуации, когда картинку не нужно отдавать в браузер, // чтобы не заставлять клиента грузить ненужные килобайты, а то и мегабайты. if (false == $this->options['noshow']) { // Открываем файл на чтение. $f = fopen($this->output, 'r') or $this->sendError(500, "could not read from cache."); // Отправляем файл клиенту. header('Content-Type: ' . $img->getType()); header('Content-Length: ' . filesize($this->output)); fpassthru($f); } else { exit; } }
/** * Обработка файла. */ public static function transform(FileNode $node) { if (0 !== strpos($node->filetype, 'image/')) { return; } $result = array(); // Относительный путь к исходному файлу $source = $node->getRealURL(); // Путь к файловому хранилищу, используется только чтобы // из полного пути сделать относительный после трансформации. $storage = Context::last()->config->getPath('modules/files/storage', 'files'); // Файлы без расширений не обрабатываем, чтобы не нагенерировать каких-нибудь странных имён. /* if (!($ext = os::getFileExtension($source))) return; */ // Правила перевода расширений в типы. $typemap = array('png' => 'image/png', 'jpg' => 'image/jpeg'); foreach (Context::last()->config->getArray(self::confroot) as $name => $settings) { if (empty($ext)) { $target = $source . '.' . $name . '.' . $settings['format']; } else { $target = substr($source, 0, -strlen($ext)) . $name . '.' . $settings['format']; } if (file_exists($target)) { unlink($target); } $im = ImageMagick::getInstance(); if ($im->open($source, $node->filetype)) { $options = array('downsize' => $settings['scalemode'] != 'crop', 'crop' => $settings['scalemode'] == 'crop', 'quality' => intval($settings['quality'])); if ($im->scale($settings['width'], $settings['height'], $options)) { if ($im->save($target, $typemap[$settings['format']])) { $tmp = array('width' => $im->getWidth(), 'height' => $im->getHeight(), 'filename' => substr($target, strlen($storage) + 1), 'filesize' => filesize($target)); $result[$name] = $tmp; } } } } return $result; }