Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 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 uploaded files.
18
 *
19
 * @author Fabien Potencier <fabien@symfony.com>
20
 * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
21
 */
22
class FileBag extends ParameterBag
23
{
24
    private static $fileKeys = ['error', 'name', 'size', 'tmp_name', 'type'];
25
 
26
    /**
27
     * @param array|UploadedFile[] $parameters An array of HTTP files
28
     */
29
    public function __construct(array $parameters = [])
30
    {
31
        $this->replace($parameters);
32
    }
33
 
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function replace(array $files = [])
38
    {
39
        $this->parameters = [];
40
        $this->add($files);
41
    }
42
 
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function set(string $key, $value)
47
    {
48
        if (!\is_array($value) && !$value instanceof UploadedFile) {
49
            throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
50
        }
51
 
52
        parent::set($key, $this->convertFileInformation($value));
53
    }
54
 
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function add(array $files = [])
59
    {
60
        foreach ($files as $key => $file) {
61
            $this->set($key, $file);
62
        }
63
    }
64
 
65
    /**
66
     * Converts uploaded files to UploadedFile instances.
67
     *
68
     * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information
69
     *
70
     * @return UploadedFile[]|UploadedFile|null A (multi-dimensional) array of UploadedFile instances
71
     */
72
    protected function convertFileInformation($file)
73
    {
74
        if ($file instanceof UploadedFile) {
75
            return $file;
76
        }
77
 
78
        if (\is_array($file)) {
79
            $file = $this->fixPhpFilesArray($file);
80
            $keys = array_keys($file);
81
            sort($keys);
82
 
83
            if ($keys == self::$fileKeys) {
84
                if (\UPLOAD_ERR_NO_FILE == $file['error']) {
85
                    $file = null;
86
                } else {
87
                    $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error'], false);
88
                }
89
            } else {
90
                $file = array_map([$this, 'convertFileInformation'], $file);
91
                if (array_keys($keys) === $keys) {
92
                    $file = array_filter($file);
93
                }
94
            }
95
        }
96
 
97
        return $file;
98
    }
99
 
100
    /**
101
     * Fixes a malformed PHP $_FILES array.
102
     *
103
     * PHP has a bug that the format of the $_FILES array differs, depending on
104
     * whether the uploaded file fields had normal field names or array-like
105
     * field names ("normal" vs. "parent[child]").
106
     *
107
     * This method fixes the array to look like the "normal" $_FILES array.
108
     *
109
     * It's safe to pass an already converted array, in which case this method
110
     * just returns the original array unmodified.
111
     *
112
     * @param array $data
113
     *
114
     * @return array
115
     */
116
    protected function fixPhpFilesArray($data)
117
    {
118
        $keys = array_keys($data);
119
        sort($keys);
120
 
121
        if (self::$fileKeys != $keys || !isset($data['name']) || !\is_array($data['name'])) {
122
            return $data;
123
        }
124
 
125
        $files = $data;
126
        foreach (self::$fileKeys as $k) {
127
            unset($files[$k]);
128
        }
129
 
130
        foreach ($data['name'] as $key => $name) {
131
            $files[$key] = $this->fixPhpFilesArray([
132
                'error' => $data['error'][$key],
133
                'name' => $name,
134
                'type' => $data['type'][$key],
135
                'tmp_name' => $data['tmp_name'][$key],
136
                'size' => $data['size'][$key],
137
            ]);
138
        }
139
 
140
        return $files;
141
    }
142
}