Overview

Packages

  • Auth
  • Config
  • Controller
  • Date
  • Db
  • Feed
    • Abstract
    • Writers
  • File
    • Decorator
  • Form
    • Element
  • Image
  • Log
    • Writer
  • Net
    • Exception
  • None
  • PHP
  • PHPMailer
  • Session
  • Util
  • Validate
    • Validator
  • Zend
    • Registry

Classes

  • File_Crypt
  • File_FileCSV
  • File_FileManager
  • File_FolderManager
  • File_Upload
  • File_Util
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Pry Framework
  4:  *
  5:  * LICENSE
  6:  *
  7:  * This source file is subject to the new BSD license that is bundled
  8:  * with this package in the file LICENSE.txt.
  9:  * 
 10:  * @version $Revision: 276 $
 11:  */
 12: 
 13: /**
 14:  * Classe d'envoi de multiples fichiers.
 15:  * En option utilisation de finfo ou mimemagic
 16:  *
 17:  * <code>
 18:  * $up = new File_Upload('dossier/uplaod/fichier','nomchamps',modeType);
 19:  * $up->setMaxFileSize('5M')->setWriteMode(2);
 20:  * $error = $up->upload();
 21:  * if(!empty($error)) $up->getSummary(); else foreach(errors as $key=>$err) echo $err;
 22:  * </code>
 23:  * 
 24:  * @category Pry
 25:  * @package File
 26:  * @version 2.1.0
 27:  * @author Olivier ROGER <oroger.fr>
 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:      * Taille max en octet du fichier
 47:      * @var int
 48:      */
 49:     private $maxFileSize;
 50: 
 51:     /**
 52:      * Dossier de destination des fichiers
 53:      * @var string
 54:      */
 55:     private $uploadDir;
 56: 
 57:     /**
 58:      * Chemin vers le fichier magicmime
 59:      * @var string
 60:      */
 61:     private $magicFile;
 62: 
 63:     /**
 64:      * Type de vérification mime
 65:      * @var int
 66:      */
 67:     private $mimeCheck;
 68: 
 69:     /**
 70:      * Mode d'écriture pour les fichiers envoyés
 71:      * @var int
 72:      */
 73:     private $writeMode;
 74: 
 75:     /**
 76:      * Mode sécurisé ou non
 77:      * @var boolean
 78:      */
 79:     private $secureMode;
 80: 
 81:     /**
 82:      * Fichier requis ou non
 83:      * @var int
 84:      */
 85:     private $required;
 86: 
 87:     /**
 88:      * Liste des extensions autorisées
 89:      * @var array
 90:      */
 91:     private $extensions;
 92: 
 93:     /**
 94:      * Liste des types mime autorisés
 95:      * @var array
 96:      */
 97:     private $mime;
 98: 
 99:     /**
100:      * Nom des champs d'upload
101:      * @var string
102:      */
103:     private $fieldName;
104: 
105:     /**
106:      * Nom des fichiers
107:      * @var string
108:      */
109:     private $fileName;
110: 
111:     /**
112:      * Nom de fichier nettoyé ou non
113:      * @var boolean
114:      */
115:     private $cleanName;
116: 
117:     /**
118:      * Préfix du nom de fichier
119:      * @var string
120:      */
121:     private $prefix;
122: 
123:     /**
124:      * Suffix du nom de fichier
125:      * @var <string
126:      */
127:     private $suffix;
128: 
129:     /**
130:      * Résumé des fichiers envoyés
131:      * @var array
132:      */
133:     private $uploadedFiles;
134: 
135:     /**
136:      * Erreur rencontrée
137:      * @var mixed
138:      */
139:     private $errors;
140: 
141:     /**
142:      * Constructeur
143:      * @param string $dir Dossier de destination des fichiers
144:      * @param string $fieldName Nom des champs d'upload
145:      * @param int [$mimeCheck] Mode de v�rification du type (d�faut navigateur)
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:      * Déclenche l'envoi de fichier
170:      * @return array
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:                     // Peut retourner des mime du style : "text/plain; charset=utf-8"
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:      * Défini la taille maximal du fichier.
244:      * Accepte un int ou une notation du type 500K, 2M
245:      * @param mixed $size
246:      * @return File_Upload
247:      */
248:     public function setMaxFileSize($size)
249:     {
250:         $this->maxFileSize =  File_Util::getOctalSize($size);
251:         return $this;
252:     }
253: 
254:     /**
255:      * Défini le dossier contenant les fichier magicmime
256:      * @param string $dir
257:      * @return File_Upload
258:      */
259:     public function setMagicFile($path)
260:     {
261:         $this->magicFile = $path;
262:         return $this;
263:     }
264: 
265:     /**
266:      * Défini le mode d'�criture
267:      * @param int $mode
268:      * @return File_Upload
269:      */
270:     public function setWriteMode($mode)
271:     {
272:         $this->writeMode    = intval($mode);
273:         return $this;
274:     }
275: 
276:     /**
277:      * Défini si les fichiers sont requis ou non
278:      * @param int $mode
279:      * @return File_Upload
280:      */
281:     public function setRequired($mode)
282:     {
283:         $this->required     = intval($mode);
284:         return $this;
285:     }
286: 
287:     /**
288:      * Défini une (string) ou plusieurs (array) extensions autorisées
289:      * @param mixed $newExt
290:      * @return File_Upload
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:      * retourne les extensions autorisées
305:      * @return array
306:      */
307:     public function getExtensions()
308:     {
309:         return $this->extensions;
310:     }
311: 
312:     /**
313:      * Supprime une extension
314:      * @param string $extToRm
315:      * @return File_Upload
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:      * Supprime toutes les extensions
328:      * @return File_Upload
329:      */
330:     public function flushAllowedExtensions()
331:     {
332:         $this->extensions = array();
333:         return $this;
334:     }
335: 
336:     /**
337:      * Défini un (string) ou plusieurs (array) type mime autorisé
338:      * @param mixed $newMime
339:      * @return File_Upload
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:      * Retourne les type mime autorisés
354:      * @return array
355:      */
356:     public function getMime()
357:     {
358:         return $this->mime;
359:     }
360: 
361:     /**
362:      * Supprime un type mime
363:      * @param string $mimeToRm
364:      * @return File_Upload
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:      * Supprime tous les types mime
377:      * @return File_Upload
378:      */
379:     public function flushAllowedMime()
380:     {
381:         $this->mime = array();
382:         return $this;
383:     }
384: 
385:     /**
386:      * Défini le nom des fichiers une fois envoyés
387:      * @param string $name
388:      * @return File_Upload
389:      */
390:     public function setFileName($name)
391:     {
392:         $this->fileName = trim($name);
393:         return $this;
394:     }
395: 
396:     /**
397:      * Défini le préfix du nom de fichier
398:      * @param string $prefix
399:      * @return File_Upload
400:      */
401:     public function setPrefix($prefix)
402:     {
403:         $this->prefix = trim($prefix);
404:         return $this;
405:     }
406: 
407:     /**
408:      * Défini le suffix du nom de fichier
409:      * @param string $suffix
410:      * @return File_Upload
411:      */
412:     public function setSuffix($suffix)
413:     {
414:         $this->suffix = trim($suffix);
415:         return $this;
416:     }
417: 
418:     /**
419:      * Défini ou non le mode sécurisé qui n'accepte aucun fichier de type application ou jugé dangereux
420:      * @param boolean $mode
421:      * @return File_Upload
422:      */
423:     public function setSecureMode($mode)
424:     {
425:         $this->secureMode($mode);
426:         return $this;
427:     }
428: 
429:     /**
430:      * Active ou non le nettoyage du nom de fichier
431:      * @param boolean $bool
432:      * @return File_Upload
433:      */
434:     public function cleanName($bool)
435:     {
436:         $this->cleanName = $bool;
437:         return $this;
438:     }
439: 
440:     /**
441:      * Retourne le tableau d'erreur
442:      * @return array
443:      */
444:     public function getError()
445:     {
446:         if(!empty($this->errors))
447:             return $this->errors;
448:         else
449:             return false;
450:     }
451: 
452:     /**
453:      * Retourne le tableau des fichiers envoyés
454:      * @return array
455:      */
456:     public function getSummary()
457:     {
458:         return $this->uploadedFiles;
459:     }
460: 
461:     /**
462:      * Vérifie qu'un chemin est correct
463:      * @param string $path
464:      * @return boolean
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:      * Ecrit le fichier sur le disque à l'emplacement souhaité
481:      * @return boolean
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:      * Vérifie la taille du fichier
524:      * @return boolean
525:      */
526:     private function checkSize()
527:     {
528:         if($this->maxFileSize > $this->_taille)
529:             return true;
530:         return false;
531:     }
532: 
533:     /**
534:      * Vérifie l'extension du fichier
535:      * @return boolean
536:      */
537:     private function checkExtension()
538:     {
539:         if(in_array($this->_ext,$this->extensions))
540:             return true;    
541:         return false;
542:     }
543: 
544:     /**
545:      * Vérifie le type mime du fichier
546:      * @return boolean
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:      * Construit le nom de fichier
564:      * @return void
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:      * Vérifie l'existance d'un fichier
580:      * @access private
581:      * @return boolean
582:      */
583:     private function exist()
584:     {
585:         if(file_exists($this->uploadDir.$this->fileNameTmp))
586:             return true;
587:         return false;
588:     }
589: }
590: ?>
Pry Framework API documentation generated by ApiGen 2.6.1