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 */ 16declare(strict_types=1); 17 18namespace Fisharebest\Webtrees\Module; 19 20use Fisharebest\Webtrees\Auth; 21use Fisharebest\Webtrees\Http\Controllers\PedigreeChartController; 22use Fisharebest\Webtrees\I18N; 23use Fisharebest\Webtrees\Individual; 24use Fisharebest\Webtrees\Module\InteractiveTree\TreeView; 25use Fisharebest\Webtrees\Tree; 26use Symfony\Component\HttpFoundation\Request; 27 28/** 29 * Class ChartsBlockModule 30 */ 31class ChartsBlockModule extends AbstractModule implements ModuleInterface, ModuleBlockInterface 32{ 33 use ModuleBlockTrait; 34 35 /** {@inheritdoc} */ 36 public function title(): string 37 { 38 /* I18N: Name of a module/block */ 39 return I18N::translate('Charts'); 40 } 41 42 /** {@inheritdoc} */ 43 public function description(): string 44 { 45 /* I18N: Description of the “Charts” module */ 46 return I18N::translate('An alternative way to display charts.'); 47 } 48 49 /** 50 * Generate the HTML content of this block. 51 * 52 * @param Tree $tree 53 * @param int $block_id 54 * @param string $ctype 55 * @param string[] $cfg 56 * 57 * @return string 58 */ 59 public function getBlock(Tree $tree, int $block_id, string $ctype = '', array $cfg = []): string 60 { 61 $PEDIGREE_ROOT_ID = $tree->getPreference('PEDIGREE_ROOT_ID'); 62 $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid'); 63 64 $type = $this->getBlockSetting($block_id, 'type', 'pedigree'); 65 $pid = $this->getBlockSetting($block_id, 'pid', Auth::check() ? ($gedcomid ?: $PEDIGREE_ROOT_ID) : $PEDIGREE_ROOT_ID); 66 67 extract($cfg, EXTR_OVERWRITE); 68 69 $person = Individual::getInstance($pid, $tree); 70 if (!$person) { 71 $pid = $PEDIGREE_ROOT_ID; 72 $this->setBlockSetting($block_id, 'pid', $pid); 73 $person = Individual::getInstance($pid, $tree); 74 } 75 76 $title = $this->title(); 77 78 if ($person) { 79 $content = ''; 80 switch ($type) { 81 case 'pedigree': 82 $title = I18N::translate('Pedigree of %s', $person->getFullName()); 83 $chart_url = route('pedigree-chart', [ 84 'xref' => $person->xref(), 85 'ged' => $person->tree()->name(), 86 'generations' => 3, 87 'layout' => PedigreeChartController::PORTRAIT, 88 ]); 89 $content = view('modules/charts/chart', [ 90 'block_id' => $block_id, 91 'chart_url' => $chart_url, 92 ]); 93 break; 94 case 'descendants': 95 $title = I18N::translate('Descendants of %s', $person->getFullName()); 96 $chart_url = route('descendants-chart', [ 97 'xref' => $person->xref(), 98 'ged' => $person->tree()->name(), 99 'generations' => 2, 100 'chart_style' => 0, 101 ]); 102 $content = view('modules/charts/chart', [ 103 'block_id' => $block_id, 104 'chart_url' => $chart_url, 105 ]); 106 break; 107 case 'hourglass': 108 $title = I18N::translate('Hourglass chart of %s', $person->getFullName()); 109 $chart_url = route('hourglass-chart', [ 110 'xref' => $person->xref(), 111 'ged' => $person->tree()->name(), 112 'generations' => 2, 113 'layout' => PedigreeChartController::PORTRAIT, 114 ]); 115 $content = view('modules/charts/chart', [ 116 'block_id' => $block_id, 117 'chart_url' => $chart_url, 118 ]); 119 break; 120 case 'treenav': 121 $title = I18N::translate('Interactive tree of %s', $person->getFullName()); 122 $mod = new InteractiveTreeModule(); 123 $tv = new TreeView(); 124 $content .= '<script>$("head").append(\'<link rel="stylesheet" href="' . $mod->css() . '" type="text/css" />\');</script>'; 125 $content .= '<script src="' . $mod->js() . '"></script>'; 126 [$html, $js] = $tv->drawViewport($person, 2); 127 $content .= $html . '<script>' . $js . '</script>'; 128 break; 129 } 130 } else { 131 $content = I18N::translate('You must select an individual and a chart type in the block preferences'); 132 } 133 134 if ($ctype !== '') { 135 if ($ctype === 'gedcom' && Auth::isManager($tree)) { 136 $config_url = route('tree-page-block-edit', [ 137 'block_id' => $block_id, 138 'ged' => $tree->name(), 139 ]); 140 } elseif ($ctype === 'user' && Auth::check()) { 141 $config_url = route('user-page-block-edit', [ 142 'block_id' => $block_id, 143 'ged' => $tree->name(), 144 ]); 145 } else { 146 $config_url = ''; 147 } 148 149 return view('modules/block-template', [ 150 'block' => str_replace('_', '-', $this->getName()), 151 'id' => $block_id, 152 'config_url' => $config_url, 153 'title' => strip_tags($title), 154 'content' => $content, 155 ]); 156 } 157 158 return $content; 159 } 160 161 /** {@inheritdoc} */ 162 public function loadAjax(): bool 163 { 164 return true; 165 } 166 167 /** {@inheritdoc} */ 168 public function isUserBlock(): bool 169 { 170 return true; 171 } 172 173 /** {@inheritdoc} */ 174 public function isGedcomBlock(): bool 175 { 176 return true; 177 } 178 179 /** 180 * Update the configuration for a block. 181 * 182 * @param Request $request 183 * @param int $block_id 184 * 185 * @return void 186 */ 187 public function saveBlockConfiguration(Request $request, int $block_id) 188 { 189 $this->setBlockSetting($block_id, 'type', $request->get('type', 'pedigree')); 190 $this->setBlockSetting($block_id, 'pid', $request->get('pid', '')); 191 } 192 193 /** 194 * An HTML form to edit block settings 195 * 196 * @param Tree $tree 197 * @param int $block_id 198 * 199 * @return void 200 */ 201 public function editBlockConfiguration(Tree $tree, int $block_id) 202 { 203 $PEDIGREE_ROOT_ID = $tree->getPreference('PEDIGREE_ROOT_ID'); 204 $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid'); 205 206 $type = $this->getBlockSetting($block_id, 'type', 'pedigree'); 207 $pid = $this->getBlockSetting($block_id, 'pid', Auth::check() ? ($gedcomid ?: $PEDIGREE_ROOT_ID) : $PEDIGREE_ROOT_ID); 208 209 $charts = [ 210 'pedigree' => I18N::translate('Pedigree'), 211 'descendants' => I18N::translate('Descendants'), 212 'hourglass' => I18N::translate('Hourglass chart'), 213 'treenav' => I18N::translate('Interactive tree'), 214 ]; 215 uasort($charts, 'Fisharebest\Webtrees\I18N::strcasecmp'); 216 217 $individual = Individual::getInstance($pid, $tree); 218 219 echo view('modules/charts/config', [ 220 'charts' => $charts, 221 'individual' => $individual, 222 'tree' => $tree, 223 'type' => $type, 224 ]); 225 } 226} 227