1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/webtrees_ynh.git synced 2024-09-03 18:26:37 +02:00
webtrees_ynh/sources/app/Functions/FunctionsCharts.php

551 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* webtrees: online genealogy
* Copyright (C) 2016 webtrees development team
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Fisharebest\Webtrees\Functions;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Family;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Theme;
/**
* Class FunctionsCharts - common functions
*/
class FunctionsCharts {
/**
* print a table cell with sosa number
*
* @param int $sosa
* @param string $pid optional pid
* @param string $arrowDirection direction of link arrow
*/
public static function printSosaNumber($sosa, $pid = "", $arrowDirection = "up") {
if (substr($sosa, -1, 1) == ".") {
$personLabel = substr($sosa, 0, -1);
} else {
$personLabel = $sosa;
}
if ($arrowDirection == "blank") {
$visibility = "hidden";
} else {
$visibility = "normal";
}
echo "<td class=\"subheaders center\" style=\"vertical-align: middle; text-indent: 0px; margin-top: 0px; white-space: nowrap; visibility: ", $visibility, ";\">";
echo $personLabel;
if ($sosa != "1" && $pid != "") {
if ($arrowDirection == "left") {
$dir = 0;
} elseif ($arrowDirection == "right") {
$dir = 1;
} elseif ($arrowDirection == "down") {
$dir = 3;
} else {
$dir = 2; // either 'blank' or 'up'
}
echo '<br>';
self::printUrlArrow('#' . $pid, $pid, $dir);
}
echo '</td>';
}
/**
* print the parents table for a family
*
* @param Family $family family gedcom ID
* @param int $sosa child sosa number
* @param string $label indi label (descendancy booklet)
* @param string $parid parent ID (descendancy booklet)
* @param string $gparid gd-parent ID (descendancy booklet)
* @param int $show_full large or small box
*/
public static function printFamilyParents(Family $family, $sosa = 0, $label = '', $parid = '', $gparid = '', $show_full = 1) {
if ($show_full) {
$pbheight = Theme::theme()->parameter('chart-box-y') + 14;
} else {
$pbheight = Theme::theme()->parameter('compact-chart-box-y') + 14;
}
$husb = $family->getHusband();
if ($husb) {
echo '<a name="', $husb->getXref(), '"></a>';
} else {
$husb = new Individual('M', "0 @M@ INDI\n1 SEX M", null, $family->getTree());
}
$wife = $family->getWife();
if ($wife) {
echo '<a name="', $wife->getXref(), '"></a>';
} else {
$wife = new Individual('F', "0 @F@ INDI\n1 SEX F", null, $family->getTree());
}
if ($sosa) {
echo '<p class="name_head">', $family->getFullName(), '</p>';
}
/**
* husband side
*/
echo '<table cellspacing="0" cellpadding="0" border="0"><tr><td rowspan="2">';
echo '<table border="0"><tr>';
if ($parid) {
if ($husb->getXref() == $parid) {
self::printSosaNumber($label);
} else {
self::printSosaNumber($label, '', 'blank');
}
} elseif ($sosa) {
self::printSosaNumber($sosa * 2);
}
if ($husb->isPendingAddtion()) {
echo '<td class="facts_value new">';
} elseif ($husb->isPendingDeletion()) {
echo '<td class="facts_value old">';
} else {
echo '<td>';
}
FunctionsPrint::printPedigreePerson($husb, $show_full);
echo '</td></tr></table>';
echo '</td>';
// husbands parents
$hfam = $husb->getPrimaryChildFamily();
if ($hfam) {
// remove the|| test for $sosa
echo '<td rowspan="2"><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td rowspan="2"><img src="' . Theme::theme()->parameter('image-vline') . '" width="3" height="' . ($pbheight + 9) . '"></td>';
echo '<td><img class="line5" src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
// husbands father
if ($hfam && $hfam->getHusband()) {
echo '<table border="0"><tr>';
if ($sosa > 0) {
self::printSosaNumber($sosa * 4, $hfam->getHusband()->getXref(), 'down');
}
if (!empty($gparid) && $hfam->getHusband()->getXref() == $gparid) {
self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
}
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
echo '</td></tr></table>';
} elseif ($hfam && !$hfam->getHusband()) {
// Empty box for grandfather
echo '<table border="0"><tr>';
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
echo '</td></tr></table>';
}
echo '</td>';
}
if ($hfam && ($sosa != -1)) {
echo '<td rowspan="2">';
self::printUrlArrow(($sosa == 0 ? '?famid=' . $hfam->getXref() . '&amp;ged=' . $hfam->getTree()->getNameUrl() : '#' . $hfam->getXref()), $hfam->getXref(), 1);
echo '</td>';
}
if ($hfam) {
// husbands mother
echo '</tr><tr><td><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
if ($hfam && $hfam->getWife()) {
echo '<table border=\'0\'><tr>';
if ($sosa > 0) {
self::printSosaNumber($sosa * 4 + 1, $hfam->getWife()->getXref(), 'down');
}
if (!empty($gparid) && $hfam->getWife()->getXref() == $gparid) {
self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
}
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
echo '</td></tr></table>';
} elseif ($hfam && !$hfam->getWife()) {
// Empty box for grandmother
echo '<table border="0"><tr>';
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
echo '</td></tr></table>';
}
echo '</td>';
}
echo '</tr></table>';
if ($sosa && $family->canShow()) {
foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) {
echo '<a href="', $family->getHtmlUrl(), '" class="details1">';
echo str_repeat('&nbsp;', 10);
echo $fact->summary();
echo '</a>';
}
} else {
echo '<br>';
}
/**
* wife side
*/
echo '<table cellspacing="0" cellpadding="0" border="0"><tr><td rowspan="2">';
echo '<table><tr>';
if ($parid) {
if ($wife->getXref() == $parid) {
self::printSosaNumber($label);
} else {
self::printSosaNumber($label, '', 'blank');
}
} elseif ($sosa) {
self::printSosaNumber($sosa * 2 + 1);
}
if ($wife->isPendingAddtion()) {
echo '<td class="facts_value new">';
} elseif ($wife->isPendingDeletion()) {
echo '<td class="facts_value old">';
} else {
echo '<td>';
}
FunctionsPrint::printPedigreePerson($wife, $show_full);
echo '</td></tr></table>';
echo '</td>';
// wifes parents
$hfam = $wife->getPrimaryChildFamily();
if ($hfam) {
echo '<td rowspan="2"><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td rowspan="2"><img src="' . Theme::theme()->parameter('image-vline') . '" width="3" height="' . ($pbheight + 9) . '"></td>';
echo '<td><img class="line5" src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
// wifes father
if ($hfam && $hfam->getHusband()) {
echo '<table><tr>';
if ($sosa > 0) {
self::printSosaNumber($sosa * 4 + 2, $hfam->getHusband()->getXref(), 'down');
}
if (!empty($gparid) && $hfam->getHusband()->getXref() == $gparid) {
self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
}
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
echo '</td></tr></table>';
} elseif ($hfam && !$hfam->getHusband()) {
// Empty box for grandfather
echo '<table border="0"><tr>';
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
echo '</td></tr></table>';
}
echo '</td>';
}
if ($hfam && ($sosa != -1)) {
echo '<td rowspan="2">';
self::printUrlArrow(($sosa == 0 ? '?famid=' . $hfam->getXref() . '&amp;ged=' . $hfam->getTree()->getNameUrl() : '#' . $hfam->getXref()), $hfam->getXref(), 1);
echo '</td>';
}
if ($hfam) {
// wifes mother
echo '</tr><tr><td><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
if ($hfam && $hfam->getWife()) {
echo '<table><tr>';
if ($sosa > 0) {
self::printSosaNumber($sosa * 4 + 3, $hfam->getWife()->getXref(), 'down');
}
if (!empty($gparid) && $hfam->getWife()->getXref() == $gparid) {
self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
}
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
echo '</td></tr></table>';
} elseif ($hfam && !$hfam->getWife()) {
// Empty box for grandmother
echo '<table border="0"><tr>';
echo '<td>';
FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
echo '</td></tr></table>';
}
echo '</td>';
}
echo '</tr></table>';
}
/**
* print the children table for a family
*
* @param Family $family family
* @param string $childid child ID
* @param int $sosa child sosa number
* @param string $label indi label (descendancy booklet)
* @param int $show_cousins display cousins on chart
* @param int $show_full large or small box
*/
public static function printFamilyChildren(Family $family, $childid = '', $sosa = 0, $label = '', $show_cousins = 0, $show_full = 1) {
if ($show_full) {
$bheight = Theme::theme()->parameter('chart-box-y');
} else {
$bheight = Theme::theme()->parameter('compact-chart-box-y');
}
$pbheight = $bheight + 14;
$children = $family->getChildren();
$numchil = count($children);
echo '<table border="0" cellpadding="0" cellspacing="2"><tr>';
if ($sosa > 0) {
echo '<td></td>';
}
echo '<td><span class="subheaders">';
if ($numchil == 0) {
echo I18N::translate('No children');
} else {
echo I18N::plural('%s child', '%s children', $numchil, $numchil);
}
echo '</span>';
if ($sosa == 0 && Auth::isEditor($family->getTree())) {
echo '<br>';
echo "<a href=\"#\" onclick=\"return add_child_to_family('", $family->getXref(), "', 'U');\">" . I18N::translate('Add a child to this family') . "</a>";
echo ' <a class="icon-sex_m_15x15" href="#" onclick="return add_child_to_family(\'', $family->getXref(), '\', \'M\');" title="', I18N::translate('son'), '"></a>';
echo ' <a class="icon-sex_f_15x15" href="#" onclick="return add_child_to_family(\'', $family->getXref(), '\', \'F\');" title="', I18N::translate('daughter'), '"></a>';
echo '<br><br>';
}
echo '</td>';
if ($sosa > 0) {
echo '<td></td><td></td>';
}
echo '</tr>';
$nchi = 1;
if ($children) {
foreach ($children as $child) {
echo '<tr>';
if ($sosa != 0) {
if ($child->getXref() == $childid) {
self::printSosaNumber($sosa, $childid);
} elseif (empty($label)) {
self::printSosaNumber("");
} else {
self::printSosaNumber($label . ($nchi++) . ".");
}
}
if ($child->isPendingAddtion()) {
echo '<td class="new">';
} elseif ($child->isPendingDeletion()) {
echo '<td class="old">';
} else {
echo '<td>';
}
FunctionsPrint::printPedigreePerson($child, $show_full);
echo '</td>';
if ($sosa != 0) {
// loop for all families where current child is a spouse
$famids = $child->getSpouseFamilies();
$maxfam = count($famids) - 1;
for ($f = 0; $f <= $maxfam; $f++) {
$famid_child = $famids[$f]->getXref();
// multiple marriages
if ($f > 0) {
echo '</tr><tr><td></td>';
echo '<td style="text-align:end; vertical-align: top;">';
//find out how many cousins there are to establish vertical line on second families
$fchildren = $famids[$f]->getChildren();
$kids = count($fchildren);
$Pheader = ($bheight - 1) * $kids;
$PBadj = 6; // default
if ($show_cousins > 0) {
if ($kids) {
$PBadj = max(0, $Pheader / 2 + $kids * 4.5);
}
}
if ($f == $maxfam) {
echo '<img height="' . ((($bheight / 2)) + $PBadj) . 'px"';
} else {
echo '<img height="' . $pbheight . 'px"';
}
echo ' width="3" src="' . Theme::theme()->parameter('image-vline') . '">';
echo '</td>';
}
echo '<td class="details1" style="text-align:center;">';
$spouse = $famids[$f]->getSpouse($child);
$marr = $famids[$f]->getFirstFact('MARR');
$div = $famids[$f]->getFirstFact('DIV');
if ($marr) {
// marriage date
echo $marr->getDate()->minimumDate()->format('%Y');
// divorce date
if ($div) {
echo '', $div->getDate()->minimumDate()->format('%Y');
}
}
echo "<br><img width=\"100%\" class=\"line5\" height=\"3\" src=\"" . Theme::theme()->parameter('image-hline') . "\" alt=\"\">";
echo "</td>";
// spouse information
echo "<td style=\"vertical-align: center;";
if (!empty($divrec)) {
echo " filter:alpha(opacity=40);opacity:0.4;\">";
} else {
echo "\">";
}
FunctionsPrint::printPedigreePerson($spouse, $show_full);
echo "</td>";
// cousins
if ($show_cousins) {
self::printCousins($famid_child, $show_full);
}
}
}
echo "</tr>";
}
} elseif ($sosa < 1) {
// message 'no children' except for sosa
if (preg_match('/\n1 NCHI (\d+)/', $family->getGedcom(), $match) && $match[1] == 0) {
echo '<tr><td><i class="icon-childless"></i> ' . I18N::translate('This family remained childless') . '</td></tr>';
}
}
echo "</table><br>";
}
/**
* print a family with Sosa-Stradonitz numbering system
* ($rootid=1, father=2, mother=3 ...)
*
* @param string $famid family gedcom ID
* @param string $childid tree root ID
* @param int $sosa starting sosa number
* @param string $label indi label (descendancy booklet)
* @param string $parid parent ID (descendancy booklet)
* @param string $gparid gd-parent ID (descendancy booklet)
* @param int $show_cousins display cousins on chart
* @param int $show_full large or small box
*/
public static function printSosaFamily($famid, $childid, $sosa, $label = '', $parid = '', $gparid = '', $show_cousins = 0, $show_full = 1) {
global $WT_TREE;
echo '<hr>';
echo '<p style="page-break-before: always;">';
if (!empty($famid)) {
echo '<a name="', $famid, '"></a>';
}
self::printFamilyParents(Family::getInstance($famid, $WT_TREE), $sosa, $label, $parid, $gparid, $show_full);
echo '<br>';
echo '<table><tr><td>';
self::printFamilyChildren(Family::getInstance($famid, $WT_TREE), $childid, $sosa, $label, $show_cousins, $show_full);
echo '</td></tr></table>';
echo '<br>';
}
/**
* print an arrow to a new url
*
* @param string $url target url
* @param string $label arrow label
* @param int $dir arrow direction 0=left 1=right 2=up 3=down (default=2)
*/
public static function printUrlArrow($url, $label, $dir = 2) {
if ($url === '') {
return;
}
// arrow direction
$adir = $dir;
if (I18N::direction() === 'rtl' && $dir === 0) {
$adir = 1;
}
if (I18N::direction() === 'rtl' && $dir === 1) {
$adir = 0;
}
// arrow style 0 1 2 3
$array_style = array('icon-larrow', 'icon-rarrow', 'icon-uarrow', 'icon-darrow');
$astyle = $array_style[$adir];
// Labels include peoples names, which may contain markup
echo '<a href="' . $url . '" title="' . strip_tags($label) . '" class="' . $astyle . '"></a>';
}
/**
* builds and returns sosa relationship name in the active language
*
* @param string $sosa sosa number
*
* @return string
*/
public static function getSosaName($sosa) {
$path = '';
while ($sosa > 1) {
if ($sosa % 2 == 1) {
$sosa -= 1;
$path = 'mot' . $path;
} else {
$path = 'fat' . $path;
}
$sosa /= 2;
}
return Functions::getRelationshipNameFromPath($path, null, null);
}
/**
* 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>';
if ($kids) {
echo '<table cellspacing="0" cellpadding="0" border="0" ><tr>';
if ($kids > 1) {
echo '<td rowspan="', $kids, '"><img width="3px" height="', (($bheight + 9) * ($kids - 1)), 'px" src="', Theme::theme()->parameter('image-vline'), '"></td>';
}
$ctkids = count($fchildren);
$i = 1;
foreach ($fchildren as $fchil) {
if ($i == 1) {
echo '<td><img width="10px" height="3px" style="vertical-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'), '"></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>';
}
}