xref: /webtrees/app/Helpers/functions.php (revision 9b93b7c342a543e7bd55b5a09d97ba0c39fc32b0)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17declare(strict_types=1);
18
19use Fig\Http\Message\StatusCodeInterface;
20use Fisharebest\Webtrees\Application;
21use Fisharebest\Webtrees\Html;
22use Fisharebest\Webtrees\Session;
23use Fisharebest\Webtrees\View as WebtreesView;
24use Fisharebest\Webtrees\Webtrees;
25use Psr\Http\Message\ResponseFactoryInterface;
26use Psr\Http\Message\ResponseInterface;
27use Psr\Http\Message\ServerRequestInterface;
28use Psr\Http\Message\StreamFactoryInterface;
29
30/**
31 * Get the IoC container, or fetch something from it.
32 *
33 * @param string|null $abstract
34 *
35 * @return mixed
36 */
37function app(string $abstract = null)
38{
39    if ($abstract === null) {
40        return Application::getInstance();
41    }
42
43    return Application::getInstance()->make($abstract);
44}
45
46/**
47 * Generate a URL to an asset file in the public folder.
48 * Add a version parameter for cache-busting.
49 *
50 * @param string $path
51 *
52 * @return string
53 */
54function asset(string $path): string
55{
56    if (Webtrees::STABILITY === '') {
57        $version = Webtrees::VERSION;
58    } else {
59        $version = filemtime(Webtrees::ROOT_DIR . 'public/' . $path);
60    }
61
62    return 'public/' . $path . '?v=' . $version;
63}
64
65/**
66 * Generate a CSRF token form field.
67 *
68 * @return string
69 */
70function csrf_field()
71{
72    return '<input type="hidden" name="csrf" value="' . e(Session::getCsrfToken()) . '">';
73}
74
75/**
76 * Get the CSRF token value.
77 *
78 * @return string
79 */
80function csrf_token()
81{
82    return Session::getCsrfToken();
83}
84
85/**
86 * @param string $url
87 * @param int    $code
88 *
89 * @return ResponseInterface
90 */
91function redirect(string $url, $code = StatusCodeInterface::STATUS_FOUND): ResponseInterface
92{
93    /** @var ResponseFactoryInterface $response_factory */
94    $response_factory = app(ResponseFactoryInterface::class);
95
96    return $response_factory
97        ->createResponse($code)
98        ->withHeader('Location', $url);
99}
100
101/**
102 * Create a response.
103 *
104 * @param mixed    $content
105 * @param int      $code
106 * @param string[] $headers
107 *
108 * @return ResponseInterface
109 */
110function response($content = '', $code = StatusCodeInterface::STATUS_OK, $headers = []): ResponseInterface
111{
112    if ($headers === []) {
113        if (is_string($content)) {
114            $headers = [
115                'Content-Type'   => 'text/html; charset=utf-8',
116                'Content-Length' => strlen($content),
117            ];
118        } else {
119            $content = json_encode($content, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
120            $headers = [
121                'Content-Type'   => 'application/json',
122                'Content-Length' => strlen($content),
123            ];
124        }
125    }
126
127    /** @var ResponseFactoryInterface $response_factory */
128    $response_factory = app(ResponseFactoryInterface::class);
129
130    /** @var StreamFactoryInterface $stream_factory */
131    $stream_factory = app(StreamFactoryInterface::class);
132
133    $stream = $stream_factory->createStream($content);
134
135    $response = $response_factory
136        ->createResponse($code)
137        ->withBody($stream);
138
139    foreach ($headers as $key => $value) {
140        $response = $response->withHeader($key, $value);
141    }
142
143    return $response;
144}
145
146/**
147 * Generate a URL for a named route.
148 *
149 * @param string $route
150 * @param array  $parameters
151 * @param bool   $absolute
152 *
153 * @return string
154 */
155function route(string $route, array $parameters = [], bool $absolute = true): string
156{
157    $parameters = ['route' => $route] + $parameters;
158
159    if ($absolute) {
160        $base_url = app(ServerRequestInterface::class)->getAttribute('base_url');
161
162        return Html::url($base_url . 'index.php', $parameters);
163    }
164
165    return Html::url('index.php', $parameters);
166}
167
168/**
169 * Cerate and render a view in a single operation.
170 *
171 * @param string  $name
172 * @param mixed[] $data
173 *
174 * @return string
175 */
176function view(string $name, array $data = [])
177{
178    return WebtreesView::make($name, $data);
179}
180