1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
6: * @package Nette\Http
7: */
8:
9:
10:
11: /**
12: * Provides access to individual files that have been uploaded by a client.
13: *
14: * @author David Grudl
15: *
16: * @property-read string $name
17: * @property-read string $sanitizedName
18: * @property-read string $contentType
19: * @property-read int $size
20: * @property-read string $temporaryFile
21: * @property-read int $error
22: * @property-read bool $ok
23: * @property-read bool $image
24: * @property-read array $imageSize
25: * @property-read string $contents
26: * @package Nette\Http
27: */
28: class HttpUploadedFile extends Object
29: {
30: /** @var string */
31: private $name;
32:
33: /** @var string */
34: private $type;
35:
36: /** @var string */
37: private $size;
38:
39: /** @var string */
40: private $tmpName;
41:
42: /** @var int */
43: private $error;
44:
45:
46: public function __construct($value)
47: {
48: foreach (array('name', 'type', 'size', 'tmp_name', 'error') as $key) {
49: if (!isset($value[$key]) || !is_scalar($value[$key])) {
50: $this->error = UPLOAD_ERR_NO_FILE;
51: return; // or throw exception?
52: }
53: }
54: $this->name = $value['name'];
55: $this->size = $value['size'];
56: $this->tmpName = $value['tmp_name'];
57: $this->error = $value['error'];
58: }
59:
60:
61: /**
62: * Returns the file name.
63: * @return string
64: */
65: public function getName()
66: {
67: return $this->name;
68: }
69:
70:
71: /**
72: * Returns the sanitized file name.
73: * @return string
74: */
75: public function getSanitizedName()
76: {
77: return trim(Strings::webalize($this->name, '.', FALSE), '.-');
78: }
79:
80:
81: /**
82: * Returns the MIME content type of an uploaded file.
83: * @return string
84: */
85: public function getContentType()
86: {
87: if ($this->isOk() && $this->type === NULL) {
88: $this->type = MimeTypeDetector::fromFile($this->tmpName);
89: }
90: return $this->type;
91: }
92:
93:
94: /**
95: * Returns the size of an uploaded file.
96: * @return int
97: */
98: public function getSize()
99: {
100: return $this->size;
101: }
102:
103:
104: /**
105: * Returns the path to an uploaded file.
106: * @return string
107: */
108: public function getTemporaryFile()
109: {
110: return $this->tmpName;
111: }
112:
113:
114: /**
115: * Returns the path to an uploaded file.
116: * @return string
117: */
118: public function __toString()
119: {
120: return (string) $this->tmpName;
121: }
122:
123:
124: /**
125: * Returns the error code. {@link http://php.net/manual/en/features.file-upload.errors.php}
126: * @return int
127: */
128: public function getError()
129: {
130: return $this->error;
131: }
132:
133:
134: /**
135: * Is there any error?
136: * @return bool
137: */
138: public function isOk()
139: {
140: return $this->error === UPLOAD_ERR_OK;
141: }
142:
143:
144: /**
145: * Move uploaded file to new location.
146: * @param string
147: * @return self
148: */
149: public function move($dest)
150: {
151: @mkdir(dirname($dest), 0777, TRUE); // @ - dir may already exist
152: @unlink($dest); // @ - file may not exists
153: if (!call_user_func(is_uploaded_file($this->tmpName) ? 'move_uploaded_file' : 'rename', $this->tmpName, $dest)) {
154: throw new InvalidStateException("Unable to move uploaded file '$this->tmpName' to '$dest'.");
155: }
156: chmod($dest, 0666);
157: $this->tmpName = $dest;
158: return $this;
159: }
160:
161:
162: /**
163: * Is uploaded file GIF, PNG or JPEG?
164: * @return bool
165: */
166: public function isImage()
167: {
168: return in_array($this->getContentType(), array('image/gif', 'image/png', 'image/jpeg'), TRUE);
169: }
170:
171:
172: /**
173: * Returns the image.
174: * @return Image
175: */
176: public function toImage()
177: {
178: return Image::fromFile($this->tmpName);
179: }
180:
181:
182: /**
183: * Returns the dimensions of an uploaded image as array.
184: * @return array
185: */
186: public function getImageSize()
187: {
188: return $this->isOk() ? @getimagesize($this->tmpName) : NULL; // @ - files smaller than 12 bytes causes read error
189: }
190:
191:
192: /**
193: * Get file contents.
194: * @return string
195: */
196: public function getContents()
197: {
198: // future implementation can try to work around safe_mode and open_basedir limitations
199: return $this->isOk() ? file_get_contents($this->tmpName) : NULL;
200: }
201:
202: }
203: