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