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