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 18*50c68a25SGreg Roachuse Exception; 19*50c68a25SGreg 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 * 53f3281ad6SGreg Roach * @param $name 54f3281ad6SGreg Roach * @param array $data 55f3281ad6SGreg Roach */ 56c1010edaSGreg Roach public function __construct($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 6708d24c7aSGreg Roach */ 68c1010edaSGreg Roach public static function share(string $key, $value) 69c1010edaSGreg Roach { 7008d24c7aSGreg Roach self::$shared_data[$key] = $value; 7108d24c7aSGreg Roach } 7208d24c7aSGreg Roach 7308d24c7aSGreg Roach /** 74ecf66805SGreg Roach * Implementation of Blade "stacks". 75ecf66805SGreg Roach * 76ecf66805SGreg Roach * @see https://laravel.com/docs/5.5/blade#stacks 77962e29c9SGreg Roach * 78962e29c9SGreg Roach * @param string $stack 79ecf66805SGreg Roach */ 80c1010edaSGreg Roach public static function push(string $stack) 81c1010edaSGreg Roach { 82ecf66805SGreg Roach self::$stack = $stack; 83ecf66805SGreg Roach ob_start(); 84ecf66805SGreg Roach } 85ecf66805SGreg Roach 86ecf66805SGreg Roach /** 87ecf66805SGreg Roach * Implementation of Blade "stacks". 88ecf66805SGreg Roach */ 89c1010edaSGreg Roach public static function endpush() 90c1010edaSGreg Roach { 91ecf66805SGreg Roach self::$stacks[self::$stack][] = ob_get_clean(); 92ecf66805SGreg Roach } 93ecf66805SGreg Roach 94ecf66805SGreg Roach /** 95ecf66805SGreg Roach * Implementation of Blade "stacks". 96ecf66805SGreg Roach * 97962e29c9SGreg Roach * @param string $stack 98962e29c9SGreg Roach * 99ecf66805SGreg Roach * @return string 100ecf66805SGreg Roach */ 101c1010edaSGreg Roach public static function stack(string $stack): string 102c1010edaSGreg Roach { 103ecf66805SGreg Roach $content = implode('', self::$stacks[$stack] ?? []); 104ecf66805SGreg Roach 105ecf66805SGreg Roach self::$stacks[$stack] = []; 106ecf66805SGreg Roach 107ecf66805SGreg Roach return $content; 108ecf66805SGreg Roach } 109ecf66805SGreg Roach 110ecf66805SGreg Roach /** 111f3281ad6SGreg Roach * Render a view. 112f3281ad6SGreg Roach * 113f3281ad6SGreg Roach * @return string 114f3281ad6SGreg Roach */ 115c1010edaSGreg Roach public function render() 116c1010edaSGreg Roach { 11708d24c7aSGreg Roach extract($this->data + self::$shared_data); 118f3281ad6SGreg Roach 119f3281ad6SGreg Roach ob_start(); 120bc241c54SGreg Roach // Do not use require, so we can catch errors for missing files 121bc241c54SGreg Roach include $this->getFilenameForView($this->name); 12275d70144SGreg Roach 123f3281ad6SGreg Roach return ob_get_clean(); 124f3281ad6SGreg Roach } 125f3281ad6SGreg Roach 126f3281ad6SGreg Roach /** 12775d70144SGreg Roach * Allow a theme to override the default views. 128f3281ad6SGreg Roach * 129f3281ad6SGreg Roach * @param string $view_name 130f3281ad6SGreg Roach * 13175d70144SGreg Roach * @return string 132*50c68a25SGreg Roach * @throws Exception 133f3281ad6SGreg Roach */ 134*50c68a25SGreg Roach public function getFilenameForView($view_name) 135c1010edaSGreg Roach { 136*50c68a25SGreg Roach foreach ($this->paths() as $path) { 137*50c68a25SGreg Roach $view_file = $path . '/' . $view_name . '.php'; 13875d70144SGreg Roach 139*50c68a25SGreg Roach if (is_file($view_file)) { 140*50c68a25SGreg Roach return $view_file; 141f21917b2SGreg Roach } 142f3281ad6SGreg Roach } 143f3281ad6SGreg Roach 144*50c68a25SGreg Roach throw new Exception('View not found: ' . e($view_name)); 145*50c68a25SGreg Roach } 146*50c68a25SGreg Roach 147f3281ad6SGreg Roach /** 148f3281ad6SGreg Roach * Cerate and render a view in a single operation. 149f3281ad6SGreg Roach * 150f3281ad6SGreg Roach * @param string $name 151f3281ad6SGreg Roach * @param mixed[] $data 152f3281ad6SGreg Roach * 153f3281ad6SGreg Roach * @return string 154f3281ad6SGreg Roach */ 155c1010edaSGreg Roach public static function make($name, $data = []) 156c1010edaSGreg Roach { 157f3281ad6SGreg Roach $view = new static($name, $data); 158f3281ad6SGreg Roach 15944116e73SGreg Roach DebugBar::addView($name, $data); 16044116e73SGreg Roach 161f3281ad6SGreg Roach return $view->render(); 162f3281ad6SGreg Roach } 163*50c68a25SGreg Roach 164*50c68a25SGreg Roach /** 165*50c68a25SGreg Roach * @return string[] 166*50c68a25SGreg Roach */ 167*50c68a25SGreg Roach private function paths(): array 168*50c68a25SGreg Roach { 169*50c68a25SGreg Roach static $paths = []; 170*50c68a25SGreg Roach 171*50c68a25SGreg Roach if (empty($paths)) { 172*50c68a25SGreg Roach // Module views 173*50c68a25SGreg Roach // @TODO - this includes disabled modules. 174*50c68a25SGreg Roach $paths = glob(WT_ROOT . WT_MODULES_DIR . '*/resources/views'); 175*50c68a25SGreg Roach // Theme views 176*50c68a25SGreg Roach $paths[] = WT_ROOT . WT_THEMES_DIR . Theme::theme()->themeId() . '/resources/views'; 177*50c68a25SGreg Roach // Core views 178*50c68a25SGreg Roach $paths[] = WT_ROOT . 'resources/views'; 179*50c68a25SGreg Roach 180*50c68a25SGreg Roach $paths = array_filter($paths, function (string $path) { return is_dir($path); }); 181*50c68a25SGreg Roach } 182*50c68a25SGreg Roach 183*50c68a25SGreg Roach return $paths; 184*50c68a25SGreg Roach } 185f3281ad6SGreg Roach} 186