1: | <?php
|
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | |
11: | |
12: | |
13: | |
14: |
|
15: |
|
16: | namespace LucidFrame\File;
|
17: |
|
18: | |
19: | |
20: | |
21: |
|
22: | class File extends \SplFileInfo
|
23: | {
|
24: |
|
25: | private $name;
|
26: |
|
27: | private $uniqueId;
|
28: |
|
29: | private $dimensions;
|
30: |
|
31: | private $uploadPath;
|
32: |
|
33: | private $originalFileName;
|
34: |
|
35: | private $fileName;
|
36: |
|
37: | private $uploads;
|
38: |
|
39: | private $error;
|
40: |
|
41: | private $imageFilterSet;
|
42: |
|
43: | private $useOriginalFileName = false;
|
44: |
|
45: | |
46: | |
47: | |
48: |
|
49: | public function __construct($fileName = '')
|
50: | {
|
51: | $this->name = $fileName;
|
52: | $this->uploadPath = FILE . 'tmp' . _DS_;
|
53: | $this->defaultImageFilterSet();
|
54: | if ($fileName) {
|
55: | parent::__construct($fileName);
|
56: | }
|
57: | }
|
58: |
|
59: | |
60: | |
61: | |
62: |
|
63: | private function defaultImageFilterSet()
|
64: | {
|
65: | $this->imageFilterSet = array(
|
66: | 'maxDimension' => '800x600',
|
67: | 'resizeMode' => FILE_RESIZE_BOTH,
|
68: | 'jpgQuality' => 75
|
69: | );
|
70: | $this->imageFilterSet = array_merge($this->imageFilterSet, _cfg('imageFilterSet'));
|
71: | $this->setImageResizeMode($this->imageFilterSet['resizeMode']);
|
72: | return $this;
|
73: | }
|
74: |
|
75: | |
76: | |
77: | |
78: | |
79: |
|
80: | private function setImageResizeMode($value)
|
81: | {
|
82: | if (in_array($value, array(FILE_RESIZE_BOTH, FILE_RESIZE_WIDTH, FILE_RESIZE_HEIGHT))) {
|
83: | $this->imageFilterSet['resizeMode'] = $value;
|
84: | } else {
|
85: | $this->imageFilterSet['resizeMode'] = FILE_RESIZE_BOTH;
|
86: | }
|
87: | return $this;
|
88: | }
|
89: |
|
90: | |
91: | |
92: | |
93: | |
94: | |
95: |
|
96: | public function set($key, $value)
|
97: | {
|
98: | if ($key === 'resize' || $key === 'resizeMode') {
|
99: | $this->setImageResizeMode($value);
|
100: | return $this;
|
101: | }
|
102: |
|
103: | if ($key === 'maxDimension') {
|
104: | $this->imageFilterSet['maxDimension'] = $value;
|
105: | return $this;
|
106: | }
|
107: |
|
108: | if ($key === 'jpgQuality') {
|
109: | $this->imageFilterSet['jpgQuality'] = $value;
|
110: | return $this;
|
111: | }
|
112: |
|
113: |
|
114: |
|
115: | if ($key === 'uniqueId' && $value & $this->name === $this->uniqueId) {
|
116: | $this->name = $value;
|
117: | }
|
118: |
|
119: | if ($key === 'uploadDir' || $key === 'uploadPath') {
|
120: | $value = rtrim(rtrim($value, '/'), _DS_) . _DS_;
|
121: | $this->uploadPath = $value;
|
122: | }
|
123: |
|
124: | $this->{$key} = $value;
|
125: |
|
126: | return $this;
|
127: | }
|
128: |
|
129: | |
130: | |
131: | |
132: | |
133: |
|
134: | public function get($key)
|
135: | {
|
136: | if ($key === 'uploadDir') {
|
137: | return $this->uploadPath;
|
138: | }
|
139: | if (isset($this->{$key})) {
|
140: | return $this->{$key};
|
141: | }
|
142: | return null;
|
143: | }
|
144: |
|
145: | |
146: | |
147: |
|
148: | public function getOriginalFileName()
|
149: | {
|
150: | return $this->originalFileName;
|
151: | }
|
152: |
|
153: | |
154: | |
155: |
|
156: | #[\ReturnTypeWillChange]
|
157: | public function getFileName()
|
158: | {
|
159: | return $this->fileName;
|
160: | }
|
161: |
|
162: | |
163: | |
164: | |
165: | |
166: | |
167: | |
168: | |
169: | |
170: | |
171: |
|
172: | public function getError()
|
173: | {
|
174: | return $this->error;
|
175: | }
|
176: |
|
177: | |
178: | |
179: | |
180: | |
181: |
|
182: | public function getErrorMessage($code)
|
183: | {
|
184: | switch ($code) {
|
185: | case UPLOAD_ERR_INI_SIZE:
|
186: | $message = _t('The uploaded file exceeds the upload_max_filesize directive in php.ini.');
|
187: | break;
|
188: | case UPLOAD_ERR_FORM_SIZE:
|
189: | $message = _t('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.');
|
190: | break;
|
191: | case UPLOAD_ERR_PARTIAL:
|
192: | $message = _t('The uploaded file was only partially uploaded.');
|
193: | break;
|
194: | case UPLOAD_ERR_NO_FILE:
|
195: | $message = _t('No file was uploaded.');
|
196: | break;
|
197: | case UPLOAD_ERR_NO_TMP_DIR:
|
198: | $message = _t('Missing a temporary folder.');
|
199: | break;
|
200: | case UPLOAD_ERR_CANT_WRITE:
|
201: | $message = _t('Failed to write file to disk.');
|
202: | break;
|
203: | case UPLOAD_ERR_EXTENSION:
|
204: | $message = _t('File upload stopped by extension.');
|
205: | break;
|
206: | case FILE_UPLOAD_ERR_MOVE:
|
207: | $message = _t('The uploaded file is not valid.');
|
208: | break;
|
209: | case FILE_UPLOAD_ERR_IMAGE_CREATE:
|
210: | $message = _t('Failed to create image from the uploaded file.');
|
211: | break;
|
212: | default:
|
213: | $message = _t('Unknown upload error.');
|
214: | break;
|
215: | }
|
216: |
|
217: | return $message;
|
218: | }
|
219: |
|
220: | |
221: | |
222: | |
223: | |
224: | |
225: | |
226: | |
227: | |
228: | |
229: | |
230: | |
231: | |
232: | |
233: | |
234: | |
235: | |
236: | |
237: |
|
238: | public function upload($file)
|
239: | {
|
240: | if (is_string($file)) {
|
241: | if (!isset($_FILES[$file])) {
|
242: | $this->error = array(
|
243: | 'code' => UPLOAD_ERR_NO_FILE,
|
244: | 'message' => $this->getErrorMessage(UPLOAD_ERR_NO_FILE)
|
245: | );
|
246: | return null;
|
247: | }
|
248: | $this->name = $file;
|
249: | $file = $_FILES[$file];
|
250: | }
|
251: |
|
252: | if (!isset($file['name']) || !isset($file['tmp_name'])) {
|
253: | $this->error = array(
|
254: | 'code' => UPLOAD_ERR_NO_FILE,
|
255: | 'message' => $this->getErrorMessage(UPLOAD_ERR_NO_FILE)
|
256: | );
|
257: | return null;
|
258: | }
|
259: |
|
260: | $fileName = stripslashes($file['name']);
|
261: | $uploadedFile = $file['tmp_name'];
|
262: | $info = pathinfo($fileName);
|
263: | $extension = strtolower($info['extension']);
|
264: | $uploaded = null;
|
265: |
|
266: | if ($fileName && $file['error'] === UPLOAD_ERR_OK) {
|
267: | $this->originalFileName = $fileName;
|
268: | $newFileName = $this->getNewFileName();
|
269: |
|
270: | if (!in_array($extension, array('jpg', 'jpeg', 'png', 'gif'))) {
|
271: |
|
272: | $uploaded = $this->move($uploadedFile, $newFileName);
|
273: | } else {
|
274: |
|
275: | if (isset($this->imageFilterSet['maxDimension']) && $this->imageFilterSet['maxDimension']) {
|
276: |
|
277: | $uploaded = $this->resizeImageByDimension($this->imageFilterSet['maxDimension'], $uploadedFile, $newFileName, $extension);
|
278: | } else {
|
279: | $uploaded = $this->move($uploadedFile, $newFileName);
|
280: | }
|
281: |
|
282: | if (is_array($this->dimensions) && count($this->dimensions)) {
|
283: | $this->resizeImageByDimension($this->dimensions, $uploadedFile, $newFileName, $extension);
|
284: | }
|
285: | }
|
286: | } else {
|
287: | $this->error = array(
|
288: | 'code' => $file['error'],
|
289: | 'message' => $this->getErrorMessage($file['error'])
|
290: | );
|
291: | }
|
292: |
|
293: | if ($uploaded) {
|
294: | $this->uploads = array(
|
295: | 'name' => $this->name,
|
296: | 'fileName' => $uploaded,
|
297: | 'originalFileName' => $this->originalFileName,
|
298: | 'extension' => $extension,
|
299: | 'dir' => $this->get('uploadDir')
|
300: | );
|
301: | }
|
302: |
|
303: | return $this->uploads;
|
304: | }
|
305: |
|
306: | |
307: | |
308: | |
309: | |
310: |
|
311: | private function getNewFileName()
|
312: | {
|
313: | $this->fileName = $this->getUniqueId() . '.' . $this->guessExtension();
|
314: |
|
315: | if ($this->useOriginalFileName) {
|
316: | $this->fileName = $this->originalFileName;
|
317: | }
|
318: |
|
319: | return $this->fileName;
|
320: | }
|
321: |
|
322: | |
323: | |
324: | |
325: |
|
326: | private function getUniqueId()
|
327: | {
|
328: | return $this->uniqueId ?: uniqid();
|
329: | }
|
330: |
|
331: | |
332: | |
333: | |
334: | |
335: |
|
336: | public function guessExtension($file = '')
|
337: | {
|
338: | $file = $file ? $file : $this->originalFileName;
|
339: |
|
340: | if ($file) {
|
341: | $info = pathinfo($file);
|
342: | return $info['extension'];
|
343: | }
|
344: |
|
345: | return '';
|
346: | }
|
347: |
|
348: | |
349: | |
350: | |
351: | |
352: | |
353: |
|
354: | protected function move($file, $newFileName)
|
355: | {
|
356: | $targetDir = $this->uploadPath;
|
357: | if (!is_dir($targetDir)) {
|
358: | @mkdir($targetDir, 0777, true);
|
359: | }
|
360: | if (@move_uploaded_file($file, $targetDir . $newFileName)) {
|
361: | return $newFileName;
|
362: | } else {
|
363: | $this->error = array(
|
364: | 'code' => FILE_UPLOAD_ERR_MOVE,
|
365: | 'message' => $this->getErrorMessage(FILE_UPLOAD_ERR_MOVE)
|
366: | );
|
367: | return null;
|
368: | }
|
369: | }
|
370: |
|
371: | |
372: | |
373: | |
374: | |
375: | |
376: | |
377: | |
378: | |
379: |
|
380: | protected function resizeImageByDimension($dimensions, $file, $newFileName, $extension = null)
|
381: | {
|
382: | $singleDimension = false;
|
383: | if (!is_array($dimensions)) {
|
384: | $dimensions = array($dimensions);
|
385: | $singleDimension = true;
|
386: | }
|
387: |
|
388: | $extension = $extension ?: strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
389: |
|
390: | if ($extension == "jpg" || $extension == "jpeg") {
|
391: | $img = imagecreatefromjpeg($file);
|
392: | } elseif ($extension == "png") {
|
393: | $img = imagecreatefrompng($file);
|
394: | } elseif ($extension == "gif") {
|
395: | $img = imagecreatefromgif($file);
|
396: | }
|
397: |
|
398: | if (isset($img) && $img) {
|
399: | if (isset($this->imageFilterSet['jpgQuality']) && is_numeric($this->imageFilterSet['jpgQuality'])) {
|
400: | $jpgQuality = $this->imageFilterSet['jpgQuality'];
|
401: | } else {
|
402: | $jpgQuality = 75;
|
403: | }
|
404: |
|
405: | foreach ($dimensions as $dimension) {
|
406: | $resize = explode('x', $dimension);
|
407: | $resizeWidth = $resize[0];
|
408: | $resizeHeight = $resize[1];
|
409: |
|
410: | if ($this->imageFilterSet['resizeMode'] == FILE_RESIZE_WIDTH) {
|
411: | $tmp = File::resizeImageWidth($img, $file, $resizeWidth, $extension);
|
412: | } elseif ($this->imageFilterSet['resizeMode'] == FILE_RESIZE_HEIGHT) {
|
413: | $tmp = File::resizeImageHeight($img, $file, $resizeHeight. $extension);
|
414: | } else {
|
415: | $tmp = File::resizeImageBoth($img, $file, $resizeWidth, $resizeHeight, $extension);
|
416: | }
|
417: |
|
418: | $targetDir = $singleDimension ? $this->uploadPath : $this->uploadPath . $dimension . _DS_;
|
419: | if (!is_dir($targetDir)) {
|
420: | @mkdir($targetDir, 0777, true);
|
421: | }
|
422: | $targetFileName = $targetDir . $newFileName;
|
423: |
|
424: | if ($extension == "gif") {
|
425: | imagegif($tmp, $targetFileName);
|
426: | } elseif ($extension == "png") {
|
427: | imagealphablending($tmp, true);
|
428: | imagesavealpha($tmp, true);
|
429: | imagepng($tmp, $targetFileName);
|
430: | } else {
|
431: | imagejpeg($tmp, $targetFileName, $jpgQuality);
|
432: | }
|
433: |
|
434: | imagedestroy($tmp);
|
435: | }
|
436: | if ($img) {
|
437: | imagedestroy($img);
|
438: | return $newFileName;
|
439: | }
|
440: | } else {
|
441: | $this->error = array(
|
442: | 'code' => FILE_UPLOAD_ERR_IMAGE_CREATE,
|
443: | 'message' => $this->getErrorMessage(FILE_UPLOAD_ERR_IMAGE_CREATE)
|
444: | );
|
445: | }
|
446: | return null;
|
447: | }
|
448: |
|
449: | |
450: | |
451: | |
452: | |
453: | |
454: | |
455: | |
456: | |
457: | |
458: |
|
459: | public static function resizeImageWidth(&$img, $file, $newWidth, $extension = null)
|
460: | {
|
461: | $extension = $extension ? $extension : strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
462: | list($width, $height) = getimagesize($file);
|
463: | $newHeight = ($height/$width) * $newWidth;
|
464: |
|
465: | $tmp = imagecreatetruecolor($newWidth, $newHeight);
|
466: | imagealphablending($tmp, false);
|
467: | if ($extension == 'png') {
|
468: | imagesavealpha($tmp, true);
|
469: | }
|
470: |
|
471: | imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
472: |
|
473: | return $tmp;
|
474: | }
|
475: |
|
476: | |
477: | |
478: | |
479: | |
480: | |
481: | |
482: | |
483: | |
484: | |
485: |
|
486: | public static function resizeImageHeight(&$img, $file, $newHeight, $extension = null)
|
487: | {
|
488: | $extension = $extension ? $extension : strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
489: |
|
490: | list($width, $height) = getimagesize($file);
|
491: | $newWidth = ($width/$height) * $newHeight;
|
492: |
|
493: | $tmp = imagecreatetruecolor($newWidth, $newHeight);
|
494: | imagealphablending($tmp, false);
|
495: | if ($extension == 'png') {
|
496: | imagesavealpha($tmp, true);
|
497: | }
|
498: |
|
499: | imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
500: |
|
501: | return $tmp;
|
502: | }
|
503: |
|
504: | |
505: | |
506: | |
507: | |
508: | |
509: | |
510: | |
511: | |
512: | |
513: | |
514: |
|
515: | public static function resizeImageBoth(&$img, $file, $newWidth, $newHeight, $extension = null)
|
516: | {
|
517: | $extension = $extension ? $extension : strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
518: |
|
519: | list($width, $height) = getimagesize($file);
|
520: |
|
521: | $scale = min($newWidth/$width, $newHeight/$height);
|
522: |
|
523: | if ($scale < 1) {
|
524: |
|
525: | $newWidth = floor($scale * $width);
|
526: |
|
527: | $newHeight = floor($scale * $height);
|
528: | } else {
|
529: |
|
530: | $newWidth = $width;
|
531: | $newHeight = $height;
|
532: | }
|
533: |
|
534: | $tmp = imagecreatetruecolor($newWidth, $newHeight);
|
535: | imagealphablending($tmp, false);
|
536: | if ($extension == 'png') {
|
537: | imagesavealpha($tmp, true);
|
538: | }
|
539: |
|
540: | imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
541: |
|
542: | return $tmp;
|
543: | }
|
544: |
|
545: | |
546: | |
547: | |
548: | |
549: | |
550: | |
551: | |
552: | |
553: | |
554: | |
555: |
|
556: | public static function img($fileName, $caption, $dimension, $desiredDimension = '0x0', array $attributes = array())
|
557: | {
|
558: | $regex = '/^[0-9]+x[0-9]+$/i';
|
559: | if (!preg_match($regex, $dimension)) {
|
560: | echo '';
|
561: | return null;
|
562: | }
|
563: | if (!preg_match($regex, $desiredDimension)) {
|
564: | $desiredDimension = '0x0';
|
565: | }
|
566: | list($imgWidth, $imgHeight) = explode('x', strtolower($dimension));
|
567: | list($desiredWidth, $desiredHeight) = explode('x', strtolower($desiredDimension));
|
568: |
|
569: | if ($imgWidth > $desiredWidth || $imgHeight > $desiredHeight) {
|
570: |
|
571: | if ($desiredWidth == 0 && $desiredHeight > 0) {
|
572: |
|
573: | $desiredWidth = floor(($imgWidth/$imgHeight) * $desiredHeight);
|
574: | $imgWidth = $desiredWidth;
|
575: | $imgHeight = $desiredHeight;
|
576: | } elseif ($desiredWidth > 0 && $desiredHeight == 0) {
|
577: |
|
578: | $desiredHeight = floor(($imgHeight/$imgWidth) * $desiredWidth);
|
579: | $imgWidth = $desiredWidth;
|
580: | $imgHeight = $desiredHeight;
|
581: | } elseif ($desiredWidth > 0 && $desiredHeight > 0) {
|
582: |
|
583: | $scale = min($desiredWidth/$imgWidth, $desiredHeight/$imgHeight);
|
584: |
|
585: | $imgWidth = floor($scale * $imgWidth);
|
586: |
|
587: | $imgHeight = floor($scale * $imgHeight);
|
588: | if ($imgWidth < $desiredWidth || $imgHeight < $desiredHeight) {
|
589: | $wDiff = $desiredWidth - $imgWidth;
|
590: | $hDiff = $desiredHeight - $desiredWidth;
|
591: | if ($wDiff > $hDiff) {
|
592: |
|
593: | $imgHeight = floor(($imgHeight/$imgWidth) * $desiredWidth);
|
594: | $imgWidth = $desiredWidth;
|
595: | } else {
|
596: |
|
597: | $imgWidth = floor(($imgWidth/$imgHeight) * $desiredHeight);
|
598: | $imgHeight = $desiredHeight;
|
599: | }
|
600: | }
|
601: | } else {
|
602: |
|
603: | $desiredWidth = $imgWidth;
|
604: | $desiredHeight = $imgHeight;
|
605: | }
|
606: | }
|
607: |
|
608: | $style = '';
|
609: | if ($imgWidth > $desiredWidth) {
|
610: | $marginH = floor(($imgWidth - $desiredWidth)/2);
|
611: | $style = 'margin-left:-'.$marginH.'px';
|
612: | }
|
613: | if ($imgHeight > $desiredHeight) {
|
614: | $marginV = floor(($imgHeight - $desiredHeight)/2);
|
615: | $style = 'margin-top:-'.$marginV.'px';
|
616: | }
|
617: | if (isset($attributes['style']) && $attributes['style']) {
|
618: | $style .= $attributes['style'];
|
619: | }
|
620: | $attributes['src'] = $fileName;
|
621: | $attributes['alt'] = _h($caption);
|
622: | $attributes['title'] = _h($caption);
|
623: | $attributes['width'] = $imgWidth;
|
624: | $attributes['height'] = $imgHeight;
|
625: | $attributes['style'] = $style;
|
626: |
|
627: | $attrHTML = '';
|
628: | foreach ($attributes as $key => $value) {
|
629: | $attrHTML .= ' ' . $key . '="' . $value .'"';
|
630: | }
|
631: | return '<img '.$attrHTML.' />';
|
632: | }
|
633: | }
|
634: | |