/** * print a child ascendancy * * @param Individual $individual * @param int $sosa child sosa number * @param int $depth the ascendancy depth to show */ public function printChildAscendancy(Individual $individual, $sosa, $depth) { echo '<li>'; echo '<table><tbody><tr><td>'; if ($sosa === 1) { echo '<img src="', Theme::theme()->parameter('image-spacer'), '" height="3" width="', Theme::theme()->parameter('chart-descendancy-indent'), '"></td><td>'; } else { echo '<img src="', Theme::theme()->parameter('image-spacer'), '" height="3" width="2" alt="">'; echo '<img src="', Theme::theme()->parameter('image-hline'), '" height="3" width="', Theme::theme()->parameter('chart-descendancy-indent') - 2, '"></td><td>'; } FunctionsPrint::printPedigreePerson($individual, $this->showFull()); echo '</td><td>'; if ($sosa > 1) { FunctionsCharts::printUrlArrow('?rootid=' . $individual->getXref() . '&PEDIGREE_GENERATIONS=' . $this->generations . '&show_full=' . $this->showFull() . '&chart_style=' . $this->chart_style . '&ged=' . $individual->getTree()->getNameUrl(), I18N::translate('Ancestors of %s', $individual->getFullName()), 3); } echo '</td><td class="details1"> <span class="person_box' . ($sosa === 1 ? 'NN' : ($sosa % 2 ? 'F' : '')) . '">', I18N::number($sosa), '</span> '; echo '</td><td class="details1"> ', FunctionsCharts::getSosaName($sosa), '</td>'; echo '</tr></tbody></table>'; // Parents $family = $individual->getPrimaryChildFamily(); if ($family && $depth > 0) { // Marriage details echo '<span class="details1">'; echo '<img src="', Theme::theme()->parameter('image-spacer'), '" height="2" width="', Theme::theme()->parameter('chart-descendancy-indent'), '" alt=""><a href="#" onclick="return expand_layer(\'sosa_', $sosa, '\');" class="top"><i id="sosa_', $sosa, '_img" class="icon-minus" title="', I18N::translate('View family'), '"></i></a>'; echo ' <span class="person_box">', I18N::number($sosa * 2), '</span> ', I18N::translate('and'); echo ' <span class="person_boxF">', I18N::number($sosa * 2 + 1), '</span>'; if ($family->canShow()) { foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) { echo ' <a href="', $family->getHtmlUrl(), '" class="details1">', $fact->summary(), '</a>'; } } echo '</span>'; // display parents recursively - or show empty boxes echo '<ul id="sosa_', $sosa, '" class="generation">'; if ($family->getHusband()) { $this->printChildAscendancy($family->getHusband(), $sosa * 2, $depth - 1); } if ($family->getWife()) { $this->printChildAscendancy($family->getWife(), $sosa * 2 + 1, $depth - 1); } echo '</ul>'; } echo '</li>'; }
echo '<p class="ui-state-error">', $controller->error_message, '</p>'; return; } switch ($controller->chart_style) { case 0: // List echo '<ul id="ancestry_chart" class="chart_common">'; $controller->printChildAscendancy($controller->root, 1, $controller->generations - 1); echo '</ul>'; echo '<br>'; break; case 1: echo '<div id="ancestry_booklet">'; // Booklet // first page : show indi facts FunctionsPrint::printPedigreePerson($controller->root, $controller->showFull()); // process the tree $ancestors = $controller->sosaAncestors($controller->generations - 1); $ancestors = array_filter($ancestors); // The SOSA array includes empty placeholders foreach ($ancestors as $sosa => $individual) { foreach ($individual->getChildFamilies() as $family) { FunctionsCharts::printSosaFamily($family->getXref(), $individual->getXref(), $sosa, '', '', '', $controller->show_cousins, $controller->showFull()); } } echo '</div>'; break; case 2: // Individual list $ancestors = $controller->sosaAncestors($controller->generations); $ancestors = array_filter($ancestors);
$lastgenStart = (int) floor($controller->treesize / 2); echo '<div id="pedigree_chart" class="layout', $controller->orientation, '">'; //Output the chart foreach ($controller->nodes as $i => $node) { // -- draw the box printf('<div id="sosa_%s" class="shadow" style="%s:%spx; top:%spx">', $i + 1, $posn, $node["x"], $node["y"]); if ($controller->orientation === $controller::OLDEST_AT_TOP) { if ($i >= $lastgenStart) { echo $controller->gotoPreviousGen($i); } } else { if (!$i) { echo $controller->getMenu(); } } FunctionsPrint::printPedigreePerson($controller->nodes[$i]['indi'], $controller->showFull()); if ($controller->orientation === $controller::OLDEST_AT_TOP) { if (!$i) { echo $controller->getMenu(); } } else { if ($i >= $lastgenStart) { echo $controller->gotoPreviousGen($i); } } echo '</div>'; } echo '<canvas id="pedigree_canvas" width="' . $controller->chartsize['x'] . '" height="' . $controller->chartsize['y'] . '"><p>No lines between boxes? Unfortunately your browser does not support the HTML5 canvas feature.</p></canvas>'; echo '</div>'; //close #pedigree_chart echo '</div>';
/** * Prints pedigree of the person passed in * * @param Individual $person * @param int $count */ private function printPersonPedigree($person, $count) { if ($count >= $this->generations) { return; } $genoffset = $this->generations; // handle pedigree n generations lines //-- calculate how tall the lines should be $lh = ($this->bhalfheight + 4) * pow(2, $genoffset - $count - 1); // //Prints empty table columns for children w/o parents up to the max generation //This allows vertical line spacing to be consistent if (count($person->getChildFamilies()) == 0) { echo '<table>'; $this->printEmptyBox($this->getBoxDimensions()->width, $this->getBoxDimensions()->height); //-- recursively get the father’s family $this->printPersonPedigree($person, $count + 1); echo '</td><td></tr>'; $this->printEmptyBox($this->getBoxDimensions()->width, $this->getBoxDimensions()->height); //-- recursively get the mother’s family $this->printPersonPedigree($person, $count + 1); echo '</td><td></tr></table>'; } // Empty box section done, now for regular pedigree foreach ($person->getChildFamilies() as $family) { echo '<table><tr><td class="tdbot">'; // Determine line height for two or more spouces // And then adjust the vertical line for the root person only $famcount = 0; if ($this->show_spouse) { // count number of spouses $famcount += count($person->getSpouseFamilies()); } $savlh = $lh; // Save current line height if ($count == 1 && $genoffset <= $famcount) { $linefactor = 0; // genoffset of 2 needs no adjustment if ($genoffset > 2) { $tblheight = $this->getBoxDimensions()->height + 8; if ($genoffset == 3) { if ($famcount == 3) { $linefactor = $tblheight / 2; } elseif ($famcount > 3) { $linefactor = $tblheight; } } if ($genoffset == 4) { if ($famcount == 4) { $linefactor = $tblheight; } elseif ($famcount > 4) { $linefactor = ($famcount - $genoffset) * ($tblheight * 1.5); } } if ($genoffset == 5) { if ($famcount == 5) { $linefactor = 0; } elseif ($famcount > 5) { $linefactor = $tblheight * ($famcount - $genoffset); } } } $lh = ($famcount - 1) * ($this->getBoxDimensions()->height + 8) - $linefactor; if ($genoffset > 5) { $lh = $savlh; } } echo '<img class="line3 pvline" src="', Theme::theme()->parameter('image-vline'), '" height="', $lh - 1, '" alt=""></td>', '<td>', '<img class="line4" src="', Theme::theme()->parameter('image-hline'), '" height="3" alt=""></td>', '<td>'; $lh = $savlh; // restore original line height //-- print the father box FunctionsPrint::printPedigreePerson($family->getHusband(), $this->showFull()); echo '</td>'; if ($family->getHusband()) { echo '<td>'; //-- recursively get the father’s family $this->printPersonPedigree($family->getHusband(), $count + 1); echo '</td>'; } else { echo '<td>'; if ($genoffset > $count) { echo '<table>'; for ($i = 1; $i < pow(2, $genoffset - $count) / 2; $i++) { $this->printEmptyBox($this->getBoxDimensions()->width, $this->getBoxDimensions()->height); echo '</tr>'; } echo '</table>'; } } echo '</tr><tr>', '<td class="tdtop"><img class="pvline" src="', Theme::theme()->parameter('image-vline'), '" height="', $lh + 1, '"></td>', '<td><img class="line4" src="', Theme::theme()->parameter('image-hline'), '" height="3"></td>', '<td>'; //-- print the mother box FunctionsPrint::printPedigreePerson($family->getWife(), $this->showFull()); echo '</td>'; if ($family->getWife()) { echo '<td>'; //-- recursively print the mother’s family $this->printPersonPedigree($family->getWife(), $count + 1); echo '</td>'; } else { echo '<td>'; if ($count < $genoffset - 1) { echo '<table>'; for ($i = 1; $i < pow(2, $genoffset - 1 - $count) / 2 + 1; $i++) { $this->printEmptyBox(); echo '</tr>'; $this->printEmptyBox(); echo '</tr>'; } echo '</table>'; } } echo '</tr>', '</table>'; break; } }
if ($n > 2 && preg_match('/son|dau|chi/', $relationships[$n - 2])) { $table[$x + 1][$y + 1] = '<div style="background:url(' . $diagonal1 . '); background-position: top right; width: 64px; height: 64px; text-align: center;"><div style="height: 32px; text-align: start;">' . Functions::getRelationshipNameFromPath($relationships[$n], Individual::getInstance($path[$n - 1], $WT_TREE), Individual::getInstance($path[$n + 1], $WT_TREE)) . '</div><div style="height: 32px; text-align: end;">' . $up_arrow . '</div></div>'; $x += 2; } else { $table[$x][$y + 1] = '<div style="background:url(' . Theme::theme()->parameter('image-vline') . ') repeat-y center; height: 64px; text-align:center; "><div style="display: inline-block; width: 50%; line-height: 32px;">' . Functions::getRelationshipNameFromPath($relationships[$n], Individual::getInstance($path[$n - 1], $WT_TREE), Individual::getInstance($path[$n + 1], $WT_TREE)) . '</div><div style="display: inline-block; width: 50%; line-height: 32px">' . $up_arrow . '</div></div>'; } $y += 2; break; } $max_x = max($max_x, $x); $min_y = min($min_y, $y); $max_y = max($max_y, $y); } else { $individual = Individual::getInstance($xref, $WT_TREE); ob_start(); FunctionsPrint::printPedigreePerson($individual, $show_full); $table[$x][$y] = ob_get_clean(); } } echo '<table style="border-collapse: collapse; margin: 20px 50px;">'; for ($y = $max_y; $y >= $min_y; --$y) { echo '<tr>'; for ($x = 0; $x <= $max_x; ++$x) { echo '<td style="padding: 0;">'; if (isset($table[$x][$y])) { echo $table[$x][$y]; } echo '</td>'; } echo '</tr>'; }
/** * Prints descendency of passed in person * * @param Individual $person person to print descendency for * @param int $count count of generations to print * @param bool $showNav * * @return int */ public function printDescendency($person, $count, $showNav = true) { global $lastGenSecondFam; if ($count > $this->dgenerations) { return 0; } $pid = $person->getXref(); $tablealign = 'right'; $otablealign = 'left'; if (I18N::direction() === 'rtl') { $tablealign = 'left'; $otablealign = 'right'; } //-- put a space between families on the last generation if ($count == $this->dgenerations - 1) { if (isset($lastGenSecondFam)) { echo '<br>'; } $lastGenSecondFam = true; } echo "<table id='table_{$pid}' class='hourglassChart' style='float:{$tablealign}'>"; echo '<tr>'; echo "<td style='text-align:{$tablealign}'>"; $numkids = 0; $families = $person->getSpouseFamilies(); $famNum = 0; $children = array(); if ($count < $this->dgenerations) { // Put all of the children in a common array foreach ($families as $family) { $famNum++; foreach ($family->getChildren() as $child) { $children[] = $child; } } $ct = count($children); if ($ct > 0) { echo "<table style='position: relative; top: auto; float: {$tablealign};'>"; for ($i = 0; $i < $ct; $i++) { $person2 = $children[$i]; $chil = $person2->getXref(); echo '<tr>'; echo '<td id="td_', $chil, '" class="', I18N::direction(), '" style="text-align:', $otablealign, '">'; $kids = $this->printDescendency($person2, $count + 1); $numkids += $kids; echo '</td>'; // Print the lines if ($ct > 1) { if ($i == 0) { // First child echo "<td style='vertical-align:bottom'><img alt='' class='line1 tvertline' id='vline_{$chil}' src='" . Theme::theme()->parameter('image-vline') . "' width='3'></td>"; } elseif ($i == $ct - 1) { // Last child echo "<td style='vertical-align:top'><img alt='' class='bvertline' id='vline_{$chil}' src='" . Theme::theme()->parameter('image-vline') . "' width='3'></td>"; } else { // Middle child echo '<td style="background: url(\'' . Theme::theme()->parameter('image-vline') . '\');"><img src=\'' . Theme::theme()->parameter('image-spacer') . '\' width="3" alt=""></td>'; } } echo '</tr>'; } echo '</table>'; } echo '</td>'; echo '<td width="', $this->getBoxDimensions()->width, '">'; } // Print the descendency expansion arrow if ($count == $this->dgenerations) { $numkids = 1; $tbwidth = $this->getBoxDimensions()->width + 16; for ($j = $count; $j < $this->dgenerations; $j++) { echo "<div style='width: ", $tbwidth, "px;'><br></div></td><td style='width:", $this->getBoxDimensions()->width, "px'>"; } $kcount = 0; foreach ($families as $family) { $kcount += $family->getNumberOfChildren(); } if ($kcount == 0) { echo "</td><td style='width:", $this->getBoxDimensions()->width, "px'>"; } else { printf(self::LINK, $this->left_arrow, $pid, 'desc', $this->showFull(), $this->show_spouse); //-- move the arrow up to line up with the correct box if ($this->show_spouse) { echo str_repeat('<br><br><br>', count($families)); } echo "</td><td style='width:", $this->getBoxDimensions()->width, "px'>"; } } echo '<table id="table2_' . $pid . '"><tr><td>'; FunctionsPrint::printPedigreePerson($person, $this->showFull()); echo '</td><td><img class="line2" src="' . Theme::theme()->parameter('image-hline') . '" width="7" height="3">'; //----- Print the spouse if ($this->show_spouse) { foreach ($families as $family) { echo "</td></tr><tr><td style='text-align:{$otablealign}'>"; //-- shrink the box for the spouses $tempw = $this->getBoxDimensions()->width; $temph = $this->getBoxDimensions()->height; $this->getBoxDimensions()->width -= 10; $this->getBoxDimensions()->height -= 10; FunctionsPrint::printPedigreePerson($family->getSpouse($person), $this->showFull()); $this->getBoxDimensions()->width = $tempw; $this->getBoxDimensions()->height = $temph; $numkids += 0.95; echo "</td><td></td>"; } //-- add offset divs to make things line up better if ($count == $this->dgenerations) { echo "<tr><td colspan '2'><div style='height:", $this->bhalfheight / 2, "px; width:", $this->getBoxDimensions()->width, "px;'><br></div>"; } } echo "</td></tr></table>"; // For the root person, print a down arrow that allows changing the root of tree if ($showNav && $count == 1) { // NOTE: If statement OK if ($person->canShowName()) { // -- print left arrow for decendants so that we can move down the tree $famids = $person->getSpouseFamilies(); //-- make sure there is more than 1 child in the family with parents $cfamids = $person->getChildFamilies(); $num = 0; foreach ($cfamids as $family) { $num += $family->getNumberOfChildren(); } if ($num > 0) { echo '<div class="center" id="childarrow" style="position:absolute; width:', $this->getBoxDimensions()->width, 'px;">'; echo '<a href="#" class="icon-darrow"></a>'; echo '<div id="childbox">'; echo '<table class="person_box"><tr><td>'; foreach ($famids as $family) { echo "<span class='name1'>" . I18N::translate('Family') . "</span>"; $spouse = $family->getSpouse($person); if ($spouse) { printf(self::SWITCH_LINK, $spouse->getXref(), $this->show_spouse, $this->showFull(), $this->generations, $spouse->getFullName()); } foreach ($family->getChildren() as $child) { printf(self::SWITCH_LINK, $child->getXref(), $this->show_spouse, $this->showFull(), $this->generations, $child->getFullName()); } } //-- print the siblings foreach ($cfamids as $family) { if ($family->getHusband() || $family->getWife()) { echo "<span class='name1'>" . I18N::translate('Parents') . "</span>"; $husb = $family->getHusband(); if ($husb) { printf(self::SWITCH_LINK, $husb->getXref(), $this->show_spouse, $this->showFull(), $this->generations, $husb->getFullName()); } $wife = $family->getWife(); if ($wife) { printf(self::SWITCH_LINK, $wife->getXref(), $this->show_spouse, $this->showFull(), $this->generations, $wife->getFullName()); } } // filter out root person from children array so only siblings remain $siblings = array_filter($family->getChildren(), function (Individual $item) use($pid) { return $item->getXref() != $pid; }); $num = count($siblings); if ($num) { echo "<span class='name1'>"; echo $num > 1 ? I18N::translate('Siblings') : I18N::translate('Sibling'); echo "</span>"; foreach ($siblings as $child) { printf(self::SWITCH_LINK, $child->getXref(), $this->show_spouse, $this->showFull(), $this->generations, $child->getFullName()); } } } echo '</td></tr></table>'; echo '</div>'; echo '</div>'; } } } echo '</td></tr></table>'; return $numkids; }
/** * print cousins list * * @param string $famid family ID * @param int $show_full large or small box */ public static function printCousins($famid, $show_full = 1) { global $WT_TREE; if ($show_full) { $bheight = Theme::theme()->parameter('chart-box-y'); } else { $bheight = Theme::theme()->parameter('compact-chart-box-y'); } $family = Family::getInstance($famid, $WT_TREE); $fchildren = $family->getChildren(); $kids = count($fchildren); echo '<td valign="middle" height="100%">'; if ($kids) { echo '<table cellspacing="0" cellpadding="0" border="0" ><tr valign="middle">'; if ($kids > 1) { echo '<td rowspan="', $kids, '" valign="middle" align="right"><img width="3px" height="', ($bheight + 9) * ($kids - 1), 'px" src="', Theme::theme()->parameter('image-vline'), '" alt=""></td>'; } $ctkids = count($fchildren); $i = 1; foreach ($fchildren as $fchil) { if ($i == 1) { echo '<td><img width="10px" height="3px" align="top"'; } else { echo '<td><img width="10px" height="3px"'; } if (I18N::direction() === 'ltr') { echo ' style="padding-right: 2px;"'; } else { echo ' style="padding-left: 2px;"'; } echo ' src="', Theme::theme()->parameter('image-hline'), '" alt=""></td><td>'; FunctionsPrint::printPedigreePerson($fchil, $show_full); echo '</td></tr>'; if ($i < $ctkids) { echo '<tr>'; $i++; } } echo '</table>'; } else { // If there is known that there are no children (as opposed to no known children) if (preg_match('/\\n1 NCHI (\\d+)/', $family->getGedcom(), $match) && $match[1] == 0) { echo ' <i class="icon-childless" title="', I18N::translate('This family remained childless'), '"></i>'; } } echo '</td>'; }
/** * Generate the HTML content of this block. * * @param int $block_id * @param bool $template * @param string[] $cfg * * @return string */ public function getBlock($block_id, $template = true, $cfg = array()) { global $WT_TREE, $ctype, $controller; $PEDIGREE_ROOT_ID = $WT_TREE->getPreference('PEDIGREE_ROOT_ID'); $gedcomid = $WT_TREE->getUserPreference(Auth::user(), 'gedcomid'); $details = $this->getBlockSetting($block_id, 'details', '0'); $type = $this->getBlockSetting($block_id, 'type', 'pedigree'); $pid = $this->getBlockSetting($block_id, 'pid', Auth::check() ? $gedcomid ? $gedcomid : $PEDIGREE_ROOT_ID : $PEDIGREE_ROOT_ID); foreach (array('details', 'type', 'pid', 'block') as $name) { if (array_key_exists($name, $cfg)) { ${$name} = $cfg[$name]; } } $person = Individual::getInstance($pid, $WT_TREE); if (!$person) { $pid = $PEDIGREE_ROOT_ID; $this->setBlockSetting($block_id, 'pid', $pid); $person = Individual::getInstance($pid, $WT_TREE); } $id = $this->getName() . $block_id; $class = $this->getName() . '_block'; if ($ctype == 'gedcom' && Auth::isManager($WT_TREE) || $ctype == 'user' && Auth::check()) { $title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&ged=' . $WT_TREE->getNameHtml() . '&ctype=' . $ctype . '"></a>'; } else { $title = ''; } if ($person) { $content = '<table cellspacing="0" cellpadding="0" border="0"><tr>'; switch ($type) { case 'pedigree': $title .= I18N::translate('Pedigree of %s', $person->getFullName()); $chartController = new HourglassController($person->getXref(), $details, false); $controller->addInlineJavascript($chartController->setupJavascript()); $content .= '<td>'; ob_start(); FunctionsPrint::printPedigreePerson($person, $details); $content .= ob_get_clean(); $content .= '</td>'; $content .= '<td>'; ob_start(); $chartController->printPersonPedigree($person, 1); $content .= ob_get_clean(); $content .= '</td>'; break; case 'descendants': $title .= I18N::translate('Descendants of %s', $person->getFullName()); $chartController = new HourglassController($person->getXref(), $details, false); $controller->addInlineJavascript($chartController->setupJavascript()); $content .= '<td>'; ob_start(); $chartController->printDescendency($person, 1, false); $content .= ob_get_clean(); $content .= '</td>'; break; case 'hourglass': $title .= I18N::translate('Hourglass chart of %s', $person->getFullName()); $chartController = new HourglassController($person->getXref(), $details, false); $controller->addInlineJavascript($chartController->setupJavascript()); $content .= '<td>'; ob_start(); $chartController->printDescendency($person, 1, false); $content .= ob_get_clean(); $content .= '</td>'; $content .= '<td>'; ob_start(); $chartController->printPersonPedigree($person, 1); $content .= ob_get_clean(); $content .= '</td>'; break; case 'treenav': $title .= I18N::translate('Interactive tree of %s', $person->getFullName()); $mod = new InteractiveTreeModule(WT_MODULES_DIR . 'tree'); $tv = new TreeView(); $content .= '<td>'; $content .= '<script>jQuery("head").append(\'<link rel="stylesheet" href="' . $mod->css() . '" type="text/css" />\');</script>'; $content .= '<script src="' . $mod->js() . '"></script>'; list($html, $js) = $tv->drawViewport($person, 2); $content .= $html . '<script>' . $js . '</script>'; $content .= '</td>'; break; } $content .= '</tr></table>'; } else { $content = I18N::translate('You must select an individual and chart type in the block configuration settings.'); } if ($template) { return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
/** * 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 '<li>'; echo '<img src="', Theme::theme()->parameter('image-spacer'), '" height="2" width="', Theme::theme()->parameter('chart-descendancy-indent') + 4, '">'; echo '<span class="details1">'; echo "<a href=\"#\" onclick=\"expand_layer('" . $uid . "'); return false;\" class=\"top\"><i id=\"" . $uid . "_img\" class=\"icon-minus\" title=\"" . I18N::translate('View this family') . "\"></i></a>"; if ($family->canShow()) { foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) { echo ' <a href="', $family->getHtmlUrl(), '" class="details1">', $fact->summary(), '</a>'; } } echo '</span>'; // print spouse $spouse = $family->getSpouse($person); echo '<ul id="' . $uid . '" class="generation">'; echo '<li>'; echo '<table><tr><td>'; FunctionsPrint::printPedigreePerson($spouse, $this->showFull()); echo '</td>'; // check if spouse has parents and add an arrow echo '<td></td>'; echo '<td>'; 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 '<br><br> '; } echo '</td></tr>'; // children $children = $family->getChildren(); echo '<tr><td colspan="3" class="details1" > '; 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 '</td></tr></table>'; echo '</li>'; if ($depth > 1) { foreach ($children as $child) { $this->printChildDescendancy($child, $depth - 1); } } echo '</ul>'; echo '</li>'; }