diff options
Diffstat (limited to 'vendor/symfony/form/Symfony/Component/Form/NativeRequestHandler.php')
-rw-r--r-- | vendor/symfony/form/Symfony/Component/Form/NativeRequestHandler.php | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/vendor/symfony/form/Symfony/Component/Form/NativeRequestHandler.php b/vendor/symfony/form/Symfony/Component/Form/NativeRequestHandler.php new file mode 100644 index 00000000..aaa4e4c0 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/NativeRequestHandler.php | |||
@@ -0,0 +1,194 @@ | |||
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\Form; | ||
13 | |||
14 | use Symfony\Component\Form\Exception\UnexpectedTypeException; | ||
15 | use Symfony\Component\Form\FormInterface; | ||
16 | use Symfony\Component\Form\RequestHandlerInterface; | ||
17 | |||
18 | /** | ||
19 | * A request handler using PHP's super globals $_GET, $_POST and $_SERVER. | ||
20 | * | ||
21 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
22 | */ | ||
23 | class NativeRequestHandler implements RequestHandlerInterface | ||
24 | { | ||
25 | /** | ||
26 | * The allowed keys of the $_FILES array. | ||
27 | * | ||
28 | * @var array | ||
29 | */ | ||
30 | private static $fileKeys = array( | ||
31 | 'error', | ||
32 | 'name', | ||
33 | 'size', | ||
34 | 'tmp_name', | ||
35 | 'type', | ||
36 | ); | ||
37 | |||
38 | /** | ||
39 | * {@inheritdoc} | ||
40 | */ | ||
41 | public function handleRequest(FormInterface $form, $request = null) | ||
42 | { | ||
43 | if (null !== $request) { | ||
44 | throw new UnexpectedTypeException($request, 'null'); | ||
45 | } | ||
46 | |||
47 | $name = $form->getName(); | ||
48 | $method = $form->getConfig()->getMethod(); | ||
49 | |||
50 | if ($method !== self::getRequestMethod()) { | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | if ('GET' === $method) { | ||
55 | if ('' === $name) { | ||
56 | $data = $_GET; | ||
57 | } else { | ||
58 | // Don't submit GET requests if the form's name does not exist | ||
59 | // in the request | ||
60 | if (!isset($_GET[$name])) { | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | $data = $_GET[$name]; | ||
65 | } | ||
66 | } else { | ||
67 | $fixedFiles = array(); | ||
68 | foreach ($_FILES as $name => $file) { | ||
69 | $fixedFiles[$name] = self::stripEmptyFiles(self::fixPhpFilesArray($file)); | ||
70 | } | ||
71 | |||
72 | if ('' === $name) { | ||
73 | $params = $_POST; | ||
74 | $files = $fixedFiles; | ||
75 | } else { | ||
76 | $default = $form->getConfig()->getCompound() ? array() : null; | ||
77 | $params = isset($_POST[$name]) ? $_POST[$name] : $default; | ||
78 | $files = isset($fixedFiles[$name]) ? $fixedFiles[$name] : $default; | ||
79 | } | ||
80 | |||
81 | if (is_array($params) && is_array($files)) { | ||
82 | $data = array_replace_recursive($params, $files); | ||
83 | } else { | ||
84 | $data = $params ?: $files; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | // Don't auto-submit the form unless at least one field is present. | ||
89 | if ('' === $name && count(array_intersect_key($data, $form->all())) <= 0) { | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | $form->submit($data, 'PATCH' !== $method); | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * Returns the method used to submit the request to the server. | ||
98 | * | ||
99 | * @return string The request method. | ||
100 | */ | ||
101 | private static function getRequestMethod() | ||
102 | { | ||
103 | $method = isset($_SERVER['REQUEST_METHOD']) | ||
104 | ? strtoupper($_SERVER['REQUEST_METHOD']) | ||
105 | : 'GET'; | ||
106 | |||
107 | if ('POST' === $method && isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { | ||
108 | $method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); | ||
109 | } | ||
110 | |||
111 | return $method; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Fixes a malformed PHP $_FILES array. | ||
116 | * | ||
117 | * PHP has a bug that the format of the $_FILES array differs, depending on | ||
118 | * whether the uploaded file fields had normal field names or array-like | ||
119 | * field names ("normal" vs. "parent[child]"). | ||
120 | * | ||
121 | * This method fixes the array to look like the "normal" $_FILES array. | ||
122 | * | ||
123 | * It's safe to pass an already converted array, in which case this method | ||
124 | * just returns the original array unmodified. | ||
125 | * | ||
126 | * This method is identical to {@link Symfony\Component\HttpFoundation\FileBag::fixPhpFilesArray} | ||
127 | * and should be kept as such in order to port fixes quickly and easily. | ||
128 | * | ||
129 | * @param array $data | ||
130 | * | ||
131 | * @return array | ||
132 | */ | ||
133 | private static function fixPhpFilesArray($data) | ||
134 | { | ||
135 | if (!is_array($data)) { | ||
136 | return $data; | ||
137 | } | ||
138 | |||
139 | $keys = array_keys($data); | ||
140 | sort($keys); | ||
141 | |||
142 | if (self::$fileKeys !== $keys || !isset($data['name']) || !is_array($data['name'])) { | ||
143 | return $data; | ||
144 | } | ||
145 | |||
146 | $files = $data; | ||
147 | foreach (self::$fileKeys as $k) { | ||
148 | unset($files[$k]); | ||
149 | } | ||
150 | |||
151 | foreach (array_keys($data['name']) as $key) { | ||
152 | $files[$key] = self::fixPhpFilesArray(array( | ||
153 | 'error' => $data['error'][$key], | ||
154 | 'name' => $data['name'][$key], | ||
155 | 'type' => $data['type'][$key], | ||
156 | 'tmp_name' => $data['tmp_name'][$key], | ||
157 | 'size' => $data['size'][$key] | ||
158 | )); | ||
159 | } | ||
160 | |||
161 | return $files; | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * Sets empty uploaded files to NULL in the given uploaded files array. | ||
166 | * | ||
167 | * @param mixed $data The file upload data. | ||
168 | * | ||
169 | * @return array|null Returns the stripped upload data. | ||
170 | */ | ||
171 | private static function stripEmptyFiles($data) | ||
172 | { | ||
173 | if (!is_array($data)) { | ||
174 | return $data; | ||
175 | } | ||
176 | |||
177 | $keys = array_keys($data); | ||
178 | sort($keys); | ||
179 | |||
180 | if (self::$fileKeys === $keys) { | ||
181 | if (UPLOAD_ERR_NO_FILE === $data['error']) { | ||
182 | return null; | ||
183 | } | ||
184 | |||
185 | return $data; | ||
186 | } | ||
187 | |||
188 | foreach ($data as $key => $value) { | ||
189 | $data[$key] = self::stripEmptyFiles($value); | ||
190 | } | ||
191 | |||
192 | return $data; | ||
193 | } | ||
194 | } | ||