Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 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\HttpKernel;
13
 
14
use Symfony\Component\BrowserKit\AbstractBrowser;
15
use Symfony\Component\BrowserKit\CookieJar;
16
use Symfony\Component\BrowserKit\History;
17
use Symfony\Component\BrowserKit\Request as DomRequest;
18
use Symfony\Component\BrowserKit\Response as DomResponse;
19
use Symfony\Component\HttpFoundation\File\UploadedFile;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpFoundation\Response;
22
 
23
/**
24
 * Simulates a browser and makes requests to an HttpKernel instance.
25
 *
26
 * @author Fabien Potencier <fabien@symfony.com>
27
 *
28
 * @method Request  getRequest()
29
 * @method Response getResponse()
30
 */
31
class HttpKernelBrowser extends AbstractBrowser
32
{
33
    protected $kernel;
34
    private bool $catchExceptions = true;
35
 
36
    /**
37
     * @param array $server The server parameters (equivalent of $_SERVER)
38
     */
39
    public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null)
40
    {
41
        // These class properties must be set before calling the parent constructor, as it may depend on it.
42
        $this->kernel = $kernel;
43
        $this->followRedirects = false;
44
 
45
        parent::__construct($server, $history, $cookieJar);
46
    }
47
 
48
    /**
49
     * Sets whether to catch exceptions when the kernel is handling a request.
50
     */
51
    public function catchExceptions(bool $catchExceptions)
52
    {
53
        $this->catchExceptions = $catchExceptions;
54
    }
55
 
56
    /**
57
     * @param Request $request
58
     *
59
     * @return Response
60
     */
61
    protected function doRequest(object $request)
62
    {
63
        $response = $this->kernel->handle($request, HttpKernelInterface::MAIN_REQUEST, $this->catchExceptions);
64
 
65
        if ($this->kernel instanceof TerminableInterface) {
66
            $this->kernel->terminate($request, $response);
67
        }
68
 
69
        return $response;
70
    }
71
 
72
    /**
73
     * @param Request $request
74
     *
75
     * @return string
76
     */
77
    protected function getScript(object $request)
78
    {
79
        $kernel = var_export(serialize($this->kernel), true);
80
        $request = var_export(serialize($request), true);
81
 
82
        $errorReporting = error_reporting();
83
 
84
        $requires = '';
85
        foreach (get_declared_classes() as $class) {
86
            if (str_starts_with($class, 'ComposerAutoloaderInit')) {
87
                $r = new \ReflectionClass($class);
88
                $file = \dirname($r->getFileName(), 2).'/autoload.php';
89
                if (file_exists($file)) {
90
                    $requires .= 'require_once '.var_export($file, true).";\n";
91
                }
92
            }
93
        }
94
 
95
        if (!$requires) {
96
            throw new \RuntimeException('Composer autoloader not found.');
97
        }
98
 
99
        $code = <<<EOF
100
<?php
101
 
102
error_reporting($errorReporting);
103
 
104
$requires
105
 
106
\$kernel = unserialize($kernel);
107
\$request = unserialize($request);
108
EOF;
109
 
110
        return $code.$this->getHandleScript();
111
    }
112
 
113
    protected function getHandleScript()
114
    {
115
        return <<<'EOF'
116
$response = $kernel->handle($request);
117
 
118
if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) {
119
    $kernel->terminate($request, $response);
120
}
121
 
122
echo serialize($response);
123
EOF;
124
    }
125
 
126
    protected function filterRequest(DomRequest $request): Request
127
    {
128
        $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $server = $request->getServer(), $request->getContent());
129
        if (!isset($server['HTTP_ACCEPT'])) {
130
            $httpRequest->headers->remove('Accept');
131
        }
132
 
133
        foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) {
134
            $httpRequest->files->set($key, $value);
135
        }
136
 
137
        return $httpRequest;
138
    }
139
 
140
    /**
141
     * Filters an array of files.
142
     *
143
     * This method created test instances of UploadedFile so that the move()
144
     * method can be called on those instances.
145
     *
146
     * If the size of a file is greater than the allowed size (from php.ini) then
147
     * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
148
     *
149
     * @see UploadedFile
150
     */
151
    protected function filterFiles(array $files): array
152
    {
153
        $filtered = [];
154
        foreach ($files as $key => $value) {
155
            if (\is_array($value)) {
156
                $filtered[$key] = $this->filterFiles($value);
157
            } elseif ($value instanceof UploadedFile) {
158
                if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) {
159
                    $filtered[$key] = new UploadedFile(
160
                        '',
161
                        $value->getClientOriginalName(),
162
                        $value->getClientMimeType(),
163
                        \UPLOAD_ERR_INI_SIZE,
164
                        true
165
                    );
166
                } else {
167
                    $filtered[$key] = new UploadedFile(
168
                        $value->getPathname(),
169
                        $value->getClientOriginalName(),
170
                        $value->getClientMimeType(),
171
                        $value->getError(),
172
                        true
173
                    );
174
                }
175
            }
176
        }
177
 
178
        return $filtered;
179
    }
180
 
181
    /**
182
     * @param Response $response
183
     */
184
    protected function filterResponse(object $response): DomResponse
185
    {
186
        // this is needed to support StreamedResponse
187
        ob_start();
188
        $response->sendContent();
189
        $content = ob_get_clean();
190
 
191
        return new DomResponse($content, $response->getStatusCode(), $response->headers->all());
192
    }
193
}