Passed
Push — 2.0 ( 401112...fa4b31 )
by Greg
13:39
created

response()   A

Complexity

Conditions 6
Paths 12

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 19
nc 12
nop 3
dl 0
loc 36
rs 9.0111
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2021 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
use Aura\Router\RouterContainer;
21
use Fig\Http\Message\StatusCodeInterface;
22
use Fisharebest\Webtrees\Html;
23
use Fisharebest\Webtrees\Session as WebtreesSession;
24
use Fisharebest\Webtrees\View as WebtreesView;
25
use Fisharebest\Webtrees\Webtrees;
26
use Psr\Http\Message\ResponseFactoryInterface;
27
use Psr\Http\Message\ResponseInterface;
28
use Psr\Http\Message\ServerRequestInterface;
29
use Psr\Http\Message\StreamFactoryInterface;
30
31
/**
32
 * Get the IoC container, or fetch something from it.
33
 *
34
 * @param string|null $abstract
35
 *
36
 * @return mixed
37
 */
38
function app(string $abstract = null)
39
{
40
    if ($abstract === null) {
41
        return Webtrees::container();
42
    }
43
44
    return Webtrees::make($abstract);
45
}
46
47
/**
48
 * Generate a URL to an asset file in the public folder.
49
 * Add a version parameter for cache-busting.
50
 *
51
 * @param string $path
52
 *
53
 * @return string
54
 */
55
function asset(string $path): string
56
{
57
    if (substr($path, -1) === '/') {
58
        $version = '';
59
    } elseif (Webtrees::STABILITY === '') {
0 ignored issues
show
introduced by
The condition Fisharebest\Webtrees\Webtrees::STABILITY === '' is always false.
Loading history...
60
        $version = '?v=' . Webtrees::VERSION;
61
    } else {
62
        $version = '?v=' . filemtime(Webtrees::ROOT_DIR . 'public/' . $path);
63
    }
64
65
    $base_url = app(ServerRequestInterface::class)->getAttribute('base_url');
66
67
    return $base_url . '/public/' . $path . $version;
68
}
69
70
/**
71
 * Generate a CSRF token form field.
72
 *
73
 * @return string
74
 */
75
function csrf_field(): string
76
{
77
    return '<input type="hidden" name="_csrf" value="' . e(WebtreesSession::getCsrfToken()) . '">';
78
}
79
80
/**
81
 * Get the CSRF token value.
82
 *
83
 * @return string
84
 */
85
function csrf_token(): string
86
{
87
    return WebtreesSession::getCsrfToken();
88
}
89
90
/**
91
 * @param string $url
92
 * @param int    $code
93
 *
94
 * @return ResponseInterface
95
 */
96
function redirect(string $url, int $code = StatusCodeInterface::STATUS_FOUND): ResponseInterface
97
{
98
    /** @var ResponseFactoryInterface $response_factory */
99
    $response_factory = app(ResponseFactoryInterface::class);
100
101
    return $response_factory
102
        ->createResponse($code)
103
        ->withHeader('Location', $url);
104
}
105
106
/**
107
 * Create a response.
108
 *
109
 * @param mixed         $content
110
 * @param int           $code
111
 * @param array<string> $headers
112
 *
113
 * @return ResponseInterface
114
 */
115
function response($content = '', int $code = StatusCodeInterface::STATUS_OK, array $headers = []): ResponseInterface
116
{
117
    if ($content === '' && $code === StatusCodeInterface::STATUS_OK) {
118
        $code = StatusCodeInterface::STATUS_NO_CONTENT;
119
    }
120
121
    if ($headers === []) {
122
        if (is_string($content)) {
123
            $headers = [
124
                'Content-Type' => 'text/html; charset=UTF-8',
125
            ];
126
        } else {
127
            $content = json_encode($content, JSON_UNESCAPED_UNICODE);
128
            $headers = [
129
                'Content-Type' => 'application/json',
130
            ];
131
        }
132
    }
133
134
    /** @var ResponseFactoryInterface $response_factory */
135
    $response_factory = app(ResponseFactoryInterface::class);
136
137
    /** @var StreamFactoryInterface $stream_factory */
138
    $stream_factory = app(StreamFactoryInterface::class);
139
140
    $stream = $stream_factory->createStream($content);
141
142
    $response = $response_factory
143
        ->createResponse($code)
144
        ->withBody($stream);
145
146
    foreach ($headers as $key => $value) {
147
        $response = $response->withHeader($key, $value);
148
    }
149
150
    return $response;
151
}
152
153
/**
154
 * Generate a URL for a named route.
155
 *
156
 * @param string                            $route_name
157
 * @param array<bool|int|string|array|null> $parameters
158
 *
159
 * @return string
160
 */
161
function route(string $route_name, array $parameters = []): string
162
{
163
    $request          = app(ServerRequestInterface::class);
164
    $base_url         = $request->getAttribute('base_url');
165
    $router_container = app(RouterContainer::class);
166
    $route            = $router_container->getMap()->getRoute($route_name);
167
168
    // Generate the URL.
169
    $url = $router_container->getGenerator()->generate($route_name, $parameters);
170
171
    // Aura ignores parameters that are not tokens.  We need to add them as query parameters.
172
    $parameters = array_filter($parameters, static function (string $key) use ($route): bool {
173
        return !str_contains($route->path, '{' . $key . '}') && !str_contains($route->path, '{/' . $key . '}');
174
    }, ARRAY_FILTER_USE_KEY);
175
176
    if ($request->getAttribute('rewrite_urls') === '1') {
177
        // Make the pretty URL absolute.
178
        $base_path = parse_url($base_url, PHP_URL_PATH) ?? '';
179
        $url = $base_url . substr($url, strlen($base_path));
180
    } else {
181
        // Turn the pretty URL into an ugly one.
182
        $path       = parse_url($url, PHP_URL_PATH);
183
        $parameters = ['route' => $path] + $parameters;
184
        $url        = $base_url . '/index.php';
185
    }
186
187
    return Html::url($url, $parameters);
188
}
189
190
/**
191
 * Create and render a view in a single operation.
192
 *
193
 * @param string       $name
194
 * @param array<mixed> $data
195
 *
196
 * @return string
197
 */
198
function view(string $name, array $data = []): string
199
{
200
    return WebtreesView::make($name, $data);
201
}
202