Overview

Namespaces

  • Inteve
    • SimpleImageStorage

Classes

  • Inteve\SimpleImageStorage\ImageStorage

Exceptions

  • Inteve\SimpleImageStorage\ImageStorageException
  • Overview
  • Namespace
  • Class
  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 
<?php

    namespace Inteve\SimpleImageStorage;

    use Nette;
    use Nette\Http\FileUpload;
    use Nette\Utils\Callback;
    use Nette\Utils\FileSystem;
    use Nette\Utils\Image;
    use Nette\Utils\Random;
    use Nette\Utils\Strings;


    class ImageStorage extends Nette\Object
    {
        /** only shrinks images */
        const SHRINK_ONLY = 1;

        /** will ignore aspect ratio */
        const STRETCH = 2;

        /** fits in given area so its dimensions are less than or equal to the required dimensions */
        const FIT = 0;

        /** fills given area so its dimensions are greater than or equal to the required dimensions */
        const FILL = 4;

        /** fills given area exactly */
        const EXACT = 8;

        /** @var string */
        private $directory;

        /** @var string */
        private $publicDirectory;

        /** @var string|NULL */
        private $storageName;

        /** @var callback|NULL */
        private $thumbnailGenerator;


        public function __construct($directory, $publicDirectory, $storageName = NULL, $thumbnailGenerator = NULL)
        {
            $this->directory = $this->normalizePath($directory, $storageName);
            $this->publicDirectory = $this->normalizePath($publicDirectory, $storageName);
            $this->storageName = $storageName;
            $this->thumbnailGenerator = $thumbnailGenerator;
        }


        /**
         * @return string
         */
        public function getDirectory()
        {
            return $this->directory;
        }


        /**
         * @param  FileUpload
         * @param  string|NULL
         * @param  array|string|NULL
         * @return string  filepath (namespace/file.ext)
         * @throws ImageStorageException
         */
        public function upload(FileUpload $image, $namespace = NULL, $mimeTypes = NULL)
        {
            if (!$image->isOk()) {
                throw new ImageStorageException('File is broken');
            }

            if (!$image->isImage()) {
                $contentType = $image->getContentType();
                $isValid = FALSE;

                if (isset($mimeTypes)) {
                    $mimeTypes = is_array($mimeTypes) ? $mimeTypes : explode(',', $mimeTypes);
                    $isValid = in_array($contentType, $mimeTypes, TRUE);
                }

                if (!$isValid) {
                    throw new ImageStorageException('File must be image, ' . $contentType . ' given');
                }
            }

            $sanitizedName = $image->getSanitizedName();
            $ext = pathinfo($sanitizedName, PATHINFO_EXTENSION);
            $sanitizedName = pathinfo($sanitizedName, PATHINFO_FILENAME) . '.' . Strings::lower($ext);

            $file = $this->generateFilePath($sanitizedName, $namespace);
            $path = $this->getPath($file);
            $image->move($path);
            return $file;
        }


        /**
         * @param  Image
         * @param  int
         * @param  int|NULL (for JPEG, PNG)
         * @param  string|NULL
         * @return string  filepath (namespace/file.ext)
         * @throws ImageStorageException
         */
        public function save(Image $image, $format, $quality = NULL, $namespace = NULL)
        {
            $ext = NULL;

            if ($format === Image::JPEG) {
                $ext = 'jpg';

            } elseif ($format === Image::PNG) {
                $ext = 'png';

            } elseif ($format === Image::GIF) {
                $ext = 'gif';

            } else {
                throw new ImageStorageException("Unknow format '$format'.");
            }

            $sanitizedName = Random::generate(5) . '.' . $ext;
            $file = $this->generateFilePath($sanitizedName, $namespace);
            $path = $this->getPath($file);
            @mkdir(dirname($path), 0777, TRUE); // @ - adresar muze existovat
            $image->save($path, $quality, $format);
            return $file;
        }


        /**
         * @param  string
         * @param  string|NULL
         * @return string
         */
        public function generateFilePath($sanitizedName, $namespace = NULL)
        {
            $name = NULL;
            $path = NULL;
            $file = NULL;

            do {
                $name = Random::generate(10) . '.' . $sanitizedName;
                $file = $this->formatFilePath($name, $namespace);
                $path = $this->getPath($file);

            } while (file_exists($path));
            return $file;
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @return void
         */
        public function delete($file)
        {
            FileSystem::delete($this->getPath($file));
            FileSystem::delete($this->directory . '/' . $this->formatThumbnailPath($file, NULL));
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @return string
         * @deprecated
         */
        public function getPath($file)
        {
            return $this->getRealPath($file);
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @return string
         */
        public function getRealPath($file)
        {
            return $this->directory . '/' . $this->formatOriginalPath($file);
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @return string
         */
        public function getPublicPath($file)
        {
            return $this->publicDirectory . '/' . $this->formatOriginalPath($file);
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @return string
         */
        public function getRealThumbnailPath($file, $width, $height, $flags = NULL, $quality = NULL)
        {
            $thumbnail = $this->prepareThumbnail($file, $width, $height, $flags, $quality);
            $path = $this->formatThumbnailPath($file, $thumbnail);
            return $this->directory . '/' . $path;
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @return string
         */
        public function getPublicThumbnailPath($file, $width, $height, $flags = NULL, $quality = NULL)
        {
            $thumbnail = $this->prepareThumbnail($file, $width, $height, $flags, $quality);
            $path = $this->formatThumbnailPath($file, $thumbnail);
            return $this->publicDirectory . '/' . $path;
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @return string
         */
        public function thumbnail($file, $width, $height, $flags = NULL, $quality = NULL)
        {
            $thumbnail = $this->prepareThumbnail($file, $width, $height, $flags, $quality);
            $path = $this->formatThumbnailPath($file, $thumbnail);

            $thumbnailPath = $this->directory . '/' . $path;

            if (!file_exists($thumbnailPath)) {
                $originalPath = $this->getPath($file);
                $this->generateThumbnail($originalPath, $thumbnailPath, $thumbnail);
            }

            return $this->publicDirectory . '/' . $path;
        }


        /**
         * @param  string
         * @param  string
         * @param  array  thumbnailData
         * @return void
         */
        private function generateThumbnail($sourceImage, $outputImage, array $thumbnail)
        {
            if (!isset($thumbnail['width']) && !isset($thumbnail['height'])) {
                throw new ImageStorageException('Width & height missing');
            }

            if ($this->thumbnailGenerator !== NULL) {
                Callback::invoke($this->thumbnailGenerator, $sourceImage, $outputImage, $thumbnail);
                return;
            }

            $image = Image::fromFile($sourceImage);
            $image->resize($thumbnail['width'], $thumbnail['height'], $thumbnail['flags']);

            FileSystem::createDir(dirname($outputImage));
            $image->save($outputImage, $thumbnail['quality']);
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @param  int|NULL
         * @return array  thumbnail data
         */
        private function prepareThumbnail($file, $width, $height, $flags = NULL, $quality = NULL)
        {
            if (!isset($width) && !isset($height)) {
                throw new ImageStorageException('Width & height missing');
            }

            $flags = (int) $flags;

            if ($flags <= 0) {
                $flags = 0; // fit

            } elseif ($flags > 8) {
                $flags = 8; // exact
            }

            return array(
                'width' => ($width > 0) ? ((int) $width) : NULL,
                'height' => ($height > 0) ? ((int) $height) : NULL,
                'quality' => ($quality > 0) ? ((int) $quality) : NULL,
                'flags' => $flags,
            );
        }


        /**
         * Sestavi cestu k originalnimu obrazku
         * @param  string  filepath (namespace/file.ext)
         * @return string
         */
        private function formatOriginalPath($file)
        {
            $data = $this->parseFilePath($file);
            return $data['namespace'] . 'o/' . $data['delimiter'] . '/' . $data['basename'];
        }


        /**
         * Sestavi cestu do slozky nahledu
         * @param  string  filepath (namespace/file.ext)
         * @return string
         */
        private function formatThumbnailPath($file, array $parameters = NULL)
        {
            $data = $this->parseFilePath($file);
            $directory = $data['namespace'] . 't/' . $data['delimiter'] . '/' . $data['filename'];

            if ($parameters === NULL) {
                return $directory;
            }

            $parts = array(
                $data['filename'],
                isset($parameters['width']) ? $parameters['width'] : 0,
                isset($parameters['height']) ? $parameters['height'] : 0,
                isset($parameters['quality']) ? $parameters['quality'] : 'n',
                isset($parameters['flags']) ? $parameters['flags'] : 0,
            );

            return $directory . '/' . implode('_', $parts) . '.' . $data['ext'];
        }


        /**
         * @param  string  filepath (namespace/file.ext)
         * @return array  [directory => (string), basename => (string), filename => (string), ext => (string)]
         */
        private function parseFilePath($file)
        {
            $file = trim($file);

            if ($file === '') {
                throw new ImageStorageException('Missing filepath');
            }

            $info = pathinfo($file);
            $basename = $info['basename'];
            return array(
                'namespace' => $info['dirname'] !== '.' ? ($info['dirname'] . '/') : NULL,
                'delimiter' => substr($basename . '00', 0, 2) . '/' . substr($basename . '00', 2, 2),
                'basename' => $info['basename'],
                'filename' => $info['filename'],
                'ext' => isset($info['extension']) ? $info['extension'] : NULL,
            );
        }


        /**
         * Sestavi "filepath" (namespace/file.ext)
         * @param  string
         * @param  string|NULL
         * @return string
         */
        private function formatFilePath($file, $namespace = NULL)
        {
            return ltrim(trim($namespace, '/') . '/' . trim($file, '/'), '/');
        }


        private function normalizePath($directory, $suffix)
        {
            return rtrim(rtrim($directory, '/') . '/' . $suffix, '/');
        }
    }


    class ImageStorageException extends \RuntimeException
    {
    }
inteve/simple-image-storage v1.6.0 API documentation API documentation generated by ApiGen