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