. */ namespace Fisharebest\Webtrees\Controller; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\Filter; use Fisharebest\Webtrees\Functions\FunctionsCharts; use Fisharebest\Webtrees\Functions\FunctionsPrint; use Fisharebest\Webtrees\GedcomTag; use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Theme; use Rhumsaa\Uuid\Uuid; /** * Controller for the descendancy chart */ class DescendancyController extends ChartController { /** @var int Show boxes for cousins */ public $show_cousins; /** @var int Determines style of chart */ public $chart_style; /** @var int Number of generations to display */ public $generations; /** @var array d'Aboville numbering system */ public $dabo_num = array(); /** @var array d'Aboville numbering system */ public $dabo_sex = array(); /** * Create the descendancy controller */ public function __construct() { global $WT_TREE; parent::__construct(); // Extract parameters from form $this->chart_style = Filter::getInteger('chart_style', 0, 3, 0); $this->generations = Filter::getInteger('generations', 2, $WT_TREE->getPreference('MAX_DESCENDANCY_GENERATIONS'), $WT_TREE->getPreference('DEFAULT_PEDIGREE_GENERATIONS')); if ($this->root && $this->root->canShowName()) { $this->setPageTitle( /* I18N: %s is an individual’s name */ I18N::translate('Descendants of %s', $this->root->getFullName()) ); } else { $this->setPageTitle(I18N::translate('Descendants')); } } /** * Print a child family * * @param Individual $person * @param int $depth the descendancy depth to show * @param string $label * @param string $gpid */ public function printChildFamily(Individual $person, $depth, $label = '1.', $gpid = '') { if ($depth < 2) { return; } foreach ($person->getSpouseFamilies() as $family) { FunctionsCharts::printSosaFamily($family->getXref(), '', -1, $label, $person->getXref(), $gpid, 0, $this->showFull()); $i = 1; foreach ($family->getChildren() as $child) { $this->printChildFamily($child, $depth - 1, $label . ($i++) . '.', $person->getXref()); } } } /** * print a child descendancy * * @param Individual $person * @param int $depth the descendancy depth to show */ public function printChildDescendancy(Individual $person, $depth) { echo "
  • "; echo "'; // check if child has parents and add an arrow echo ''; echo '"; echo "
    "; if ($depth == $this->generations) { echo '\"\""; } else { echo ''; echo ''; } FunctionsPrint::printPedigreePerson($person, $this->showFull()); echo ''; foreach ($person->getChildFamilies() as $cfamily) { foreach ($cfamily->getSpouses() as $parent) { FunctionsCharts::printUrlArrow('?rootid=' . $parent->getXref() . '&generations=' . $this->generations . '&chart_style=' . $this->chart_style . '&show_full=' . $this->showFull() . '&ged=' . $parent->getTree()->getNameUrl(), I18N::translate('Start at parents'), 2); // only show the arrow for one of the parents break; } } // d'Aboville child number $level = $this->generations - $depth; if ($this->showFull()) { echo '

     '; } echo ''; //needed so that RTL languages will display this properly if (!isset($this->dabo_num[$level])) { $this->dabo_num[$level] = 0; } $this->dabo_num[$level]++; $this->dabo_num[$level + 1] = 0; $this->dabo_sex[$level] = $person->getSex(); for ($i = 0; $i <= $level; $i++) { $isf = $this->dabo_sex[$i]; if ($isf === 'M') { $isf = ''; } if ($isf === 'U') { $isf = 'NN'; } echo " " . $this->dabo_num[$i] . " "; if ($i < $level) { echo '.'; } } echo ""; echo "
    "; echo "
  • "; // loop for each spouse foreach ($person->getSpouseFamilies() as $family) { $this->printFamilyDescendancy($person, $family, $depth); } } /** * print a family descendancy * * @param Individual $person * @param Family $family * @param int $depth the descendancy depth to show */ private function printFamilyDescendancy(Individual $person, Family $family, $depth) { $uid = Uuid::uuid4(); // create a unique ID // print marriage info echo '
  • '; echo ''; echo ''; echo ""; if ($family->canShow()) { foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) { echo ' ', $fact->summary(), ''; } } echo ''; // print spouse $spouse = $family->getSpouse($person); echo '
      '; echo '
    • '; echo ''; // check if spouse has parents and add an arrow echo ''; echo ''; // children $children = $family->getChildren(); echo '
      '; FunctionsPrint::printPedigreePerson($spouse, $this->showFull()); echo ''; if ($spouse) { foreach ($spouse->getChildFamilies() as $cfamily) { foreach ($cfamily->getSpouses() as $parent) { FunctionsCharts::printUrlArrow('?rootid=' . $parent->getXref() . '&generations=' . $this->generations . '&chart_style=' . $this->chart_style . '&show_full=' . $this->showFull() . '&ged=' . $parent->getTree()->getNameUrl(), I18N::translate('Start at parents'), 2); // only show the arrow for one of the parents break; } } } if ($this->showFull()) { echo '

       '; } echo '
        '; if ($children) { echo GedcomTag::getLabel('NCHI') . ': ' . count($children); } else { // Distinguish between no children (NCHI 0) and no recorded // children (no CHIL records) if (strpos($family->getGedcom(), '\n1 NCHI 0')) { echo GedcomTag::getLabel('NCHI') . ': ' . count($children); } else { echo I18N::translate('No children'); } } echo '
      '; echo '
    • '; if ($depth > 1) { foreach ($children as $child) { $this->printChildDescendancy($child, $depth - 1); } } echo '
    '; echo '
  • '; } /** * Find all the individuals that are descended from an individual. * * @param Individual $person * @param int $n * @param Individual[] $array * * @return Individual[] */ public function individualDescendancy(Individual $person, $n, $array) { if ($n < 1) { return $array; } $array[$person->getXref()] = $person; foreach ($person->getSpouseFamilies() as $family) { $spouse = $family->getSpouse($person); if ($spouse) { $array[$spouse->getXref()] = $spouse; } foreach ($family->getChildren() as $child) { $array = $this->individualDescendancy($child, $n - 1, $array); } } return $array; } /** * Find all the families that are descended from an individual. * * @param Individual $person * @param int $n * @param Family[] $array * * @return Family[] */ public function familyDescendancy($person, $n, $array) { if ($n < 1) { return $array; } foreach ($person->getSpouseFamilies() as $family) { $array[$family->getXref()] = $family; foreach ($family->getChildren() as $child) { $array = $this->familyDescendancy($child, $n - 1, $array); } } return $array; } }