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 */ 16namespace Fisharebest\Webtrees\Controller; 17 18use Fisharebest\Webtrees\Filter; 19use Fisharebest\Webtrees\I18N; 20use Fisharebest\Webtrees\Individual; 21use Fisharebest\Webtrees\Theme; 22 23/** 24 * Base controller for all chart pages 25 */ 26class ChartController extends PageController 27{ 28 /** @var Individual Who is chart about? */ 29 public $root; 30 31 /** @var bool determines the detail shown in the personbox */ 32 private $show_full; 33 34 /** @var string An error message, in case we cannot construct the chart */ 35 public $error_message; 36 37 /** @var \stdClass personbox dimensions */ 38 private $box; 39 /** 40 * Create the chart controller 41 * 42 * @param int $show_full needed for use by charts module 43 */ 44 public function __construct($show_full = 1) 45 { 46 global $WT_TREE; 47 48 parent::__construct(); 49 50 $rootid = Filter::get('rootid', WT_REGEX_XREF); 51 $this->root = Individual::getInstance($rootid, $WT_TREE); 52 if (!$this->root) { 53 // Missing root individual? Show the chart for someone. 54 $this->root = $this->getSignificantIndividual(); 55 } 56 57 if (!$this->root) { 58 http_response_code(404); 59 $this->error_message = I18N::translate('This individual does not exist or you do not have permission to view it.'); 60 } 61 62 // Extract parameter from form 63 if ($show_full) { 64 $this->show_full = Filter::getInteger('show_full', 0, 1, $WT_TREE->getPreference('PEDIGREE_FULL_DETAILS')); 65 } else { 66 $this->show_full = 0; 67 } 68 69 $this->box = new \stdClass(); 70 if ($this->showFull()) { 71 $this->box->width = Theme::theme()->parameter('chart-box-x'); 72 $this->box->height = Theme::theme()->parameter('chart-box-y'); 73 } else { 74 $this->box->width = Theme::theme()->parameter('compact-chart-box-x'); 75 $this->box->height = Theme::theme()->parameter('compact-chart-box-y'); 76 } 77 } 78 79 /** 80 * Get significant information from this page, to allow other pages such as 81 * charts and reports to initialise with the same records 82 * 83 * @return Individual 84 */ 85 public function getSignificantIndividual() 86 { 87 if ($this->root) { 88 return $this->root; 89 } else { 90 return parent::getSignificantIndividual(); 91 } 92 } 93 94 /** 95 * Find the direct-line ancestors of an individual. Array indexes are SOSA numbers. 96 * 97 * @param int $generations 98 * 99 * @return Individual[] 100 */ 101 public function sosaAncestors($generations) 102 { 103 $ancestors = array( 104 1 => $this->root, 105 ); 106 107 // Subtract one generation, as this algorithm includes parents. 108 $max = pow(2, $generations - 1); 109 110 for ($i = 1; $i < $max; $i++) { 111 $ancestors[$i * 2] = null; 112 $ancestors[$i * 2 + 1] = null; 113 $person = $ancestors[$i]; 114 if ($person) { 115 $family = $person->getPrimaryChildFamily(); 116 if ($family) { 117 if ($family->getHusband()) { 118 $ancestors[$i * 2] = $family->getHusband(); 119 } 120 if ($family->getWife()) { 121 $ancestors[$i * 2 + 1] = $family->getWife(); 122 } 123 } 124 } 125 } 126 127 return $ancestors; 128 } 129 130 /** 131 * Function showFull 132 * 133 * @return bool 134 */ 135 public function showFull() 136 { 137 return $this->show_full; 138 } 139 140 /** 141 * Function boxDimensions 142 * 143 * @return \stdClass 144 */ 145 public function getBoxDimensions() 146 { 147 return $this->box; 148 } 149} 150