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