vendor/symfony/src/Symfony/Component/HttpFoundation/FileBag.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\HttpFoundation;
       
    13 
       
    14 use Symfony\Component\HttpFoundation\File\UploadedFile;
       
    15 
       
    16 /**
       
    17  * FileBag is a container for HTTP headers.
       
    18  *
       
    19  * @author Fabien Potencier <fabien@symfony.com>
       
    20  * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
       
    21  *
       
    22  * @api
       
    23  */
       
    24 class FileBag extends ParameterBag
       
    25 {
       
    26     static private $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
       
    27 
       
    28     /**
       
    29      * Constructor.
       
    30      *
       
    31      * @param array $parameters An array of HTTP files
       
    32      *
       
    33      * @api
       
    34      */
       
    35     public function __construct(array $parameters = array())
       
    36     {
       
    37         $this->replace($parameters);
       
    38     }
       
    39 
       
    40     /**
       
    41      * (non-PHPdoc)
       
    42      * @see Symfony\Component\HttpFoundation\ParameterBag::replace()
       
    43      *
       
    44      * @api
       
    45      */
       
    46     public function replace(array $files = array())
       
    47     {
       
    48         $this->parameters = array();
       
    49         $this->add($files);
       
    50     }
       
    51 
       
    52     /**
       
    53      * (non-PHPdoc)
       
    54      * @see Symfony\Component\HttpFoundation\ParameterBag::set()
       
    55      *
       
    56      * @api
       
    57      */
       
    58     public function set($key, $value)
       
    59     {
       
    60         if (is_array($value) || $value instanceof UploadedFile) {
       
    61             parent::set($key, $this->convertFileInformation($value));
       
    62         } else {
       
    63             throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
       
    64         }
       
    65     }
       
    66 
       
    67     /**
       
    68      * (non-PHPdoc)
       
    69      * @see Symfony\Component\HttpFoundation\ParameterBag::add()
       
    70      *
       
    71      * @api
       
    72      */
       
    73     public function add(array $files = array())
       
    74     {
       
    75         foreach ($files as $key => $file) {
       
    76             $this->set($key, $file);
       
    77         }
       
    78     }
       
    79 
       
    80     /**
       
    81      * Converts uploaded files to UploadedFile instances.
       
    82      *
       
    83      * @param  array|UploadedFile $file A (multi-dimensional) array of uploaded file information
       
    84      *
       
    85      * @return array A (multi-dimensional) array of UploadedFile instances
       
    86      */
       
    87     protected function convertFileInformation($file)
       
    88     {
       
    89         if ($file instanceof UploadedFile) {
       
    90             return $file;
       
    91         }
       
    92 
       
    93         $file = $this->fixPhpFilesArray($file);
       
    94         if (is_array($file)) {
       
    95             $keys = array_keys($file);
       
    96             sort($keys);
       
    97 
       
    98             if ($keys == self::$fileKeys) {
       
    99                 if (UPLOAD_ERR_NO_FILE == $file['error']) {
       
   100                     $file = null;
       
   101                 } else {
       
   102                     $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
       
   103                 }
       
   104             } else {
       
   105                 $file = array_map(array($this, 'convertFileInformation'), $file);
       
   106             }
       
   107         }
       
   108 
       
   109         return $file;
       
   110     }
       
   111 
       
   112     /**
       
   113      * Fixes a malformed PHP $_FILES array.
       
   114      *
       
   115      * PHP has a bug that the format of the $_FILES array differs, depending on
       
   116      * whether the uploaded file fields had normal field names or array-like
       
   117      * field names ("normal" vs. "parent[child]").
       
   118      *
       
   119      * This method fixes the array to look like the "normal" $_FILES array.
       
   120      *
       
   121      * It's safe to pass an already converted array, in which case this method
       
   122      * just returns the original array unmodified.
       
   123      *
       
   124      * @param  array $data
       
   125      * @return array
       
   126      */
       
   127     protected function fixPhpFilesArray($data)
       
   128     {
       
   129         if (!is_array($data)) {
       
   130             return $data;
       
   131         }
       
   132 
       
   133         $keys = array_keys($data);
       
   134         sort($keys);
       
   135 
       
   136         if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
       
   137             return $data;
       
   138         }
       
   139 
       
   140         $files = $data;
       
   141         foreach (self::$fileKeys as $k) {
       
   142             unset($files[$k]);
       
   143         }
       
   144 
       
   145         foreach (array_keys($data['name']) as $key) {
       
   146             $files[$key] = $this->fixPhpFilesArray(array(
       
   147                 'error'    => $data['error'][$key],
       
   148                 'name'     => $data['name'][$key],
       
   149                 'type'     => $data['type'][$key],
       
   150                 'tmp_name' => $data['tmp_name'][$key],
       
   151                 'size'     => $data['size'][$key]
       
   152             ));
       
   153         }
       
   154 
       
   155         return $files;
       
   156     }
       
   157 }