Exemplo n.º 1
2
/**
 * print the information for an individual chart box
 *
 * find and print a given individuals information for a pedigree chart
 * @param string $pid the Gedcom Xref ID of the individual to print
 */
function print_pedigree_person_nav2($pid)
{
    global $spouselinks, $parentlinks, $step_parentlinks, $persons, $person_step, $person_parent;
    global $natdad, $natmom;
    $person = WT_Individual::getInstance($pid);
    if ($pid == false || empty($person)) {
        $spouselinks = false;
        $parentlinks = false;
        $step_parentlinks = false;
    }
    $tmp = array('M' => '', 'F' => 'F', 'U' => 'NN');
    $isF = $tmp[$person->getSex()];
    $spouselinks = "";
    $parentlinks = "";
    $step_parentlinks = "";
    if ($person->canShowName()) {
        //-- draw a box for the family popup
        $spouselinks .= "<table id=\"flyoutFam\" class=\"person_box{$isF}\"><tr><td class=\"name2 ltr\">";
        $spouselinks .= "<b>" . WT_I18N::translate('Family') . "</b> (" . $person->getFullName() . ")<br>";
        $parentlinks .= "<table id=\"flyoutPar\" class=\"person_box{$isF}\"><tr><td class=\"name2 ltr\">";
        $parentlinks .= "<b>" . WT_I18N::translate('Parents') . "</b> (" . $person->getFullName() . ")<br>";
        $step_parentlinks .= "<table id=\"flyoutStep\" class=\"person_box{$isF}\"><tr><td class=\"name2 ltr\">";
        $step_parentlinks .= "<b>" . WT_I18N::translate('Parents') . "</b> (" . $person->getFullName() . ")<br>";
        $persons = '';
        $person_parent = '';
        $person_step = '';
        //-- parent families --------------------------------------
        foreach ($person->getChildFamilies() as $family) {
            $husb = $family->getHusband($person);
            $wife = $family->getWife($person);
            $children = $family->getChildren();
            if ($husb || $children) {
                if ($husb) {
                    $person_parent = "Yes";
                    if ($husb->canShowName()) {
                        $fulln = strip_tags($husb->getFullName());
                        $parentlinks .= "<a href=\"#\" onclick=\"opener.insertRowToTable(";
                        $parentlinks .= "'" . $husb->getXref() . "', ";
                        // pid = PID
                        $parentlinks .= "'" . htmlentities($fulln) . "', ";
                        // nam = Name
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "''";
                        $parentlinks .= ");\">";
                        $parentlinks .= $husb->getFullName();
                        $parentlinks .= "</a>";
                    } else {
                        $parentlinks .= WT_I18N::translate('Private');
                    }
                    $natdad = "yes";
                }
            }
            if ($wife || $children) {
                if ($wife) {
                    $person_parent = "Yes";
                    if ($wife->canShowName()) {
                        $fulln = strip_tags($wife->getFullName());
                        $parentlinks .= "<a href=\"#\" onclick=\"opener.insertRowToTable(";
                        $parentlinks .= "'" . $wife->getXref() . "',";
                        // pid = PID
                        $parentlinks .= "'" . htmlentities($fulln) . "',";
                        // nam = Full Name
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "'',";
                        $parentlinks .= "''";
                        $parentlinks .= ");\">";
                        $parentlinks .= $wife->getFullName();
                        $parentlinks .= "</a>";
                    } else {
                        $parentlinks .= WT_I18N::translate('Private');
                    }
                    $parentlinks .= "<br>";
                    $natmom = "yes";
                }
            }
        }
        //-- step families -----------------------------------------
        $fams = $person->getChildStepFamilies();
        foreach ($fams as $family) {
            if (!is_null($family)) {
                $husb = $family->getHusband($person);
                $wife = $family->getWife($person);
                $children = $family->getChildren();
                if ($natdad == "yes") {
                } else {
                    // Husband -----------------------
                    if (($husb || $children) && $husb->getLabel() != ".") {
                        if ($husb) {
                            $person_step = "Yes";
                            $tmp = $husb->getXref();
                            if ($husb->canShowName()) {
                                $parentlinks .= "<a href=\"individual.php?pid={$tmp}&amp;&amp;gedcom=" . WT_GEDURL . "\">";
                                $parentlinks .= $husb->getFullName();
                                $parentlinks .= "</a>";
                            } else {
                                $parentlinks .= WT_I18N::translate('Private');
                            }
                            $parentlinks .= "<br>";
                        }
                    }
                }
                if ($natmom == "yes") {
                } else {
                    // Wife ----------------------------
                    if ($wife || $children) {
                        if ($wife) {
                            $person_step = "Yes";
                            $tmp = $wife->getXref();
                            if ($wife->canShowName()) {
                                $parentlinks .= "<a href=\"individual.php?pid={$tmp}&amp;gedcom=" . WT_GEDURL . "\">";
                                $parentlinks .= $wife->getFullName();
                                $parentlinks .= "</a>";
                            } else {
                                $parentlinks .= WT_I18N::translate('Private');
                            }
                            $parentlinks .= "<br>";
                        }
                    }
                }
            }
        }
        // Spouse Families -------------------------------------- @var $family Family
        foreach ($person->getSpouseFamilies() as $family) {
            $spouse = $family->getSpouse($person);
            $children = $family->getChildren();
            // Spouse ------------------------------
            if ($spouse && $spouse->canShowName()) {
                $spouselinks .= "<a href=\"#\" onclick=\"opener.insertRowToTable(";
                $spouselinks .= "'" . $spouse->getXref() . "',";
                // pid = PID
                $spouselinks .= "'" . strip_tags($spouse->getFullName()) . "',";
                // Full Name
                $spouselinks .= "'',";
                $spouselinks .= "'',";
                $spouselinks .= "'',";
                $spouselinks .= "'',";
                $spouselinks .= "'',";
                $spouselinks .= "'',";
                $spouselinks .= "'',";
                $spouselinks .= "''";
                $spouselinks .= ");\">";
                $spouselinks .= $spouse->getFullName();
                // Full Name
                $spouselinks .= "</a>";
            } else {
                $spouselinks .= WT_I18N::translate('Private');
            }
            $spouselinks .= "</a>";
            if ($spouse->getFullName() != "") {
                $persons = "Yes";
            }
            // Children ------------------------------   @var $child Person
            $spouselinks .= "<div id='spouseFam'>";
            $spouselinks .= "<ul class=\"clist\">";
            foreach ($children as $child) {
                $persons = "Yes";
                if ($child->canShowName()) {
                    $fulln = strip_tags($child->getFullName());
                    $spouselinks .= "<li>";
                    $spouselinks .= "<a href=\"#\" onclick=\"opener.insertRowToTable(";
                    $spouselinks .= "'" . $child->getXref() . "',";
                    // pid = PID
                    $spouselinks .= "'" . htmlentities($fulln) . "',";
                    // nam = Name
                    $spouselinks .= "'',";
                    $spouselinks .= "'',";
                    $spouselinks .= "'',";
                    $spouselinks .= "'',";
                    $spouselinks .= "'',";
                    $spouselinks .= "'',";
                    $spouselinks .= "'',";
                    $spouselinks .= "''";
                    $spouselinks .= ");\">";
                    $spouselinks .= $child->getFullName();
                    // Full Name
                    $spouselinks .= "</a>";
                } else {
                    $spouselinks .= WT_I18N::translate('Private');
                }
                $spouselinks .= "</li>";
            }
            $spouselinks .= "</ul>";
            $spouselinks .= "</div>";
        }
        if ($persons != "Yes") {
            $spouselinks .= "(" . WT_I18N::translate('none') . ")</td></tr></table>";
        } else {
            $spouselinks .= "</td></tr></table>";
        }
        if ($person_parent != "Yes") {
            $parentlinks .= "(" . WT_I18N::translate_c('unknown family', 'unknown') . ")</td></tr></table>";
        } else {
            $parentlinks .= "</td></tr></table>";
        }
        if ($person_step != "Yes") {
            $step_parentlinks .= "(" . WT_I18N::translate_c('unknown family', 'unknown') . ")</td></tr></table>";
        } else {
            $step_parentlinks .= "</td></tr></table>";
        }
    }
}
Exemplo n.º 2
1
function get_lds_glance(WT_Individual $indi)
{
    $BAPL = $indi->getFacts('BAPL') ? 'B' : '_';
    $ENDL = $indi->getFacts('ENDL') ? 'E' : '_';
    $SLGC = $indi->getFacts('SLGC') ? 'C' : '_';
    $SLGS = '_';
    foreach ($indi->getSpouseFamilies() as $family) {
        if ($family->getFacts('SLGS')) {
            $SLGS = '';
        }
    }
    return $BAPL . $ENDL . $SLGS . $SLGC;
}
Exemplo n.º 3
0
 private static function isRelated(WT_Individual $target, $distance)
 {
     static $cache = null;
     $user_individual = WT_Individual::getInstance(WT_USER_GEDCOM_ID);
     if ($user_individual) {
         if (!$cache) {
             $cache = array(0 => array($user_individual), 1 => array());
             foreach ($user_individual->getFacts('FAM[CS]', false, WT_PRIV_HIDE) as $fact) {
                 $family = $fact->getTarget();
                 if ($family) {
                     $cache[1][] = $family;
                 }
             }
         }
     } else {
         // No individual linked to this account?  Cannot use relationship privacy.
         return true;
     }
     // Double the distance, as we count the INDI-FAM and FAM-INDI links separately
     $distance *= 2;
     // Consider each path length in turn
     for ($n = 0; $n <= $distance; ++$n) {
         if (array_key_exists($n, $cache)) {
             // We have already calculated all records with this length
             if ($n % 2 == 0 && in_array($target, $cache[$n], true)) {
                 return true;
             }
         } else {
             // Need to calculate these paths
             $cache[$n] = array();
             if ($n % 2 == 0) {
                 // Add FAM->INDI links
                 foreach ($cache[$n - 1] as $family) {
                     foreach ($family->getFacts('HUSB|WIFE|CHIL', false, WT_PRIV_HIDE) as $fact) {
                         $individual = $fact->getTarget();
                         // Don’t backtrack
                         if ($individual && !in_array($individual, $cache[$n - 2], true)) {
                             $cache[$n][] = $individual;
                         }
                     }
                 }
                 if (in_array($target, $cache[$n], true)) {
                     return true;
                 }
             } else {
                 // Add INDI->FAM links
                 foreach ($cache[$n - 1] as $individual) {
                     foreach ($individual->getFacts('FAM[CS]', false, WT_PRIV_HIDE) as $fact) {
                         $family = $fact->getTarget();
                         // Don’t backtrack
                         if ($family && !in_array($family, $cache[$n - 2], true)) {
                             $cache[$n][] = $family;
                         }
                     }
                 }
             }
         }
     }
     return false;
 }
Exemplo n.º 4
0
 public function __construct()
 {
     parent::__construct();
     $this->rootid = WT_Filter::get('rootid', WT_REGEX_XREF);
     if ($this->rootid) {
         $this->root = WT_Individual::getInstance($this->rootid);
     } else {
         // Missing rootid parameter?  Do something.
         $this->root = $this->getSignificantIndividual();
         $this->rootid = $this->root->getXref();
     }
     if (!$this->root || !$this->root->canShowName()) {
         header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
         $this->error_message = WT_I18N::translate('This individual does not exist or you do not have permission to view it.');
         $this->rootid = null;
     }
 }
Exemplo n.º 5
0
 public function getTarget()
 {
     $xref = trim($this->getValue(), '@');
     switch ($this->tag) {
         case 'FAMC':
         case 'FAMS':
             return WT_Family::getInstance($xref, $this->getParent()->getGedcomId());
         case 'HUSB':
         case 'WIFE':
         case 'CHIL':
             return WT_Individual::getInstance($xref, $this->getParent()->getGedcomId());
         case 'SOUR':
             return WT_Source::getInstance($xref, $this->getParent()->getGedcomId());
         case 'OBJE':
             return WT_Media::getInstance($xref, $this->getParent()->getGedcomId());
         case 'REPO':
             return WT_Repository::getInstance($xref, $this->getParent()->getGedcomId());
         case 'NOTE':
             return WT_Note::getInstance($xref, $this->getParent()->getGedcomId());
         default:
             return WT_GedcomRecord::getInstance($xref, $this->getParent()->getGedcomId());
     }
 }
Exemplo n.º 6
0
    private function show_list()
    {
        global $controller;
        $controller = new WT_Controller_Page();
        $controller->setPageTitle($this->getTitle())->pageHeader()->addExternalJavascript(WT_JQUERY_DATATABLES_URL)->addInlineJavascript('
				jQuery("#story_table").dataTable({
					dom: \'<"H"pf<"dt-clear">irl>t<"F"pl>\',
					' . WT_I18N::datatablesI18N() . ',
					autoWidth: false,
					paging: true,
					pagingType: "full_numbers",
					lengthChange: true,
					filter: true,
					info: true,
					jQueryUI: true,
					sorting: [[0,"asc"]],
					columns: [
						/* 0-name */ null,
						/* 1-NAME */ null
					]
				});
			');
        $stories = WT_DB::prepare("SELECT block_id, xref" . " FROM `##block` b" . " WHERE module_name=?" . " AND gedcom_id=?" . " ORDER BY xref")->execute(array($this->getName(), WT_GED_ID))->fetchAll();
        echo '<h2 class="center">', WT_I18N::translate('Stories'), '</h2>';
        if (count($stories) > 0) {
            echo '<table id="story_table" class="width100">';
            echo '<thead><tr>
				<th>', WT_I18N::translate('Story title'), '</th>
				<th>', WT_I18N::translate('Individual'), '</th>
				</tr></thead>
				<tbody>';
            foreach ($stories as $story) {
                $indi = WT_Individual::getInstance($story->xref);
                $story_title = get_block_setting($story->block_id, 'title');
                $languages = get_block_setting($story->block_id, 'languages');
                if (!$languages || in_array(WT_LOCALE, explode(',', $languages))) {
                    if ($indi) {
                        if ($indi->canShow()) {
                            echo '<tr><td><a href="' . $indi->getHtmlUrl() . '#stories">' . $story_title . '</a></td><td><a href="' . $indi->getHtmlUrl() . '#stories">' . $indi->getFullName() . '</a></td></tr>';
                        }
                    } else {
                        echo '<tr><td>', $story_title, '</td><td class="error">', $story->xref, '</td></tr>';
                    }
                }
            }
            echo '</tbody></table>';
        }
    }
Exemplo n.º 7
0
 private static function search_indis_year_range($startyear, $endyear)
 {
     // At present, the lifespan chart is driven by Gregorian years.
     // We ought to allow it to work with other calendars...
     $gregorian_calendar = new GregorianCalendar();
     $startjd = $gregorian_calendar->ymdToJd($startyear, 1, 1);
     $endjd = $gregorian_calendar->ymdToJd($endyear, 12, 31);
     $sql = "SELECT DISTINCT i_id AS xref, i_file AS gedcom_id, i_gedcom AS gedcom" . " FROM `##individuals`" . " JOIN `##dates` ON i_id=d_gid AND i_file=d_file" . " WHERE i_file=? AND d_julianday1 BETWEEN ? AND ?";
     $rows = WT_DB::prepare($sql)->execute(array(WT_GED_ID, $startjd, $endjd))->fetchAll();
     $list = array();
     foreach ($rows as $row) {
         $list[] = WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
     }
     return $list;
 }
Exemplo n.º 8
0
    private function pedigreeMapJavascript($hideflags, $hidelines)
    {
        global $controller, $SHOW_HIGHLIGHT_IMAGES, $PEDIGREE_GENERATIONS;
        // The HomeControl returns the map to the original position and style
        $js = 'function HomeControl(controlDiv, pm_map) {' . 'controlDiv.style.paddingTop = "5px";
			controlDiv.style.paddingRight = "0px";' . 'var controlUI = document.createElement("DIV");
			controlUI.style.backgroundColor = "white";
			controlUI.style.color = "black";
			controlUI.style.borderColor = "black";
			controlUI.style.borderColor = "black";
			controlUI.style.borderStyle = "solid";
			controlUI.style.borderWidth = "2px";
			controlUI.style.cursor = "pointer";
			controlUI.style.textAlign = "center";
			controlUI.title = "";
			controlDiv.appendChild(controlUI);' . 'var controlText = document.createElement("DIV");
			controlText.style.fontFamily = "Arial,sans-serif";
			controlText.style.fontSize = "12px";
			controlText.style.paddingLeft = "15px";
			controlText.style.paddingRight = "15px";
			controlText.innerHTML = "<b>' . WT_I18N::translate('Redraw map') . '<\\/b>";
			controlUI.appendChild(controlText);' . 'google.maps.event.addDomListener(controlUI, "click", function() {
				pm_map.setMapTypeId(google.maps.MapTypeId.TERRAIN),
				pm_map.fitBounds(bounds),
				pm_map.setCenter(bounds.getCenter()),
				infowindow.close()
				if (document.getElementById(lastlinkid) != null) {
					document.getElementById(lastlinkid).className = "person_box:target";
				}
			});
		}' . 'function myclick(i) {
			if (document.getElementById(lastlinkid) != null) {
				document.getElementById(lastlinkid).className = "person_box:target";
			}
			google.maps.event.trigger(gmarkers[i], "click");
		}' . 'var side_bar_html = "";' . 'var gmarkers = [];
		var i = 0;
		var lastlinkid;
		var infowindow = new google.maps.InfoWindow({});' . 'var gicons = [];
		gicons["1"]        = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon1.png")
		gicons["1"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["2"]         = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2.png")
		gicons["2"].shadow  = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["2L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2L.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(28, 28) // Image anchor
								);
		gicons["2L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(32, 27) // Shadow anchor is base of image
								);
		gicons["2R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2R.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(4, 28)  // Image anchor
								);
		gicons["2R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(15, 27) // Shadow anchor is base of image
								);
		gicons["2Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2Ls.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(22, 22) // Image anchor
								);
		gicons["2Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2Rs.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(2, 22)  // Image anchor
								);
		gicons["3"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3.png")
		gicons["3"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["3L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3L.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(28, 28) // Image anchor
								);
		gicons["3L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(32, 27) // Shadow anchor is base of image
								);
		gicons["3R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3R.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(4, 28)  // Image anchor
								);
		gicons["3R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(15, 27) // Shadow anchor is base of image
								);
		gicons["3Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3Ls.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(22, 22) // Image anchor
								);
		gicons["3Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3Rs.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(2, 22)  // Image anchor
								);
		gicons["4"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4.png")
		gicons["4"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["4L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4L.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(28, 28) // Image anchor
								);
		gicons["4L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(32, 27) // Shadow anchor is base of image
								);
		gicons["4R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4R.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(4, 28)  // Image anchor
								);
		gicons["4R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(15, 27) // Shadow anchor is base of image
								);
		gicons["4Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4Ls.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(22, 22) // Image anchor
								);
		gicons["4Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4Rs.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(2, 22)  // Image anchor
								);
		gicons["5"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5.png")
		gicons["5"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["5L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5L.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(28, 28) // Image anchor
								);
		gicons["5L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(32, 27) // Shadow anchor is base of image
								);
		gicons["5R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5R.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(4, 28)  // Image anchor
								);
		gicons["5R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(15, 27) // Shadow anchor is base of image
								);
		gicons["5Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5Ls.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(22, 22) // Image anchor
								);
		gicons["5Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5Rs.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(2, 22)  // Image anchor
								);
		gicons["6"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6.png")
		gicons["6"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["6L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6L.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(28, 28) // Image anchor
								);
		gicons["6L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(32, 27) // Shadow anchor is base of image
								);
		gicons["6R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6R.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(4, 28)  // Image anchor
								);
		gicons["6R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(15, 27) // Shadow anchor is base of image
								);
		gicons["6Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6Ls.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(22, 22) // Image anchor
								);
		gicons["6Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6Rs.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(2, 22)  // Image anchor
								);
		gicons["7"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7.png")
		gicons["7"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["7L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7L.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(28, 28) // Image anchor
								);
		gicons["7L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(32, 27) // Shadow anchor is base of image
								);
		gicons["7R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7R.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(4, 28)  // Image anchor
								);
		gicons["7R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(15, 27) // Shadow anchor is base of image
								);
		gicons["7Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7Ls.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(22, 22) // Image anchor
								);
		gicons["7Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7Rs.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(2, 22)  // Image anchor
								);
		gicons["8"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8.png")
		gicons["8"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png",
									new google.maps.Size(37, 34), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(10, 34) // Shadow anchor is base of image
								);
		gicons["8L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8L.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(28, 28) // Image anchor
								);
		gicons["8L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(32, 27) // Shadow anchor is base of image
								);
		gicons["8R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8R.png",
									new google.maps.Size(32, 32), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(4, 28)  // Image anchor
								);
		gicons["8R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png",
									new google.maps.Size(49, 32), // Shadow size
									new google.maps.Point(0, 0),  // Shadow origin
									new google.maps.Point(15, 27) // Shadow anchor is base of image
								);
		gicons["8Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8Ls.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(22, 22) // Image anchor
								);
		gicons["8Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8Rs.png",
									new google.maps.Size(24, 24), // Image size
									new google.maps.Point(0, 0),  // Image origin
									new google.maps.Point(2, 22)  // Image anchor
								);' . 'function createMarker(point, name, html, mhtml, icontype) {
			var contentString = "<div id=\'iwcontent_edit\'>"+mhtml+"<\\/div>";' . 'var marker = new google.maps.Marker({
				icon:     gicons[icontype],
				shadow:   gicons[icontype].shadow,
				map:      pm_map,
				position: point,
				zIndex:   0
			});
			var linkid = "link"+i;
			google.maps.event.addListener(marker, "click", function() {
				infowindow.close();
				infowindow.setContent(contentString);
				infowindow.open(pm_map, marker);
				document.getElementById(linkid).className = "person_box";
				if (document.getElementById(lastlinkid) != null) {
					document.getElementById(lastlinkid).className = "person_box:target";
				}
				lastlinkid=linkid;
			});' . 'gmarkers[i] = marker;' . 'side_bar_html += "<br><div id=\'"+linkid+"\' onclick=\'myclick(" + i + ")\'>" + html +"<br></div>";
			i++;
			return marker;
		};' . 'var myOptions = {
			zoom: 6,
			center: new google.maps.LatLng(0, 0),
			mapTypeId: google.maps.MapTypeId.TERRAIN,  // ROADMAP, SATELLITE, HYBRID, TERRAIN
			mapTypeControlOptions: {
				style: google.maps.MapTypeControlStyle.DROPDOWN_MENU  // DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR
			},
			navigationControlOptions: {
				position: google.maps.ControlPosition.TOP_RIGHT,  // BOTTOM, BOTTOM_LEFT, LEFT, TOP, etc
				style: google.maps.NavigationControlStyle.SMALL   // ANDROID, DEFAULT, SMALL, ZOOM_PAN
			},
			streetViewControl: false,  // Show Pegman or not
			scrollwheel: true
		};
		var pm_map = new google.maps.Map(document.getElementById("pm_map"), myOptions);
		google.maps.event.addListener(pm_map, "click", function() {
			if (document.getElementById(lastlinkid) != null) {
				document.getElementById(lastlinkid).className = "person_box:target";
			}
		infowindow.close();
		});' . 'var homeControlDiv = document.createElement("DIV");
		var homeControl = new HomeControl(homeControlDiv, pm_map);
		homeControlDiv.index = 1;
		pm_map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv);' . 'var bounds = new google.maps.LatLngBounds();';
        // add the points
        $curgen = 1;
        $count = 0;
        $colored_line = array('1' => '#FF0000', '2' => '#0000FF', '3' => '#00FF00', '4' => '#FFFF00', '5' => '#00FFFF', '6' => '#FF00FF', '7' => '#C0C0FF', '8' => '#808000');
        $lat = array();
        $lon = array();
        $latlongval = array();
        $flags = array();
        for ($i = 0; $i < $controller->treesize; $i++) {
            // moved up to grab the sex of the individuals
            $person = WT_Individual::getInstance($controller->treeid[$i]);
            if ($person) {
                $name = $person->getFullName();
                // -- check to see if we have moved to the next generation
                if ($i + 1 >= pow(2, $curgen)) {
                    $curgen++;
                }
                $relationship = get_close_relationship_name($controller->root, $person);
                $event = '<img src="' . WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/images/sq' . $curgen . '.png" width="10" height="10"> ' . '<strong>' . $relationship . '</strong>';
                // add thumbnail image
                if ($SHOW_HIGHLIGHT_IMAGES) {
                    $image = $person->displayImage();
                } else {
                    $image = '';
                }
                // end of add image
                $dataleft = WT_Filter::escapeJs($image . $event . ' — ' . $name);
                $datamid = WT_Filter::escapeJs(' <span><a href="' . $person->getHtmlUrl() . '">(' . WT_I18N::translate('View person') . ')</a></span>');
                $dataright = WT_Filter::escapeJs('<br><strong>' . WT_I18N::translate('Birth:') . '&nbsp;</strong>' . $person->getBirthDate()->Display(false) . ' — ' . $person->getBirthPlace());
                $latlongval[$i] = $this->getLatitudeAndLongitudeFromPlaceLocation($person->getBirthPlace());
                if ($latlongval[$i]) {
                    $lat[$i] = (double) str_replace(array('N', 'S', ','), array('', '-', '.'), $latlongval[$i]->pl_lati);
                    $lon[$i] = (double) str_replace(array('E', 'W', ','), array('', '-', '.'), $latlongval[$i]->pl_long);
                    if ($lat[$i] || $lon[$i]) {
                        if (!$hideflags && $latlongval[$i]->pl_icon) {
                            $flags[$i] = $latlongval[$i]->pl_icon;
                            $ffile = strrchr($latlongval[$i]->pl_icon, '/');
                            $ffile = substr($ffile, 1, strpos($ffile, '.') - 1);
                            if (empty($flags[$ffile])) {
                                $flags[$ffile] = $i;
                                // Only generate the flag once
                                $js .= 'var point = new google.maps.LatLng(' . $lat[$i] . ',' . $lon[$i] . ');';
                                $js .= 'var Marker1_0_flag = new google.maps.MarkerImage();';
                                $js .= 'Marker1_0_flag.image = "' . WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/' . $flags[$i] . '";';
                                $js .= 'Marker1_0_flag.shadow = "' . WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/images/flag_shadow.png";';
                                $js .= 'Marker1_0_flag.iconSize = new google.maps.Size(25, 15);';
                                $js .= 'Marker1_0_flag.shadowSize = new google.maps.Size(35, 45);';
                                $js .= 'Marker1_0_flag.iconAnchor = new google.maps.Point(1, 45);';
                                $js .= 'var Marker1_0 = new google.maps.LatLng(point, {icon:Marker1_0_flag});';
                            }
                        }
                        $marker_number = $curgen;
                        $dups = 0;
                        for ($k = 0; $k < $i; $k++) {
                            if ($latlongval[$i] == $latlongval[$k]) {
                                $dups++;
                                switch ($dups) {
                                    case 1:
                                        $marker_number = $curgen . 'L';
                                        break;
                                    case 2:
                                        $marker_number = $curgen . 'R';
                                        break;
                                    case 3:
                                        $marker_number = $curgen . 'Ls';
                                        break;
                                    case 4:
                                        $marker_number = $curgen . 'Rs';
                                        break;
                                    case 5:
                                        //adjust position where markers have same coodinates
                                    //adjust position where markers have same coodinates
                                    default:
                                        $marker_number = $curgen;
                                        $lon[$i] = $lon[$i] + 0.0025;
                                        $lat[$i] = $lat[$i] + 0.0025;
                                        break;
                                }
                            }
                        }
                        $js .= 'var point = new google.maps.LatLng(' . $lat[$i] . ',' . $lon[$i] . ');';
                        $js .= "var marker = createMarker(point, \"" . WT_Filter::escapeJs($name) . "\",\"<div>" . $dataleft . $datamid . $dataright . "</div>\", \"";
                        $js .= "<div class='iwstyle'>";
                        $js .= "<a href='module.php?ged=" . WT_GEDURL . "&amp;mod=googlemap&amp;mod_action=pedigree_map&amp;rootid=" . $person->getXref() . "&amp;PEDIGREE_GENERATIONS={$PEDIGREE_GENERATIONS}";
                        if ($hideflags) {
                            $js .= '&amp;hideflags=1';
                        }
                        if ($hidelines) {
                            $js .= '&amp;hidelines=1';
                        }
                        $js .= "' title='" . WT_I18N::translate('Pedigree map') . "'>" . $dataleft . "</a>" . $datamid . $dataright . "</div>\", \"" . $marker_number . "\");";
                        // Construct the polygon lines
                        if (!$hidelines) {
                            $to_child = intval(($i - 1) / 2);
                            // Draw a line from parent to child
                            if (array_key_exists($to_child, $lat) && $lat[$to_child] != 0 && $lon[$to_child] != 0) {
                                $js .= '
								var linecolor;
								var plines;
								var lines = [new google.maps.LatLng(' . $lat[$i] . ',' . $lon[$i] . '),
									new google.maps.LatLng(' . $lat[$to_child] . ',' . $lon[$to_child] . ')];
								linecolor = "' . $colored_line[$curgen] . '";
								plines = new google.maps.Polygon({
									paths: lines,
									strokeColor: linecolor,
									strokeOpacity: 0.8,
									strokeWeight: 3,
									fillColor: "#FF0000",
									fillOpacity: 0.1
								});
								plines.setMap(pm_map);';
                            }
                        }
                        // Extend and fit marker bounds
                        $js .= 'bounds.extend(point);';
                        $js .= 'pm_map.fitBounds(bounds);';
                        $count++;
                    }
                }
            } else {
                $latlongval[$i] = null;
            }
        }
        $js .= 'pm_map.setCenter(bounds.getCenter());' . 'google.maps.event.addListener(infowindow, "closeclick", function() {
			document.getElementById(lastlinkid).className = "person_box:target";
		});' . 'document.getElementById("side_bar").innerHTML = side_bar_html;' . 'var contextmenu = document.createElement("div");
			contextmenu.style.visibility="hidden";
			contextmenu.innerHTML = "<a href=\'#\' onclick=\'zoomIn()\'><div class=\'optionbox\'>&nbsp;&nbsp;' . WT_I18N::translate('Zoom in') . '&nbsp;&nbsp;</div></a>"
								+ "<a href=\'#\' onclick=\'zoomOut()\'><div class=\'optionbox\'>&nbsp;&nbsp;' . WT_I18N::translate('Zoom out') . '&nbsp;&nbsp;</div></a>"
								+ "<a href=\'#\' onclick=\'zoomInHere()\'><div class=\'optionbox\'>&nbsp;&nbsp;' . WT_I18N::translate('Zoom in here') . '</div></a>"
								+ "<a href=\'#\' onclick=\'zoomOutHere()\'><div class=\'optionbox\'>&nbsp;&nbsp;' . WT_I18N::translate('Zoom out here') . '&nbsp;&nbsp;</div></a>"
								+ "<a href=\'#\' onclick=\'centreMapHere()\'><div class=\'optionbox\'>&nbsp;&nbsp;' . WT_I18N::translate('Center map here') . '&nbsp;&nbsp;</div></a>";' . 'google.maps.event.addListener(pm_map,"singlerightclick", function(pixel,tile) {' . 'clickedPixel = pixel;
			var x=pixel.x;
			var y=pixel.y;
			if (x > pm_map.getSize().width - 120) { x = pm_map.getSize().width - 120 }
			if (y > pm_map.getSize().height - 100) { y = pm_map.getSize().height - 100 }
			var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x,y));
			pos.apply(contextmenu);
			contextmenu.style.visibility = "visible";
		});
		' . 'function zoomIn() {' . 'pm_map.zoomIn();' . 'contextmenu.style.visibility="hidden";
		}
		function zoomOut() {' . 'pm_map.zoomOut();' . 'contextmenu.style.visibility="hidden";
		}
		function zoomInHere() {' . 'var point = pm_map.fromContainerPixelToLatLng(clickedPixel)
			pm_map.zoomIn(point,true);' . 'contextmenu.style.visibility="hidden";
		}
		function zoomOutHere() {' . 'var point = pm_map.fromContainerPixelToLatLng(clickedPixel)
			pm_map.setCenter(point,pm_map.getZoom()-1);' . 'contextmenu.style.visibility="hidden";
		}
		function centreMapHere() {' . 'var point = pm_map.fromContainerPixelToLatLng(clickedPixel)
			pm_map.setCenter(point);' . 'contextmenu.style.visibility="hidden";
		}' . 'google.maps.event.addListener(pm_map, "click", function() {
			contextmenu.style.visibility="hidden";
		});';
        return $js;
    }
Exemplo n.º 9
0
 private static function associate_facts(WT_Individual $person)
 {
     $facts = array();
     $associates = array_merge($person->linkedIndividuals('ASSO'), $person->linkedIndividuals('_ASSO'), $person->linkedFamilies('ASSO'), $person->linkedFamilies('_ASSO'));
     foreach ($associates as $associate) {
         foreach ($associate->getFacts() as $fact) {
             $arec = $fact->getAttribute('_ASSO');
             if (!$arec) {
                 $arec = $fact->getAttribute('ASSO');
             }
             if ($arec) {
                 // Extract the important details from the fact
                 $factrec = '1 ' . $fact->getTag();
                 if (preg_match('/\\n2 DATE .*/', $fact->getGedcom(), $match)) {
                     $factrec .= $match[0];
                 }
                 if (preg_match('/\\n2 PLAC .*/', $fact->getGedcom(), $match)) {
                     $factrec .= $match[0];
                 }
                 if ($associate instanceof WT_Family) {
                     foreach ($associate->getSpouses() as $spouse) {
                         $factrec .= "\n2 _ASSO @" . $spouse->getXref() . '@';
                     }
                 } else {
                     $factrec .= "\n2 _ASSO @" . $associate->getXref() . '@';
                     // CHR/BAPM events are commonly used.  Generate the reverse relationship
                     if (preg_match('/^(?:BAPM|CHR)$/', $fact->getTag()) && preg_match('/2 _?ASSO @(' . $person->getXref() . ')@\\n3 RELA god(?:parent|mother|father)/', $fact->getGedcom())) {
                         switch ($associate->getSex()) {
                             case 'M':
                                 $factrec .= "\n3 RELA godson";
                                 break;
                             case 'F':
                                 $factrec .= "\n3 RELA goddaughter";
                                 break;
                             case 'U':
                                 $factrec .= "\n3 RELA godchild";
                                 break;
                         }
                     }
                 }
                 $facts[] = new WT_Fact($factrec, $associate, 'asso');
             }
         }
     }
     return $facts;
 }
Exemplo n.º 10
0
function format_fam_table($datalist)
{
    global $GEDCOM, $SHOW_LAST_CHANGE, $SEARCH_SPIDER, $controller;
    $table_id = 'table-fam-' . Uuid::uuid4();
    // lists requires a unique ID in case there are multiple lists per page
    $controller->addExternalJavascript(WT_JQUERY_DATATABLES_URL)->addInlineJavascript('
			jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))};
			jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))};
			jQuery("#' . $table_id . '").dataTable( {
				dom: \'<"H"<"filtersH_' . $table_id . '"><"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\',
				' . WT_I18N::datatablesI18N() . ',
				jQueryUI: true,
				autoWidth: false,
				processing: true,
				retrieve: true,
				columns: [
					/*  0 husb givn */ {dataSort: 2},
					/*  1 husb surn */ {dataSort: 3},
					/*  2 GIVN,SURN */ {type: "unicode", visible: false},
					/*  3 SURN,GIVN */ {type: "unicode", visible: false},
					/*  4 age       */ {dataSort: 5, class: "center"},
					/*  5 AGE       */ {type: "num", visible: false},
					/*  6 wife givn */ {dataSort: 8},
					/*  7 wife surn */ {dataSort: 9},
					/*  8 GIVN,SURN */ {type: "unicode", visible: false},
					/*  9 SURN,GIVN */ {type: "unicode", visible: false},
					/* 10 age       */ {dataSort: 11, class: "center"},
					/* 11 AGE       */ {type: "num", visible: false},
					/* 12 marr date */ {dataSort: 13},
					/* 13 MARR:DATE */ {visible: false},
					/* 14 anniv     */ {dataSort: 13, class: "center"},
					/* 15 marr plac */ {type: "unicode"},
					/* 16 children  */ {dataSort: 17, class: "center"},
					/* 17 NCHI      */ {type: "num", visible: false},
					/* 18 CHAN      */ {dataSort: 19, visible: ' . ($SHOW_LAST_CHANGE ? 'true' : 'false') . '},
					/* 19 CHAN_sort */ {visible: false},
					/* 20 MARR      */ {visible: false},
					/* 21 DEAT      */ {visible: false},
					/* 22 TREE      */ {visible: false}
				],
				sorting: [[1, "asc"]],
				displayLength: 20,
				pagingType: "full_numbers"
		   });

			jQuery("#' . $table_id . '")
			/* Hide/show parents */
			.on("click", ".btn-toggle-parents", function() {
				jQuery(this).toggleClass("ui-state-active");
				jQuery(".parents", jQuery(this).closest("table").DataTable().rows().nodes()).slideToggle();
			})
			/* Hide/show statistics */
			.on("click",  ".btn-toggle-statistics", function() {
				jQuery(this).toggleClass("ui-state-active");
				jQuery("#fam_list_table-charts_' . $table_id . '").slideToggle();
			})
			/* Filter buttons in table header */
			.on("click", "button[data-filter-column]", function() {
				var btn = $(this);
				// De-activate the other buttons in this button group
				btn.siblings().removeClass("ui-state-active");
				// Apply (or clear) this filter
				var col = jQuery("#' . $table_id . '").DataTable().column(btn.data("filter-column"));
				if (btn.hasClass("ui-state-active")) {
					btn.removeClass("ui-state-active");
					col.search("").draw();
				} else {
					btn.addClass("ui-state-active");
					col.search(btn.data("filter-value")).draw();
				}
			});

			jQuery(".fam-list").css("visibility", "visible");
			jQuery(".loading-image").css("display", "none");
	');
    $stats = new WT_Stats($GEDCOM);
    $max_age = max($stats->oldestMarriageMaleAge(), $stats->oldestMarriageFemaleAge()) + 1;
    //-- init chart data
    for ($age = 0; $age <= $max_age; $age++) {
        $marr_by_age[$age] = '';
    }
    for ($year = 1550; $year < 2030; $year += 10) {
        $birt_by_decade[$year] = '';
        $marr_by_decade[$year] = '';
    }
    $html = '
		<div class="loading-image">&nbsp;</div>
		<div class="fam-list">
			<table id="' . $table_id . '">
				<thead>
					<tr>
						<th colspan="23">
							<div class="btn-toolbar">
								<div class="btn-group">
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="N"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show individuals who are alive or couples where both partners are alive.') . '"
									>
										' . WT_I18N::translate('Both alive') . '
									</button>
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="W"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples where only the female partner is deceased.') . '"
									>
										' . WT_I18N::translate('Widower') . '
									</button>
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="H"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples where only the male partner is deceased.') . '"
									>
										' . WT_I18N::translate('Widow') . '
									</button>
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="Y"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show individuals who are dead or couples where both partners are deceased.') . '"
									>
										' . WT_I18N::translate('Both dead') . '
									</button>
								</div>
								<div class="btn-group">
									<button
										type="button"
										data-filter-column="22"
										data-filter-value="R"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show “roots” couples or individuals.  These individuals may also be called “patriarchs”.  They are individuals who have no parents recorded in the database.') . '"
									>
										' . WT_I18N::translate('Roots') . '
									</button>
									<button
										type="button"
										data-filter-column="22"
										data-filter-value="L"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show “leaves” couples or individuals.  These are individuals who are alive but have no children recorded in the database.') . '"
									>
										' . WT_I18N::translate('Leaves') . '
									</button>
								</div>
								<div class="btn-group">
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="U"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples with an unknown marriage date.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('MARR') . '
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="YES"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples who married more than 100 years ago.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('MARR') . '&gt;100
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="Y100"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples who married within the last 100 years.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('MARR') . '&lt;=100
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="D"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show divorced couples.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('DIV') . '
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="M"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples where either partner married more than once.') . '"
									>
										' . WT_I18N::translate('Multiple marriages') . '
									</button>
								</div>
							</div>
						</th>
					</tr>
					<tr>
						<th>' . WT_Gedcom_Tag::getLabel('GIVN') . '</th>
						<th>' . WT_Gedcom_Tag::getLabel('SURN') . '</th>
						<th>HUSB:GIVN_SURN</th>
						<th>HUSB:SURN_GIVN</th>
						<th>' . WT_Gedcom_Tag::getLabel('AGE') . '</th>
						<th>AGE</th>
						<th>' . WT_Gedcom_Tag::getLabel('GIVN') . '</th>
						<th>' . WT_Gedcom_Tag::getLabel('SURN') . '</th>
						<th>WIFE:GIVN_SURN</th>
						<th>WIFE:SURN_GIVN</th>
						<th>' . WT_Gedcom_Tag::getLabel('AGE') . '</th>
						<th>AGE</th>
						<th>' . WT_Gedcom_Tag::getLabel('MARR') . '</th>
						<th>MARR:DATE</th>
						<th><i class="icon-reminder" title="' . WT_I18N::translate('Anniversary') . '"></i></th>
						<th>' . WT_Gedcom_Tag::getLabel('PLAC') . '</th>
						<th><i class="icon-children" title="' . WT_I18N::translate('Children') . '"></i></th>
					<th>NCHI</th>
					<th' . ($SHOW_LAST_CHANGE ? '' : '') . '>' . WT_Gedcom_Tag::getLabel('CHAN') . '</th>
					<th' . ($SHOW_LAST_CHANGE ? '' : '') . '>CHAN</th>
					<th>MARR</th>
					<th>DEAT</th>
					<th>TREE</th>
				</tr>
			</thead>
			<tfoot>
				<tr>
					<th colspan="23">
						<div class="btn-toolbar">
							<div class="btn-group">
								<button type="button" class="ui-state-default btn-toggle-parents">
									' . WT_I18N::translate('Show parents') . '
								</button>
								<button type="button" class="ui-state-default btn-toggle-statistics">
									' . WT_I18N::translate('Show statistics charts') . '
								</button>
							</div>
						</div>
					</th>
				</tr>
			</tfoot>
			<tbody>';
    $d100y = new WT_Date(date('Y') - 100);
    // 100 years ago
    foreach ($datalist as $family) {
        //-- Retrieve husband and wife
        $husb = $family->getHusband();
        if (is_null($husb)) {
            $husb = new WT_Individual('H', '0 @H@ INDI', null, WT_GED_ID);
        }
        $wife = $family->getWife();
        if (is_null($wife)) {
            $wife = new WT_Individual('W', '0 @W@ INDI', null, WT_GED_ID);
        }
        if (!$family->canShow()) {
            continue;
        }
        if ($family->isNew()) {
            $class = ' class="new"';
        } elseif ($family->isOld()) {
            $class = ' class="old"';
        } else {
            $class = '';
        }
        $html .= '<tr' . $class . '>';
        //-- Husband name(s)
        $html .= '<td colspan="2">';
        foreach ($husb->getAllNames() as $num => $name) {
            if ($name['type'] == 'NAME') {
                $title = '';
            } else {
                $title = 'title="' . strip_tags(WT_Gedcom_Tag::getLabel($name['type'], $husb)) . '"';
            }
            if ($num == $husb->getPrimaryName()) {
                $class = ' class="name2"';
                $sex_image = $husb->getSexImage();
                list($surn, $givn) = explode(',', $name['sort']);
            } else {
                $class = '';
                $sex_image = '';
            }
            // Only show married names if they are the name we are filtering by.
            if ($name['type'] != '_MARNM' || $num == $husb->getPrimaryName()) {
                $html .= '<a ' . $title . ' href="' . $family->getHtmlUrl() . '"' . $class . '>' . highlight_search_hits($name['full']) . '</a>' . $sex_image . '<br>';
            }
        }
        // Husband parents
        $html .= $husb->getPrimaryParentsNames('parents details1', 'none');
        $html .= '</td>';
        // Dummy column to match colspan in header
        $html .= '<td style="display:none;"></td>';
        //-- Husb GIVN
        // Use "AAAA" as a separator (instead of ",") as Javascript.localeCompare() ignores
        // punctuation and "ANN,ROACH" would sort after "ANNE,ROACH", instead of before it.
        // Similarly, @N.N. would sort as NN.
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . '</td>';
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . '</td>';
        $mdate = $family->getMarriageDate();
        //-- Husband age
        $hdate = $husb->getBirthDate();
        if ($hdate->isOK() && $mdate->isOK()) {
            if ($hdate->gregorianYear() >= 1550 && $hdate->gregorianYear() < 2030) {
                $birt_by_decade[(int) ($hdate->gregorianYear() / 10) * 10] .= $husb->getSex();
            }
            $hage = WT_Date::getAge($hdate, $mdate, 0);
            if ($hage >= 0 && $hage <= $max_age) {
                $marr_by_age[$hage] .= $husb->getSex();
            }
        }
        $html .= '<td>' . WT_Date::getAge($hdate, $mdate, 2) . '</td><td>' . WT_Date::getAge($hdate, $mdate, 1) . '</td>';
        //-- Wife name(s)
        $html .= '<td colspan="2">';
        foreach ($wife->getAllNames() as $num => $name) {
            if ($name['type'] == 'NAME') {
                $title = '';
            } else {
                $title = 'title="' . strip_tags(WT_Gedcom_Tag::getLabel($name['type'], $wife)) . '"';
            }
            if ($num == $wife->getPrimaryName()) {
                $class = ' class="name2"';
                $sex_image = $wife->getSexImage();
                list($surn, $givn) = explode(',', $name['sort']);
            } else {
                $class = '';
                $sex_image = '';
            }
            // Only show married names if they are the name we are filtering by.
            if ($name['type'] != '_MARNM' || $num == $wife->getPrimaryName()) {
                $html .= '<a ' . $title . ' href="' . $family->getHtmlUrl() . '"' . $class . '>' . highlight_search_hits($name['full']) . '</a>' . $sex_image . '<br>';
            }
        }
        // Wife parents
        $html .= $wife->getPrimaryParentsNames('parents details1', 'none');
        $html .= '</td>';
        // Dummy column to match colspan in header
        $html .= '<td style="display:none;"></td>';
        //-- Wife GIVN
        //-- Husb GIVN
        // Use "AAAA" as a separator (instead of ",") as Javascript.localeCompare() ignores
        // punctuation and "ANN,ROACH" would sort after "ANNE,ROACH", instead of before it.
        // Similarly, @N.N. would sort as NN.
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . '</td>';
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . '</td>';
        $mdate = $family->getMarriageDate();
        //-- Wife age
        $wdate = $wife->getBirthDate();
        if ($wdate->isOK() && $mdate->isOK()) {
            if ($wdate->gregorianYear() >= 1550 && $wdate->gregorianYear() < 2030) {
                $birt_by_decade[(int) ($wdate->gregorianYear() / 10) * 10] .= $wife->getSex();
            }
            $wage = WT_Date::getAge($wdate, $mdate, 0);
            if ($wage >= 0 && $wage <= $max_age) {
                $marr_by_age[$wage] .= $wife->getSex();
            }
        }
        $html .= '<td>' . WT_Date::getAge($wdate, $mdate, 2) . '</td><td>' . WT_Date::getAge($wdate, $mdate, 1) . '</td>';
        //-- Marriage date
        $html .= '<td>';
        if ($marriage_dates = $family->getAllMarriageDates()) {
            foreach ($marriage_dates as $n => $marriage_date) {
                if ($n) {
                    $html .= '<br>';
                }
                $html .= '<div>' . $marriage_date->Display(!$SEARCH_SPIDER) . '</div>';
            }
            if ($marriage_dates[0]->gregorianYear() >= 1550 && $marriage_dates[0]->gregorianYear() < 2030) {
                $marr_by_decade[(int) ($marriage_dates[0]->gregorianYear() / 10) * 10] .= $husb->getSex() . $wife->getSex();
            }
        } elseif ($family->getFacts('_NMR')) {
            $html .= WT_I18N::translate('no');
        } elseif ($family->getFacts('MARR')) {
            $html .= WT_I18N::translate('yes');
        } else {
            $html .= '&nbsp;';
        }
        $html .= '</td>';
        //-- Event date (sortable)hidden by datatables code
        $html .= '<td>';
        if ($marriage_dates) {
            $html .= $marriage_date->JD();
        } else {
            $html .= 0;
        }
        $html .= '</td>';
        //-- Marriage anniversary
        $html .= '<td>' . WT_Date::getAge($mdate, null, 2) . '</td>';
        //-- Marriage place
        $html .= '<td>';
        foreach ($family->getAllMarriagePlaces() as $n => $marriage_place) {
            $tmp = new WT_Place($marriage_place, WT_GED_ID);
            if ($n) {
                $html .= '<br>';
            }
            if ($SEARCH_SPIDER) {
                $html .= $tmp->getShortName();
            } else {
                $html .= '<a href="' . $tmp->getURL() . '" title="' . strip_tags($tmp->getFullName()) . '">';
                $html .= highlight_search_hits($tmp->getShortName()) . '</a>';
            }
        }
        $html .= '</td>';
        //-- Number of children
        $nchi = $family->getNumberOfChildren();
        $html .= '<td>' . WT_I18N::number($nchi) . '</td><td>' . $nchi . '</td>';
        //-- Last change
        if ($SHOW_LAST_CHANGE) {
            $html .= '<td>' . $family->LastChangeTimestamp() . '</td>';
        } else {
            $html .= '<td>&nbsp;</td>';
        }
        //-- Last change hidden sort column
        if ($SHOW_LAST_CHANGE) {
            $html .= '<td>' . $family->LastChangeTimestamp(true) . '</td>';
        } else {
            $html .= '<td>&nbsp;</td>';
        }
        //-- Sorting by marriage date
        $html .= '<td>';
        if (!$family->canShow() || !$mdate->isOK()) {
            $html .= 'U';
        } else {
            if (WT_Date::Compare($mdate, $d100y) > 0) {
                $html .= 'Y100';
            } else {
                $html .= 'YES';
            }
        }
        if ($family->getFacts(WT_EVENTS_DIV)) {
            $html .= 'D';
        }
        if (count($husb->getSpouseFamilies()) > 1 || count($wife->getSpouseFamilies()) > 1) {
            $html .= 'M';
        }
        $html .= '</td>';
        //-- Sorting alive/dead
        $html .= '<td>';
        if ($husb->isDead() && $wife->isDead()) {
            $html .= 'Y';
        }
        if ($husb->isDead() && !$wife->isDead()) {
            if ($wife->getSex() == 'F') {
                $html .= 'H';
            }
            if ($wife->getSex() == 'M') {
                $html .= 'W';
            }
            // male partners
        }
        if (!$husb->isDead() && $wife->isDead()) {
            if ($husb->getSex() == 'M') {
                $html .= 'W';
            }
            if ($husb->getSex() == 'F') {
                $html .= 'H';
            }
            // female partners
        }
        if (!$husb->isDead() && !$wife->isDead()) {
            $html .= 'N';
        }
        $html .= '</td>';
        //-- Roots or Leaves
        $html .= '<td>';
        if (!$husb->getChildFamilies() && !$wife->getChildFamilies()) {
            $html .= 'R';
        } elseif (!$husb->isDead() && !$wife->isDead() && $family->getNumberOfChildren() < 1) {
            $html .= 'L';
        } else {
            $html .= '&nbsp;';
        }
        $html .= '</td>
		</tr>';
    }
    $html .= '
				</tbody>
			</table>
			<div id="fam_list_table-charts_' . $table_id . '" style="display:none">
				<table class="list-charts">
					<tr>
						<td>
							' . print_chart_by_decade($birt_by_decade, WT_I18N::translate('Decade of birth')) . '
						</td>
						<td>
							' . print_chart_by_decade($marr_by_decade, WT_I18N::translate('Decade of marriage')) . '
						</td>
					</tr>
					<tr>
						<td colspan="2">
							' . print_chart_by_age($marr_by_age, WT_I18N::translate('Age in year of marriage')) . '
						</td>
					</tr>
				</table>
			</div>
		</div>';
    return $html;
}
Exemplo n.º 11
0
 /**
  * get the person box stylesheet class for the given person
  *
  * @param WT_Individual $person
  *
  * @return string returns 'person_box', 'person_boxF', or 'person_boxNN'
  */
 function getPersonStyle($person)
 {
     switch ($person->getSex()) {
         case 'M':
             $class = 'person_box';
             break;
         case 'F':
             $class = 'person_boxF';
             break;
         default:
             $class = 'person_boxNN';
             break;
     }
     if ($person->isOld()) {
         $class .= ' old';
     } elseif ($person->isNew()) {
         $class .= ' new';
     }
     return $class;
 }
Exemplo n.º 12
0
function get_relationship_name_from_path($path, WT_Individual $person1 = null, WT_Individual $person2 = null)
{
    if (!preg_match('/^(mot|fat|par|hus|wif|spo|son|dau|chi|bro|sis|sib)*$/', $path)) {
        // TODO: Update all the “3 RELA ” values in class_person
        return '<span class="error">' . $path . '</span>';
    }
    // The path does not include the starting person.  In some languages, the
    // translation for a man’s (relative) is different to a woman’s (relative),
    // due to inflection.
    $sex1 = $person1 ? $person1->getSex() : 'U';
    // The sex of the last person in the relationship determines the name in
    // many cases.  e.g. great-aunt / great-uncle
    if (preg_match('/(fat|hus|son|bro)$/', $path)) {
        $sex2 = 'M';
    } elseif (preg_match('/(mot|wif|dau|sis)$/', $path)) {
        $sex2 = 'F';
    } else {
        $sex2 = 'U';
    }
    switch ($path) {
        case '':
            return WT_I18N::translate('self');
            //  Level One relationships
        //  Level One relationships
        case 'mot':
            return WT_I18N::translate('mother');
        case 'fat':
            return WT_I18N::translate('father');
        case 'par':
            return WT_I18N::translate('parent');
        case 'hus':
            if ($person1 && $person2) {
                foreach ($person1->getSpouseFamilies() as $family) {
                    if ($person2 === $family->getSpouse($person1)) {
                        if ($family->getFacts('_NMR')) {
                            return WT_I18N::translate_c('MALE', 'partner');
                        } elseif ($family->getFacts(WT_EVENTS_DIV)) {
                            return WT_I18N::translate('ex-husband');
                        }
                    }
                }
            }
            return WT_I18N::translate('husband');
        case 'wif':
            if ($person1 && $person1) {
                foreach ($person1->getSpouseFamilies() as $family) {
                    if ($person2 === $family->getSpouse($person1)) {
                        if ($family->getFacts('_NMR')) {
                            return WT_I18N::translate_c('FEMALE', 'partner');
                        } elseif ($family->getFacts(WT_EVENTS_DIV)) {
                            return WT_I18N::translate('ex-wife');
                        }
                    }
                }
            }
            return WT_I18N::translate('wife');
        case 'spo':
            if ($person1 && $person2) {
                foreach ($person1->getSpouseFamilies() as $family) {
                    if ($person2 === $family->getSpouse($person1)) {
                        if ($family->getFacts('_NMR')) {
                            return WT_I18N::translate_c('MALE/FEMALE', 'partner');
                        } elseif ($family->getFacts(WT_EVENTS_DIV)) {
                            return WT_I18N::translate('ex-spouse');
                        }
                    }
                }
            }
            return WT_I18N::translate('spouse');
        case 'son':
            return WT_I18N::translate('son');
        case 'dau':
            return WT_I18N::translate('daughter');
        case 'chi':
            return WT_I18N::translate('child');
        case 'bro':
            if ($person1 && $person2) {
                $dob1 = $person1->getBirthDate();
                $dob2 = $person2->getBirthDate();
                if ($dob1->isOK() && $dob2->isOK()) {
                    if (abs($dob1->JD() - $dob2->JD()) < 2 && !$dob1->qual1 && !$dob2->qual1) {
                        // Exclude BEF, AFT, etc.
                        return WT_I18N::translate('twin brother');
                    } elseif ($dob1->MaxJD() < $dob2->MinJD()) {
                        return WT_I18N::translate('younger brother');
                    } elseif ($dob1->MinJD() > $dob2->MaxJD()) {
                        return WT_I18N::translate('elder brother');
                    }
                }
            }
            return WT_I18N::translate('brother');
        case 'sis':
            if ($person1 && $person2) {
                $dob1 = $person1->getBirthDate();
                $dob2 = $person2->getBirthDate();
                if ($dob1->isOK() && $dob2->isOK()) {
                    if (abs($dob1->JD() - $dob2->JD()) < 2 && !$dob1->qual1 && !$dob2->qual1) {
                        // Exclude BEF, AFT, etc.
                        return WT_I18N::translate('twin sister');
                    } elseif ($dob1->MaxJD() < $dob2->MinJD()) {
                        return WT_I18N::translate('younger sister');
                    } elseif ($dob1->MinJD() > $dob2->MaxJD()) {
                        return WT_I18N::translate('elder sister');
                    }
                }
            }
            return WT_I18N::translate('sister');
        case 'sib':
            if ($person1 && $person2) {
                $dob1 = $person1->getBirthDate();
                $dob2 = $person2->getBirthDate();
                if ($dob1->isOK() && $dob2->isOK()) {
                    if (abs($dob1->JD() - $dob2->JD()) < 2 && !$dob1->qual1 && !$dob2->qual1) {
                        // Exclude BEF, AFT, etc.
                        return WT_I18N::translate('twin sibling');
                    } elseif ($dob1->MaxJD() < $dob2->MinJD()) {
                        return WT_I18N::translate('younger sibling');
                    } elseif ($dob1->MinJD() > $dob2->MaxJD()) {
                        return WT_I18N::translate('elder sibling');
                    }
                }
            }
            return WT_I18N::translate('sibling');
            // Level Two relationships
        // Level Two relationships
        case 'brochi':
            return WT_I18N::translate_c('brother’s child', 'nephew/niece');
        case 'brodau':
            return WT_I18N::translate_c('brother’s daughter', 'niece');
        case 'broson':
            return WT_I18N::translate_c('brother’s son', 'nephew');
        case 'browif':
            return WT_I18N::translate_c('brother’s wife', 'sister-in-law');
        case 'chichi':
            return WT_I18N::translate_c('child’s child', 'grandchild');
        case 'chidau':
            return WT_I18N::translate_c('child’s daughter', 'granddaughter');
        case 'chihus':
            return WT_I18N::translate_c('child’s husband', 'son-in-law');
        case 'chison':
            return WT_I18N::translate_c('child’s son', 'grandson');
        case 'chispo':
            return WT_I18N::translate_c('child’s spouse', 'son/daughter-in-law');
        case 'chiwif':
            return WT_I18N::translate_c('child’s wife', 'daughter-in-law');
        case 'dauchi':
            return WT_I18N::translate_c('daughter’s child', 'grandchild');
        case 'daudau':
            return WT_I18N::translate_c('daughter’s daughter', 'granddaughter');
        case 'dauhus':
            return WT_I18N::translate_c('daughter’s husband', 'son-in-law');
        case 'dauson':
            return WT_I18N::translate_c('daughter’s son', 'grandson');
        case 'fatbro':
            return WT_I18N::translate_c('father’s brother', 'uncle');
        case 'fatchi':
            return WT_I18N::translate_c('father’s child', 'half-sibling');
        case 'fatdau':
            return WT_I18N::translate_c('father’s daughter', 'half-sister');
        case 'fatfat':
            return WT_I18N::translate_c('father’s father', 'paternal grandfather');
        case 'fatmot':
            return WT_I18N::translate_c('father’s mother', 'paternal grandmother');
        case 'fatpar':
            return WT_I18N::translate_c('father’s parent', 'paternal grandparent');
        case 'fatsib':
            return WT_I18N::translate_c('father’s sibling', 'aunt/uncle');
        case 'fatsis':
            return WT_I18N::translate_c('father’s sister', 'aunt');
        case 'fatson':
            return WT_I18N::translate_c('father’s son', 'half-brother');
        case 'fatwif':
            return WT_I18N::translate_c('father’s wife', 'step-mother');
        case 'husbro':
            return WT_I18N::translate_c('husband’s brother', 'brother-in-law');
        case 'huschi':
            return WT_I18N::translate_c('husband’s child', 'step-child');
        case 'husdau':
            return WT_I18N::translate_c('husband’s daughter', 'step-daughter');
        case 'husfat':
            return WT_I18N::translate_c('husband’s father', 'father-in-law');
        case 'husmot':
            return WT_I18N::translate_c('husband’s mother', 'mother-in-law');
        case 'hussib':
            return WT_I18N::translate_c('husband’s sibling', 'brother/sister-in-law');
        case 'hussis':
            return WT_I18N::translate_c('husband’s sister', 'sister-in-law');
        case 'husson':
            return WT_I18N::translate_c('husband’s son', 'step-son');
        case 'motbro':
            return WT_I18N::translate_c('mother’s brother', 'uncle');
        case 'motchi':
            return WT_I18N::translate_c('mother’s child', 'half-sibling');
        case 'motdau':
            return WT_I18N::translate_c('mother’s daughter', 'half-sister');
        case 'motfat':
            return WT_I18N::translate_c('mother’s father', 'maternal grandfather');
        case 'mothus':
            return WT_I18N::translate_c('mother’s husband', 'step-father');
        case 'motmot':
            return WT_I18N::translate_c('mother’s mother', 'maternal grandmother');
        case 'motpar':
            return WT_I18N::translate_c('mother’s parent', 'maternal grandparent');
        case 'motsib':
            return WT_I18N::translate_c('mother’s sibling', 'aunt/uncle');
        case 'motsis':
            return WT_I18N::translate_c('mother’s sister', 'aunt');
        case 'motson':
            return WT_I18N::translate_c('mother’s son', 'half-brother');
        case 'parbro':
            return WT_I18N::translate_c('parent’s brother', 'uncle');
        case 'parchi':
            return WT_I18N::translate_c('parent’s child', 'half-sibling');
        case 'pardau':
            return WT_I18N::translate_c('parent’s daughter', 'half-sister');
        case 'parfat':
            return WT_I18N::translate_c('parent’s father', 'grandfather');
        case 'parmot':
            return WT_I18N::translate_c('parent’s mother', 'grandmother');
        case 'parpar':
            return WT_I18N::translate_c('parent’s parent', 'grandparent');
        case 'parsib':
            return WT_I18N::translate_c('parent’s sibling', 'aunt/uncle');
        case 'parsis':
            return WT_I18N::translate_c('parent’s sister', 'aunt');
        case 'parson':
            return WT_I18N::translate_c('parent’s son', 'half-brother');
        case 'parspo':
            return WT_I18N::translate_c('parent’s spouse', 'step-parent');
        case 'sibchi':
            return WT_I18N::translate_c('sibling’s child', 'nephew/niece');
        case 'sibdau':
            return WT_I18N::translate_c('sibling’s daughter', 'niece');
        case 'sibson':
            return WT_I18N::translate_c('sibling’s son', 'nephew');
        case 'sibspo':
            return WT_I18N::translate_c('sibling’s spouse', 'brother/sister-in-law');
        case 'sischi':
            return WT_I18N::translate_c('sister’s child', 'nephew/niece');
        case 'sisdau':
            return WT_I18N::translate_c('sister’s daughter', 'niece');
        case 'sishus':
            return WT_I18N::translate_c('sister’s husband', 'brother-in-law');
        case 'sisson':
            return WT_I18N::translate_c('sister’s son', 'nephew');
        case 'sonchi':
            return WT_I18N::translate_c('son’s child', 'grandchild');
        case 'sondau':
            return WT_I18N::translate_c('son’s daughter', 'granddaughter');
        case 'sonson':
            return WT_I18N::translate_c('son’s son', 'grandson');
        case 'sonwif':
            return WT_I18N::translate_c('son’s wife', 'daughter-in-law');
        case 'spobro':
            return WT_I18N::translate_c('spouse’s brother', 'brother-in-law');
        case 'spochi':
            return WT_I18N::translate_c('spouse’s child', 'step-child');
        case 'spodau':
            return WT_I18N::translate_c('spouse’s daughter', 'step-daughter');
        case 'spofat':
            return WT_I18N::translate_c('spouse’s father', 'father-in-law');
        case 'spomot':
            return WT_I18N::translate_c('spouse’s mother', 'mother-in-law');
        case 'sposis':
            return WT_I18N::translate_c('spouse’s sister', 'sister-in-law');
        case 'sposon':
            return WT_I18N::translate_c('spouse’s son', 'step-son');
        case 'spopar':
            return WT_I18N::translate_c('spouse’s parent', 'mother/father-in-law');
        case 'sposib':
            return WT_I18N::translate_c('spouse’s sibling', 'brother/sister-in-law');
        case 'wifbro':
            return WT_I18N::translate_c('wife’s brother', 'brother-in-law');
        case 'wifchi':
            return WT_I18N::translate_c('wife’s child', 'step-child');
        case 'wifdau':
            return WT_I18N::translate_c('wife’s daughter', 'step-daughter');
        case 'wiffat':
            return WT_I18N::translate_c('wife’s father', 'father-in-law');
        case 'wifmot':
            return WT_I18N::translate_c('wife’s mother', 'mother-in-law');
        case 'wifsib':
            return WT_I18N::translate_c('wife’s sibling', 'brother/sister-in-law');
        case 'wifsis':
            return WT_I18N::translate_c('wife’s sister', 'sister-in-law');
        case 'wifson':
            return WT_I18N::translate_c('wife’s son', 'step-son');
            // Level Three relationships
            // I have commented out some of the unknown-sex relationships that are unlikely to to occur.
            // Feel free to add them in, if you think they might be needed
        // Level Three relationships
        // I have commented out some of the unknown-sex relationships that are unlikely to to occur.
        // Feel free to add them in, if you think they might be needed
        case 'brochichi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s child’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s child’s child', 'great-nephew/niece');
            }
        case 'brochidau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s child’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s child’s daughter', 'great-niece');
            }
        case 'brochison':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s child’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s child’s son', 'great-nephew');
            }
        case 'brodauchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s daughter’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s daughter’s child', 'great-nephew/niece');
            }
        case 'brodaudau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s daughter’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s daughter’s daughter', 'great-niece');
            }
        case 'brodauhus':
            return WT_I18N::translate_c('brother’s daughter’s husband', 'nephew-in-law');
        case 'brodauson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s daughter’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s daughter’s son', 'great-nephew');
            }
        case 'brosonchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s son’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s son’s child', 'great-nephew/niece');
            }
        case 'brosondau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s son’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s son’s daughter', 'great-niece');
            }
        case 'brosonson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s son’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s son’s son', 'great-nephew');
            }
        case 'brosonwif':
            return WT_I18N::translate_c('brother’s son’s wife', 'niece-in-law');
        case 'browifbro':
            return WT_I18N::translate_c('brother’s wife’s brother', 'brother-in-law');
        case 'browifsib':
            return WT_I18N::translate_c('brother’s wife’s sibling', 'brother/sister-in-law');
        case 'browifsis':
            return WT_I18N::translate_c('brother’s wife’s sister', 'sister-in-law');
        case 'chichichi':
            return WT_I18N::translate_c('child’s child’s child', 'great-grandchild');
        case 'chichidau':
            return WT_I18N::translate_c('child’s child’s daughter', 'great-granddaughter');
        case 'chichison':
            return WT_I18N::translate_c('child’s child’s son', 'great-grandson');
        case 'chidauchi':
            return WT_I18N::translate_c('child’s daughter’s child', 'great-grandchild');
        case 'chidaudau':
            return WT_I18N::translate_c('child’s daughter’s daughter', 'great-granddaughter');
        case 'chidauhus':
            return WT_I18N::translate_c('child’s daughter’s husband', 'granddaughter’s husband');
        case 'chidauson':
            return WT_I18N::translate_c('child’s daughter’s son', 'great-grandson');
        case 'chisonchi':
            return WT_I18N::translate_c('child’s son’s child', 'great-grandchild');
        case 'chisondau':
            return WT_I18N::translate_c('child’s son’s daughter', 'great-granddaughter');
        case 'chisonson':
            return WT_I18N::translate_c('child’s son’s son', 'great-grandson');
        case 'chisonwif':
            return WT_I18N::translate_c('child’s son’s wife', 'grandson’s wife');
        case 'dauchichi':
            return WT_I18N::translate_c('daughter’s child’s child', 'great-grandchild');
        case 'dauchidau':
            return WT_I18N::translate_c('daughter’s child’s daughter', 'great-granddaughter');
        case 'dauchison':
            return WT_I18N::translate_c('daughter’s child’s son', 'great-grandson');
        case 'daudauchi':
            return WT_I18N::translate_c('daughter’s daughter’s child', 'great-grandchild');
        case 'daudaudau':
            return WT_I18N::translate_c('daughter’s daughter’s daughter', 'great-granddaughter');
        case 'daudauhus':
            return WT_I18N::translate_c('daughter’s daughter’s husband', 'granddaughter’s husband');
        case 'daudauson':
            return WT_I18N::translate_c('daughter’s daughter’s son', 'great-grandson');
        case 'dauhusfat':
            return WT_I18N::translate_c('daughter’s husband’s father', 'son-in-law’s father');
        case 'dauhusmot':
            return WT_I18N::translate_c('daughter’s husband’s mother', 'son-in-law’s mother');
        case 'dauhuspar':
            return WT_I18N::translate_c('daughter’s husband’s parent', 'son-in-law’s parent');
        case 'dausonchi':
            return WT_I18N::translate_c('daughter’s son’s child', 'great-grandchild');
        case 'dausondau':
            return WT_I18N::translate_c('daughter’s son’s daughter', 'great-granddaughter');
        case 'dausonson':
            return WT_I18N::translate_c('daughter’s son’s son', 'great-grandson');
        case 'dausonwif':
            return WT_I18N::translate_c('daughter’s son’s wife', 'grandson’s wife');
        case 'fatbrochi':
            return WT_I18N::translate_c('father’s brother’s child', 'first cousin');
        case 'fatbrodau':
            return WT_I18N::translate_c('father’s brother’s daughter', 'first cousin');
        case 'fatbroson':
            return WT_I18N::translate_c('father’s brother’s son', 'first cousin');
        case 'fatbrowif':
            return WT_I18N::translate_c('father’s brother’s wife', 'aunt');
        case 'fatfatbro':
            return WT_I18N::translate_c('father’s father’s brother', 'great-uncle');
        case 'fatfatfat':
            return WT_I18N::translate_c('father’s father’s father', 'great-grandfather');
        case 'fatfatmot':
            return WT_I18N::translate_c('father’s father’s mother', 'great-grandmother');
        case 'fatfatpar':
            return WT_I18N::translate_c('father’s father’s parent', 'great-grandparent');
        case 'fatfatsib':
            return WT_I18N::translate_c('father’s father’s sibling', 'great-aunt/uncle');
        case 'fatfatsis':
            return WT_I18N::translate_c('father’s father’s sister', 'great-aunt');
        case 'fatmotbro':
            return WT_I18N::translate_c('father’s mother’s brother', 'great-uncle');
        case 'fatmotfat':
            return WT_I18N::translate_c('father’s mother’s father', 'great-grandfather');
        case 'fatmotmot':
            return WT_I18N::translate_c('father’s mother’s mother', 'great-grandmother');
        case 'fatmotpar':
            return WT_I18N::translate_c('father’s mother’s parent', 'great-grandparent');
        case 'fatmotsib':
            return WT_I18N::translate_c('father’s mother’s sibling', 'great-aunt/uncle');
        case 'fatmotsis':
            return WT_I18N::translate_c('father’s mother’s sister', 'great-aunt');
        case 'fatparbro':
            return WT_I18N::translate_c('father’s parent’s brother', 'great-uncle');
        case 'fatparfat':
            return WT_I18N::translate_c('father’s parent’s father', 'great-grandfather');
        case 'fatparmot':
            return WT_I18N::translate_c('father’s parent’s mother', 'great-grandmother');
        case 'fatparpar':
            return WT_I18N::translate_c('father’s parent’s parent', 'great-grandparent');
        case 'fatparsib':
            return WT_I18N::translate_c('father’s parent’s sibling', 'great-aunt/uncle');
        case 'fatparsis':
            return WT_I18N::translate_c('father’s parent’s sister', 'great-aunt');
        case 'fatsischi':
            return WT_I18N::translate_c('father’s sister’s child', 'first cousin');
        case 'fatsisdau':
            return WT_I18N::translate_c('father’s sister’s daughter', 'first cousin');
        case 'fatsishus':
            return WT_I18N::translate_c('father’s sister’s husband', 'uncle');
        case 'fatsisson':
            return WT_I18N::translate_c('father’s sister’s son', 'first cousin');
        case 'fatwifchi':
            return WT_I18N::translate_c('father’s wife’s child', 'step-sibling');
        case 'fatwifdau':
            return WT_I18N::translate_c('father’s wife’s daughter', 'step-sister');
        case 'fatwifson':
            return WT_I18N::translate_c('father’s wife’s son', 'step-brother');
        case 'husbrowif':
            return WT_I18N::translate_c('husband’s brother’s wife', 'sister-in-law');
        case 'hussishus':
            return WT_I18N::translate_c('husband’s sister’s husband', 'brother-in-law');
        case 'motbrochi':
            return WT_I18N::translate_c('mother’s brother’s child', 'first cousin');
        case 'motbrodau':
            return WT_I18N::translate_c('mother’s brother’s daughter', 'first cousin');
        case 'motbroson':
            return WT_I18N::translate_c('mother’s brother’s son', 'first cousin');
        case 'motbrowif':
            return WT_I18N::translate_c('mother’s brother’s wife', 'aunt');
        case 'motfatbro':
            return WT_I18N::translate_c('mother’s father’s brother', 'great-uncle');
        case 'motfatfat':
            return WT_I18N::translate_c('mother’s father’s father', 'great-grandfather');
        case 'motfatmot':
            return WT_I18N::translate_c('mother’s father’s mother', 'great-grandmother');
        case 'motfatpar':
            return WT_I18N::translate_c('mother’s father’s parent', 'great-grandparent');
        case 'motfatsib':
            return WT_I18N::translate_c('mother’s father’s sibling', 'great-aunt/uncle');
        case 'motfatsis':
            return WT_I18N::translate_c('mother’s father’s sister', 'great-aunt');
        case 'mothuschi':
            return WT_I18N::translate_c('mother’s husband’s child', 'step-sibling');
        case 'mothusdau':
            return WT_I18N::translate_c('mother’s husband’s daughter', 'step-sister');
        case 'mothusson':
            return WT_I18N::translate_c('mother’s husband’s son', 'step-brother');
        case 'motmotbro':
            return WT_I18N::translate_c('mother’s mother’s brother', 'great-uncle');
        case 'motmotfat':
            return WT_I18N::translate_c('mother’s mother’s father', 'great-grandfather');
        case 'motmotmot':
            return WT_I18N::translate_c('mother’s mother’s mother', 'great-grandmother');
        case 'motmotpar':
            return WT_I18N::translate_c('mother’s mother’s parent', 'great-grandparent');
        case 'motmotsib':
            return WT_I18N::translate_c('mother’s mother’s sibling', 'great-aunt/uncle');
        case 'motmotsis':
            return WT_I18N::translate_c('mother’s mother’s sister', 'great-aunt');
        case 'motparbro':
            return WT_I18N::translate_c('mother’s parent’s brother', 'great-uncle');
        case 'motparfat':
            return WT_I18N::translate_c('mother’s parent’s father', 'great-grandfather');
        case 'motparmot':
            return WT_I18N::translate_c('mother’s parent’s mother', 'great-grandmother');
        case 'motparpar':
            return WT_I18N::translate_c('mother’s parent’s parent', 'great-grandparent');
        case 'motparsib':
            return WT_I18N::translate_c('mother’s parent’s sibling', 'great-aunt/uncle');
        case 'motparsis':
            return WT_I18N::translate_c('mother’s parent’s sister', 'great-aunt');
        case 'motsischi':
            return WT_I18N::translate_c('mother’s sister’s child', 'first cousin');
        case 'motsisdau':
            return WT_I18N::translate_c('mother’s sister’s daughter', 'first cousin');
        case 'motsishus':
            return WT_I18N::translate_c('mother’s sister’s husband', 'uncle');
        case 'motsisson':
            return WT_I18N::translate_c('mother’s sister’s son', 'first cousin');
        case 'parbrowif':
            return WT_I18N::translate_c('parent’s brother’s wife', 'aunt');
        case 'parfatbro':
            return WT_I18N::translate_c('parent’s father’s brother', 'great-uncle');
        case 'parfatfat':
            return WT_I18N::translate_c('parent’s father’s father', 'great-grandfather');
        case 'parfatmot':
            return WT_I18N::translate_c('parent’s father’s mother', 'great-grandmother');
        case 'parfatpar':
            return WT_I18N::translate_c('parent’s father’s parent', 'great-grandparent');
        case 'parfatsib':
            return WT_I18N::translate_c('parent’s father’s sibling', 'great-aunt/uncle');
        case 'parfatsis':
            return WT_I18N::translate_c('parent’s father’s sister', 'great-aunt');
        case 'parmotbro':
            return WT_I18N::translate_c('parent’s mother’s brother', 'great-uncle');
        case 'parmotfat':
            return WT_I18N::translate_c('parent’s mother’s father', 'great-grandfather');
        case 'parmotmot':
            return WT_I18N::translate_c('parent’s mother’s mother', 'great-grandmother');
        case 'parmotpar':
            return WT_I18N::translate_c('parent’s mother’s parent', 'great-grandparent');
        case 'parmotsib':
            return WT_I18N::translate_c('parent’s mother’s sibling', 'great-aunt/uncle');
        case 'parmotsis':
            return WT_I18N::translate_c('parent’s mother’s sister', 'great-aunt');
        case 'parparbro':
            return WT_I18N::translate_c('parent’s parent’s brother', 'great-uncle');
        case 'parparfat':
            return WT_I18N::translate_c('parent’s parent’s father', 'great-grandfather');
        case 'parparmot':
            return WT_I18N::translate_c('parent’s parent’s mother', 'great-grandmother');
        case 'parparpar':
            return WT_I18N::translate_c('parent’s parent’s parent', 'great-grandparent');
        case 'parparsib':
            return WT_I18N::translate_c('parent’s parent’s sibling', 'great-aunt/uncle');
        case 'parparsis':
            return WT_I18N::translate_c('parent’s parent’s sister', 'great-aunt');
        case 'parsishus':
            return WT_I18N::translate_c('parent’s sister’s husband', 'uncle');
        case 'parspochi':
            return WT_I18N::translate_c('parent’s spouse’s child', 'step-sibling');
        case 'parspodau':
            return WT_I18N::translate_c('parent’s spouse’s daughter', 'step-sister');
        case 'parsposon':
            return WT_I18N::translate_c('parent’s spouse’s son', 'step-brother');
        case 'sibchichi':
            return WT_I18N::translate_c('sibling’s child’s child', 'great-nephew/niece');
        case 'sibchidau':
            return WT_I18N::translate_c('sibling’s child’s daughter', 'great-niece');
        case 'sibchison':
            return WT_I18N::translate_c('sibling’s child’s son', 'great-nephew');
        case 'sibdauchi':
            return WT_I18N::translate_c('sibling’s daughter’s child', 'great-nephew/niece');
        case 'sibdaudau':
            return WT_I18N::translate_c('sibling’s daughter’s daughter', 'great-niece');
        case 'sibdauhus':
            return WT_I18N::translate_c('sibling’s daughter’s husband', 'nephew-in-law');
        case 'sibdauson':
            return WT_I18N::translate_c('sibling’s daughter’s son', 'great-nephew');
        case 'sibsonchi':
            return WT_I18N::translate_c('sibling’s son’s child', 'great-nephew/niece');
        case 'sibsondau':
            return WT_I18N::translate_c('sibling’s son’s daughter', 'great-niece');
        case 'sibsonson':
            return WT_I18N::translate_c('sibling’s son’s son', 'great-nephew');
        case 'sibsonwif':
            return WT_I18N::translate_c('sibling’s son’s wife', 'niece-in-law');
        case 'sischichi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s child’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s child’s child', 'great-nephew/niece');
            }
        case 'sischidau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s child’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s child’s daughter', 'great-niece');
            }
        case 'sischison':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s child’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s child’s son', 'great-nephew');
            }
        case 'sisdauchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s daughter’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s daughter’s child', 'great-nephew/niece');
            }
        case 'sisdaudau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s daughter’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s daughter’s daughter', 'great-niece');
            }
        case 'sisdauhus':
            return WT_I18N::translate_c('sisters’s daughter’s husband', 'nephew-in-law');
        case 'sisdauson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s daughter’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s daughter’s son', 'great-nephew');
            }
        case 'sishusbro':
            return WT_I18N::translate_c('sister’s husband’s brother', 'brother-in-law');
        case 'sishussib':
            return WT_I18N::translate_c('sister’s husband’s sibling', 'brother/sister-in-law');
        case 'sishussis':
            return WT_I18N::translate_c('sister’s husband’s sister', 'sister-in-law');
        case 'sissonchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s son’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s son’s child', 'great-nephew/niece');
            }
        case 'sissondau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s son’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s son’s daughter', 'great-niece');
            }
        case 'sissonson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s son’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s son’s son', 'great-nephew');
            }
        case 'sissonwif':
            return WT_I18N::translate_c('sisters’s son’s wife', 'niece-in-law');
        case 'sonchichi':
            return WT_I18N::translate_c('son’s child’s child', 'great-grandchild');
        case 'sonchidau':
            return WT_I18N::translate_c('son’s child’s daughter', 'great-granddaughter');
        case 'sonchison':
            return WT_I18N::translate_c('son’s child’s son', 'great-grandson');
        case 'sondauchi':
            return WT_I18N::translate_c('son’s daughter’s child', 'great-grandchild');
        case 'sondaudau':
            return WT_I18N::translate_c('son’s daughter’s daughter', 'great-granddaughter');
        case 'sondauhus':
            return WT_I18N::translate_c('son’s daughter’s husband', 'granddaughter’s husband');
        case 'sondauson':
            return WT_I18N::translate_c('son’s daughter’s son', 'great-grandson');
        case 'sonsonchi':
            return WT_I18N::translate_c('son’s son’s child', 'great-grandchild');
        case 'sonsondau':
            return WT_I18N::translate_c('son’s son’s daughter', 'great-granddaughter');
        case 'sonsonson':
            return WT_I18N::translate_c('son’s son’s son', 'great-grandson');
        case 'sonsonwif':
            return WT_I18N::translate_c('son’s son’s wife', 'grandson’s wife');
        case 'sonwiffat':
            return WT_I18N::translate_c('son’s wife’s father', 'daughter-in-law’s father');
        case 'sonwifmot':
            return WT_I18N::translate_c('son’s wife’s mother', 'daughter-in-law’s mother');
        case 'sonwifpar':
            return WT_I18N::translate_c('son’s wife’s parent', 'daughter-in-law’s parent');
        case 'wifbrowif':
            return WT_I18N::translate_c('wife’s brother’s wife', 'sister-in-law');
        case 'wifsishus':
            return WT_I18N::translate_c('wife’s sister’s husband', 'brother-in-law');
            // Some “special case” level four relationships that have specific names in certain languages
        // Some “special case” level four relationships that have specific names in certain languages
        case 'fatfatbrowif':
            return WT_I18N::translate_c('father’s father’s brother’s wife', 'great-aunt');
        case 'fatfatsibspo':
            return WT_I18N::translate_c('father’s father’s sibling’s spouse', 'great-aunt/uncle');
        case 'fatfatsishus':
            return WT_I18N::translate_c('father’s father’s sister’s husband', 'great-uncle');
        case 'fatmotbrowif':
            return WT_I18N::translate_c('father’s mother’s brother’s wife', 'great-aunt');
        case 'fatmotsibspo':
            return WT_I18N::translate_c('father’s mother’s sibling’s spouse', 'great-aunt/uncle');
        case 'fatmotsishus':
            return WT_I18N::translate_c('father’s mother’s sister’s husband', 'great-uncle');
        case 'fatparbrowif':
            return WT_I18N::translate_c('father’s parent’s brother’s wife', 'great-aunt');
        case 'fatparsibspo':
            return WT_I18N::translate_c('father’s parent’s sibling’s spouse', 'great-aunt/uncle');
        case 'fatparsishus':
            return WT_I18N::translate_c('father’s parent’s sister’s husband', 'great-uncle');
        case 'motfatbrowif':
            return WT_I18N::translate_c('mother’s father’s brother’s wife', 'great-aunt');
        case 'motfatsibspo':
            return WT_I18N::translate_c('mother’s father’s sibling’s spouse', 'great-aunt/uncle');
        case 'motfatsishus':
            return WT_I18N::translate_c('mother’s father’s sister’s husband', 'great-uncle');
        case 'motmotbrowif':
            return WT_I18N::translate_c('mother’s mother’s brother’s wife', 'great-aunt');
        case 'motmotsibspo':
            return WT_I18N::translate_c('mother’s mother’s sibling’s spouse', 'great-aunt/uncle');
        case 'motmotsishus':
            return WT_I18N::translate_c('mother’s mother’s sister’s husband', 'great-uncle');
        case 'motparbrowif':
            return WT_I18N::translate_c('mother’s parent’s brother’s wife', 'great-aunt');
        case 'motparsibspo':
            return WT_I18N::translate_c('mother’s parent’s sibling’s spouse', 'great-aunt/uncle');
        case 'motparsishus':
            return WT_I18N::translate_c('mother’s parent’s sister’s husband', 'great-uncle');
        case 'parfatbrowif':
            return WT_I18N::translate_c('parent’s father’s brother’s wife', 'great-aunt');
        case 'parfatsibspo':
            return WT_I18N::translate_c('parent’s father’s sibling’s spouse', 'great-aunt/uncle');
        case 'parfatsishus':
            return WT_I18N::translate_c('parent’s father’s sister’s husband', 'great-uncle');
        case 'parmotbrowif':
            return WT_I18N::translate_c('parent’s mother’s brother’s wife', 'great-aunt');
        case 'parmotsibspo':
            return WT_I18N::translate_c('parent’s mother’s sibling’s spouse', 'great-aunt/uncle');
        case 'parmotsishus':
            return WT_I18N::translate_c('parent’s mother’s sister’s husband', 'great-uncle');
        case 'parparbrowif':
            return WT_I18N::translate_c('parent’s parent’s brother’s wife', 'great-aunt');
        case 'parparsibspo':
            return WT_I18N::translate_c('parent’s parent’s sibling’s spouse', 'great-aunt/uncle');
        case 'parparsishus':
            return WT_I18N::translate_c('parent’s parent’s sister’s husband', 'great-uncle');
        case 'fatfatbrodau':
            return WT_I18N::translate_c('father’s father’s brother’s daughter', 'first cousin once removed ascending');
        case 'fatfatbroson':
            return WT_I18N::translate_c('father’s father’s brother’s son', 'first cousin once removed ascending');
        case 'fatfatbrochi':
            return WT_I18N::translate_c('father’s father’s brother’s child', 'first cousin once removed ascending');
        case 'fatfatsisdau':
            return WT_I18N::translate_c('father’s father’s sister’s daughter', 'first cousin once removed ascending');
        case 'fatfatsisson':
            return WT_I18N::translate_c('father’s father’s sister’s son', 'first cousin once removed ascending');
        case 'fatfatsischi':
            return WT_I18N::translate_c('father’s father’s sister’s child', 'first cousin once removed ascending');
        case 'fatmotbrodau':
            return WT_I18N::translate_c('father’s mother’s brother’s daughter', 'first cousin once removed ascending');
        case 'fatmotbroson':
            return WT_I18N::translate_c('father’s mother’s brother’s son', 'first cousin once removed ascending');
        case 'fatmotbrochi':
            return WT_I18N::translate_c('father’s mother’s brother’s child', 'first cousin once removed ascending');
        case 'fatmotsisdau':
            return WT_I18N::translate_c('father’s mother’s sister’s daughter', 'first cousin once removed ascending');
        case 'fatmotsisson':
            return WT_I18N::translate_c('father’s mother’s sister’s son', 'first cousin once removed ascending');
        case 'fatmotsischi':
            return WT_I18N::translate_c('father’s mother’s sister’s child', 'first cousin once removed ascending');
        case 'motfatbrodau':
            return WT_I18N::translate_c('mother’s father’s brother’s daughter', 'first cousin once removed ascending');
        case 'motfatbroson':
            return WT_I18N::translate_c('mother’s father’s brother’s son', 'first cousin once removed ascending');
        case 'motfatbrochi':
            return WT_I18N::translate_c('mother’s father’s brother’s child', 'first cousin once removed ascending');
        case 'motfatsisdau':
            return WT_I18N::translate_c('mother’s father’s sister’s daughter', 'first cousin once removed ascending');
        case 'motfatsisson':
            return WT_I18N::translate_c('mother’s father’s sister’s son', 'first cousin once removed ascending');
        case 'motfatsischi':
            return WT_I18N::translate_c('mother’s father’s sister’s child', 'first cousin once removed ascending');
        case 'motmotbrodau':
            return WT_I18N::translate_c('mother’s mother’s brother’s daughter', 'first cousin once removed ascending');
        case 'motmotbroson':
            return WT_I18N::translate_c('mother’s mother’s brother’s son', 'first cousin once removed ascending');
        case 'motmotbrochi':
            return WT_I18N::translate_c('mother’s mother’s brother’s child', 'first cousin once removed ascending');
        case 'motmotsisdau':
            return WT_I18N::translate_c('mother’s mother’s sister’s daughter', 'first cousin once removed ascending');
        case 'motmotsisson':
            return WT_I18N::translate_c('mother’s mother’s sister’s son', 'first cousin once removed ascending');
        case 'motmotsischi':
            return WT_I18N::translate_c('mother’s mother’s sister’s child', 'first cousin once removed ascending');
    }
    // Some “special case” level five relationships that have specific names in certain languages
    if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)dau$/', $path)) {
        return WT_I18N::translate_c('grandfather’s brother’s granddaughter', 'second cousin');
    } else {
        if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)son$/', $path)) {
            return WT_I18N::translate_c('grandfather’s brother’s grandson', 'second cousin');
        } else {
            if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)chi$/', $path)) {
                return WT_I18N::translate_c('grandfather’s brother’s grandchild', 'second cousin');
            } else {
                if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)dau$/', $path)) {
                    return WT_I18N::translate_c('grandfather’s sister’s granddaughter', 'second cousin');
                } else {
                    if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)son$/', $path)) {
                        return WT_I18N::translate_c('grandfather’s sister’s grandson', 'second cousin');
                    } else {
                        if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)chi$/', $path)) {
                            return WT_I18N::translate_c('grandfather’s sister’s grandchild', 'second cousin');
                        } else {
                            if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)dau$/', $path)) {
                                return WT_I18N::translate_c('grandfather’s sibling’s granddaughter', 'second cousin');
                            } else {
                                if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)son$/', $path)) {
                                    return WT_I18N::translate_c('grandfather’s sibling’s grandson', 'second cousin');
                                } else {
                                    if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)chi$/', $path)) {
                                        return WT_I18N::translate_c('grandfather’s sibling’s grandchild', 'second cousin');
                                    } else {
                                        if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)dau$/', $path)) {
                                            return WT_I18N::translate_c('grandmother’s brother’s granddaughter', 'second cousin');
                                        } else {
                                            if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)son$/', $path)) {
                                                return WT_I18N::translate_c('grandmother’s brother’s grandson', 'second cousin');
                                            } else {
                                                if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)chi$/', $path)) {
                                                    return WT_I18N::translate_c('grandmother’s brother’s grandchild', 'second cousin');
                                                } else {
                                                    if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)dau$/', $path)) {
                                                        return WT_I18N::translate_c('grandmother’s sister’s granddaughter', 'second cousin');
                                                    } else {
                                                        if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)son$/', $path)) {
                                                            return WT_I18N::translate_c('grandmother’s sister’s grandson', 'second cousin');
                                                        } else {
                                                            if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)chi$/', $path)) {
                                                                return WT_I18N::translate_c('grandmother’s sister’s grandchild', 'second cousin');
                                                            } else {
                                                                if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)dau$/', $path)) {
                                                                    return WT_I18N::translate_c('grandmother’s sibling’s granddaughter', 'second cousin');
                                                                } else {
                                                                    if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)son$/', $path)) {
                                                                        return WT_I18N::translate_c('grandmother’s sibling’s grandson', 'second cousin');
                                                                    } else {
                                                                        if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)chi$/', $path)) {
                                                                            return WT_I18N::translate_c('grandmother’s sibling’s grandchild', 'second cousin');
                                                                        } else {
                                                                            if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)dau$/', $path)) {
                                                                                return WT_I18N::translate_c('grandparent’s brother’s granddaughter', 'second cousin');
                                                                            } else {
                                                                                if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)son$/', $path)) {
                                                                                    return WT_I18N::translate_c('grandparent’s brother’s grandson', 'second cousin');
                                                                                } else {
                                                                                    if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)chi$/', $path)) {
                                                                                        return WT_I18N::translate_c('grandparent’s brother’s grandchild', 'second cousin');
                                                                                    } else {
                                                                                        if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)dau$/', $path)) {
                                                                                            return WT_I18N::translate_c('grandparent’s sister’s granddaughter', 'second cousin');
                                                                                        } else {
                                                                                            if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)son$/', $path)) {
                                                                                                return WT_I18N::translate_c('grandparent’s sister’s grandson', 'second cousin');
                                                                                            } else {
                                                                                                if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)chi$/', $path)) {
                                                                                                    return WT_I18N::translate_c('grandparent’s sister’s grandchild', 'second cousin');
                                                                                                } else {
                                                                                                    if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)dau$/', $path)) {
                                                                                                        return WT_I18N::translate_c('grandparent’s sibling’s granddaughter', 'second cousin');
                                                                                                    } else {
                                                                                                        if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)son$/', $path)) {
                                                                                                            return WT_I18N::translate_c('grandparent’s sibling’s grandson', 'second cousin');
                                                                                                        } else {
                                                                                                            if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)chi$/', $path)) {
                                                                                                                return WT_I18N::translate_c('grandparent’s sibling’s grandchild', 'second cousin');
                                                                                                            }
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // Look for generic/pattern relationships.
    // TODO: these are heavily based on English relationship names.
    // We need feedback from other languages to improve this.
    // Dutch has special names for 8 generations of great-great-..., so these need explicit naming
    // Spanish has special names for four but also has two different numbering patterns
    if (preg_match('/^((?:mot|fat|par)+)(bro|sis|sib)$/', $path, $match)) {
        // siblings of direct ancestors
        $up = strlen($match[1]) / 3;
        $bef_last = substr($path, -6, 3);
        switch ($up) {
            case 3:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great-grandfather’s brother', 'great-great-uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great-grandmother’s brother', 'great-great-uncle');
                            } else {
                                return WT_I18N::translate_c('great-grandparent’s brother', 'great-great-uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great-great-aunt');
                    case 'U':
                        return WT_I18N::translate('great-great-aunt/uncle');
                }
                break;
            case 4:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great-great-grandfather’s brother', 'great-great-great-uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great-great-grandmother’s brother', 'great-great-great-uncle');
                            } else {
                                return WT_I18N::translate_c('great-great-grandparent’s brother', 'great-great-great-uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great-great-great-aunt');
                    case 'U':
                        return WT_I18N::translate('great-great-great-aunt/uncle');
                }
                break;
            case 5:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great-great-great-grandfather’s brother', 'great ×4 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great-great-great-grandmother’s brother', 'great ×4 uncle');
                            } else {
                                return WT_I18N::translate_c('great-great-great-grandparent’s brother', 'great ×4 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×4 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×4 aunt/uncle');
                }
                break;
            case 6:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great ×4 grandfather’s brother', 'great ×5 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great ×4 grandmother’s brother', 'great ×5 uncle');
                            } else {
                                return WT_I18N::translate_c('great ×4 grandparent’s brother', 'great ×5 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×5 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×5 aunt/uncle');
                }
                break;
            case 7:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great ×5 grandfather’s brother', 'great ×6 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great ×5 grandmother’s brother', 'great ×6 uncle');
                            } else {
                                return WT_I18N::translate_c('great ×5 grandparent’s brother', 'great ×6 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×6 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×6 aunt/uncle');
                }
                break;
            case 8:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great ×6 grandfather’s brother', 'great ×7 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great ×6 grandmother’s brother', 'great ×7 uncle');
                            } else {
                                return WT_I18N::translate_c('great ×6 grandparent’s brother', 'great ×7 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×7 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×7 aunt/uncle');
                }
                break;
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 uncle is a Danish great ×10 uncle.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'da':
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d uncle', $up - 4);
                            case 'F':
                                return WT_I18N::translate('great ×%d aunt', $up - 4);
                            case 'U':
                                return WT_I18N::translate('great ×%d aunt/uncle', $up - 4);
                        }
                    case 'pl':
                        switch ($sex2) {
                            case 'M':
                                if ($bef_last == 'fat') {
                                    return WT_I18N::translate_c('great ×(%d-1) grandfather’s brother', 'great ×%d uncle', $up - 2);
                                } else {
                                    if ($bef_last == 'mot') {
                                        return WT_I18N::translate_c('great ×(%d-1) grandmother’s brother', 'great ×%d uncle', $up - 2);
                                    } else {
                                        return WT_I18N::translate_c('great ×(%d-1) grandparent’s brother', 'great ×%d uncle', $up - 2);
                                    }
                                }
                            case 'F':
                                return WT_I18N::translate('great ×%d aunt', $up - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d aunt/uncle', $up - 2);
                        }
                    case 'it':
                        // Source: Michele Locati
                    // Source: Michele Locati
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d uncle', $up - 1);
                            case 'F':
                                return WT_I18N::translate('great ×%d aunt', $up - 1);
                            case 'U':
                                return WT_I18N::translate('great ×%d aunt/uncle', $up - 1);
                        }
                }
        }
    }
    if (preg_match('/^(?:bro|sis|sib)((?:son|dau|chi)+)$/', $path, $match)) {
        // direct descendants of siblings
        $down = strlen($match[1]) / 3 + 1;
        // Add one, as we count generations from the common ancestor
        $first = substr($path, 0, 3);
        switch ($down) {
            case 4:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-grandson', 'great-great-nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-grandson', 'great-great-nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-nephew', 'great-great-nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-granddaughter', 'great-great-niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-granddaughter', 'great-great-niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-niece', 'great-great-niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-grandchild', 'great-great-nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-grandchild', 'great-great-nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-nephew/niece', 'great-great-nephew/niece');
                            }
                        }
                }
            case 5:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-grandson', 'great-great-great-nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-grandson', 'great-great-great-nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-great-nephew', 'great-great-great-nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-granddaughter', 'great-great-great-niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-granddaughter', 'great-great-great-niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-great-niece', 'great-great-great-niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-grandchild', 'great-great-great-nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-grandchild', 'great-great-great-nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-great-nephew/niece', 'great-great-great-nephew/niece');
                            }
                        }
                }
            case 6:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-great-grandson', 'great ×4 nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-great-grandson', 'great ×4 nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×4 nephew', 'great ×4 nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-great-granddaughter', 'great ×4 niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-great-granddaughter', 'great ×4 niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×4 niece', 'great ×4 niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-great-grandchild', 'great ×4 nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-great-grandchild', 'great ×4 nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×4 nephew/niece', 'great ×4 nephew/niece');
                            }
                        }
                }
            case 7:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great ×4 grandson', 'great ×5 nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great ×4 grandson', 'great ×5 nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×5 nephew', 'great ×5 nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great ×4 granddaughter', 'great ×5 niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great ×4 granddaughter', 'great ×5 niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×5 niece', 'great ×5 niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great ×4 grandchild', 'great ×5 nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great ×4 grandchild', 'great ×5 nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×5 nephew/niece', 'great ×5 nephew/niece');
                            }
                        }
                }
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 nephew is a Polish great ×11 nephew.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'pl':
                        // Source: Lukasz Wilenski
                        switch ($sex2) {
                            case 'M':
                                if ($first == 'bro' && $sex1 == 'M') {
                                    return WT_I18N::translate_c('(a man’s) brother’s great ×(%d-1) grandson', 'great ×%d nephew', $down - 3);
                                } else {
                                    if ($first == 'sis' && $sex1 == 'M') {
                                        return WT_I18N::translate_c('(a man’s) sister’s great ×(%d-1) grandson', 'great ×%d nephew', $down - 3);
                                    } else {
                                        return WT_I18N::translate_c('(a woman’s) great ×%d nephew', 'great ×%d nephew', $down - 3);
                                    }
                                }
                            case 'F':
                                if ($first == 'bro' && $sex1 == 'M') {
                                    return WT_I18N::translate_c('(a man’s) brother’s great ×(%d-1) granddaughter', 'great ×%d niece', $down - 3);
                                } else {
                                    if ($first == 'sis' && $sex1 == 'M') {
                                        return WT_I18N::translate_c('(a man’s) sister’s great ×(%d-1) granddaughter', 'great ×%d niece', $down - 3);
                                    } else {
                                        return WT_I18N::translate_c('(a woman’s) great ×%d niece', 'great ×%d niece', $down - 3);
                                    }
                                }
                            case 'U':
                                if ($first == 'bro' && $sex1 == 'M') {
                                    return WT_I18N::translate_c('(a man’s) brother’s great ×(%d-1) grandchild', 'great ×%d nephew/niece', $down - 3);
                                } else {
                                    if ($first == 'sis' && $sex1 == 'M') {
                                        return WT_I18N::translate_c('(a man’s) sister’s great ×(%d-1) grandchild', 'great ×%d nephew/niece', $down - 3);
                                    } else {
                                        return WT_I18N::translate_c('(a woman’s) great ×%d nephew/niece', 'great ×%d nephew/niece', $down - 3);
                                    }
                                }
                        }
                    case 'he':
                        // Source: Meliza Amity
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d nephew', $down - 1);
                            case 'F':
                                return WT_I18N::translate('great ×%d niece', $down - 1);
                            case 'U':
                                return WT_I18N::translate('great ×%d nephew/niece', $down - 1);
                        }
                    case 'it':
                        // Source: Michele Locati.
                    // Source: Michele Locati.
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d nephew', $down - 2);
                            case 'F':
                                return WT_I18N::translate('great ×%d niece', $down - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d nephew/niece', $down - 2);
                        }
                }
        }
    }
    if (preg_match('/^((?:mot|fat|par)*)$/', $path, $match)) {
        // direct ancestors
        $up = strlen($match[1]) / 3;
        switch ($up) {
            case 4:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great-great-grandfather');
                    case 'F':
                        return WT_I18N::translate('great-great-grandmother');
                    case 'U':
                        return WT_I18N::translate('great-great-grandparent');
                }
                break;
            case 5:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great-great-great-grandfather');
                    case 'F':
                        return WT_I18N::translate('great-great-great-grandmother');
                    case 'U':
                        return WT_I18N::translate('great-great-great-grandparent');
                }
                break;
            case 6:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×4 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×4 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×4 grandparent');
                }
                break;
            case 7:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×5 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×5 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×5 grandparent');
                }
                break;
            case 8:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×6 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×6 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×6 grandparent');
                }
                break;
            case 9:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×7 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×7 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×7 grandparent');
                }
                break;
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 grandfather is a Danish great ×11 grandfather.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'da':
                        // Source: Patrick Sorensen
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandfather', $up - 3);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 3);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 3);
                        }
                    case 'it':
                        // Source: Michele Locati
                    // Source: Michele Locati
                    case 'es':
                        // Source: Wes Groleau
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandfather', $up);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up);
                        }
                    case 'fr':
                        // Source: Jacqueline Tetreault
                    // Source: Jacqueline Tetreault
                    case 'fr_CA':
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandfather', $up - 1);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 1);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 1);
                        }
                    case 'nn':
                        // Source: Hogne Røed Nilsen (https://bugs.launchpad.net/webtrees/+bug/1168553)
                    // Source: Hogne Røed Nilsen (https://bugs.launchpad.net/webtrees/+bug/1168553)
                    case 'nb':
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d grandfather', $up - 3);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 3);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 3);
                        }
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d grandfather', $up - 2);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 2);
                        }
                }
        }
    }
    if (preg_match('/^((?:son|dau|chi)*)$/', $path, $match)) {
        // direct descendants
        $up = strlen($match[1]) / 3;
        switch ($up) {
            case 4:
                switch ($sex2) {
                    case 'son':
                        return WT_I18N::translate('great-great-grandson');
                    case 'dau':
                        return WT_I18N::translate('great-great-granddaughter');
                    case 'chi':
                        return WT_I18N::translate('great-great-grandchild');
                }
                break;
            case 5:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great-great-great-grandson');
                    case 'F':
                        return WT_I18N::translate('great-great-great-granddaughter');
                    case 'U':
                        return WT_I18N::translate('great-great-great-grandchild');
                }
                break;
            case 6:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×4 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×4 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×4 grandchild');
                }
                break;
            case 7:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×5 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×5 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×5 grandchild');
                }
                break;
            case 8:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×6 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×6 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×6 grandchild');
                }
                break;
            case 9:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×7 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×7 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×7 grandchild');
                }
                break;
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 grandson is a Danish great ×11 grandson.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'nn':
                        // Source: Hogne Røed Nilsen
                    // Source: Hogne Røed Nilsen
                    case 'nb':
                    case 'da':
                        // Source: Patrick Sorensen
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandson', $up - 3);
                            case 'F':
                                return WT_I18N::translate('great ×%d granddaughter', $up - 3);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandchild', $up - 3);
                        }
                    case 'it':
                        // Source: Michele Locati
                    // Source: Michele Locati
                    case 'es':
                        // Source: Wes Groleau (adding doesn’t change behavior, but needs to be better researched)
                    // Source: Wes Groleau (adding doesn’t change behavior, but needs to be better researched)
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d grandson', $up - 2);
                            case 'F':
                                return WT_I18N::translate('great ×%d granddaughter', $up - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandchild', $up - 2);
                        }
                }
        }
    }
    if (preg_match('/^((?:mot|fat|par)+)(?:bro|sis|sib)((?:son|dau|chi)+)$/', $path, $match)) {
        // cousins in English
        $ascent = $match[1];
        $descent = $match[2];
        $up = strlen($ascent) / 3;
        $down = strlen($descent) / 3;
        $cousin = min($up, $down);
        // Moved out of switch (en/default case) so that
        $removed = abs($down - $up);
        // Spanish (and other languages) can use it, too.
        // Different languages have different rules for naming cousins.  For example,
        // an English “second cousin once removed” is a Polish “cousin of 7th degree”.
        //
        // Need to find out which languages use which rules.
        switch (WT_LOCALE) {
            case 'pl':
                // Source: Lukasz Wilenski
                return cousin_name($up + $down + 2, $sex2);
            case 'it':
                // Source: Michele Locati.  See italian_cousins_names.zip
                // http://webtrees.net/forums/8-translation/1200-great-xn-grandparent?limit=6&start=6
                return cousin_name($up + $down - 3, $sex2);
            case 'es':
                // Source: Wes Groleau.  See http://UniGen.us/Parentesco.html & http://UniGen.us/Parentesco-D.html
                if ($down == $up) {
                    return cousin_name($cousin, $sex2);
                } elseif ($down < $up) {
                    return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('sib' . $descent, null, null));
                } else {
                    switch ($sex2) {
                        case 'M':
                            return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('bro' . $descent, null, null));
                        case 'F':
                            return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('sis' . $descent, null, null));
                        case 'U':
                            return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('sib' . $descent, null, null));
                    }
                }
            case 'en_AU':
                // See: http://en.wikipedia.org/wiki/File:CousinTree.svg
            // See: http://en.wikipedia.org/wiki/File:CousinTree.svg
            case 'en_GB':
            case 'en_US':
            default:
                switch ($removed) {
                    case 0:
                        return cousin_name($cousin, $sex2);
                    case 1:
                        if ($up > $down) {
                            /* I18N: %s=“fifth cousin”, etc. http://www.ancestry.com/learn/library/article.aspx?article=2856 */
                            return WT_I18N::translate('%s once removed ascending', cousin_name($cousin, $sex2));
                        } else {
                            /* I18N: %s=“fifth cousin”, etc. http://www.ancestry.com/learn/library/article.aspx?article=2856 */
                            return WT_I18N::translate('%s once removed descending', cousin_name($cousin, $sex2));
                        }
                    case 2:
                        if ($up > $down) {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s twice removed ascending', cousin_name($cousin, $sex2));
                        } else {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s twice removed descending', cousin_name($cousin, $sex2));
                        }
                    case 3:
                        if ($up > $down) {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s three times removed ascending', cousin_name($cousin, $sex2));
                        } else {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s three times removed descending', cousin_name($cousin, $sex2));
                        }
                    default:
                        if ($up > $down) {
                            /* I18N: %1$s=“fifth cousin”, etc., %2$d>=4 */
                            return WT_I18N::translate('%1$s %2$d times removed ascending', cousin_name($cousin, $sex2), $removed);
                        } else {
                            /* I18N: %1$s=“fifth cousin”, etc., %2$d>=4 */
                            return WT_I18N::translate('%1$s %2$d times removed descending', cousin_name($cousin, $sex2), $removed);
                        }
                }
        }
    }
    // Split the relationship into sub-relationships, e.g., third-cousin’s great-uncle.
    // Try splitting at every point, and choose the path with the shorted translated name.
    $relationship = null;
    $path1 = substr($path, 0, 3);
    $path2 = substr($path, 3);
    while ($path2) {
        $tmp = WT_I18N::translate('%1$s’s %2$s', get_relationship_name_from_path($path1, null, null), get_relationship_name_from_path($path2, null, null));
        if (!$relationship || strlen($tmp) < strlen($relationship)) {
            $relationship = $tmp;
        }
        $path1 .= substr($path2, 0, 3);
        $path2 = substr($path2, 3);
    }
    return $relationship;
}
Exemplo n.º 13
0
    public function configureBlock($block_id)
    {
        global $ctype, $controller;
        $PEDIGREE_ROOT_ID = get_gedcom_setting(WT_GED_ID, 'PEDIGREE_ROOT_ID');
        if (WT_Filter::postBool('save') && WT_Filter::checkCsrf()) {
            set_block_setting($block_id, 'details', WT_Filter::postBool('details'));
            set_block_setting($block_id, 'type', WT_Filter::post('type', 'pedigree|descendants|hourglass|treenav', 'pedigree'));
            set_block_setting($block_id, 'pid', WT_Filter::post('pid', WT_REGEX_XREF));
            exit;
        }
        $details = get_block_setting($block_id, 'details', false);
        $type = get_block_setting($block_id, 'type', 'pedigree');
        $pid = get_block_setting($block_id, 'pid', WT_USER_ID ? WT_USER_GEDCOM_ID ? WT_USER_GEDCOM_ID : $PEDIGREE_ROOT_ID : $PEDIGREE_ROOT_ID);
        $controller->addExternalJavascript(WT_STATIC_URL . 'js/autocomplete.js')->addInlineJavascript('autocomplete();');
        ?>
		<tr><td class="descriptionbox wrap width33"><?php 
        echo WT_I18N::translate('Chart type');
        ?>
</td>
		<td class="optionbox">
			<select name="type">
				<option value="pedigree"<?php 
        if ($type == "pedigree") {
            echo " selected=\"selected\"";
        }
        ?>
><?php 
        echo WT_I18N::translate('Pedigree');
        ?>
</option>
				<option value="descendants"<?php 
        if ($type == "descendants") {
            echo " selected=\"selected\"";
        }
        ?>
><?php 
        echo WT_I18N::translate('Descendants');
        ?>
</option>
				<option value="hourglass"<?php 
        if ($type == "hourglass") {
            echo " selected=\"selected\"";
        }
        ?>
><?php 
        echo WT_I18N::translate('Hourglass chart');
        ?>
</option>
				<option value="treenav"<?php 
        if ($type == "treenav") {
            echo " selected=\"selected\"";
        }
        ?>
><?php 
        echo WT_I18N::translate('Interactive tree');
        ?>
</option>
			</select>
		</td></tr>
		<tr>
			<td class="descriptionbox wrap width33"><?php 
        echo WT_I18N::translate('Show details');
        ?>
</td>
		<td class="optionbox">
			<select name="details">
					<option value="no" <?php 
        if (!$details) {
            echo " selected=\"selected\"";
        }
        ?>
><?php 
        echo WT_I18N::translate('no');
        ?>
</option>
					<option value="yes" <?php 
        if ($details) {
            echo " selected=\"selected\"";
        }
        ?>
><?php 
        echo WT_I18N::translate('yes');
        ?>
</option>
			</select>
			</td>
		</tr>
		<tr>
			<td class="descriptionbox wrap width33"><?php 
        echo WT_I18N::translate('Individual');
        ?>
</td>
			<td class="optionbox">
				<input data-autocomplete-type="INDI" type="text" name="pid" id="pid" value="<?php 
        echo $pid;
        ?>
" size="5">
				<?php 
        echo print_findindi_link('pid');
        $root = WT_Individual::getInstance($pid);
        if ($root) {
            echo ' <span class="list_item">', $root->getFullName(), $root->format_first_major_fact(WT_EVENTS_BIRT, 1), '</span>';
        }
        ?>
			</td>
		</tr>
		<?php 
        require_once WT_ROOT . 'includes/functions/functions_edit.php';
        $block = get_block_setting($block_id, 'block', false);
        echo '<tr><td class="descriptionbox wrap width33">';
        echo WT_I18N::translate('Add a scrollbar when block contents grow');
        echo '</td><td class="optionbox">';
        echo edit_field_yes_no('block', $block);
        echo '</td></tr>';
    }
Exemplo n.º 14
0
/**
 * creates an array with all of the individual ids to be displayed on an ascendancy chart
 *
 * the id in position 1 is the root person.  The other positions are filled according to the following algorithm
 * if an individual is at position $i then individual $i’s father will occupy position ($i*2) and $i’s mother
 * will occupy ($i*2)+1
 *
 * @param string $rootid
 * @param int    $maxgen
 *
 * @return array $treeid
 */
function ancestry_array($rootid, $maxgen = 0)
{
    global $PEDIGREE_GENERATIONS;
    // -- maximum size of the id array
    if ($maxgen == 0) {
        $maxgen = $PEDIGREE_GENERATIONS;
    }
    $treesize = pow(2, $maxgen);
    $treeid = array();
    $treeid[0] = "";
    $treeid[1] = $rootid;
    // -- fill in the id array
    for ($i = 1; $i < $treesize / 2; $i++) {
        $treeid[$i * 2] = false;
        // -- father
        $treeid[$i * 2 + 1] = false;
        // -- mother
        $person = WT_Individual::getInstance($treeid[$i]);
        if ($person) {
            $family = $person->getPrimaryChildFamily();
            if ($family) {
                if ($family->getHusband()) {
                    $treeid[$i * 2] = $family->getHusband()->getXref();
                }
                if ($family->getWife()) {
                    $treeid[$i * 2 + 1] = $family->getWife()->getXref();
                }
            }
        }
    }
    return $treeid;
}
Exemplo n.º 15
0
function print_media_links($factrec, $level)
{
    global $SEARCH_SPIDER, $HIDE_GEDCOM_ERRORS;
    $nlevel = $level + 1;
    if (preg_match_all("/{$level} OBJE @(.*)@/", $factrec, $omatch, PREG_SET_ORDER) == 0) {
        return;
    }
    $objectNum = 0;
    while ($objectNum < count($omatch)) {
        $media_id = $omatch[$objectNum][1];
        $media = WT_Media::getInstance($media_id);
        if ($media) {
            if ($media->canShow()) {
                if ($objectNum > 0) {
                    echo '<br class="media-separator" style="clear:both;">';
                }
                echo '<div class="media-display"><div class="media-display-image">';
                echo $media->displayImage();
                echo '</div>';
                // close div "media-display-image"
                echo '<div class="media-display-title">';
                if ($SEARCH_SPIDER) {
                    echo $media->getFullName();
                } else {
                    echo '<a href="mediaviewer.php?mid=', $media->getXref(), '&amp;ged=', WT_GEDURL, '">', $media->getFullName(), '</a>';
                }
                // NOTE: echo the notes of the media
                echo '<p>';
                echo print_fact_notes($media->getGedcom(), 1);
                $ttype = preg_match("/" . ($nlevel + 1) . " TYPE (.*)/", $media->getGedcom(), $match);
                if ($ttype > 0) {
                    $mediaType = WT_Gedcom_Tag::getFileFormTypeValue($match[1]);
                    echo '<p class="label">', WT_I18N::translate('Type'), ': </span> <span class="field">', $mediaType, '</p>';
                }
                echo '</p>';
                //-- print spouse name for marriage events
                $ct = preg_match("/WT_SPOUSE: (.*)/", $factrec, $match);
                if ($ct > 0) {
                    $spouse = WT_Individual::getInstance($match[1]);
                    if ($spouse) {
                        echo '<a href="', $spouse->getHtmlUrl(), '">';
                        echo $spouse->getFullName();
                        echo '</a>';
                    }
                    if (empty($SEARCH_SPIDER)) {
                        $ct = preg_match("/WT_FAMILY_ID: (.*)/", $factrec, $match);
                        if ($ct > 0) {
                            $famid = trim($match[1]);
                            $family = WT_Family::getInstance($famid);
                            if ($family) {
                                if ($spouse) {
                                    echo " - ";
                                }
                                echo '<a href="', $family->getHtmlUrl(), '">', WT_I18N::translate('View family'), '</a>';
                            }
                        }
                    }
                }
                echo print_fact_notes($media->getGedcom(), $nlevel);
                echo print_fact_sources($media->getGedcom(), $nlevel);
                echo '</div>';
                //close div "media-display-title"
                echo '</div>';
                //close div "media-display"
            }
        } elseif (!$HIDE_GEDCOM_ERRORS) {
            echo '<p class="ui-state-error">', $media_id, '</p>';
        }
        $objectNum++;
    }
}
Exemplo n.º 16
0
 function advancedSearch($justSql = false, $table = "individuals", $prefix = "i")
 {
     $this->myindilist = array();
     $fct = count($this->fields);
     if ($fct == 0) {
         return;
     }
     // Dynamic SQL query, plus bind variables
     $sql = "SELECT DISTINCT ind.i_id AS xref, ind.i_file AS gedcom_id, ind.i_gedcom AS gedcom FROM `##individuals` ind";
     $bind = array();
     // Join the following tables
     $father_name = false;
     $mother_name = false;
     $spouse_family = false;
     $indi_name = false;
     $indi_date = false;
     $fam_date = false;
     $indi_plac = false;
     $fam_plac = false;
     foreach ($this->fields as $n => $field) {
         if ($this->values[$n]) {
             if (substr($field, 0, 14) == 'FAMC:HUSB:NAME') {
                 $father_name = true;
             } elseif (substr($field, 0, 14) == 'FAMC:WIFE:NAME') {
                 $mother_name = true;
             } elseif (substr($field, 0, 4) == 'NAME') {
                 $indi_name = true;
             } elseif (strpos($field, ':DATE') !== false) {
                 if (substr($field, 0, 4) == 'FAMS') {
                     $fam_date = true;
                     $spouse_family = true;
                 } else {
                     $indi_date = true;
                 }
             } elseif (strpos($field, ':PLAC') !== false) {
                 if (substr($field, 0, 4) == 'FAMS') {
                     $fam_plac = true;
                     $spouse_family = true;
                 } else {
                     $indi_plac = true;
                 }
             }
         }
     }
     if ($father_name || $mother_name) {
         $sql .= " JOIN `##link`   l_1 ON (l_1.l_file=ind.i_file AND l_1.l_from=ind.i_id AND l_1.l_type='FAMC')";
     }
     if ($father_name) {
         $sql .= " JOIN `##link`   l_2 ON (l_2.l_file=ind.i_file AND l_2.l_from=l_1.l_to AND l_2.l_type='HUSB')";
         $sql .= " JOIN `##name`   f_n ON (f_n.n_file=ind.i_file AND f_n.n_id  =l_2.l_to)";
     }
     if ($mother_name) {
         $sql .= " JOIN `##link`   l_3 ON (l_3.l_file=ind.i_file AND l_3.l_from=l_1.l_to AND l_3.l_type='WIFE')";
         $sql .= " JOIN `##name`   m_n ON (m_n.n_file=ind.i_file AND m_n.n_id  =l_3.l_to)";
     }
     if ($spouse_family) {
         $sql .= " JOIN `##link`     l_4 ON (l_4.l_file=ind.i_file AND l_4.l_from=ind.i_id AND l_4.l_type='FAMS')";
         $sql .= " JOIN `##families` fam ON (fam.f_file=ind.i_file AND fam.f_id  =l_4.l_to)";
     }
     if ($indi_name) {
         $sql .= " JOIN `##name`   i_n ON (i_n.n_file=ind.i_file AND i_n.n_id=ind.i_id)";
     }
     if ($indi_date) {
         $sql .= " JOIN `##dates`  i_d ON (i_d.d_file=ind.i_file AND i_d.d_gid=ind.i_id)";
     }
     if ($fam_date) {
         $sql .= " JOIN `##dates`  f_d ON (f_d.d_file=ind.i_file AND f_d.d_gid=fam.f_id)";
     }
     if ($indi_plac) {
         $sql .= " JOIN `##placelinks`   i_pl ON (i_pl.pl_file=ind.i_file AND i_pl.pl_gid =ind.i_id)";
         $sql .= " JOIN (" . "SELECT CONCAT_WS(', ', p1.p_place, p2.p_place, p3.p_place, p4.p_place, p5.p_place, p6.p_place, p7.p_place, p8.p_place, p9.p_place) AS place, p1.p_id AS id, p1.p_file AS file" . " FROM      `##places` AS p1" . " LEFT JOIN `##places` AS p2 ON (p1.p_parent_id=p2.p_id)" . " LEFT JOIN `##places` AS p3 ON (p2.p_parent_id=p3.p_id)" . " LEFT JOIN `##places` AS p4 ON (p3.p_parent_id=p4.p_id)" . " LEFT JOIN `##places` AS p5 ON (p4.p_parent_id=p5.p_id)" . " LEFT JOIN `##places` AS p6 ON (p5.p_parent_id=p6.p_id)" . " LEFT JOIN `##places` AS p7 ON (p6.p_parent_id=p7.p_id)" . " LEFT JOIN `##places` AS p8 ON (p7.p_parent_id=p8.p_id)" . " LEFT JOIN `##places` AS p9 ON (p8.p_parent_id=p9.p_id)" . ") AS i_p ON (i_p.file  =ind.i_file AND i_pl.pl_p_id= i_p.id)";
     }
     if ($fam_plac) {
         $sql .= " JOIN `##placelinks`   f_pl ON (f_pl.pl_file=ind.i_file AND f_pl.pl_gid =fam.f_id)";
         $sql .= " JOIN (" . "SELECT CONCAT_WS(', ', p1.p_place, p2.p_place, p3.p_place, p4.p_place, p5.p_place, p6.p_place, p7.p_place, p8.p_place, p9.p_place) AS place, p1.p_id AS id, p1.p_file AS file" . " FROM      `##places` AS p1" . " LEFT JOIN `##places` AS p2 ON (p1.p_parent_id=p2.p_id)" . " LEFT JOIN `##places` AS p3 ON (p2.p_parent_id=p3.p_id)" . " LEFT JOIN `##places` AS p4 ON (p3.p_parent_id=p4.p_id)" . " LEFT JOIN `##places` AS p5 ON (p4.p_parent_id=p5.p_id)" . " LEFT JOIN `##places` AS p6 ON (p5.p_parent_id=p6.p_id)" . " LEFT JOIN `##places` AS p7 ON (p6.p_parent_id=p7.p_id)" . " LEFT JOIN `##places` AS p8 ON (p7.p_parent_id=p8.p_id)" . " LEFT JOIN `##places` AS p9 ON (p8.p_parent_id=p9.p_id)" . ") AS f_p ON (f_p.file  =ind.i_file AND f_pl.pl_p_id= f_p.id)";
     }
     // Add the where clause
     $sql .= " WHERE ind.i_file=?";
     $bind[] = WT_GED_ID;
     for ($i = 0; $i < $fct; $i++) {
         $field = $this->fields[$i];
         $value = $this->values[$i];
         if ($value === '') {
             continue;
         }
         $parts = preg_split("/:/", $field . '::::');
         if ($parts[0] == 'NAME') {
             // NAME:*
             switch ($parts[1]) {
                 case 'GIVN':
                     switch ($parts[2]) {
                         case 'EXACT':
                             $sql .= " AND i_n.n_givn=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND i_n.n_givn LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND i_n.n_givn LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_givn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_givn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_givn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_givn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                     }
                     break;
                 case 'SURN':
                     switch ($parts[2]) {
                         case 'EXACT':
                             $sql .= " AND i_n.n_surname=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND i_n.n_surname LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND i_n.n_surname LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_surn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= " AND (" . implode(' OR ', $sdx) . ")";
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_surn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_surn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= " AND (" . implode(' OR ', $sdx) . ")";
                                 break;
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_surn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                     }
                     break;
                 case 'NICK':
                 case '_MARNM':
                 case '_HEB':
                 case '_AKA':
                     $sql .= " AND i_n.n_type=? AND i_n.n_full LIKE CONCAT('%', ?, '%')";
                     $bind[] = $parts[1];
                     $bind[] = $value;
                     break;
             }
         } elseif ($parts[1] == 'DATE') {
             // *:DATE
             $date = new WT_Date($value);
             if ($date->isOK()) {
                 $jd1 = $date->date1->minJD;
                 if ($date->date2) {
                     $jd2 = $date->date2->maxJD;
                 } else {
                     $jd2 = $date->date1->maxJD;
                 }
                 if (!empty($this->plusminus[$i])) {
                     $adjd = $this->plusminus[$i] * 365;
                     //echo $jd1.":".$jd2.":".$adjd;
                     $jd1 = $jd1 - $adjd;
                     $jd2 = $jd2 + $adjd;
                 }
                 $sql .= " AND i_d.d_fact=? AND i_d.d_julianday1>=? AND i_d.d_julianday2<=?";
                 $bind[] = $parts[0];
                 $bind[] = $jd1;
                 $bind[] = $jd2;
             }
         } elseif ($parts[0] == 'FAMS' && $parts[2] == 'DATE') {
             // FAMS:*:DATE
             $date = new WT_Date($value);
             if ($date->isOK()) {
                 $jd1 = $date->date1->minJD;
                 if ($date->date2) {
                     $jd2 = $date->date2->maxJD;
                 } else {
                     $jd2 = $date->date1->maxJD;
                 }
                 if (!empty($this->plusminus[$i])) {
                     $adjd = $this->plusminus[$i] * 365;
                     //echo $jd1.":".$jd2.":".$adjd;
                     $jd1 = $jd1 - $adjd;
                     $jd2 = $jd2 + $adjd;
                 }
                 $sql .= " AND f_d.d_fact=? AND f_d.d_julianday1>=? AND f_d.d_julianday2<=?";
                 $bind[] = $parts[1];
                 $bind[] = $jd1;
                 $bind[] = $jd2;
             }
         } elseif ($parts[1] == 'PLAC') {
             // *:PLAC
             // SQL can only link a place to a person/family, not to an event.
             $sql .= " AND i_p.place LIKE CONCAT('%', ?, '%')";
             //$sql.=" AND i_p.p_place=?";
             $bind[] = $value;
         } elseif ($parts[0] == 'FAMS' && $parts[2] == 'PLAC') {
             // FAMS:*:PLAC
             // SQL can only link a place to a person/family, not to an event.
             $sql .= " AND f_p.place LIKE CONCAT('%', ?, '%')";
             $bind[] = $value;
         } elseif ($parts[0] == 'FAMC' && $parts[2] == 'NAME') {
             $table = $parts[1] == 'HUSB' ? 'f_n' : 'm_n';
             // NAME:*
             switch ($parts[3]) {
                 case 'GIVN':
                     switch ($parts[4]) {
                         case 'EXACT':
                             $sql .= " AND {$table}.n_givn=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND {$table}.n_givn LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND {$table}.n_givn LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_givn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_givn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_givn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                                 break;
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_givn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                     }
                     break;
                 case 'SURN':
                     switch ($parts[4]) {
                         case 'EXACT':
                             $sql .= " AND {$table}.n_surname=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND {$table}.n_surname LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND {$table}.n_surname LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_surn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_surn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_surn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_surn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                     }
                     break;
             }
         } elseif ($parts[0] == 'FAMS') {
             $sql .= " AND fam.f_gedcom LIKE CONCAT('%', ?, '%')";
             $bind[] = $value;
         } else {
             $sql .= " AND ind.i_gedcom LIKE CONCAT('%', ?, '%')";
             $bind[] = $value;
         }
     }
     $rows = WT_DB::prepare($sql)->execute($bind)->fetchAll();
     foreach ($rows as $row) {
         $person = WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
         // Check for XXXX:PLAC fields, which were only partially matched by SQL
         foreach ($this->fields as $n => $field) {
             if ($this->values[$n] && preg_match('/^(' . WT_REGEX_TAG . '):PLAC$/', $field, $match)) {
                 if (!preg_match('/\\n1 ' . $match[1] . '(\\n[2-9].*)*\\n2 PLAC .*' . preg_quote($this->values[$n], '/') . '/i', $person->getGedcom())) {
                     continue 2;
                 }
             }
         }
         $this->myindilist[] = $person;
     }
 }
Exemplo n.º 17
0
function add_descendancy(&$list, $pid, $parents = false, $generations = -1)
{
    $person = WT_Individual::getInstance($pid);
    if ($person == null) {
        return;
    }
    if (!isset($list[$pid])) {
        $list[$pid] = $person;
    }
    if (!isset($list[$pid]->generation)) {
        $list[$pid]->generation = 0;
    }
    foreach ($person->getSpouseFamilies() as $family) {
        if ($parents) {
            $husband = $family->getHusband();
            $wife = $family->getWife();
            if ($husband) {
                $list[$husband->getXref()] = $husband;
                if (isset($list[$pid]->generation)) {
                    $list[$husband->getXref()]->generation = $list[$pid]->generation - 1;
                } else {
                    $list[$husband->getXref()]->generation = 1;
                }
            }
            if ($wife) {
                $list[$wife->getXref()] = $wife;
                if (isset($list[$pid]->generation)) {
                    $list[$wife->getXref()]->generation = $list[$pid]->generation - 1;
                } else {
                    $list[$wife->getXref()]->generation = 1;
                }
            }
        }
        $children = $family->getChildren();
        foreach ($children as $child) {
            if ($child) {
                $list[$child->getXref()] = $child;
                if (isset($list[$pid]->generation)) {
                    $list[$child->getXref()]->generation = $list[$pid]->generation + 1;
                } else {
                    $list[$child->getXref()]->generation = 2;
                }
            }
        }
        if ($generations == -1 || $list[$pid]->generation + 1 < $generations) {
            foreach ($children as $child) {
                add_descendancy($list, $child->getXref(), $parents, $generations);
                // recurse on the childs family
            }
        }
    }
}
Exemplo n.º 18
0
 /**
  * Get the thumbnail image for the given person
  *
  * @param WT_Individual $individual
  *
  * @return string
  */
 private function getThumbnail(WT_Individual $individual)
 {
     global $SHOW_HIGHLIGHT_IMAGES;
     if ($SHOW_HIGHLIGHT_IMAGES) {
         return $individual->displayImage();
     } else {
         return '';
     }
 }
Exemplo n.º 19
0
 public function getSignificantIndividual()
 {
     if ($this->pids) {
         return WT_Individual::getInstance($this->pids[0]);
     } else {
         return parent::getSignificantIndividual();
     }
 }
Exemplo n.º 20
0
 /**
  * Generate both the HTML and PNG components of the fan chart
  *
  * The HTML and PNG components both require the same co-ordinate calculations,
  * so we generate them using the same code, but we send them in separate
  * HTTP requests.
  *
  * @param string   $what     "png" or "html"
  * @param string[] $fanChart Presentation parameters, provided by the theme.
  *
  * @return string
  */
 public function generate_fan_chart($what, $fanChart)
 {
     $treeid = ancestry_array($this->root->getXref(), $this->generations);
     $fanw = 640 * $this->fan_width / 100;
     $fandeg = 90 * $this->fan_style;
     $html = '';
     $treesize = count($treeid);
     // generations count
     $gen = log($treesize) / log(2) - 1;
     $sosa = $treesize - 1;
     // fan size
     if ($fandeg == 0) {
         $fandeg = 360;
     }
     $fandeg = min($fandeg, 360);
     $fandeg = max($fandeg, 90);
     $cx = $fanw / 2 - 1;
     // center x
     $cy = $cx;
     // center y
     $rx = $fanw - 1;
     $rw = $fanw / ($gen + 1);
     $fanh = $fanw;
     // fan height
     if ($fandeg == 180) {
         $fanh = round($fanh * ($gen + 1) / ($gen * 2));
     }
     if ($fandeg == 270) {
         $fanh = round($fanh * 0.86);
     }
     $scale = $fanw / 640;
     // image init
     $image = ImageCreate($fanw, $fanh);
     $white = ImageColorAllocate($image, 0xff, 0xff, 0xff);
     ImageFilledRectangle($image, 0, 0, $fanw, $fanh, $white);
     ImageColorTransparent($image, $white);
     $color = ImageColorAllocate($image, hexdec(substr($fanChart['color'], 1, 2)), hexdec(substr($fanChart['color'], 3, 2)), hexdec(substr($fanChart['color'], 5, 2)));
     $bgcolor = ImageColorAllocate($image, hexdec(substr($fanChart['bgColor'], 1, 2)), hexdec(substr($fanChart['bgColor'], 3, 2)), hexdec(substr($fanChart['bgColor'], 5, 2)));
     $bgcolorM = ImageColorAllocate($image, hexdec(substr($fanChart['bgMColor'], 1, 2)), hexdec(substr($fanChart['bgMColor'], 3, 2)), hexdec(substr($fanChart['bgMColor'], 5, 2)));
     $bgcolorF = ImageColorAllocate($image, hexdec(substr($fanChart['bgFColor'], 1, 2)), hexdec(substr($fanChart['bgFColor'], 3, 2)), hexdec(substr($fanChart['bgFColor'], 5, 2)));
     // imagemap
     $imagemap = '<map id="fanmap" name="fanmap">';
     // loop to create fan cells
     while ($gen >= 0) {
         // clean current generation area
         $deg2 = 360 + ($fandeg - 180) / 2;
         $deg1 = $deg2 - $fandeg;
         ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bgcolor, IMG_ARC_PIE);
         $rx -= 3;
         // calculate new angle
         $p2 = pow(2, $gen);
         $angle = $fandeg / $p2;
         $deg2 = 360 + ($fandeg - 180) / 2;
         $deg1 = $deg2 - $angle;
         // special case for rootid cell
         if ($gen == 0) {
             $deg1 = 90;
             $deg2 = 360 + $deg1;
         }
         // draw each cell
         while ($sosa >= $p2) {
             $pid = $treeid[$sosa];
             $person = WT_Individual::getInstance($pid);
             if ($person) {
                 $name = $person->getFullName();
                 $addname = $person->getAddName();
                 $text = WT_I18N::reverseText($name);
                 if ($addname) {
                     $text .= "\n" . WT_I18N::reverseText($addname);
                 }
                 $text .= "\n" . WT_I18N::reverseText($person->getLifeSpan());
                 switch ($person->getSex()) {
                     case 'M':
                         $bg = $bgcolorM;
                         break;
                     case 'F':
                         $bg = $bgcolorF;
                         break;
                     case 'U':
                         $bg = $bgcolor;
                         break;
                 }
                 ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bg, IMG_ARC_PIE);
                 // split and center text by lines
                 $wmax = (int) ($angle * 7 / $fanChart['size'] * $scale);
                 $wmax = min($wmax, 35 * $scale);
                 if ($gen == 0) {
                     $wmax = min($wmax, 17 * $scale);
                 }
                 $text = $this->split_align_text($text, $wmax);
                 // text angle
                 $tangle = 270 - ($deg1 + $angle / 2);
                 if ($gen == 0) {
                     $tangle = 0;
                 }
                 // calculate text position
                 $deg = $deg1 + 0.44;
                 if ($deg2 - $deg1 > 40) {
                     $deg = $deg1 + ($deg2 - $deg1) / 11;
                 }
                 if ($deg2 - $deg1 > 80) {
                     $deg = $deg1 + ($deg2 - $deg1) / 7;
                 }
                 if ($deg2 - $deg1 > 140) {
                     $deg = $deg1 + ($deg2 - $deg1) / 4;
                 }
                 if ($gen == 0) {
                     $deg = 180;
                 }
                 $rad = deg2rad($deg);
                 $mr = ($rx - $rw / 4) / 2;
                 if ($gen > 0 && $deg2 - $deg1 > 80) {
                     $mr = $rx / 2;
                 }
                 $tx = $cx + $mr * cos($rad);
                 $ty = $cy - $mr * -sin($rad);
                 if ($sosa == 1) {
                     $ty -= $mr / 2;
                 }
                 // print text
                 ImageTtfText($image, (double) $fanChart['size'], $tangle, $tx, $ty, $color, $fanChart['font'], $text);
                 $imagemap .= '<area shape="poly" coords="';
                 // plot upper points
                 $mr = $rx / 2;
                 $deg = $deg1;
                 while ($deg <= $deg2) {
                     $rad = deg2rad($deg);
                     $tx = round($cx + $mr * cos($rad));
                     $ty = round($cy - $mr * -sin($rad));
                     $imagemap .= "{$tx},{$ty},";
                     $deg += ($deg2 - $deg1) / 6;
                 }
                 // plot lower points
                 $mr = ($rx - $rw) / 2;
                 $deg = $deg2;
                 while ($deg >= $deg1) {
                     $rad = deg2rad($deg);
                     $tx = round($cx + $mr * cos($rad));
                     $ty = round($cy - $mr * -sin($rad));
                     $imagemap .= "{$tx},{$ty},";
                     $deg -= ($deg2 - $deg1) / 6;
                 }
                 // join first point
                 $mr = $rx / 2;
                 $deg = $deg1;
                 $rad = deg2rad($deg);
                 $tx = round($cx + $mr * cos($rad));
                 $ty = round($cy - $mr * -sin($rad));
                 $imagemap .= "{$tx},{$ty}";
                 // add action url
                 $imagemap .= '" href="#' . $pid . '"';
                 $tempURL = 'fanchart.php?rootid=' . $pid . '&amp;generations=' . $this->generations . '&amp;fan_width=' . $this->fan_width . '&amp;fan_style=' . $this->fan_style . '&amp;ged=' . WT_GEDURL;
                 $html .= '<div id="' . $pid . '" class="fan_chart_menu">';
                 $html .= '<div class="person_box"><div class="details1">';
                 $html .= '<a href="' . $person->getHtmlUrl() . '" class="name1">' . $name;
                 if ($addname) {
                     $html .= $addname;
                 }
                 $html .= '</a>';
                 $html .= '<ul class="charts">';
                 $html .= "<li><a href=\"pedigree.php?rootid={$pid}&amp;amp;ged=" . WT_GEDURL . "\" >" . WT_I18N::translate('Pedigree') . "</a></li>";
                 if (array_key_exists('googlemap', WT_Module::getActiveModules())) {
                     $html .= "<li><a href=\"module.php?mod=googlemap&amp;mod_action=pedigree_map&amp;rootid=" . $pid . "&amp;ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Pedigree map') . "</a></li>";
                 }
                 if (WT_USER_GEDCOM_ID && WT_USER_GEDCOM_ID != $pid) {
                     $html .= "<li><a href=\"relationship.php?pid1=" . WT_USER_GEDCOM_ID . "&amp;pid2={$pid}&amp;ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Relationship to me') . "</a></li>";
                 }
                 $html .= "<li><a href=\"descendancy.php?rootid={$pid}&amp;ged=" . WT_GEDURL . "\" >" . WT_I18N::translate('Descendants') . "</a></li>";
                 $html .= "<li><a href=\"ancestry.php?rootid={$pid}&amp;ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Ancestors') . "</a></li>";
                 $html .= "<li><a href=\"compact.php?rootid={$pid}&amp;ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Compact tree') . "</a></li>";
                 $html .= "<li><a href=\"" . $tempURL . "\">" . WT_I18N::translate('Fan chart') . "</a></li>";
                 $html .= "<li><a href=\"hourglass.php?rootid={$pid}&amp;ged=" . WT_GEDURL . "\">" . WT_I18N::translate('Hourglass chart') . "</a></li>";
                 if (array_key_exists('tree', WT_Module::getActiveModules())) {
                     $html .= '<li><a href="module.php?mod=tree&amp;mod_action=treeview&amp;ged=' . WT_GEDURL . '&amp;rootid=' . $pid . '">' . WT_I18N::translate('Interactive tree') . '</a></li>';
                 }
                 $html .= '</ul>';
                 // spouse(s) and children
                 foreach ($person->getSpouseFamilies() as $family) {
                     $spouse = $family->getSpouse($person);
                     if ($spouse) {
                         $html .= '<a href="' . $spouse->getHtmlUrl() . '" class="name1">' . $spouse->getFullName() . '</a>';
                         $kids = $family->getChildren();
                         if ($kids) {
                             $html .= '<ul class="children">';
                             foreach ($kids as $child) {
                                 $html .= '<li><a href="' . $child->getHtmlUrl() . '" class="name1">' . $child->getFullName() . '</a></li>';
                             }
                             $html .= '</ul>';
                         }
                     }
                 }
                 // siblings
                 foreach ($person->getChildFamilies() as $family) {
                     $children = $family->getChildren();
                     if ($children) {
                         $html .= '<div class="name1">' . WT_I18N::plural('Sibling', 'Siblings', count($children) - 1) . '</div>';
                         $html .= '<ul class="siblings">';
                         foreach ($children as $sibling) {
                             if ($sibling !== $person) {
                                 $html .= '<li><a href="' . $sibling->getHtmlUrl() . '" class="name1"> ' . $sibling->getFullName() . '</a></li>';
                             }
                         }
                         $html .= '</ul>';
                     }
                 }
                 $html .= '</div></div>';
                 $html .= '</div>';
                 $imagemap .= ' alt="' . strip_tags($person->getFullName()) . '" title="' . strip_tags($person->getFullName()) . '">';
             }
             $deg1 -= $angle;
             $deg2 -= $angle;
             $sosa--;
         }
         $rx -= $rw;
         $gen--;
     }
     $imagemap .= '</map>';
     switch ($what) {
         case 'html':
             $image_title = WT_I18N::translate('Fan chart of %s', strip_tags($person->getFullName()));
             return $html . $imagemap . '<div id="fan_chart_img"><img src="' . WT_SCRIPT_NAME . '?rootid=' . $this->rootid . '&amp;fan_style=' . $this->fan_style . '&amp;generations=' . $this->generations . '&amp;fan_width=' . $this->fan_width . '&amp;img=1" width="' . $fanw . '" height="' . $fanh . '" alt="' . $image_title . '" title="' . $image_title . '" usemap="#fanmap"></div>';
         case 'png':
             header('Content-Type: image/png');
             ImageStringUp($image, 1, $fanw - 10, $fanh / 3, WT_SERVER_NAME . WT_SCRIPT_PATH, $color);
             ImagePng($image);
             ImageDestroy($image);
     }
 }
Exemplo n.º 21
0
 /**
  * Find all the families that are descended from an individual.
  *
  * @param WT_Individual $person
  * @param int           $n
  * @param WT_Family[]   $array
  *
  * @return WT_Family[]
  */
 public function fam_desc($person, $n, $array)
 {
     if ($n < 1) {
         return $array;
     }
     foreach ($person->getSpouseFamilies() as $family) {
         $array[$family->getXref()] = $family;
         foreach ($family->getChildren() as $child) {
             $array = $this->fam_desc($child, $n - 1, $array);
         }
     }
     return $array;
 }
Exemplo n.º 22
0
    global $tags, $values;
    $indexes = $tags[$tag];
    $vals = array();
    foreach ($indexes as $i) {
        $vals[] = $values[$i];
    }
    return $vals;
}
//-- setup the arrays
$newvars = array();
foreach ($vars as $name => $var) {
    $newvars[$name]['id'] = $var;
    if (!empty($type[$name])) {
        switch ($type[$name]) {
            case 'INDI':
                $record = WT_Individual::getInstance($var);
                if ($record && $record->canShowName()) {
                    $newvars[$name]['gedcom'] = $record->privatizeGedcom(WT_USER_ACCESS_LEVEL);
                } else {
                    $action = 'setup';
                }
                break;
            case 'FAM':
                $record = WT_Family::getInstance($var);
                if ($record && $record->canShowName()) {
                    $newvars[$name]['gedcom'] = $record->privatizeGedcom(WT_USER_ACCESS_LEVEL);
                } else {
                    $action = 'setup';
                }
                break;
            case 'SOUR':
Exemplo n.º 23
0
 public static function getChartsMenu()
 {
     global $SEARCH_SPIDER, $controller;
     if ($SEARCH_SPIDER || !WT_GED_ID) {
         return null;
     }
     $indi_xref = $controller->getSignificantIndividual()->getXref();
     $menu = new WT_Menu(WT_I18N::translate('Charts'), 'pedigree.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart');
     // Build a sortable list of submenu items and then sort it in localized name order
     $menuList = array('pedigree' => WT_I18N::translate('Pedigree'), 'descendancy' => WT_I18N::translate('Descendants'), 'ancestry' => WT_I18N::translate('Ancestors'), 'compact' => WT_I18N::translate('Compact tree'), 'hourglass' => WT_I18N::translate('Hourglass chart'), 'familybook' => WT_I18N::translate('Family book'), 'timeline' => WT_I18N::translate('Timeline'), 'lifespan' => WT_I18N::translate('Lifespans'), 'relationship' => WT_I18N::translate('Relationships'), 'statistics' => WT_I18N::translate('Statistics'));
     if (function_exists('imagettftext')) {
         $menuList['fanchart'] = WT_I18N::translate('Fan chart');
     }
     // TODO: Use WT_Module_Chart ??
     if (array_key_exists('tree', WT_Module::getActiveModules())) {
         $menuList['tree'] = WT_I18N::translate('Interactive tree');
     }
     if (array_key_exists('googlemap', WT_Module::getActiveModules())) {
         $menuList['pedigree_map'] = WT_I18N::translate('Pedigree map');
     }
     asort($menuList);
     // Produce the submenus in localized name order
     foreach ($menuList as $menuType => $menuName) {
         switch ($menuType) {
             case 'pedigree':
                 $submenu = new WT_Menu($menuName, 'pedigree.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-pedigree');
                 $menu->addSubmenu($submenu);
                 break;
             case 'descendancy':
                 $submenu = new WT_Menu($menuName, 'descendancy.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-descendancy');
                 $menu->addSubmenu($submenu);
                 break;
             case 'ancestry':
                 $submenu = new WT_Menu($menuName, 'ancestry.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-ancestry');
                 $menu->addSubmenu($submenu);
                 break;
             case 'compact':
                 $submenu = new WT_Menu($menuName, 'compact.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-compact');
                 $menu->addSubmenu($submenu);
                 break;
             case 'fanchart':
                 $submenu = new WT_Menu($menuName, 'fanchart.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-fanchart');
                 $menu->addSubmenu($submenu);
                 break;
             case 'hourglass':
                 $submenu = new WT_Menu($menuName, 'hourglass.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-hourglass');
                 $menu->addSubmenu($submenu);
                 break;
             case 'familybook':
                 $submenu = new WT_Menu($menuName, 'familybook.php?rootid=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-familybook');
                 $menu->addSubmenu($submenu);
                 break;
             case 'timeline':
                 $submenu = new WT_Menu($menuName, 'timeline.php?pids%5B%5D=' . $indi_xref . '&amp;ged=' . WT_GEDURL, 'menu-chart-timeline');
                 if ($controller instanceof WT_Controller_Family && $controller->record) {
                     // Build a sortable list of submenu items and then sort it in localized name order
                     $menuList = array();
                     $menuList['parentTimeLine'] = WT_I18N::translate('Show couple on timeline chart');
                     $menuList['childTimeLine'] = WT_I18N::translate('Show children on timeline chart');
                     $menuList['familyTimeLine'] = WT_I18N::translate('Show family on timeline chart');
                     asort($menuList);
                     // Produce the submenus in localized name order
                     foreach ($menuList as $submenuType => $submenuName) {
                         switch ($submenuType) {
                             case 'parentTimeLine':
                                 // charts / parents_timeline
                                 $subsubmenu = new WT_Menu($submenuName, 'timeline.php?' . $controller->getTimelineIndis(array('HUSB', 'WIFE')) . '&amp;ged=' . WT_GEDURL, 'menu-chart-timeline-parents');
                                 $submenu->addSubmenu($subsubmenu);
                                 break;
                             case 'childTimeLine':
                                 // charts / children_timeline
                                 $subsubmenu = new WT_Menu($submenuName, 'timeline.php?' . $controller->getTimelineIndis(array('CHIL')) . '&amp;ged=' . WT_GEDURL, 'menu-chart-timeline-children');
                                 $submenu->addSubmenu($subsubmenu);
                                 break;
                             case 'familyTimeLine':
                                 // charts / family_timeline
                                 $subsubmenu = new WT_Menu($submenuName, 'timeline.php?' . $controller->getTimelineIndis(array('HUSB', 'WIFE', 'CHIL')) . '&amp;ged=' . WT_GEDURL, 'menu-chart-timeline-family');
                                 $submenu->addSubmenu($subsubmenu);
                                 break;
                         }
                     }
                 }
                 $menu->addSubmenu($submenu);
                 break;
             case 'lifespan':
                 $submenu = new WT_Menu($menuName, 'lifespan.php?pids%5B%5D=' . $indi_xref . '&amp;addFamily=1&amp;ged=' . WT_GEDURL, 'menu-chart-lifespan');
                 $menu->addSubmenu($submenu);
                 break;
             case 'relationship':
                 if ($indi_xref) {
                     // Pages focused on a specific person - from the person, to me
                     $pid1 = WT_USER_GEDCOM_ID ? WT_USER_GEDCOM_ID : WT_USER_ROOT_ID;
                     $pid2 = $indi_xref;
                     if ($pid1 == $pid2) {
                         $pid2 = '';
                     }
                     $submenu = new WT_Menu(WT_I18N::translate('Relationships'), 'relationship.php?pid1=' . $pid1 . '&amp;pid2=' . $pid2 . '&amp;ged=' . WT_GEDURL, 'menu-chart-relationship');
                     if (array_key_exists('user_favorites', WT_Module::getActiveModules())) {
                         // Add a submenu showing relationship from this person to each of our favorites
                         foreach (user_favorites_WT_Module::getFavorites(WT_USER_ID) as $favorite) {
                             if ($favorite['type'] == 'INDI' && $favorite['gedcom_id'] == WT_GED_ID) {
                                 $person = WT_Individual::getInstance($favorite['gid']);
                                 if ($person instanceof WT_Individual) {
                                     $subsubmenu = new WT_Menu($person->getFullName(), 'relationship.php?pid1=' . $person->getXref() . '&amp;pid2=' . $pid2 . '&amp;ged=' . WT_GEDURL, 'menu-chart-relationship-' . $person->getXref() . '-' . $pid2);
                                     $submenu->addSubmenu($subsubmenu);
                                 }
                             }
                         }
                     }
                 } else {
                     // Regular pages - from me, to somebody
                     $pid1 = WT_USER_GEDCOM_ID ? WT_USER_GEDCOM_ID : WT_USER_ROOT_ID;
                     $pid2 = '';
                     $submenu = new WT_Menu(WT_I18N::translate('Relationships'), 'relationship.php?pid1=' . $pid1 . '&amp;pid2=' . $pid2 . '&amp;ged=' . WT_GEDURL, 'menu-chart-relationship');
                 }
                 $menu->addSubmenu($submenu);
                 break;
             case 'statistics':
                 $submenu = new WT_Menu($menuName, 'statistics.php?ged=' . WT_GEDURL, 'menu-chart-statistics');
                 $menu->addSubmenu($submenu);
                 break;
             case 'tree':
                 $submenu = new WT_Menu($menuName, 'module.php?mod=tree&amp;mod_action=treeview&amp;ged=' . WT_GEDURL . '&amp;rootid=' . $indi_xref, 'menu-chart-tree');
                 $menu->addSubmenu($submenu);
                 break;
             case 'pedigree_map':
                 $submenu = new WT_Menu($menuName, 'module.php?ged=' . WT_GEDURL . '&amp;mod=googlemap&amp;mod_action=pedigree_map&amp;rootid=' . $indi_xref, 'menu-chart-pedigree_map');
                 $menu->addSubmenu($submenu);
                 break;
         }
     }
     return $menu;
 }
Exemplo n.º 24
0
 public function getCartList()
 {
     global $WT_SESSION;
     // Keep track of the INDI from the parent page, otherwise it will
     // get lost after ajax updates
     $pid = WT_Filter::get('pid', WT_REGEX_XREF);
     if (!$WT_SESSION->cart[WT_GED_ID]) {
         $out = WT_I18N::translate('Your clippings cart is empty.');
     } else {
         $out = '<ul>';
         foreach (array_keys($WT_SESSION->cart[WT_GED_ID]) as $xref) {
             $record = WT_GedcomRecord::getInstance($xref);
             if ($record && ($record::RECORD_TYPE == 'INDI' || $record::RECORD_TYPE == 'FAM')) {
                 // Just show INDI/FAM in the sidbar
                 switch ($record::RECORD_TYPE) {
                     case 'INDI':
                         $icon = 'icon-indis';
                         break;
                     case 'FAM':
                         $icon = 'icon-sfamily';
                         break;
                 }
                 $out .= '<li>';
                 if (!empty($icon)) {
                     $out .= '<i class="' . $icon . '"></i>';
                 }
                 $out .= '<a href="' . $record->getHtmlUrl() . '">';
                 if ($record::RECORD_TYPE == 'INDI') {
                     $out .= $record->getSexImage();
                 }
                 $out .= ' ' . $record->getFullName() . ' ';
                 if ($record::RECORD_TYPE == 'INDI' && $record->canShow()) {
                     $out .= ' (' . $record->getLifeSpan() . ')';
                 }
                 $out .= '</a>';
                 $out .= '<a class="icon-remove remove_cart" href="module.php?mod=' . $this->getName() . '&amp;mod_action=ajax&amp;sb_action=clippings&amp;remove=' . $xref . '&amp;pid=' . $pid . '" title="' . WT_I18N::translate('Remove') . '"></a>';
                 $out .= '</li>';
             }
         }
         $out .= '</ul>';
     }
     if ($WT_SESSION->cart[WT_GED_ID]) {
         $out .= '<br><a href="module.php?mod=' . $this->getName() . '&amp;mod_action=ajax&amp;sb_action=clippings&amp;empty=true&amp;pid=' . $pid . '" class="remove_cart">' . WT_I18N::translate('Empty the clippings cart') . '</a>' . help_link('empty_cart', $this->getName()) . '<br>' . '<a href="module.php?mod=' . $this->getName() . '&amp;mod_action=ajax&amp;sb_action=clippings&amp;download=true&amp;pid=' . $pid . '" class="add_cart">' . WT_I18N::translate('Download') . '</a>';
     }
     $record = WT_Individual::getInstance($pid);
     if ($record && !array_key_exists($record->getXref(), $WT_SESSION->cart[WT_GED_ID])) {
         $out .= '<br><a href="module.php?mod=' . $this->getName() . '&amp;mod_action=ajax&amp;sb_action=clippings&amp;add=' . $pid . '&amp;pid=' . $pid . '" class="add_cart"><i class="icon-clippings"></i> ' . WT_I18N::translate('Add %s to the clippings cart', $record->getFullName()) . '</a>';
     }
     return $out;
 }
Exemplo n.º 25
0
 /**
  * Fetch a list of individuals with specified names
  *
  * To search for unknown names, use $surn="@N.N.", $salpha="@" or $galpha="@"
  * To search for names with no surnames, use $salpha=","
  *
  * @param string $surn   if set, only fetch people with this surname
  * @param string $salpha if set, only fetch surnames starting with this letter
  * @param string $galpha if set, only fetch given names starting with this letter
  * @param bool   $marnm  if set, include married names
  * @param bool   $fams   if set, only fetch individuals with FAMS records
  * @param int    $ged_id if set, only fetch individuals from this gedcom
  *
  * @return WT_Individual[]
  */
 public static function individuals($surn, $salpha, $galpha, $marnm, $fams, $ged_id)
 {
     $sql = "SELECT i_id AS xref, i_file AS gedcom_id, i_gedcom AS gedcom, n_full " . "FROM `##individuals` " . "JOIN `##name` ON (n_id=i_id AND n_file=i_file) " . ($fams ? "JOIN `##link` ON (n_id=l_from AND n_file=l_file AND l_type='FAMS') " : "") . "WHERE n_file={$ged_id} " . ($marnm ? "" : "AND n_type!='_MARNM'");
     if ($surn) {
         $sql .= " AND n_surn COLLATE '" . WT_I18N::$collation . "'=" . WT_DB::quote($surn);
     } elseif ($salpha == ',') {
         $sql .= " AND n_surn=''";
     } elseif ($salpha == '@') {
         $sql .= " AND n_surn='@N.N.'";
     } elseif ($salpha) {
         $sql .= " AND " . self::_getInitialSql('n_surn', $salpha);
     } else {
         // All surnames
         $sql .= " AND n_surn NOT IN ('', '@N.N.')";
     }
     if ($galpha) {
         $sql .= " AND " . self::_getInitialSql('n_givn', $galpha);
     }
     $sql .= " ORDER BY CASE n_surn WHEN '@N.N.' THEN 1 ELSE 0 END, n_surn COLLATE '" . WT_I18N::$collation . "', CASE n_givn WHEN '@P.N.' THEN 1 ELSE 0 END, n_givn COLLATE '" . WT_I18N::$collation . "'";
     $list = array();
     $rows = WT_DB::prepare($sql)->fetchAll();
     foreach ($rows as $row) {
         $person = WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
         // The name from the database may be private - check the filtered list...
         foreach ($person->getAllNames() as $n => $name) {
             if ($name['fullNN'] == $row->n_full) {
                 $person->setPrimaryName($n);
                 // We need to clone $person, as we may have multiple references to the
                 // same person in this list, and the "primary name" would otherwise
                 // be shared amongst all of them.
                 $list[] = clone $person;
                 break;
             }
         }
     }
     return $list;
 }
Exemplo n.º 26
0
 /**
  * Calculates number of generations a person has
  *
  * @param string $pid ID of person to see how far down the descendency goes
  * @param int    $depth Pass in 0 and it calculates how far down descendency goes
  *
  * @return int Number of generations the descendency actually goes
  */
 function max_descendency_generations($pid, $depth)
 {
     if ($depth > $this->generations) {
         return $depth;
     }
     $person = WT_Individual::getInstance($pid);
     if (is_null($person)) {
         return $depth;
     }
     $maxdc = $depth;
     foreach ($person->getSpouseFamilies() as $family) {
         foreach ($family->getChildren() as $child) {
             $dc = $this->max_descendency_generations($child->getXref(), $depth + 1);
             if ($dc >= $this->generations) {
                 return $dc;
             }
             if ($dc > $maxdc) {
                 $maxdc = $dc;
             }
         }
     }
     $maxdc++;
     if ($maxdc == 1) {
         $maxdc++;
     }
     return $maxdc;
 }
Exemplo n.º 27
0
 public function getSignificantIndividual()
 {
     static $individual;
     // Only query the DB once.
     if (!$individual && WT_USER_ROOT_ID) {
         $individual = WT_Individual::getInstance(WT_USER_ROOT_ID);
     }
     if (!$individual && WT_USER_GEDCOM_ID) {
         $individual = WT_Individual::getInstance(WT_USER_GEDCOM_ID);
     }
     if (!$individual) {
         $individual = WT_Individual::getInstance(get_gedcom_setting(WT_GED_ID, 'PEDIGREE_ROOT_ID'));
     }
     if (!$individual) {
         $individual = WT_Individual::getInstance(WT_DB::prepare("SELECT MIN(i_id) FROM `##individuals` WHERE i_file=?")->execute(array(WT_GED_ID))->fetchOne());
     }
     if (!$individual) {
         // always return a record
         $individual = new WT_Individual('I', '0 @I@ INDI', null, WT_GED_ID);
     }
     return $individual;
 }
Exemplo n.º 28
0
function get_calendar_events($jd1, $jd2, $facts = '', $ged_id = WT_GED_ID)
{
    // If no facts specified, get all except these
    $skipfacts = "CHAN,BAPL,SLGC,SLGS,ENDL,CENS,RESI,NOTE,ADDR,OBJE,SOUR,PAGE,DATA,TEXT";
    if ($facts != '_TODO') {
        $skipfacts .= ',_TODO';
    }
    $found_facts = array();
    // Events that start or end during the period
    $where = "WHERE (d_julianday1>={$jd1} AND d_julianday1<={$jd2} OR d_julianday2>={$jd1} AND d_julianday2<={$jd2})";
    // Restrict to certain types of fact
    if (empty($facts)) {
        $excl_facts = "'" . preg_replace('/\\W+/', "','", $skipfacts) . "'";
        $where .= " AND d_fact NOT IN ({$excl_facts})";
    } else {
        $incl_facts = "'" . preg_replace('/\\W+/', "','", $facts) . "'";
        $where .= " AND d_fact IN ({$incl_facts})";
    }
    // Only get events from the current gedcom
    $where .= " AND d_file=" . $ged_id;
    // Now fetch these events
    $ind_sql = "SELECT d_gid AS xref, i_file AS gedcom_id, i_gedcom AS gedcom, 'INDI' AS type, d_type, d_day, d_month, d_year, d_fact, d_type FROM `##dates`, `##individuals` {$where} AND d_gid=i_id AND d_file=i_file GROUP BY d_julianday1, d_gid ORDER BY d_julianday1";
    $fam_sql = "SELECT d_gid AS xref, f_file AS gedcom_id, f_gedcom AS gedcom, 'FAM'  AS type, d_type, d_day, d_month, d_year, d_fact, d_type FROM `##dates`, `##families`    {$where} AND d_gid=f_id AND d_file=f_file GROUP BY d_julianday1, d_gid ORDER BY d_julianday1";
    foreach (array($ind_sql, $fam_sql) as $sql) {
        $rows = WT_DB::prepare($sql)->fetchAll();
        foreach ($rows as $row) {
            if ($row->type == 'INDI') {
                $record = WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
            } else {
                $record = WT_Family::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
            }
            $anniv_date = new WT_Date($row->d_type . ' ' . $row->d_day . ' ' . $row->d_month . ' ' . $row->d_year);
            foreach ($record->getFacts(str_replace(' ', '|', $facts)) as $fact) {
                if ($fact->getDate() == $anniv_date) {
                    $fact->anniv = 0;
                    $found_facts[] = $fact;
                }
            }
        }
    }
    return $found_facts;
}
Exemplo n.º 29
-1
 protected function _canShowByType($access_level)
 {
     // Hide a family if any member is private
     preg_match_all('/\\n1 (?:CHIL|HUSB|WIFE) @(' . WT_REGEX_XREF . ')@/', $this->gedcom, $matches);
     foreach ($matches[1] as $match) {
         $person = WT_Individual::getInstance($match);
         if ($person && !$person->canShow($access_level)) {
             return false;
         }
     }
     return true;
 }
Exemplo n.º 30
-1
/**
 * print the information for an individual chart box
 *
 * find and print a given individuals information for a pedigree chart
 *
 * @param string $pid The Gedcom Xref ID of the individual  to print
 * @param string $currpid
 * @param string $censyear
 *
 */
function print_pedigree_person_nav2($pid, $currpid, $censyear)
{
    global $PEDIGREE_FULL_DETAILS;
    global $TEXT_DIRECTION, $DEFAULT_PEDIGREE_GENERATIONS, $OLD_PGENS, $talloffset, $PEDIGREE_LAYOUT;
    global $show_full;
    global $SEARCH_SPIDER;
    global $spouselinks, $parentlinks, $step_parentlinks, $persons, $person_step, $person_parent;
    global $natdad, $natmom, $censyear;
    if (empty($show_full)) {
        $show_full = 0;
    }
    if (empty($PEDIGREE_FULL_DETAILS)) {
        $PEDIGREE_FULL_DETAILS = 0;
    }
    if (!isset($OLD_PGENS)) {
        $OLD_PGENS = $DEFAULT_PEDIGREE_GENERATIONS;
    }
    if (!isset($talloffset)) {
        $talloffset = $PEDIGREE_LAYOUT;
    }
    $person = WT_Individual::getInstance($pid);
    if ($pid == false || empty($person)) {
        $spouselinks = false;
        $parentlinks = false;
        $step_parentlinks = false;
    }
    $tmp = array('M' => '', 'F' => 'F', 'U' => 'NN');
    $isF = $tmp[$person->getSex()];
    $spouselinks = "";
    $parentlinks = "";
    $step_parentlinks = "";
    if ($person->canShowName() && !$SEARCH_SPIDER) {
        //-- draw a box for the family popup
        if ($TEXT_DIRECTION == "rtl") {
            $spouselinks .= "<table class=\"rtlnav person_box{$isF}\"><tr><td align=\"right\" style=\"font-size:10px;font-weight:normal;\" class=\"name2 nowrap\">";
            $spouselinks .= "<b>" . WT_I18N::translate('Family') . "</b> (" . $person->getFullName() . ")<br>";
            $parentlinks .= "<table class=\"rtlnav person_box{$isF}\"><tr><td align=\"right\" style=\"font-size:10px;font-weight:normal;\" class=\"name2 nowrap\">";
            $parentlinks .= "<b>" . WT_I18N::translate('Parents') . "</b> (" . $person->getFullName() . ")<br>";
            $step_parentlinks .= "<table class=\"rtlnav person_box{$isF}\"><tr><td align=\"right\" style=\"font-size:10px;font-weight:normal;\" class=\"name2 nowrap\">";
            $step_parentlinks .= "<b>" . WT_I18N::translate('Parents') . "</b> (" . $person->getFullName() . ")<br>";
        } else {
            $spouselinks .= "<table class=\"ltrnav person_box{$isF}\"><tr><td align=\"left\" style=\"font-size:10px;font-weight:normal;\" class=\"name2 nowrap\">";
            $spouselinks .= "<b>" . WT_I18N::translate('Family') . "</b> (" . $person->getFullName() . ")<br>";
            $parentlinks .= "<table class=\"ltrnav person_box{$isF}\"><tr><td align=\"left\" style=\"font-size:10px;font-weight:normal;\" class=\"name2 nowrap\">";
            $parentlinks .= "<b>" . WT_I18N::translate('Parents') . "</b> (" . $person->getFullName() . ")<br>";
            $step_parentlinks .= "<table class=\"ltrnav person_box{$isF}\"><tr><td align=\"left\" style=\"font-size:10px;font-weight:normal;\" class=\"name2 nowrap\">";
            $step_parentlinks .= "<b>" . WT_I18N::translate('Parents') . "</b> (" . $person->getFullName() . ")<br>";
        }
        $persons = "";
        $person_parent = "";
        $person_step = "";
        //-- Parent families --------------------------------------
        foreach ($person->getChildFamilies() as $family) {
            $husb = $family->getHusband();
            $wife = $family->getWife();
            $children = $family->getChildren();
            $num = count($children);
            $marrdate = $family->getMarriageDate();
            //-- Get Parent Children’s Name, DOB, DOD --------------------------
            if (isset($children)) {
                $chBLDarray = array();
                foreach ($children as $child) {
                    $chnam = $child->getAllNames();
                    $chfulln = rtrim($chnam[0]['givn'], '*') . " " . $chnam[0]['surname'];
                    $chfulln = str_replace('"', "", $chfulln);
                    // Must remove quotes completely here
                    $chfulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                    $chfulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                    // Child’s Full Name
                    $chdob = ($child->getBirthDate()->minJD() + $child->getBirthDate()->maxJD()) / 2;
                    // Child’s Date of Birth (Julian)
                    $chdod = ($child->getDeathDate()->minJD() + $child->getDeathDate()->maxJD()) / 2;
                    // Child’s Date of Death (Julian)
                    $chBLD = $chfulln . ", " . $chdob . ", " . $chdod;
                    array_push($chBLDarray, $chBLD);
                }
            }
            //-- Parent Husband ------------------------------
            if ($husb || $num > 0) {
                if ($husb) {
                    //-- Parent Husbands Parents ----------------------
                    $gparent = WT_Individual::getInstance($husb->getXref());
                    $parfams = $gparent->getChildFamilies();
                    foreach ($parfams as $pfamily) {
                        $phusb = $pfamily->getHusband();
                        $pwife = $pfamily->getWife();
                        if ($phusb) {
                            $pHusbFBP = $phusb->getBirthPlace();
                        }
                        if ($pwife) {
                            $pHusbMBP = $pwife->getBirthPlace();
                        }
                    }
                    //-- Parent Husbands Details ----------------------
                    $person_parent = "Yes";
                    if ($husb->canShowName()) {
                        $nam = $husb->getAllNames();
                        $fulln = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
                        $fulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        $fulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        for ($i = 0; $i < count($nam); $i++) {
                            if ($nam[$i]['type'] == '_MARNM') {
                                $fulmn = rtrim($nam[$i]['givn'], '*') . "&nbsp;" . $nam[$i]['surname'];
                            }
                        }
                        $parentlinks .= "<a class=\"linka\" href=\"#\" onclick=\"insertRowToTable(";
                        $parentlinks .= "'" . $husb->getXref() . "',";
                        // pid = PID
                        $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                        // nam = Name
                        if (isset($fulmn)) {
                            $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                            // mnam = Full Married Name
                        } else {
                            $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                            // mnam = Full Name
                        }
                        if ($currpid == "Wife" || $currpid == "Husband") {
                            $parentlinks .= "'Father in Law',";
                            // label = 1st Gen Male Relationship
                        } else {
                            $parentlinks .= "'Grand-Father',";
                            // label = 2st Gen Male Relationship
                        }
                        $parentlinks .= "'" . $husb->getSex() . "',";
                        // sex = Gender
                        $parentlinks .= "''" . ",";
                        // cond = Condition (Married etc)
                        if ($marrdate) {
                            $parentlinks .= "'" . ($marrdate->minJD() + $marrdate->maxJD()) / 2 . "',";
                            // dom = Date of Marriage (Julian)
                        }
                        $parentlinks .= "'" . ($husb->getBirthDate()->minJD() + $husb->getBirthDate()->maxJD()) / 2 . "',";
                        // dob = Date of Birth
                        if ($husb->getbirthyear() >= 1) {
                            $parentlinks .= "'" . ($censyear - $husb->getbirthyear()) . "',";
                            // age =  Census Year - Year of Birth
                        } else {
                            $parentlinks .= "''" . ",";
                            // age =  Undefined
                        }
                        $parentlinks .= "'" . ($husb->getDeathDate()->minJD() + $husb->getDeathDate()->maxJD()) / 2 . "',";
                        // dod = Date of Death
                        $parentlinks .= "''" . ",";
                        // occu  = Occupation
                        $parentlinks .= "'" . WT_Filter::escapeHtml($husb->getBirthPlace()) . "'" . ",";
                        // birthpl = Individuals Birthplace
                        if (isset($pHusbFBP)) {
                            $parentlinks .= "'" . WT_Filter::escapeHtml($pHusbFBP) . "'" . ",";
                            // fbirthpl = Fathers Birthplace
                        } else {
                            $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // fbirthpl = Fathers Birthplace
                        }
                        if (isset($pHusbMBP)) {
                            $parentlinks .= "'" . WT_Filter::escapeHtml($pHusbMBP) . "'" . ",";
                            // mbirthpl = Mothers Birthplace
                        } else {
                            $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // mbirthpl = Mothers Birthplace
                        }
                        if (isset($chBLDarray) && $husb->getSex() == "F") {
                            $chBLDarray = implode("::", $chBLDarray);
                            $parentlinks .= "'" . $chBLDarray . "'";
                            // Array of Children (name, birthdate, deathdate)
                        } else {
                            $parentlinks .= "''";
                        }
                        $parentlinks .= ");\">";
                        $parentlinks .= $husb->getFullName();
                        // Full Name (Link)
                        $parentlinks .= "</a>";
                    } else {
                        $parentlinks .= WT_I18N::translate('Private');
                    }
                    $natdad = "yes";
                }
            }
            //-- Parent Wife ------------------------------
            if ($wife || $num > 0) {
                if ($wife) {
                    //-- Parent Wifes Parents ----------------------
                    $gparent = WT_Individual::getInstance($wife->getXref());
                    $parfams = $gparent->getChildFamilies();
                    foreach ($parfams as $pfamily) {
                        $pwhusb = $pfamily->getHusband();
                        $pwwife = $pfamily->getWife();
                        if ($pwhusb) {
                            $pWifeFBP = $pwhusb->getBirthPlace();
                        }
                        if ($pwwife) {
                            $pWifeMBP = $pwwife->getBirthPlace();
                        }
                    }
                    //-- Parent Wifes Details ----------------------
                    $person_parent = "Yes";
                    if ($wife->canShowName()) {
                        $nam = $wife->getAllNames();
                        $fulln = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
                        $fulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        $fulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        $husbnam = null;
                        for ($i = 0; $i < count($nam); $i++) {
                            if ($nam[$i]['type'] == '_MARNM') {
                                $fulmn = rtrim($nam[$i]['givn'], '*') . "&nbsp;" . $nam[$i]['surname'];
                            }
                        }
                        $parentlinks .= "<a class=\"linka\" href=\"#\" onclick=\"insertRowToTable(";
                        $parentlinks .= "'" . $wife->getXref() . "',";
                        // pid = PID
                        $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                        // nam = Name
                        if (isset($fulmn)) {
                            $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulmn)) . "',";
                            // mnam = Full Married Name
                        } else {
                            $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                            // mnam = Full Name
                        }
                        if ($currpid == "Wife" || $currpid == "Husband") {
                            $parentlinks .= "'Mother in Law',";
                            // label = 1st Gen Female Relationship
                        } else {
                            $parentlinks .= "'Grand-Mother',";
                            // label = 2st Gen Female Relationship
                        }
                        $parentlinks .= "'" . $wife->getSex() . "',";
                        // sex = Gender
                        $parentlinks .= "''" . ",";
                        // cond = Condition (Married etc)
                        if ($marrdate) {
                            $parentlinks .= "'" . ($marrdate->minJD() + $marrdate->maxJD()) / 2 . "',";
                            // dom = Date of Marriage (Julian)
                        }
                        $parentlinks .= "'" . ($wife->getBirthDate()->minJD() + $wife->getBirthDate()->maxJD()) / 2 . "',";
                        // dob = Date of Birth
                        if ($wife->getbirthyear() >= 1) {
                            $parentlinks .= "'" . ($censyear - $wife->getbirthyear()) . "',";
                            // age =  Census Year - Year of Birth
                        } else {
                            $parentlinks .= "''" . ",";
                            // age =  Undefined
                        }
                        $parentlinks .= "'" . ($wife->getDeathDate()->minJD() + $wife->getDeathDate()->maxJD()) / 2 . "',";
                        // dod = Date of Death
                        $parentlinks .= "''" . ",";
                        // occu  = Occupation
                        $parentlinks .= "'" . WT_Filter::escapeHtml($wife->getBirthPlace()) . "'" . ",";
                        // birthpl = Individuals Birthplace
                        if (isset($pWifeFBP)) {
                            $parentlinks .= "'" . WT_Filter::escapeHtml($pWifeFBP) . "'" . ",";
                            // fbirthpl = Fathers Birthplace
                        } else {
                            $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // fbirthpl = Fathers Birthplace Not Known
                        }
                        if (isset($pWifeMBP)) {
                            $parentlinks .= "'" . WT_Filter::escapeHtml($pWifeMBP) . "'" . ",";
                            // mbirthpl = Mothers Birthplace
                        } else {
                            $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // mbirthpl = Mothers Birthplace Not Known
                        }
                        if (isset($chBLDarray) && $wife->getSex() == "F") {
                            $chBLDarray = implode("::", $chBLDarray);
                            $parentlinks .= "'" . $chBLDarray . "'";
                            // Array of Children (name, birthdate, deathdate)
                        } else {
                            $parentlinks .= "''";
                        }
                        $parentlinks .= ");\">";
                        $parentlinks .= $wife->getFullName();
                        // Full Name (Link)
                        $parentlinks .= "</a>";
                    } else {
                        $parentlinks .= WT_I18N::translate('Private');
                    }
                    $natmom = "yes";
                }
            }
        }
        //-- Step families -----------------------------------------
        foreach ($person->getChildStepFamilies() as $family) {
            $husb = $family->getHusband();
            $wife = $family->getWife();
            $children = $family->getChildren();
            $num = count($children);
            $marrdate = $family->getMarriageDate();
            //-- Get StepParent’s Children’s Name, DOB, DOD --------------------------
            if (isset($children)) {
                $chBLDarray = array();
                foreach ($children as $child) {
                    $chnam = $child->getAllNames();
                    $chfulln = rtrim($chnam[0]['givn'], '*') . " " . $chnam[0]['surname'];
                    $chfulln = str_replace('"', "", $chfulln);
                    // Must remove quotes completely here
                    $chfulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                    $chfulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                    // Child’s Full Name
                    $chdob = ($child->getBirthDate()->minJD() + $child->getBirthDate()->maxJD()) / 2;
                    // Child’s Date of Birth (Julian)
                    $chdod = ($child->getDeathDate()->minJD() + $child->getDeathDate()->maxJD()) / 2;
                    // Child’s Date of Death (Julian)
                    $chBLD = $chfulln . ", " . $chdob . ", " . $chdod;
                    array_push($chBLDarray, $chBLD);
                }
            }
            //-- Step Husband --------------------------------------
            if ($natdad == "yes") {
            } else {
                if (($husb || $num > 0) && $husb !== $person) {
                    if ($husb) {
                        //-- Step Husbands Parents -----------------------------
                        $gparent = WT_Individual::getInstance($husb->getXref());
                        $parfams = $gparent->getChildFamilies();
                        foreach ($parfams as $pfamily) {
                            $phusb = $pfamily->getHusband();
                            $pwife = $pfamily->getWife();
                            if ($phusb) {
                                $pHusbFBP = $phusb->getBirthPlace();
                            }
                            if ($pwife) {
                                $pHusbMBP = $pwife->getBirthPlace();
                            }
                        }
                        //-- Step Husband Details ------------------------------
                        $person_step = "Yes";
                        if ($husb->canShowName()) {
                            $nam = $husb->getAllNames();
                            $fulln = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
                            $fulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                            $fulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                            for ($i = 0; $i < count($nam); $i++) {
                                if ($nam[$i]['type'] == '_MARNM') {
                                    $fulmn = rtrim($nam[$i]['givn'], '*') . "&nbsp;" . $nam[$i]['surname'];
                                }
                            }
                            $parentlinks .= "<a class=\"linka\" href=\"#\" onclick=\"insertRowToTable(";
                            $parentlinks .= "'" . $husb->getXref() . "',";
                            // pid = PID
                            $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                            // nam = Name
                            if (isset($fulmn)) {
                                $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                                // mnam = Full Married Name
                            } else {
                                $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                                // mnam = Full Name
                            }
                            if ($currpid == "Wife" || $currpid == "Husband") {
                                $parentlinks .= "'Step Father-in-Law',";
                                // label = 1st Gen Male Relationship
                            } else {
                                $parentlinks .= "'Step Grand-Father',";
                                // label = 2st Gen Male Relationship
                            }
                            $parentlinks .= "'" . $husb->getSex() . "',";
                            // sex = Gender
                            $parentlinks .= "''" . ",";
                            // cond = Condition (Married etc)
                            if ($marrdate) {
                                $parentlinks .= "'" . ($marrdate->minJD() + $marrdate->maxJD()) / 2 . "',";
                                // dom = Date of Marriage (Julian)
                            }
                            $parentlinks .= "'" . ($husb->getBirthDate()->minJD() + $husb->getBirthDate()->maxJD()) / 2 . "',";
                            // dob = Date of Birth
                            if ($husb->getbirthyear() >= 1) {
                                $parentlinks .= "'" . ($censyear - $husb->getbirthyear()) . "',";
                                // age =  Census Year - Year of Birth
                            } else {
                                $parentlinks .= "''" . ",";
                                // age =  Undefined
                            }
                            $parentlinks .= "'" . ($husb->getDeathDate()->minJD() + $husb->getDeathDate()->maxJD()) / 2 . "',";
                            // dod = Date of Death
                            $parentlinks .= "''" . ",";
                            // occu  = Occupation
                            $parentlinks .= "'" . WT_Filter::escapeHtml($husb->getBirthPlace()) . "'" . ",";
                            // birthpl = Individuals Birthplace
                            if (isset($pHusbFBP)) {
                                $parentlinks .= "'" . WT_Filter::escapeHtml($pHusbFBP) . "'" . ",";
                                // fbirthpl = Fathers Birthplace
                            } else {
                                $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                                // fbirthpl = Fathers Birthplace
                            }
                            if (isset($pHusbMBP)) {
                                $parentlinks .= "'" . WT_Filter::escapeHtml($pHusbMBP) . "'" . ",";
                                // mbirthpl = Mothers Birthplace
                            } else {
                                $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                                // mbirthpl = Mothers Birthplace
                            }
                            if (isset($chBLDarray) && $husb->getSex() == "F") {
                                $chBLDarray = implode("::", $chBLDarray);
                                $parentlinks .= "'" . $chBLDarray . "'";
                                // Array of Children (name, birthdate, deathdate)
                            } else {
                                $parentlinks .= "''";
                            }
                            $parentlinks .= ");\">";
                            $parentlinks .= $husb->getFullName();
                            // Full Name (Link)
                            $parentlinks .= "</a>";
                        } else {
                            $parentlinks .= WT_I18N::translate('Private');
                        }
                    }
                }
            }
            //-- Step Wife ----------------------------------------
            if ($natmom == "yes") {
            } else {
                if ($wife || $num > 0) {
                    if ($wife) {
                        //-- Step Wifes Parents ---------------------------
                        $gparent = WT_Individual::getInstance($wife->getXref());
                        $parfams = $gparent->getChildFamilies();
                        foreach ($parfams as $pfamily) {
                            $pwhusb = $pfamily->getHusband();
                            $pwwife = $pfamily->getWife();
                            if ($pwhusb) {
                                $pWifeFBP = $pwhusb->getBirthPlace();
                            }
                            if ($pwwife) {
                                $pWifeMBP = $pwwife->getBirthPlace();
                            }
                        }
                        //-- Step Wife Details ------------------------------
                        $person_step = "Yes";
                        if ($wife->canShowName()) {
                            $nam = $wife->getAllNames();
                            $fulln = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
                            $fulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                            $fulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                            $husbnam = null;
                            for ($i = 0; $i < count($nam); $i++) {
                                if ($nam[$i]['type'] == '_MARNM') {
                                    $fulmn = rtrim($nam[$i]['givn'], '*') . "&nbsp;" . $nam[$i]['surname'];
                                }
                            }
                            $parentlinks .= "<a class=\"linka\" href=\"#\" onclick=\"insertRowToTable(";
                            $parentlinks .= "'" . $wife->getXref() . "',";
                            // pid = PID
                            $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                            // nam = Name
                            if (isset($fulmn)) {
                                $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulmn)) . "',";
                                // mnam = Full Married Name
                            } else {
                                $parentlinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                                // mnam = Full Name
                            }
                            if ($currpid == "Wife" || $currpid == "Husband") {
                                $parentlinks .= "'Step Mother-in-Law',";
                                // label = 1st Gen Female Relationship
                            } else {
                                $parentlinks .= "'Step Grand-Mother',";
                                // label = 2st Gen Female Relationship
                            }
                            $parentlinks .= "'" . $wife->getSex() . "',";
                            // sex = Gender
                            $parentlinks .= "''" . ",";
                            // cond = Condition (Married etc)
                            if ($marrdate) {
                                $parentlinks .= "'" . ($marrdate->minJD() + $marrdate->maxJD()) / 2 . "',";
                                // dom = Date of Marriage (Julian)
                            }
                            $parentlinks .= "'" . ($wife->getBirthDate()->minJD() + $wife->getBirthDate()->maxJD()) / 2 . "',";
                            // dob = Date of Birth
                            if ($wife->getbirthyear() >= 1) {
                                $parentlinks .= "'" . ($censyear - $wife->getbirthyear()) . "',";
                                // age =  Census Year - Year of Birth
                            } else {
                                $parentlinks .= "''" . ",";
                                // age =  Undefined
                            }
                            $parentlinks .= "'" . ($wife->getDeathDate()->minJD() + $wife->getDeathDate()->maxJD()) / 2 . "',";
                            // dod = Date of Death
                            $parentlinks .= "''" . ",";
                            // occu  = Occupation
                            $parentlinks .= "'" . WT_Filter::escapeHtml($wife->getBirthPlace()) . "'" . ",";
                            // birthpl = Individuals Birthplace
                            if (isset($pWifeFBP)) {
                                $parentlinks .= "'" . WT_Filter::escapeHtml($pWifeFBP) . "'" . ",";
                                // fbirthpl = Fathers Birthplace
                            } else {
                                $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                                // fbirthpl = Fathers Birthplace Not Known
                            }
                            if (isset($pWifeMBP)) {
                                $parentlinks .= "'" . WT_Filter::escapeHtml($pWifeMBP) . "'" . ",";
                                // mbirthpl = Mothers Birthplace
                            } else {
                                $parentlinks .= "'UNK, UNK, UNK, UNK'" . ",";
                                // mbirthpl = Mothers Birthplace Not Known
                            }
                            if (isset($chBLDarray) && $wife->getSex() == "F") {
                                $chBLDarray = implode("::", $chBLDarray);
                                $parentlinks .= "'" . $chBLDarray . "'";
                                // Array of Children (name, birthdate, deathdate)
                            } else {
                                $parentlinks .= "''";
                            }
                            $parentlinks .= ");\">";
                            $parentlinks .= $wife->getFullName();
                            // Full Name (Link)
                            $parentlinks .= "</a>";
                        } else {
                            $parentlinks .= WT_I18N::translate('Private');
                        }
                    }
                }
            }
        }
        // Spouse Families ------------------------------------------
        foreach ($person->getSpouseFamilies() as $family) {
            $spouse = $family->getSpouse($person);
            $children = $family->getChildren();
            $num = count($children);
            $marrdate = $family->getMarriageDate();
            $is_wife = $family->getWife();
            //-- Get Spouse’s Children’s Name, DOB, DOD --------------------------
            if (isset($children)) {
                $chBLDarray = array();
                foreach ($children as $child) {
                    $chnam = $child->getAllNames();
                    $chfulln = rtrim($chnam[0]['givn'], '*') . " " . $chnam[0]['surname'];
                    $chfulln = str_replace('"', "", $chfulln);
                    // Must remove quotes completely here
                    $chfulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                    $chfulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                    // Child’s Full Name
                    $chdob = ($child->getBirthDate()->minJD() + $child->getBirthDate()->maxJD()) / 2;
                    // Child’s Date of Birth (Julian)
                    $chdod = ($child->getDeathDate()->minJD() + $child->getDeathDate()->maxJD()) / 2;
                    // Child’s Date of Death (Julian)
                    $chBLD = $chfulln . ", " . $chdob . ", " . $chdod;
                    array_push($chBLDarray, $chBLD);
                }
            }
            //-- Spouse -----------------------------------------
            if ($spouse || $num > 0) {
                if ($spouse) {
                    //-- Spouse Parents -----------------------------
                    $gparent = WT_Individual::getInstance($spouse->getXref());
                    $spousefams = $gparent->getChildFamilies();
                    foreach ($spousefams as $pfamily) {
                        $phusb = $pfamily->getHusband();
                        $pwife = $pfamily->getWife();
                        if ($phusb) {
                            $pSpouseFBP = $phusb->getBirthPlace();
                        }
                        if ($pwife) {
                            $pSpouseMBP = $pwife->getBirthPlace();
                        }
                    }
                    //-- Spouse Details -----------------------------
                    if ($spouse->canShowName()) {
                        $nam = $spouse->getAllNames();
                        $fulln = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
                        $fulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        $fulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        // If spouse is a wife, then get her married name or default to her birth name
                        for ($i = 0; $i < count($nam); $i++) {
                            if ($nam[$i]['type'] == '_MARNM' && $is_wife) {
                                $fulmn = rtrim($nam[$i]['givn'], '*') . "&nbsp;" . $nam[$i]['surname'];
                            } else {
                                $fulmn = $fulln;
                            }
                        }
                        $spouselinks .= "<a href=\"#\" onclick=\"insertRowToTable(";
                        $spouselinks .= "'" . $spouse->getXref() . "',";
                        // pid = PID
                        $spouselinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                        // nam = Name
                        if (isset($fulmn)) {
                            $spouselinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulmn)) . "',";
                            // mnam = Full Married Name
                        } else {
                            $spouselinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                            // mnam = Full Name
                        }
                        if ($currpid == "Son" || $currpid == "Daughter") {
                            if ($spouse->getSex() == "M") {
                                $spouselinks .= "'Son in Law',";
                                // label = Male Relationship
                            } else {
                                $spouselinks .= "'Daughter in Law',";
                                // label = Female Relationship
                            }
                        } else {
                            if ($spouse->getSex() == "M") {
                                $spouselinks .= "'Brother in Law',";
                                // label = Male Relationship
                            } else {
                                $spouselinks .= "'Sister in Law',";
                                // label = Female Relationship
                            }
                        }
                        $spouselinks .= "'" . $spouse->getSex() . "',";
                        // sex = Gender
                        $spouselinks .= "''" . ",";
                        // cond = Condition (Married etc)
                        if ($marrdate) {
                            $spouselinks .= "'" . ($marrdate->minJD() + $marrdate->maxJD()) / 2 . "',";
                            // dom = Date of Marriage (Julian)
                        }
                        $spouselinks .= "'" . ($spouse->getBirthDate()->minJD() + $spouse->getBirthDate()->maxJD()) / 2 . "',";
                        // dob = Date of Birth
                        if ($spouse->getbirthyear() >= 1) {
                            $spouselinks .= "'" . ($censyear - $spouse->getbirthyear()) . "',";
                            // age =  Census Year - Year of Birth
                        } else {
                            $spouselinks .= "''" . ",";
                            // age =  Undefined
                        }
                        $spouselinks .= "'" . ($spouse->getDeathDate()->minJD() + $spouse->getDeathDate()->maxJD()) / 2 . "',";
                        // dod = Date of Death
                        $spouselinks .= "''" . ",";
                        // occu  = Occupation
                        $spouselinks .= "'" . WT_Filter::escapeHtml($spouse->getBirthPlace()) . "'" . ",";
                        // birthpl = Individuals Birthplace
                        if (isset($pSpouseFBP)) {
                            $spouselinks .= "'" . WT_Filter::escapeHtml($pSpouseFBP) . "'" . ",";
                            // fbirthpl = Fathers Birthplace
                        } else {
                            $spouselinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // fbirthpl = Fathers Birthplace Not Known
                        }
                        if (isset($pSpouseMBP)) {
                            $spouselinks .= "'" . WT_Filter::escapeHtml($pSpouseMBP) . "'" . ",";
                            // mbirthpl = Mothers Birthplace
                        } else {
                            $spouselinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // mbirthpl = Mothers Birthplace Not Known
                        }
                        if (isset($chBLDarray) && $spouse->getSex() == "F") {
                            $chBLDarray = implode("::", $chBLDarray);
                            $spouselinks .= "'" . $chBLDarray . "'";
                            // Array of Children (name, birthdate, deathdate)
                        } else {
                            $spouselinks .= "''";
                        }
                        $spouselinks .= ");\">";
                        $spouselinks .= $spouse->getFullName();
                        // Full Name (Link)
                        $spouselinks .= "</a>";
                    } else {
                        $spouselinks .= WT_I18N::translate('Private');
                    }
                    $spouselinks .= "</a>";
                    if ($spouse->getFullName() != "") {
                        $persons = "Yes";
                    }
                }
            }
            // Children -------------------------------------
            $spouselinks .= "<ul class=\"clist\">";
            foreach ($children as $child) {
                if ($child) {
                    $persons = "Yes";
                    //-- Childs Parents ---------------------
                    $gparent = WT_Individual::getInstance($child->getXref());
                    foreach ($gparent->getChildFamilies() as $family) {
                        $husb = $family->getHusband();
                        $wife = $family->getWife();
                        if ($husb) {
                            $ChildFBP = $husb->getBirthPlace();
                        }
                        if ($wife) {
                            $ChildMBP = $wife->getBirthPlace();
                        }
                    }
                    // Get Child’s Children
                    $chBLDarray = array();
                    foreach ($child->getSpouseFamilies() as $childfamily) {
                        $chchildren = $childfamily->getChildren();
                        foreach ($chchildren as $chchild) {
                            $chnam = $chchild->getAllNames();
                            $chfulln = rtrim($chnam[0]['givn'], '*') . " " . $chnam[0]['surname'];
                            $chfulln = str_replace('"', "", $chfulln);
                            // Must remove quotes completely here
                            $chfulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                            $chfulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $chfulln);
                            // Child’s Full Name
                            $chdob = ($chchild->getBirthDate()->minJD() + $chchild->getBirthDate()->maxJD()) / 2;
                            // Child’s Date of Birth (Julian)
                            $chdod = ($chchild->getDeathDate()->minJD() + $chchild->getDeathDate()->maxJD()) / 2;
                            // Child’s Date of Death (Julian)
                            $chBLD = $chfulln . ", " . $chdob . ", " . $chdod;
                            array_push($chBLDarray, $chBLD);
                        }
                    }
                    // Get Childs marriage status ------------
                    $marrdate = "";
                    $chhusbnam = null;
                    foreach ($child->getSpouseFamilies() as $childfamily) {
                        $marrdate = $childfamily->getMarriageDate();
                        if ($childfamily->getHusband()) {
                            $chhusbnam = $childfamily->getHusband()->getAllNames();
                        }
                    }
                    // Childs Details -------------------------
                    $spouselinks .= "<li>";
                    if ($child->canShowName()) {
                        $nam = $child->getAllNames();
                        $fulln = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
                        $fulln = str_replace("@N.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        $fulln = str_replace("@P.N.", "(" . WT_I18N::translate('unknown') . ")", $fulln);
                        $husbnam = null;
                        // Get childs married name if available
                        $chfulmn = null;
                        $chnam = $child->getAllNames();
                        if ($chhusbnam[0]['surname'] == "@N.N." || $chhusbnam[0]['surname'] == "") {
                            // if Husband or his name is not known then use wifes birth name
                            $husbnam = $nam[0]['surname'];
                        } else {
                            $husbnam = $chhusbnam[0]['surname'];
                        }
                        for ($i = 0; $i < count($nam); $i++) {
                            if ($chnam[$i]['type'] == '_MARNM') {
                                $chfulmn = rtrim($chnam[$i]['givn'], '*') . "&nbsp;" . $husbnam;
                            }
                        }
                        $spouselinks .= "<a href=\"#\" onclick=\"insertRowToTable(";
                        $spouselinks .= "'" . $child->getXref() . "',";
                        // pid = PID
                        $spouselinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                        // nam = Name
                        if (isset($chfulmn)) {
                            $spouselinks .= "'" . WT_Filter::escapeHtml(strip_tags($chfulmn)) . "',";
                            // mnam = Full Married Name
                        } else {
                            $spouselinks .= "'" . WT_Filter::escapeHtml(strip_tags($fulln)) . "',";
                            // mnam = Full Name
                        }
                        if ($currpid == "Son" || $currpid == "Daughter") {
                            if ($child->getSex() == "M") {
                                $spouselinks .= "'Grand-Son',";
                                // label = Male Relationship
                            } else {
                                $spouselinks .= "'Grand-Daughter',";
                                // label = Female Relationship
                            }
                        } else {
                            if ($child->getSex() == "M") {
                                $spouselinks .= "'Nephew',";
                                // label = Male Relationship
                            } else {
                                $spouselinks .= "'Niece',";
                                // label = Female Relationship
                            }
                        }
                        $spouselinks .= "'" . $child->getSex() . "',";
                        // sex = Gender
                        $spouselinks .= "''" . ",";
                        // cond = Condition (Married etc)
                        if ($marrdate) {
                            $spouselinks .= "'" . ($marrdate->minJD() + $marrdate->maxJD()) / 2 . "',";
                            // dom = Date of Marriage (Julian)
                        } else {
                            $spouselinks .= "'nm'" . ",";
                        }
                        $spouselinks .= "'" . ($child->getBirthDate()->minJD() + $child->getBirthDate()->maxJD()) / 2 . "',";
                        // dob = Date of Birth
                        if ($child->getbirthyear() >= 1) {
                            $spouselinks .= "'" . ($censyear - $child->getbirthyear()) . "',";
                            // age =  Census Year - Year of Birth
                        } else {
                            $spouselinks .= "''" . ",";
                            // age =  Undefined
                        }
                        $spouselinks .= "'" . ($child->getDeathDate()->minJD() + $child->getDeathDate()->maxJD()) / 2 . "',";
                        // dod = Date of Death
                        $spouselinks .= "''" . ",";
                        // occu  = Occupation
                        $spouselinks .= "'" . WT_Filter::escapeHtml($child->getBirthPlace()) . "'" . ",";
                        // birthpl = Individuals Birthplace
                        if (isset($ChildFBP)) {
                            $spouselinks .= "'" . WT_Filter::escapeHtml($ChildFBP) . "'" . ",";
                            // fbirthpl = Fathers Birthplace
                        } else {
                            $spouselinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // fbirthpl = Fathers Birthplace Not Known
                        }
                        if (isset($ChildMBP)) {
                            $spouselinks .= "'" . WT_Filter::escapeHtml($ChildMBP) . "'" . ",";
                            // mbirthpl = Mothers Birthplace
                        } else {
                            $spouselinks .= "'UNK, UNK, UNK, UNK'" . ",";
                            // mbirthpl = Mothers Birthplace Not Known
                        }
                        if (isset($chBLDarray) && $child->getSex() == "F") {
                            $chBLDarray = implode("::", $chBLDarray);
                            $spouselinks .= "'" . $chBLDarray . "'";
                            // Array of Children (name, birthdate, deathdate)
                        } else {
                            $spouselinks .= "''";
                        }
                        $spouselinks .= ");\">";
                        $spouselinks .= $child->getFullName();
                        // Full Name (Link)
                        $spouselinks .= "</a>";
                        $spouselinks .= "</li>";
                    } else {
                        $spouselinks .= WT_I18N::translate('Private');
                    }
                }
            }
            $spouselinks .= "</ul>";
        }
        if ($persons != "Yes") {
            $spouselinks .= "(" . WT_I18N::translate('none') . ")</td></tr></table>";
        } else {
            $spouselinks .= "</td></tr></table>";
        }
        if ($person_parent != "Yes") {
            $parentlinks .= "(" . WT_I18N::translate_c('unknown family', 'unknown') . ")</td></tr></table>";
        } else {
            $parentlinks .= "</td></tr></table>";
        }
        if ($person_step != "Yes") {
            $step_parentlinks .= "(" . WT_I18N::translate_c('unknown family', 'unknown') . ")</td></tr></table>";
        } else {
            $step_parentlinks .= "</td></tr></table>";
        }
    }
}