xref: /webtrees/app/Helpers/functions.php (revision 4a9ddbdc843a36af7eb5d2b033322ebf95e5dc43)
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 (substr($path, -1) === '/') {
57        $version = '';
58    } elseif (Webtrees::STABILITY === '') {
59        $version = '?v=' . Webtrees::VERSION;
60    } else {
61        $version = '?v=' . filemtime(Webtrees::ROOT_DIR . 'public/' . $path);
62    }
63
64    return 'public/' . $path . $version;
65}
66
67/**
68 * Generate a CSRF token form field.
69 *
70 * @return string
71 */
72function csrf_field()
73{
74    return '<input type="hidden" name="csrf" value="' . e(Session::getCsrfToken()) . '">';
75}
76
77/**
78 * Get the CSRF token value.
79 *
80 * @return string
81 */
82function csrf_token()
83{
84    return Session::getCsrfToken();
85}
86
87/**
88 * @param string $url
89 * @param int    $code
90 *
91 * @return ResponseInterface
92 */
93function redirect(string $url, $code = StatusCodeInterface::STATUS_FOUND): ResponseInterface
94{
95    /** @var ResponseFactoryInterface $response_factory */
96    $response_factory = app(ResponseFactoryInterface::class);
97
98    return $response_factory
99        ->createResponse($code)
100        ->withHeader('Location', $url);
101}
102
103/**
104 * Create a response.
105 *
106 * @param mixed    $content
107 * @param int      $code
108 * @param string[] $headers
109 *
110 * @return ResponseInterface
111 */
112function response($content = '', $code = StatusCodeInterface::STATUS_OK, $headers = []): ResponseInterface
113{
114    if ($headers === []) {
115        if (is_string($content)) {
116            $headers = [
117                'Content-Type'   => 'text/html; charset=utf-8',
118                'Content-Length' => strlen($content),
119            ];
120        } else {
121            $content = json_encode($content, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
122            $headers = [
123                'Content-Type'   => 'application/json',
124                'Content-Length' => strlen($content),
125            ];
126        }
127    }
128
129    /** @var ResponseFactoryInterface $response_factory */
130    $response_factory = app(ResponseFactoryInterface::class);
131
132    /** @var StreamFactoryInterface $stream_factory */
133    $stream_factory = app(StreamFactoryInterface::class);
134
135    $stream = $stream_factory->createStream($content);
136
137    $response = $response_factory
138        ->createResponse($code)
139        ->withBody($stream);
140
141    foreach ($headers as $key => $value) {
142        $response = $response->withHeader($key, $value);
143    }
144
145    return $response;
146}
147
148/**
149 * Generate a URL for a named route.
150 *
151 * @param string $route
152 * @param array  $parameters
153 * @param bool   $absolute
154 *
155 * @return string
156 */
157function route(string $route, array $parameters = [], bool $absolute = true): string
158{
159    $parameters = ['route' => $route] + $parameters;
160
161    if ($absolute) {
162        $base_url = app(ServerRequestInterface::class)->getAttribute('base_url');
163
164        return Html::url($base_url . 'index.php', $parameters);
165    }
166
167    return Html::url('index.php', $parameters);
168}
169
170/**
171 * Cerate and render a view in a single operation.
172 *
173 * @param string  $name
174 * @param mixed[] $data
175 *
176 * @return string
177 */
178function view(string $name, array $data = [])
179{
180    return WebtreesView::make($name, $data);
181}
182