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