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