1: | <?php
|
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | |
11: | |
12: | |
13: | |
14: |
|
15: |
|
16: | namespace LucidFrame\Core;
|
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: | $uploaded = null;
|
264: |
|
265: | if (empty($info['extension'])) {
|
266: | $extension = _mime2ext($file['type']);
|
267: | $fileName .= '.' . $extension;
|
268: | } else {
|
269: | $extension = strtolower($info['extension']);
|
270: | }
|
271: |
|
272: | if ($fileName && $file['error'] === UPLOAD_ERR_OK) {
|
273: | $this->originalFileName = $fileName;
|
274: | $newFileName = $this->getNewFileName();
|
275: |
|
276: | if (!in_array($extension, array('jpg', 'jpeg', 'png', 'gif'))) {
|
277: |
|
278: | $uploaded = $this->move($uploadedFile, $newFileName);
|
279: | } else {
|
280: |
|
281: | if (isset($this->imageFilterSet['maxDimension']) && $this->imageFilterSet['maxDimension']) {
|
282: |
|
283: | $uploaded = $this->resizeImageByDimension($this->imageFilterSet['maxDimension'], $uploadedFile, $newFileName, $extension);
|
284: | } else {
|
285: | $uploaded = $this->move($uploadedFile, $newFileName);
|
286: | }
|
287: |
|
288: | if (is_array($this->dimensions) && count($this->dimensions)) {
|
289: | $this->resizeImageByDimension($this->dimensions, $uploadedFile, $newFileName, $extension);
|
290: | }
|
291: | }
|
292: | } else {
|
293: | $this->error = array(
|
294: | 'code' => $file['error'],
|
295: | 'message' => $this->getErrorMessage($file['error'])
|
296: | );
|
297: | }
|
298: |
|
299: | if ($uploaded) {
|
300: | $this->uploads = array(
|
301: | 'name' => $this->name,
|
302: | 'fileName' => $uploaded,
|
303: | 'originalFileName' => $this->originalFileName,
|
304: | 'extension' => $extension,
|
305: | 'dir' => $this->get('uploadDir')
|
306: | );
|
307: | }
|
308: |
|
309: | return $this->uploads;
|
310: | }
|
311: |
|
312: | |
313: | |
314: | |
315: | |
316: |
|
317: | private function getNewFileName()
|
318: | {
|
319: | $this->fileName = $this->getUniqueId() . '.' . $this->guessExtension();
|
320: |
|
321: | if ($this->useOriginalFileName) {
|
322: | $this->fileName = $this->originalFileName;
|
323: | }
|
324: |
|
325: | return $this->fileName;
|
326: | }
|
327: |
|
328: | |
329: | |
330: | |
331: |
|
332: | private function getUniqueId()
|
333: | {
|
334: | return $this->uniqueId ?: uniqid();
|
335: | }
|
336: |
|
337: | |
338: | |
339: | |
340: | |
341: |
|
342: | public function guessExtension($file = '')
|
343: | {
|
344: | $file = $file ?: $this->originalFileName;
|
345: |
|
346: | if ($file) {
|
347: | $info = pathinfo($file);
|
348: | return $info['extension'];
|
349: | }
|
350: |
|
351: | return '';
|
352: | }
|
353: |
|
354: | |
355: | |
356: | |
357: | |
358: | |
359: |
|
360: | protected function move($file, $newFileName)
|
361: | {
|
362: | $targetDir = $this->uploadPath;
|
363: | if (!is_dir($targetDir)) {
|
364: | @mkdir($targetDir, 0777, true);
|
365: | }
|
366: | if (@move_uploaded_file($file, $targetDir . $newFileName)) {
|
367: | return $newFileName;
|
368: | } else {
|
369: | $this->error = array(
|
370: | 'code' => FILE_UPLOAD_ERR_MOVE,
|
371: | 'message' => $this->getErrorMessage(FILE_UPLOAD_ERR_MOVE)
|
372: | );
|
373: | return null;
|
374: | }
|
375: | }
|
376: |
|
377: | |
378: | |
379: | |
380: | |
381: | |
382: | |
383: | |
384: | |
385: |
|
386: | protected function resizeImageByDimension($dimensions, $file, $newFileName, $extension = null)
|
387: | {
|
388: | $singleDimension = false;
|
389: | if (!is_array($dimensions)) {
|
390: | $dimensions = array($dimensions);
|
391: | $singleDimension = true;
|
392: | }
|
393: |
|
394: | $extension = $extension ?: strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
395: |
|
396: | if ($extension == "jpg" || $extension == "jpeg") {
|
397: | $img = imagecreatefromjpeg($file);
|
398: | } elseif ($extension == "png") {
|
399: | $img = imagecreatefrompng($file);
|
400: | } elseif ($extension == "gif") {
|
401: | $img = imagecreatefromgif($file);
|
402: | }
|
403: |
|
404: | if (isset($img) && $img) {
|
405: | if (isset($this->imageFilterSet['jpgQuality']) && is_numeric($this->imageFilterSet['jpgQuality'])) {
|
406: | $jpgQuality = $this->imageFilterSet['jpgQuality'];
|
407: | } else {
|
408: | $jpgQuality = 75;
|
409: | }
|
410: |
|
411: | foreach ($dimensions as $dimension) {
|
412: | $resize = explode('x', $dimension);
|
413: | $resizeWidth = $resize[0];
|
414: | $resizeHeight = $resize[1];
|
415: |
|
416: | if ($this->imageFilterSet['resizeMode'] == FILE_RESIZE_WIDTH) {
|
417: | $tmp = File::resizeImageWidth($img, $file, $resizeWidth, $extension);
|
418: | } elseif ($this->imageFilterSet['resizeMode'] == FILE_RESIZE_HEIGHT) {
|
419: | $tmp = File::resizeImageHeight($img, $file, $resizeHeight. $extension);
|
420: | } else {
|
421: | $tmp = File::resizeImageBoth($img, $file, $resizeWidth, $resizeHeight, $extension);
|
422: | }
|
423: |
|
424: | $targetDir = $singleDimension ? $this->uploadPath : $this->uploadPath . $dimension . _DS_;
|
425: | if (!is_dir($targetDir)) {
|
426: | @mkdir($targetDir, 0777, true);
|
427: | }
|
428: | $targetFileName = $targetDir . $newFileName;
|
429: |
|
430: | if ($extension == "gif") {
|
431: | imagegif($tmp, $targetFileName);
|
432: | } elseif ($extension == "png") {
|
433: | imagealphablending($tmp, true);
|
434: | imagesavealpha($tmp, true);
|
435: | imagepng($tmp, $targetFileName);
|
436: | } else {
|
437: | imagejpeg($tmp, $targetFileName, $jpgQuality);
|
438: | }
|
439: |
|
440: | imagedestroy($tmp);
|
441: | }
|
442: | if ($img) {
|
443: | imagedestroy($img);
|
444: | return $newFileName;
|
445: | }
|
446: | } else {
|
447: | $this->error = array(
|
448: | 'code' => FILE_UPLOAD_ERR_IMAGE_CREATE,
|
449: | 'message' => $this->getErrorMessage(FILE_UPLOAD_ERR_IMAGE_CREATE)
|
450: | );
|
451: | }
|
452: | return null;
|
453: | }
|
454: |
|
455: | |
456: | |
457: | |
458: | |
459: | |
460: | |
461: | |
462: | |
463: | |
464: |
|
465: | public static function resizeImageWidth(&$img, $file, $newWidth, $extension = null)
|
466: | {
|
467: | $extension = $extension ? $extension : strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
468: | list($width, $height) = getimagesize($file);
|
469: | $newHeight = ($height/$width) * $newWidth;
|
470: |
|
471: | $tmp = imagecreatetruecolor($newWidth, $newHeight);
|
472: | imagealphablending($tmp, false);
|
473: | if ($extension == 'png') {
|
474: | imagesavealpha($tmp, true);
|
475: | }
|
476: |
|
477: | imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
478: |
|
479: | return $tmp;
|
480: | }
|
481: |
|
482: | |
483: | |
484: | |
485: | |
486: | |
487: | |
488: | |
489: | |
490: | |
491: |
|
492: | public static function resizeImageHeight(&$img, $file, $newHeight, $extension = null)
|
493: | {
|
494: | $extension = $extension ? $extension : strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
495: |
|
496: | list($width, $height) = getimagesize($file);
|
497: | $newWidth = ($width/$height) * $newHeight;
|
498: |
|
499: | $tmp = imagecreatetruecolor($newWidth, $newHeight);
|
500: | imagealphablending($tmp, false);
|
501: | if ($extension == 'png') {
|
502: | imagesavealpha($tmp, true);
|
503: | }
|
504: |
|
505: | imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
506: |
|
507: | return $tmp;
|
508: | }
|
509: |
|
510: | |
511: | |
512: | |
513: | |
514: | |
515: | |
516: | |
517: | |
518: | |
519: | |
520: |
|
521: | public static function resizeImageBoth(&$img, $file, $newWidth, $newHeight, $extension = null)
|
522: | {
|
523: | $extension = $extension ? $extension : strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
524: |
|
525: | list($width, $height) = getimagesize($file);
|
526: |
|
527: | $scale = min($newWidth/$width, $newHeight/$height);
|
528: |
|
529: | if ($scale < 1) {
|
530: |
|
531: | $newWidth = floor($scale * $width);
|
532: |
|
533: | $newHeight = floor($scale * $height);
|
534: | } else {
|
535: |
|
536: | $newWidth = $width;
|
537: | $newHeight = $height;
|
538: | }
|
539: |
|
540: | $tmp = imagecreatetruecolor($newWidth, $newHeight);
|
541: | imagealphablending($tmp, false);
|
542: | if ($extension == 'png') {
|
543: | imagesavealpha($tmp, true);
|
544: | }
|
545: |
|
546: | imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
547: |
|
548: | return $tmp;
|
549: | }
|
550: |
|
551: | |
552: | |
553: | |
554: | |
555: | |
556: | |
557: | |
558: | |
559: | |
560: | |
561: |
|
562: | public static function img($fileName, $caption, $dimension, $desiredDimension = '0x0', array $attributes = array())
|
563: | {
|
564: | $regex = '/^[0-9]+x[0-9]+$/i';
|
565: | if (!preg_match($regex, $dimension)) {
|
566: | echo '';
|
567: | return null;
|
568: | }
|
569: | if (!preg_match($regex, $desiredDimension)) {
|
570: | $desiredDimension = '0x0';
|
571: | }
|
572: | list($imgWidth, $imgHeight) = explode('x', strtolower($dimension));
|
573: | list($desiredWidth, $desiredHeight) = explode('x', strtolower($desiredDimension));
|
574: |
|
575: | if ($imgWidth > $desiredWidth || $imgHeight > $desiredHeight) {
|
576: |
|
577: | if ($desiredWidth == 0 && $desiredHeight > 0) {
|
578: |
|
579: | $desiredWidth = floor(($imgWidth/$imgHeight) * $desiredHeight);
|
580: | $imgWidth = $desiredWidth;
|
581: | $imgHeight = $desiredHeight;
|
582: | } elseif ($desiredWidth > 0 && $desiredHeight == 0) {
|
583: |
|
584: | $desiredHeight = floor(($imgHeight/$imgWidth) * $desiredWidth);
|
585: | $imgWidth = $desiredWidth;
|
586: | $imgHeight = $desiredHeight;
|
587: | } elseif ($desiredWidth > 0 && $desiredHeight > 0) {
|
588: |
|
589: | $scale = min($desiredWidth/$imgWidth, $desiredHeight/$imgHeight);
|
590: |
|
591: | $imgWidth = floor($scale * $imgWidth);
|
592: |
|
593: | $imgHeight = floor($scale * $imgHeight);
|
594: | if ($imgWidth < $desiredWidth || $imgHeight < $desiredHeight) {
|
595: | $wDiff = $desiredWidth - $imgWidth;
|
596: | $hDiff = $desiredHeight - $desiredWidth;
|
597: | if ($wDiff > $hDiff) {
|
598: |
|
599: | $imgHeight = floor(($imgHeight/$imgWidth) * $desiredWidth);
|
600: | $imgWidth = $desiredWidth;
|
601: | } else {
|
602: |
|
603: | $imgWidth = floor(($imgWidth/$imgHeight) * $desiredHeight);
|
604: | $imgHeight = $desiredHeight;
|
605: | }
|
606: | }
|
607: | } else {
|
608: |
|
609: | $desiredWidth = $imgWidth;
|
610: | $desiredHeight = $imgHeight;
|
611: | }
|
612: | }
|
613: |
|
614: | $style = '';
|
615: | if ($imgWidth > $desiredWidth) {
|
616: | $marginH = floor(($imgWidth - $desiredWidth)/2);
|
617: | $style = 'margin-left:-'.$marginH.'px';
|
618: | }
|
619: | if ($imgHeight > $desiredHeight) {
|
620: | $marginV = floor(($imgHeight - $desiredHeight)/2);
|
621: | $style = 'margin-top:-'.$marginV.'px';
|
622: | }
|
623: | if (isset($attributes['style']) && $attributes['style']) {
|
624: | $style .= $attributes['style'];
|
625: | }
|
626: | $attributes['src'] = $fileName;
|
627: | $attributes['alt'] = _h($caption);
|
628: | $attributes['title'] = _h($caption);
|
629: | $attributes['width'] = $imgWidth;
|
630: | $attributes['height'] = $imgHeight;
|
631: | $attributes['style'] = $style;
|
632: |
|
633: | $attrHTML = '';
|
634: | foreach ($attributes as $key => $value) {
|
635: | $attrHTML .= ' ' . $key . '="' . $value .'"';
|
636: | }
|
637: | return '<img '.$attrHTML.' />';
|
638: | }
|
639: | }
|
640: | |