/lib/Molinos/Image/Editor.php
PHP | 242 lines | 164 code | 46 blank | 32 comment | 38 complexity | aa652a1762d3ad0bc0381ed8b4005060 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0
- <?php
- /**
- * ??? ??? ????????? ???????? ?? ?????????.
- *
- * @todo ???????? ?? ????? ImageAPI.
- *
- * @package Molinos_CMS
- * @subpackage Image
- * @author Justin Forest <justin.forest@gmail.com>
- * @copyright 2006-2011 molinos.ru
- * @license http://www.gnu.org/copyleft/gpl.html GPL
- */
- class Molinos_Image_Editor
- {
- private $folder;
- private $filename;
- private $source;
- private $output;
- private $nw;
- private $nh;
- public static function hookRemoteCall(Molinos_Core_Context $ctx)
- {
- $img = new Molinos_Image_Editor($ctx);
- $img->sendFile();
- exit();
- }
- // ????? ??????????, ??????? ???????????? ??? ?????????????? ???????????,
- // ??????????? - ? ????????????
- private $options = array(
- 'fid' => null,
- 'scale' => 100,
- 'mirrorV' => false,
- 'mirrorH' => false,
- 'angle' => 0,
- 'offsetX' => 0,
- 'offsetY' => 0,
- 'cropLeft' => 0,
- 'cropTop' => 0,
- 'cropRight' => 0,
- 'cropBottom' => 0,
- 'merge' => null,
- 'noshow' => false,
- );
- private $node = null;
- private $mergeNode = null;
- public function __construct(Molinos_Core_Context $ctx)
- {
- $nodeapi = Molinos_Core_API::getInstance('node');
- // ???? ????? id ?????????? ?????? ?? ??????, ????????
- if (null == $ctx->request->get('fid', null) or null == $ctx->request->get('scale', null))
- $this->sendError(500, 'usage: ?q=imgtoolkit.rpc&fid=attachment[&operation=parameter...]');
- foreach ($this->options as $k => $v) {
- if ($p = $ctx->request->get($k)) {
- if (in_array($k, array('noshow', 'merge', 'fid', 'mirrorH', 'mirrorV')))
- $this->options[$k] = $p;
- else
- $this->options[$k] = floatval($p);
- }
- // ????????? ??? ?????-?????? ??? ????
- $outfile .= "{$this->options[$k]},";
- }
- $outfile = trim($outfile, ',');
- $node = $nodeapi->load(array('class' => 'file', 'id' => $this->options['fid']));
- if (empty($node))
- self::sendError(404, 'attachment not found.');
- $this->node = $node;
- $this->filename = $node->filename;
- $this->folder = dirname($node->uri);
- $this->sourceDir = dirname($node->uri);
- $this->source = $node->uri;
- $this->output = $this->folder . '/' . $outfile;
- if (null != $this->options['merge']) {
- $this->mergeNode = $nodeapi->load(array('class' => 'file', 'id' => $this->options['merge']));
- if (empty($this->mergeNode))
- self::sendError(404, 'merge attachment not found.');
- }
- }
- private function sendError($code, $more = null)
- {
- $codes = array(
- '200' => 'OK',
- '400' => 'Bad Request',
- '404' => 'Not Found',
- '415' => 'Bad Media Type',
- '500' => 'Internal Server Error',
- );
- if (!isset($codes[$code]))
- $code = 500;
- $text = $codes[$code];
- header("HTTP/1.1 {$code} {$text}");
- header("Content-Type: text/plain; charset=utf-8");
- print $text;
- if ($more !== null)
- print ": ".$more;
- exit();
- }
- public function sendFile()
- {
- if (!is_file($this->source) or !is_readable($this->source))
- $this->sendError(404, 'could not find this attachment.');
- // ???????? ??????? ???? ?? ??????. ????????? ?????? ???? ???? ???????? ?????????.
- $img = Molinos_Image_Scaler::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();
- }
- }
- private function processImage($img)
- {
- try {
- $origSize = $img->getImageSize();
- // ???????????????
- $nw = intval($origSize[0] * $this->options['scale'] / 100);
- $nh = intval($origSize[1] * $this->options['scale'] / 100);
- if (!$img->scale($nw, $nh))
- $this->sendError(500, "could not resize the image");
- // ?????????????? ?? ?????????
- if (true == $this->options['mirrorV'])
- $img->mirror('v');
- // ?????????????? ?? ???????????
- if (true == $this->options['mirrorH'])
- $img->mirror('h');
- // ??????? ?? ???????? ????
- $angle = $this->options['angle'];
- if (is_numeric($angle) && ($angle != 360 or $angle != 0))
- $img->rotate(-($angle));
- // ???????? ???????
- $offsetX = $this->options['offsetX'];
- $offsetY = $this->options['offsetY'];
- if (is_numeric($offsetX) && is_numeric($offsetY)) {
- $img->moveTo($offsetX, $offsetY);
- }
- // ???????????? ?? ???????? ?????????
- $size = $img->getImageSize();
- $dX = $this->options['cropLeft'];
- $dY = $this->options['cropTop'];
- $dW = $this->options['cropRight'];
- $dH = $this->options['cropBottom'];
- $nW = $size[0] - $dW - $dX;
- $nH = $size[1] - $dH - $dY;
- if (!$img->crop($dX, $dY, $nW, $nH))
- $this->sendError(500, "could not crop the image");
- if (null != $this->mergeNode) {
- if (!$img->watermark($this->mergeNode->uri))
- $this->sendError(500, "could not merge the image");
- }
- if (!is_dir($this->folder) and !mkdir($this->folder))
- $this->sendError(500, "could not create the cache directory: ".$this->folder);
- if (!is_writable($this->folder))
- $this->sendError(500, "could not cache the image.");
- if (!$img->save($this->output))
- $this->sendError(500, "could not write the resized image");
- } catch (Exception $e) {
- $this->sendError(500, $e->getMessage());
- }
- }
- private function sendFileDownload($img)
- {
- ini_set('zlib.output_compression', 0);
- $headers = array();
- $headers[] = "Content-Type: ". $this->node->filetype;
- $headers[] = "Content-Length: ". $this->node->filesize;
- $download = (strstr($this->node->filetype, 'shockwave') === false);
- if ($download)
- $headers[] = "Content-Disposition: attachment; filename=\"{$this->node->filename}\"";
- foreach ($headers as $item)
- header($item);
- $f = fopen($this->source, 'rb')
- or $this->sendError(403, "could not read the file");
- fpassthru($f);
- }
- }