1f3281ad6SGreg Roach<?php 2f3281ad6SGreg Roach/** 3f3281ad6SGreg Roach * webtrees: online genealogy 41062a142SGreg Roach * Copyright (C) 2018 webtrees development team 5f3281ad6SGreg Roach * This program is free software: you can redistribute it and/or modify 6f3281ad6SGreg Roach * it under the terms of the GNU General Public License as published by 7f3281ad6SGreg Roach * the Free Software Foundation, either version 3 of the License, or 8f3281ad6SGreg Roach * (at your option) any later version. 9f3281ad6SGreg Roach * This program is distributed in the hope that it will be useful, 10f3281ad6SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 11f3281ad6SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12f3281ad6SGreg Roach * GNU General Public License for more details. 13f3281ad6SGreg Roach * You should have received a copy of the GNU General Public License 14f3281ad6SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 15f3281ad6SGreg Roach */ 16f3281ad6SGreg Roachnamespace Fisharebest\Webtrees; 17f3281ad6SGreg Roach 1850c68a25SGreg Roachuse Exception; 1950c68a25SGreg Roach 20f3281ad6SGreg Roach/** 21f3281ad6SGreg Roach * Simple view/template class. 22f3281ad6SGreg Roach */ 23c1010edaSGreg Roachclass View 24c1010edaSGreg Roach{ 25f3281ad6SGreg Roach /** 26f3281ad6SGreg Roach * @var string The (file) name of the view. 27f3281ad6SGreg Roach */ 28f3281ad6SGreg Roach private $name; 29f3281ad6SGreg Roach 30f3281ad6SGreg Roach /** 31f3281ad6SGreg Roach * @var mixed[] Data to be inserted into the view. 32f3281ad6SGreg Roach */ 33f3281ad6SGreg Roach private $data; 34f3281ad6SGreg Roach 35f3281ad6SGreg Roach /** 3608d24c7aSGreg Roach * @var mixed[] Data to be inserted into all views. 3708d24c7aSGreg Roach */ 3808d24c7aSGreg Roach private static $shared_data = []; 3908d24c7aSGreg Roach 4008d24c7aSGreg Roach /** 41ecf66805SGreg Roach * @var string Implementation of Blade "stacks". 42ecf66805SGreg Roach */ 43ecf66805SGreg Roach private static $stack; 44ecf66805SGreg Roach 45ecf66805SGreg Roach /** 46ecf66805SGreg Roach * @var array[] Implementation of Blade "stacks". 47ecf66805SGreg Roach */ 48ecf66805SGreg Roach private static $stacks = []; 49ecf66805SGreg Roach 50ecf66805SGreg Roach /** 51f3281ad6SGreg Roach * Createa view from a template name and optional data. 52f3281ad6SGreg Roach * 53fa4036e8SGreg Roach * @param string $name 54f3281ad6SGreg Roach * @param array $data 55f3281ad6SGreg Roach */ 56fa4036e8SGreg Roach public function __construct(string $name, $data = []) 57c1010edaSGreg Roach { 58f3281ad6SGreg Roach $this->name = $name; 59f3281ad6SGreg Roach $this->data = $data; 60f3281ad6SGreg Roach } 61f3281ad6SGreg Roach 62f3281ad6SGreg Roach /** 6308d24c7aSGreg Roach * Shared data that is available to all views. 64962e29c9SGreg Roach * 65962e29c9SGreg Roach * @param string $key 66962e29c9SGreg Roach * @param mixed $value 67fa4036e8SGreg Roach * 68fa4036e8SGreg Roach * @return void 6908d24c7aSGreg Roach */ 70c1010edaSGreg Roach public static function share(string $key, $value) 71c1010edaSGreg Roach { 7208d24c7aSGreg Roach self::$shared_data[$key] = $value; 7308d24c7aSGreg Roach } 7408d24c7aSGreg Roach 7508d24c7aSGreg Roach /** 76ecf66805SGreg Roach * Implementation of Blade "stacks". 77ecf66805SGreg Roach * 78ecf66805SGreg Roach * @see https://laravel.com/docs/5.5/blade#stacks 79962e29c9SGreg Roach * 80962e29c9SGreg Roach * @param string $stack 81fa4036e8SGreg Roach * 82fa4036e8SGreg Roach * @return void 83ecf66805SGreg Roach */ 84c1010edaSGreg Roach public static function push(string $stack) 85c1010edaSGreg Roach { 86ecf66805SGreg Roach self::$stack = $stack; 87ecf66805SGreg Roach ob_start(); 88ecf66805SGreg Roach } 89ecf66805SGreg Roach 90ecf66805SGreg Roach /** 91ecf66805SGreg Roach * Implementation of Blade "stacks". 92fa4036e8SGreg Roach * 93fa4036e8SGreg Roach * @return void 94ecf66805SGreg Roach */ 95c1010edaSGreg Roach public static function endpush() 96c1010edaSGreg Roach { 97ecf66805SGreg Roach self::$stacks[self::$stack][] = ob_get_clean(); 98ecf66805SGreg Roach } 99ecf66805SGreg Roach 100ecf66805SGreg Roach /** 101ecf66805SGreg Roach * Implementation of Blade "stacks". 102ecf66805SGreg Roach * 103962e29c9SGreg Roach * @param string $stack 104962e29c9SGreg Roach * 105ecf66805SGreg Roach * @return string 106ecf66805SGreg Roach */ 107c1010edaSGreg Roach public static function stack(string $stack): string 108c1010edaSGreg Roach { 109ecf66805SGreg Roach $content = implode('', self::$stacks[$stack] ?? []); 110ecf66805SGreg Roach 111ecf66805SGreg Roach self::$stacks[$stack] = []; 112ecf66805SGreg Roach 113ecf66805SGreg Roach return $content; 114ecf66805SGreg Roach } 115ecf66805SGreg Roach 116ecf66805SGreg Roach /** 117f3281ad6SGreg Roach * Render a view. 118f3281ad6SGreg Roach * 119f3281ad6SGreg Roach * @return string 120f3281ad6SGreg Roach */ 121*8f53f488SRico Sonntag public function render(): string 122c1010edaSGreg Roach { 12308d24c7aSGreg Roach extract($this->data + self::$shared_data); 124f3281ad6SGreg Roach 125f3281ad6SGreg Roach ob_start(); 126bc241c54SGreg Roach // Do not use require, so we can catch errors for missing files 127bc241c54SGreg Roach include $this->getFilenameForView($this->name); 12875d70144SGreg Roach 129f3281ad6SGreg Roach return ob_get_clean(); 130f3281ad6SGreg Roach } 131f3281ad6SGreg Roach 132f3281ad6SGreg Roach /** 13375d70144SGreg Roach * Allow a theme to override the default views. 134f3281ad6SGreg Roach * 135f3281ad6SGreg Roach * @param string $view_name 136f3281ad6SGreg Roach * 13775d70144SGreg Roach * @return string 13850c68a25SGreg Roach * @throws Exception 139f3281ad6SGreg Roach */ 140*8f53f488SRico Sonntag public function getFilenameForView($view_name): string 141c1010edaSGreg Roach { 14250c68a25SGreg Roach foreach ($this->paths() as $path) { 14350c68a25SGreg Roach $view_file = $path . '/' . $view_name . '.php'; 14475d70144SGreg Roach 14550c68a25SGreg Roach if (is_file($view_file)) { 14650c68a25SGreg Roach return $view_file; 147f21917b2SGreg Roach } 148f3281ad6SGreg Roach } 149f3281ad6SGreg Roach 15050c68a25SGreg Roach throw new Exception('View not found: ' . e($view_name)); 15150c68a25SGreg Roach } 15250c68a25SGreg Roach 153f3281ad6SGreg Roach /** 154f3281ad6SGreg Roach * Cerate and render a view in a single operation. 155f3281ad6SGreg Roach * 156f3281ad6SGreg Roach * @param string $name 157f3281ad6SGreg Roach * @param mixed[] $data 158f3281ad6SGreg Roach * 159f3281ad6SGreg Roach * @return string 160f3281ad6SGreg Roach */ 161*8f53f488SRico Sonntag public static function make($name, $data = []): string 162c1010edaSGreg Roach { 163f3281ad6SGreg Roach $view = new static($name, $data); 164f3281ad6SGreg Roach 16544116e73SGreg Roach DebugBar::addView($name, $data); 16644116e73SGreg Roach 167f3281ad6SGreg Roach return $view->render(); 168f3281ad6SGreg Roach } 16950c68a25SGreg Roach 17050c68a25SGreg Roach /** 17150c68a25SGreg Roach * @return string[] 17250c68a25SGreg Roach */ 17350c68a25SGreg Roach private function paths(): array 17450c68a25SGreg Roach { 17550c68a25SGreg Roach static $paths = []; 17650c68a25SGreg Roach 17750c68a25SGreg Roach if (empty($paths)) { 17850c68a25SGreg Roach // Module views 17950c68a25SGreg Roach // @TODO - this includes disabled modules. 18050c68a25SGreg Roach $paths = glob(WT_ROOT . WT_MODULES_DIR . '*/resources/views'); 18150c68a25SGreg Roach // Theme views 18250c68a25SGreg Roach $paths[] = WT_ROOT . WT_THEMES_DIR . Theme::theme()->themeId() . '/resources/views'; 18350c68a25SGreg Roach // Core views 18450c68a25SGreg Roach $paths[] = WT_ROOT . 'resources/views'; 18550c68a25SGreg Roach 186bdb3725aSGreg Roach $paths = array_filter($paths, function (string $path): bool { 187bdb3725aSGreg Roach return is_dir($path); 188bdb3725aSGreg Roach }); 18950c68a25SGreg Roach } 19050c68a25SGreg Roach 19150c68a25SGreg Roach return $paths; 19250c68a25SGreg Roach } 193f3281ad6SGreg Roach} 194