1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace Pry\File;
14:
15: use Pry\Util\Strings;
16: use Pry\File\Util;
17:
18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
34: class Upload
35: {
36:
37: const MIME_CHECK_BROWSER = 1;
38: const MIME_CHECK_FINFO = 2;
39: const MIME_CHECK_MIMETYPE = 3;
40: const MIME_CHECK_NONE = 4;
41: const REQUIRE_ALL = 1;
42: const REQUIRE_YES = 2;
43: const REQUIRE_NO = 3;
44: const WMODE_OVERWRITE = 1;
45: const WMODE_COPY = 2;
46: const WMODE_CANCEL = 3;
47:
48: 49: 50: 51:
52: private $maxFileSize;
53:
54: 55: 56: 57:
58: private $uploadDir;
59:
60: 61: 62: 63:
64: private $magicFile;
65:
66: 67: 68: 69:
70: private $mimeCheck;
71:
72: 73: 74: 75:
76: private $writeMode;
77:
78: 79: 80: 81:
82: private $secureMode;
83:
84: 85: 86: 87:
88: private $required;
89:
90: 91: 92: 93:
94: private $extensions;
95:
96: 97: 98: 99:
100: private $mime;
101:
102: 103: 104: 105:
106: private $fieldName;
107:
108: 109: 110: 111:
112: private $fileName;
113:
114: 115: 116: 117:
118: private $cleanName;
119:
120: 121: 122: 123:
124: private $prefix;
125:
126: 127: 128: 129:
130: private $suffix;
131:
132: 133: 134: 135:
136: private $uploadedFiles;
137:
138: 139: 140: 141:
142: private $errors;
143:
144: 145: 146: 147: 148: 149:
150: public function __construct($dir, $fieldName, $mimeCheck = 1)
151: {
152: $this->maxFileSize = str_replace('M', '', ini_get('upload_max_filesize')) * 1024 * 1024;
153: $this->uploadDir = $this->checkPath($dir);
154: $this->magicFile = '';
155: $this->mimeCheck = intval($mimeCheck);
156: $this->writeMode = self::WMODE_OVERWRITE;
157: $this->required = self::REQUIRE_NO;
158: $this->extensions = array('jpg', 'png', 'gif', 'zip', 'rar', 'avi', 'wmv', 'mpg', 'pdf', 'doc', 'docx', 'xls', 'txt');
159: $this->mime = array('image/gif', 'image/jpeg', 'image/png', 'text/plain', 'application/pdf');
160: $this->fieldName = $fieldName;
161: $this->fileName = '';
162: $this->fileNameTmp = '';
163: $this->prefix = '';
164: $this->suffix = '';
165: $this->uploadedFiles = array();
166: $this->secureMode = false;
167: $this->cleanName = false;
168: $this->errors = array();
169: }
170:
171: 172: 173: 174:
175: public function upload()
176: {
177: if (!isset($_FILES[$this->fieldName]['tmp_name']))
178: throw new \UnexpectedValueException('Erreur : Aucune données de fichier');
179:
180: $nbFile = count($_FILES[$this->fieldName]['tmp_name']);
181:
182: for ($i = 0; $i < $nbFile; $i++) {
183: $this->fileNameTmp = '';
184: $this->_taille = $_FILES[$this->fieldName]['size'][$i];
185: $this->_nom = $_FILES[$this->fieldName]['name'][$i];
186: $this->_temp = $_FILES[$this->fieldName]['tmp_name'][$i];
187: $this->_mime = $_FILES[$this->fieldName]['type'][$i];
188: if (!empty($this->_nom))
189: $this->_ext = Util::getExtension($this->_nom);
190: $this->_error = $_FILES[$this->fieldName]['error'][$i];
191:
192: if ($this->_error == UPLOAD_ERR_OK && is_uploaded_file($_FILES[$this->fieldName]['tmp_name'][$i]))
193: {
194: if ($this->mimeCheck == self::MIME_CHECK_FINFO)
195: {
196: $finfo = new finfo(FILEINFO_MIME, $this->magicFile);
197: $this->_mime = @$finfo->file(realpath($this->_temp));
198:
199: $posVirgule = strpos($this->_mime, ';');
200: if ($posVirgule !== false)
201: $this->_mime = substr($this->_mime, 0, $posVirgule);
202: }
203: elseif ($this->mimeCheck == self::MIME_CHECK_MIMETYPE)
204: $this->_mime = mime_content_type(realpath($this->_temp));
205: elseif ($this->mimeCheck == self::MIME_CHECK_NONE)
206: $this->_mime = false;
207:
208: if ($this->checkSize())
209: {
210: if ($this->checkExtension())
211: {
212: if ($this->checkMime())
213: {
214: $this->buildName();
215: if (!$this->write())
216: {
217: $this->errors[$i] = "Impossible d'�crire sur le disque";
218: }
219: }
220: else
221: {
222: $this->errors[$i] = "Ce type de fichier n'est pas autoris�";
223: }
224: }
225: else
226: {
227: $this->errors[$i] = "L'extension du fichier n'est pas autoris�e";
228: }
229: }
230: else
231: {
232: $this->errors[$i] = "Le fichier d�passe la limite de taille autoris�e";
233: }
234: }
235: else
236: {
237: if ($this->required == self::REQUIRE_ALL || $this->required == self::REQUIRE_YES && $i == 0)
238: $this->errors[$i] = "Erreur pendant l'upload. Fichier trop volumineux ?";
239: }
240: }
241: return $this->getError();
242: }
243:
244: 245: 246: 247: 248: 249:
250: public function setMaxFileSize($size)
251: {
252: $this->maxFileSize = Util::getOctalSize($size);
253: return $this;
254: }
255:
256: 257: 258: 259: 260:
261: public function setMagicFile($path)
262: {
263: $this->magicFile = $path;
264: return $this;
265: }
266:
267: 268: 269: 270: 271:
272: public function setWriteMode($mode)
273: {
274: $this->writeMode = intval($mode);
275: return $this;
276: }
277:
278: 279: 280: 281: 282:
283: public function setRequired($mode)
284: {
285: $this->required = intval($mode);
286: return $this;
287: }
288:
289: 290: 291: 292: 293:
294: public function setAllowedExtensions($newExt)
295: {
296: if (is_array($newExt))
297: foreach ($newExt as $value)
298: $this->extensions[] = $value;
299: else
300: $this->extensions[] = $newExt;
301:
302: return $this;
303: }
304:
305: 306: 307: 308:
309: public function getExtensions()
310: {
311: return $this->extensions;
312: }
313:
314: 315: 316: 317: 318:
319: public function removeExtension($extToRm)
320: {
321: $cle = array_search($extToRm, $this->extensions);
322: if ($cle)
323: unset($this->extensions[$cle]);
324:
325: return $this;
326: }
327:
328: 329: 330: 331:
332: public function flushAllowedExtensions()
333: {
334: $this->extensions = array();
335: return $this;
336: }
337:
338: 339: 340: 341: 342:
343: public function setAllowedMime($newMime)
344: {
345: if (is_array($newMime))
346: foreach ($newMime as $value)
347: $this->mime[] = $value;
348: else
349: $this->mime[] = $newMime;
350:
351: return $this;
352: }
353:
354: 355: 356: 357:
358: public function getMime()
359: {
360: return $this->mime;
361: }
362:
363: 364: 365: 366: 367:
368: public function removeMime($mimeToRm)
369: {
370: $cle = array_search($mimeToRm, $this->mime);
371: if ($cle)
372: unset($this->mime[$cle]);
373:
374: return $this;
375: }
376:
377: 378: 379: 380:
381: public function flushAllowedMime()
382: {
383: $this->mime = array();
384: return $this;
385: }
386:
387: 388: 389: 390: 391:
392: public function setFileName($name)
393: {
394: $this->fileName = trim($name);
395: return $this;
396: }
397:
398: 399: 400: 401: 402:
403: public function setPrefix($prefix)
404: {
405: $this->prefix = trim($prefix);
406: return $this;
407: }
408:
409: 410: 411: 412: 413:
414: public function setSuffix($suffix)
415: {
416: $this->suffix = trim($suffix);
417: return $this;
418: }
419:
420: 421: 422: 423: 424:
425: public function setSecureMode($mode)
426: {
427: $this->secureMode($mode);
428: return $this;
429: }
430:
431: 432: 433: 434: 435:
436: public function cleanName($bool)
437: {
438: $this->cleanName = $bool;
439: return $this;
440: }
441:
442: 443: 444: 445:
446: public function getError()
447: {
448: if (!empty($this->errors))
449: return $this->errors;
450: else
451: return false;
452: }
453:
454: 455: 456: 457:
458: public function getSummary()
459: {
460: return $this->uploadedFiles;
461: }
462:
463: 464: 465: 466: 467:
468: private function checkPath($path)
469: {
470: $path = trim($path);
471: if ($path[0] == '/')
472: $path = substr($path, 1);
473: if (!is_dir($path))
474: throw new \InvalidArgumentException($path . ' n\'est pas un répertoire valide');
475: if (!is_writable($path))
476: throw new \RuntimeException($path . ' n\'est pas ouvert en écriture');
477:
478: return $path;
479: }
480:
481: 482: 483: 484:
485: private function write()
486: {
487:
488: if ($this->writeMode == self::WMODE_OVERWRITE)
489: {
490: if ($this->exist())
491: unlink($this->uploadDir . $this->fileNameTmp);
492: $uploaded = move_uploaded_file($this->_temp, $this->uploadDir . $this->fileNameTmp);
493: }
494: elseif ($this->writeMode == self::WMODE_COPY)
495: {
496: if ($this->exist())
497: $this->fileName = 'Copie_de_' . $this->fileNameTmp;
498: $uploaded = move_uploaded_file($this->_temp, $this->uploadDir . $this->fileNameTmp);
499: }
500: else
501: {
502: if (!$this->exist())
503: $uploaded = move_uploaded_file($this->_temp, $this->uploadDir . $this->fileNameTmp);
504: else
505: $uploaded = false;
506: }
507:
508: if ($uploaded)
509: {
510: $this->uploadedFiles[] = array(
511: 'nom' => $this->fileNameTmp,
512: 'nom_base' => $this->_nom,
513: 'ext' => $this->_ext,
514: 'mime' => $this->_mime,
515: 'path' => $this->uploadDir,
516: 'octet' => $this->_taille,
517: 'size' => number_format($this->_taille / 1024, 2, '.', '')
518: );
519: return true;
520: }
521: return false;
522: }
523:
524: 525: 526: 527:
528: private function checkSize()
529: {
530: if ($this->maxFileSize > $this->_taille)
531: return true;
532: return false;
533: }
534:
535: 536: 537: 538:
539: private function checkExtension()
540: {
541: if (in_array($this->_ext, $this->extensions))
542: return true;
543: return false;
544: }
545:
546: 547: 548: 549:
550: private function checkMime()
551: {
552: if ($this->mimeCheck != self::MIME_CHECK_NONE)
553: {
554: if ($this->secureMode)
555: {
556: if (!in_array($this->_mime, $this->mime) || strpos($this->_mime, 'application') || preg_match("/.php$|.php3$|.php5$|.inc$|.js$|.exe$/i", $this->_ext))
557: return false;
558: } else
559: {
560: if (!in_array($this->_mime, $this->mime))
561: return false;
562: }
563: }
564: return true;
565: }
566:
567: 568: 569: 570:
571: private function buildName()
572: {
573: if ($this->fileName == '')
574: $this->fileNameTmp = substr($this->_nom, 0, strrpos($this->_nom, '.'));
575: else
576: $this->fileNameTmp = $this->filename;
577:
578: if ($this->cleanName)
579: $this->fileNameTmp = Strings::clean($this->fileNameTmp);
580: $this->fileNameTmp = $this->prefix . $this->fileNameTmp . $this->suffix . '.' . $this->_ext;
581: }
582:
583: 584: 585: 586: 587:
588: private function exist()
589: {
590: if (file_exists($this->uploadDir . $this->fileNameTmp))
591: return true;
592: return false;
593: }
594:
595: }
596:
597: ?>