]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/form/Symfony/Component/Form/NativeRequestHandler.php
twig implementation
[github/wallabag/wallabag.git] / vendor / symfony / form / Symfony / Component / Form / NativeRequestHandler.php
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 }