Overview

Namespaces

  • None
  • PHP
  • Pry
    • Auth
      • Interfaces
    • Config
    • Controller
    • Date
    • Db
    • Feed
      • Abstracts
      • Writers
    • File
      • Decorator
    • Form
      • Element
    • Image
    • Log
      • Writer
    • Net
      • Exception
    • Session
    • Util
    • Validate
      • Validator
    • View

Classes

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