Code

< 40 %
40-60 %
> 60 %
1
<?php
2
/**
3
 * ImageWrapper.php
4
 * @author Revin Roman http://phptime.ru
5
 */
6
7
namespace rmrevin\yii\module\File;
8
9
use Imagine\Image\ImageInterface;
10
use Imagine\Image\ManipulatorInterface;
11
use rmrevin\yii\module\File\component\Image;
12
use rmrevin\yii\module\File\models\File;
13
use yii\helpers\FileHelper;
14
use yii\helpers\Json;
15
use yii\helpers\StringHelper;
16
17
/**
18
 * Class ImageWrapper
19
 * @package rmrevin\yii\module\File
20
 */
21
class ImageWrapper extends \yii\base\Object
22
{
23
24
    /** @var \rmrevin\yii\module\File\models\File */
25
    public $File = null;
26
27
    /** @var array */
28
    public $result = [null, null];
29
30
    /** @var array */
31
    private $mark = [];
32
33
    /**
34
     * @param \rmrevin\yii\module\File\models\File $File
35
     * @return self
36
     */
37 4
    public static function load(File $File)
38
    {
39 4
        return new self(['File' => $File]);
40
    }
41
42
    /**
43
     * @return string
44
     */
45 1
    public function __toString()
46
    {
47 1
        return (string)$this->result[1];
48
    }
49
50
    /**
51
     * @param callable $handler
52
     */
53 1
    public function save($handler)
54
    {
55 1
        $mark = $this->calculateMark();
56
57 1
        $this->result = $this->getMarkedFilePath($mark);
58
59 1
        if (!file_exists($this->result[0])) {
60 1
            \Yii::trace('create new file cache:' . $this->File->id, __METHOD__);
61 1
            $this->createMarkedFile($handler(), $mark);
62 1
        } else {
63 1
            \Yii::trace('file already cached:' . $this->File->id . ' (' . Json::encode($this->mark) . ')', __METHOD__);
64
        }
65
66 1
        \Yii::endProfile('manipulating with file `' . $this->File->id . '`', 'services\File\models\File');
67 1
    }
68
69
    /**
70
     * @param integer $width
71
     * @param integer $height
72
     * @param string $filter
73
     * @return self
74
     */
75 1 View Code Duplication
    public function resize($width, $height, $filter = ImageInterface::FILTER_UNDEFINED)
76
    {
77 1
        \Yii::trace('resize file', __METHOD__);
78
79 1
        $this->mark(__METHOD__, func_get_args());
80
        $this->save(function () use ($width, $height, $filter) {
81 1
            return Image::resize($this->File->getAbsolutePath(), $width, $height, $filter);
82 1
        });
83
84 1
        return $this;
85
    }
86
87
    /**
88
     * @param integer $width
89
     * @param string $filter
90
     * @return self
91
     */
92 1 View Code Duplication
    public function resizeByWidth($width, $filter = ImageInterface::FILTER_UNDEFINED)
93
    {
94 1
        \Yii::trace('resizeByWidth file', __METHOD__);
95
96 1
        $this->mark(__METHOD__, func_get_args());
97
        $this->save(function () use ($width, $filter) {
98 1
            return Image::resizeByWidth($this->File->getAbsolutePath(), $width, $filter);
99 1
        });
100
101 1
        return $this;
102
103 1
    }
104
105
    /**
106
     * @param integer $height
107
     * @param string $filter
108
     * @return self
109
     */
110 1 View Code Duplication
    public function resizeByHeight($height, $filter = ImageInterface::FILTER_UNDEFINED)
111
    {
112 1
        \Yii::trace('resizeByHeight file', __METHOD__);
113
114 1
        $this->mark(__METHOD__, func_get_args());
115
        $this->save(function () use ($height, $filter) {
116 1
            return Image::resizeByHeight($this->File->getAbsolutePath(), $height, $filter);
117 1
        });
118
119 1
        return $this;
120
    }
121
122
    /**
123
     * @param integer $width
124
     * @param integer $height
125
     * @param array $start
126
     * @return self
127
     */
128 1 View Code Duplication
    public function crop($width, $height, array $start = [0, 0])
129
    {
130 1
        \Yii::trace('crop file', __METHOD__);
131
132 1
        $this->mark(__METHOD__, func_get_args());
133
        $this->save(function () use ($width, $height, $start) {
134 1
            return Image::crop($this->File->getAbsolutePath(), $width, $height, $start);
135 1
        });
136
137 1
        return $this;
138
    }
139
140
    /**
141
     * @param integer $width
142
     * @param integer $height
143
     * @param string $mode
144
     * @return self
145
     */
146 1 View Code Duplication
    public function thumbnail($width, $height, $mode = ManipulatorInterface::THUMBNAIL_OUTBOUND)
147
    {
148 1
        \Yii::trace('thumbnail file', __METHOD__);
149
150 1
        $this->mark(__METHOD__, func_get_args());
151
        $this->save(function () use ($width, $height, $mode) {
152 1
            return Image::thumbnail($this->File->getAbsolutePath(), $width, $height, $mode);
153 1
        });
154
155 1
        return $this;
156
    }
157
158
    /**
159
     * @param string $watermarkFilename
160
     * @param array $start
161
     * @return self
162
     */
163 1
    public function watermark($watermarkFilename, array $start = [0, 0])
164
    {
165 1
        \Yii::trace('watermark file', __METHOD__);
166
167 1
        $this->mark(__METHOD__, func_get_args());
168
        $this->save(function () use ($watermarkFilename, $start) {
169 1
            return Image::watermark($this->File->getAbsolutePath(), $watermarkFilename, $start);
170 1
        });
171
172 1
        return $this;
173
    }
174
175
    /**
176
     * @param string $text
177
     * @param string $fontFile
178
     * @param array $start
179
     * @param array $fontOptions
180
     * @return self
181
     */
182 1 View Code Duplication
    public function text($text, $fontFile, array $start = [0, 0], array $fontOptions = [])
183
    {
184 1
        \Yii::trace('text file', __METHOD__);
185
186 1
        $this->mark(__METHOD__, func_get_args());
187
        $this->save(function () use ($text, $fontFile, $start, $fontOptions) {
188 1
            return Image::text($this->File->getAbsolutePath(), $text, $fontFile, $start, $fontOptions);
189 1
        });
190
191 1
        return $this;
192
    }
193
194
    /**
195
     * @param int $margin
196
     * @param string $color
197
     * @param int $alpha
198
     * @return self
199
     */
200 1
    public function frame($margin = 20, $color = '666', $alpha = 100)
201
    {
202 1
        \Yii::trace('frame file', __METHOD__);
203
204 1
        $this->mark(__METHOD__, func_get_args());
205 1
        $this->save(function () use ($margin, $color, $alpha) {
206 1
            return Image::frame($this->File->getAbsolutePath(), $margin, $color, $alpha);
207 1
        });
208
209 1
        return $this;
210
    }
211
212
    /**
213
     * @return string[]
214
     */
215 1
    private function getPath()
216
    {
217 1
        $filename = basename($this->File->name);
218 1
        $p1 = StringHelper::byteSubstr($filename, 0, 2);
219 1
        $p2 = StringHelper::byteSubstr($filename, 2, 2);
220 1
        $p = DIRECTORY_SEPARATOR . $p1 . DIRECTORY_SEPARATOR . $p2;
221
222
        return [
223 1
            Module::module()->storage_path . $p,
224 1
            Module::module()->storage_web_path . $p
225 1
        ];
226
    }
227
228
    /**
229
     * @param string $mark
230
     * @return string[]
231
     */
232 1
    private function getMarkedFilePath($mark)
233
    {
234 1
        \Yii::trace('calculate mark file path', __METHOD__);
235
236 1
        $ext = pathinfo($this->File->name, PATHINFO_EXTENSION);
237
238 1
        list($path, $web_path) = $this->getPath();
239 1
        $mark_file_path = $path . DIRECTORY_SEPARATOR . $mark . '.' . $ext;
240 1
        $mark_file_web_path = $web_path . '/' . $mark . '.' . $ext;
241
242 1
        return [$mark_file_path, $mark_file_web_path];
243
    }
244
245
    /**
246
     * @param \Imagine\Image\ImageInterface $Image
247
     * @param string $mark
248
     */
249 1
    private function createMarkedFile(ImageInterface $Image, $mark)
250
    {
251 1
        \Yii::beginProfile('create cache file:' . $this->File->id, __METHOD__);
252
253 1
        list($mark_file_path, $mark_file_web_path) = $this->getMarkedFilePath($mark);
254
255 1
        $mark_dir_path = dirname($mark_file_path);
256 1
        if (!file_exists($mark_dir_path) || !is_dir($mark_dir_path)) {
257 1
            FileHelper::createDirectory($mark_dir_path);
258 1
        }
259
260 1
        $Image->save($mark_file_path, ['quality' => 90]);
261 1
        @chmod($mark_file_path, 0664);
262
263 1
        \Yii::endProfile('create cache file:' . $this->File->id, __METHOD__);
264 1
    }
265
266
267
    /**
268
     * @param string $method
269
     * @param array $data
270
     */
271 1
    private function mark($method, array $data)
272
    {
273 1
        $this->mark = func_get_args();
274 1
    }
275
276
    /**
277
     * @return string
278
     */
279 1
    private function calculateMark()
280
    {
281 1
        return sha1(Json::encode($this->mark));
282
    }
283
}