Exemple #1
0
 /**
  * Find all the individuals that are descended from an individual.
  *
  * @param WT_Individual   $person
  * @param int             $n
  * @param WT_Individual[] $array
  *
  * @return WT_Individual[]
  */
 public function indi_desc(WT_Individual $person, $n, $array)
 {
     if ($n < 1) {
         return $array;
     }
     $array[$person->getXref()] = $person;
     foreach ($person->getSpouseFamilies() as $family) {
         $spouse = $family->getSpouse($person);
         if ($spouse) {
             $array[$spouse->getXref()] = $spouse;
         }
         foreach ($family->getChildren() as $child) {
             $array = $this->indi_desc($child, $n - 1, $array);
         }
     }
     return $array;
 }
Exemple #2
0
 /**
  * Prints descendency of passed in person
  *
  * @param WT_Individual $person person to print descendency for
  * @param mixed         $count  count of generations to print
  * @param bool          $showNav
  *
  * @return int
  */
 function print_descendency($person, $count, $showNav = true)
 {
     global $TEXT_DIRECTION, $WT_IMAGES, $bheight, $bwidth, $bhalfheight, $lastGenSecondFam;
     if ($count > $this->dgenerations) {
         return;
     }
     if (!$person) {
         return;
     }
     $pid = $person->getXref();
     $tablealign = 'right';
     $otablealign = 'left';
     if ($TEXT_DIRECTION == 'rtl') {
         $tablealign = 'left';
         $otablealign = 'right';
     }
     //-- put a space between families on the last generation
     if ($count == $this->dgenerations - 1) {
         if (isset($lastGenSecondFam)) {
             echo "<br>";
         }
         $lastGenSecondFam = true;
     }
     echo "<table id=\"table_{$pid}\" align=\"" . $tablealign . "\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
     echo "<tr>";
     echo "<td align=\"{$tablealign}\" width=\"100%\">";
     $numkids = 0;
     $families = $person->getSpouseFamilies();
     $famNum = 0;
     $children = array();
     if ($count < $this->dgenerations) {
         // Put all of the children in a common array
         foreach ($families as $family) {
             $famNum++;
             foreach ($family->getChildren() as $child) {
                 $children[] = $child;
             }
         }
         $ct = count($children);
         if ($ct > 0) {
             echo "<table style=\"position: relative; top: auto; text-align: {$tablealign};\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
             for ($i = 0; $i < $ct; $i++) {
                 $person2 = $children[$i];
                 $chil = $person2->getXref();
                 echo '<tr>';
                 echo "<td id=\"td_{$chil}\" class=\"{$TEXT_DIRECTION}\" align=\"{$otablealign}\">";
                 $kids = $this->print_descendency($person2, $count + 1);
                 $numkids += $kids;
                 echo '</td>';
                 // Print the lines
                 if ($ct > 1) {
                     if ($i == 0) {
                         // First child
                         echo "<td valign=\"bottom\"><img class=\"line1\" name=\"tvertline\" id=\"vline_{$chil}\" src=\"" . $WT_IMAGES["vline"] . "\" width=\"3\"></td>";
                     } elseif ($i == $ct - 1) {
                         // Last child
                         echo "<td valign=\"top\"><img name=\"bvertline\" id=\"vline_{$chil}\" src=\"" . $WT_IMAGES["vline"] . "\" width=\"3\"></td>";
                     } else {
                         // Middle child
                         echo "<td style=\"background: url('" . $WT_IMAGES["vline"] . "');\"><img src=\"" . $WT_IMAGES["spacer"] . "\" width=\"3\"></td>";
                     }
                 }
                 echo '</tr>';
             }
             echo '</table>';
         }
         echo '</td>';
         echo '<td width="', $bwidth, '">';
     }
     // Print the descendency expansion arrow
     if ($count == $this->dgenerations) {
         $numkids = 1;
         $tbwidth = $bwidth + 16;
         for ($j = $count; $j < $this->dgenerations; $j++) {
             echo "<div style=\"width: " . $tbwidth . "px;\"><br></div></td><td width=\"{$bwidth}\">";
         }
         $kcount = 0;
         foreach ($families as $family) {
             $kcount += $family->getNumberOfChildren();
         }
         if ($kcount == 0) {
             echo "&nbsp;</td><td width=\"{$bwidth}\">";
         } else {
             echo "<a href=\"{$pid}\" onclick=\"return changeDis('td_" . $pid . "','" . $pid . "','" . $this->show_full . "','" . $this->show_spouse . "','" . $this->box_width . "')\" class=\"" . $this->left_arrow . "\"></a>";
             //-- move the arrow up to line up with the correct box
             if ($this->show_spouse) {
                 echo str_repeat('<br><br><br>', count($families));
             }
             echo "</td><td width=\"{$bwidth}\">";
         }
     }
     echo "<table id=\"table2_{$pid}\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td>";
     print_pedigree_person($person);
     echo "</td><td><img class=\"line2\" src=\"" . $WT_IMAGES["hline"] . "\" width=\"7\" height=\"3\" alt=\"\">";
     //----- Print the spouse
     if ($this->show_spouse) {
         foreach ($families as $family) {
             echo "</td></tr><tr><td align=\"{$otablealign}\">";
             //-- shrink the box for the spouses
             $tempw = $bwidth;
             $temph = $bheight;
             $bwidth -= 10;
             $bheight -= 10;
             print_pedigree_person($family->getSpouse($person));
             $bwidth = $tempw;
             $bheight = $temph;
             $numkids += 0.95;
             echo "</td><td></td>";
         }
         //-- add offset divs to make things line up better
         if ($count == $this->dgenerations) {
             echo "<tr><td colspan\"2\"><div style=\"height: " . $bhalfheight / 2 . "px; width: " . $bwidth . "px;\"><br></div>";
         }
     }
     echo "</td></tr></table>";
     // For the root person, print a down arrow that allows changing the root of tree
     if ($showNav && $count == 1) {
         // NOTE: If statement OK
         if ($person->canShowName()) {
             // -- print left arrow for decendants so that we can move down the tree
             $famids = $person->getSpouseFamilies();
             //-- make sure there is more than 1 child in the family with parents
             $cfamids = $person->getChildFamilies();
             $num = 0;
             foreach ($cfamids as $family) {
                 $num += $family->getNumberOfChildren();
             }
             // NOTE: If statement OK
             if ($num > 0) {
                 echo '<div class="center" id="childarrow" style="position:absolute; width:', $bwidth, 'px;">';
                 echo '<a href="#" class="icon-darrow"></a><br>';
                 echo '<div id="childbox">';
                 echo '<table class="person_box"><tr><td>';
                 foreach ($famids as $family) {
                     $spouse = $family->getSpouse($person);
                     if ($spouse) {
                         $spid = $spouse->getXref();
                         echo "<a href=\"hourglass.php?rootid={$spid}&amp;show_spouse={$this->show_spouse}&amp;show_full={$this->show_full}&amp;generations={$this->generations}&amp;box_width={$this->box_width}\" class=\"name1\">";
                         echo $spouse->getFullName();
                         echo '</a><br>';
                     }
                     foreach ($family->getChildren() as $child) {
                         $cid = $child->getXref();
                         echo "&nbsp;&nbsp;<a href=\"hourglass.php?rootid={$cid}&amp;show_spouse={$this->show_spouse}&amp;show_full={$this->show_full}&amp;generations={$this->generations}&amp;box_width={$this->box_width}\" class=\"name1\">";
                         echo $child->getFullName();
                         echo '</a><br>';
                     }
                 }
                 //-- print the siblings
                 foreach ($cfamids as $family) {
                     if ($family->getHusband() || $family->getWife()) {
                         echo "<span class=\"name1\"><br>" . WT_I18N::translate('Parents') . "<br></span>";
                         $husb = $family->getHusband();
                         if ($husb) {
                             $spid = $husb->getXref();
                             echo "&nbsp;&nbsp;<a href=\"hourglass.php?rootid={$spid}&amp;show_spouse={$this->show_spouse}&amp;show_full={$this->show_full}&amp;generations={$this->generations}&amp;box_width={$this->box_width}\" class=\"name1\">";
                             echo $husb->getFullName();
                             echo '</a><br>';
                         }
                         $wife = $family->getWife();
                         if ($wife) {
                             $spid = $wife->getXref();
                             echo "&nbsp;&nbsp;<a href=\"hourglass.php?rootid={$spid}&amp;show_spouse={$this->show_spouse}&amp;show_full={$this->show_full}&amp;generations={$this->generations}&amp;box_width={$this->box_width}\" class=\"name1\">";
                             echo $wife->getFullName();
                             echo '</a><br>';
                         }
                     }
                     $num = $family->getNumberOfChildren();
                     if ($num > 2) {
                         echo "<span class=\"name1\"><br>" . WT_I18N::translate('Siblings') . "<br></span>";
                     }
                     if ($num == 2) {
                         echo "<span class=\"name1\"><br>" . WT_I18N::translate('Sibling') . "<br></span>";
                     }
                     foreach ($family->getChildren() as $child) {
                         $cid = $child->getXref();
                         if ($cid != $pid) {
                             echo "&nbsp;&nbsp;<a href=\"hourglass.php?rootid={$cid}&amp;show_spouse={$this->show_spouse}&amp;show_full={$this->show_full}&amp;generations={$this->generations}&amp;box_width={$this->box_width}\" class=\"name1\">";
                             echo $child->getFullName();
                             echo '</a><br>';
                         }
                     }
                 }
                 echo '</td></tr></table>';
                 echo '</div>';
                 echo '</div>';
             }
         }
     }
     echo '</td></tr>';
     echo '</table>';
     return $numkids;
 }
/**
 * print the parents table for a family
 *
 * @param WT_Family $family family gedcom ID
 * @param int       $sosa   child sosa number
 * @param string    $label  indi label (descendancy booklet)
 * @param string    $parid  parent ID (descendancy booklet)
 * @param string    $gparid gd-parent ID (descendancy booklet)
 * @param int       $personcount
 */
function print_family_parents(WT_Family $family, $sosa = 0, $label = '', $parid = '', $gparid = '', $personcount = 1)
{
    global $pbwidth, $pbheight, $WT_IMAGES;
    $husb = $family->getHusband();
    if ($husb) {
        echo '<a name="', $husb->getXref(), '"></a>';
    } else {
        $husb = new WT_Individual('M', "0 @M@ INDI\n1 SEX M", null, WT_GED_ID);
    }
    $wife = $family->getWife();
    if ($wife) {
        echo '<a name="', $wife->getXref(), '"></a>';
    } else {
        $wife = new WT_Individual('F', "0 @F@ INDI\n1 SEX F", null, WT_GED_ID);
    }
    if ($sosa) {
        echo '<p class="name_head">', $family->getFullName(), '</p>';
    }
    /**
     * husband side
     */
    echo "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr><td rowspan=\"2\">";
    echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>";
    if ($parid) {
        if ($husb->getXref() == $parid) {
            print_sosa_number($label);
        } else {
            print_sosa_number($label, "", "blank");
        }
    } elseif ($sosa) {
        print_sosa_number($sosa * 2);
    }
    if ($husb->isNew()) {
        echo '<td valign="top" class="facts_value new">';
    } elseif ($husb->isOld()) {
        echo '<td valign="top" class="facts_value old">';
    } else {
        echo '<td valign="top">';
    }
    print_pedigree_person($husb, 1, 2, $personcount);
    echo "</td></tr></table>";
    echo "</td>";
    // husband’s parents
    $hfam = $husb->getPrimaryChildFamily();
    if ($hfam) {
        // remove the|| test for $sosa
        echo "<td rowspan=\"2\"><img src=\"" . $WT_IMAGES["hline"] . "\" alt=\"\"></td><td rowspan=\"2\"><img src=\"" . $WT_IMAGES["vline"] . "\" width=\"3\" height=\"" . ($pbheight + 9) . "\" alt=\"\"></td>";
        echo "<td><img class=\"line5\" src=\"" . $WT_IMAGES["hline"] . "\" alt=\"\"></td><td>";
        // husband’s father
        if ($hfam && $hfam->getHusband()) {
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>";
            if ($sosa > 0) {
                print_sosa_number($sosa * 4, $hfam->getHusband()->getXref(), "down");
            }
            if (!empty($gparid) && $hfam->getHusband()->getXref() == $gparid) {
                print_sosa_number(trim(substr($label, 0, -3), ".") . ".");
            }
            echo "<td valign=\"top\">";
            print_pedigree_person(WT_Individual::getInstance($hfam->getHusband()->getXref()), 1, 4, $personcount);
            echo "</td></tr></table>";
        } elseif ($hfam && !$hfam->getHusband()) {
            // here for empty box for grandfather
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>";
            echo '<td valign="top">';
            print_pedigree_person($hfam->getHusband());
            echo '</td></tr></table>';
        }
        echo "</td>";
    }
    if ($hfam && $sosa != -1) {
        echo '<td valign="middle" rowspan="2">';
        print_url_arrow($hfam->getXref(), $sosa == 0 ? '?famid=' . $hfam->getXref() . '&amp;ged=' . WT_GEDURL : '#' . $hfam->getXref(), $hfam->getXref(), 1);
        echo '</td>';
    }
    if ($hfam) {
        // remove the|| test for $sosa
        // husband’s mother
        echo "</tr><tr><td><img src=\"" . $WT_IMAGES["hline"] . "\" alt=\"\"></td><td>";
        if ($hfam && $hfam->getWife()) {
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>";
            if ($sosa > 0) {
                print_sosa_number($sosa * 4 + 1, $hfam->getWife()->getXref(), "down");
            }
            if (!empty($gparid) && $hfam->getWife()->getXref() == $gparid) {
                print_sosa_number(trim(substr($label, 0, -3), ".") . ".");
            }
            echo '<td valign="top">';
            print_pedigree_person(WT_Individual::getInstance($hfam->getWife()->getXref()), 1, 5, $personcount);
            echo '</td></tr></table>';
        } elseif ($hfam && !$hfam->getWife()) {
            // here for empty box for grandmother
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>";
            echo '<td valign="top">';
            print_pedigree_person($hfam->getWife());
            echo '</td></tr></table>';
        }
        echo '</td>';
    }
    echo '</tr></table>';
    if ($sosa && $family->canShow()) {
        foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) {
            echo '<a href="', $family->getHtmlUrl(), '" class="details1">';
            echo str_repeat('&nbsp;', 10);
            echo $fact->summary();
            echo '</a>';
        }
    } else {
        echo '<br>';
    }
    /**
     * wife side
     */
    echo "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr><td rowspan=\"2\">";
    echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\"><tr>";
    if ($parid) {
        if ($wife->getXref() == $parid) {
            print_sosa_number($label);
        } else {
            print_sosa_number($label, "", "blank");
        }
    } elseif ($sosa) {
        print_sosa_number($sosa * 2 + 1);
    }
    if ($wife->isNew()) {
        echo '<td valign="top" class="facts_value new">';
    } elseif ($wife->isOld()) {
        echo '<td valign="top" class="facts_value old">';
    } else {
        echo '<td valign="top">';
    }
    print_pedigree_person($wife, 1, 3, $personcount);
    echo "</td></tr></table>";
    echo "</td>";
    // wife’s parents
    $hfam = $wife->getPrimaryChildFamily();
    if ($hfam) {
        // remove the|| test for $sosa
        echo "<td rowspan=\"2\"><img src=\"" . $WT_IMAGES["hline"] . "\" alt=\"\"></td><td rowspan=\"2\"><img src=\"" . $WT_IMAGES["vline"] . "\" width=\"3\" height=\"" . ($pbheight + 9) . "\" alt=\"\"></td>";
        echo "<td><img class=\"line5\" src=\"" . $WT_IMAGES["hline"] . "\" alt=\"\"></td><td>";
        // wife’s father
        if ($hfam && $hfam->getHusband()) {
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\"><tr>";
            if ($sosa > 0) {
                print_sosa_number($sosa * 4 + 2, $hfam->getHusband()->getXref(), "down");
            }
            if (!empty($gparid) && $hfam->getHusband()->getXref() == $gparid) {
                print_sosa_number(trim(substr($label, 0, -3), ".") . ".");
            }
            echo "<td valign=\"top\">";
            print_pedigree_person(WT_Individual::getInstance($hfam->getHusband()->getXref()), 1, 6, $personcount);
            echo "</td></tr></table>";
        } elseif ($hfam && !$hfam->getHusband()) {
            // here for empty box for grandfather
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>";
            echo '<td valign="top">';
            print_pedigree_person($hfam->getHusband());
            echo '</td></tr></table>';
        }
        echo "</td>";
    }
    if ($hfam && $sosa != -1) {
        echo '<td valign="middle" rowspan="2">';
        print_url_arrow($hfam->getXref(), $sosa == 0 ? '?famid=' . $hfam->getXref() . '&amp;ged=' . WT_GEDURL : '#' . $hfam->getXref(), $hfam->getXref(), 1);
        echo '</td>';
    }
    if ($hfam) {
        // remove the|| test for $sosa
        // wife’s mother
        echo "</tr><tr><td><img src=\"" . $WT_IMAGES["hline"] . "\" alt=\"\"></td><td>";
        if ($hfam && $hfam->getWife()) {
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\"><tr>";
            if ($sosa > 0) {
                print_sosa_number($sosa * 4 + 3, $hfam->getWife()->getXref(), "down");
            }
            if (!empty($gparid) && $hfam->getWife()->getXref() == $gparid) {
                print_sosa_number(trim(substr($label, 0, -3), ".") . ".");
            }
            echo "<td valign=\"top\">";
            print_pedigree_person(WT_Individual::getInstance($hfam->getWife()->getXref()), 1, 7, $personcount);
            echo "</td></tr></table>";
        } elseif ($hfam && !$hfam->getWife()) {
            // here for empty box for grandmother
            echo "<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>";
            echo '<td valign="top">';
            print_pedigree_person($hfam->getWife());
            echo '</td></tr></table>';
        }
        echo '</td>';
    }
    echo "</tr></table>";
}
/**
 * print the information for an individual chart box
 *
 * find and print a given individuals information for a pedigree chart
 *
 * @param WT_Individual $person The person to print
 * @param int           $style  the style to print the box in, 1 for smaller boxes, 2 for larger boxes
 * @param int           $count  on some charts it is important to keep a count of how many boxes were printed
 * @param string        $personcount
 */
function print_pedigree_person($person, $style = 1, $count = 0, $personcount = "1")
{
    global $GEDCOM;
    global $SHOW_HIGHLIGHT_IMAGES, $bwidth, $bheight, $PEDIGREE_FULL_DETAILS, $SHOW_PEDIGREE_PLACES;
    global $TEXT_DIRECTION, $DEFAULT_PEDIGREE_GENERATIONS, $OLD_PGENS, $talloffset, $PEDIGREE_LAYOUT;
    global $chart_style, $box_width, $generations, $show_spouse, $show_full;
    global $CHART_BOX_TAGS, $SHOW_LDS_AT_GLANCE, $PEDIGREE_SHOW_GENDER;
    global $SEARCH_SPIDER;
    if ($style != 2) {
        $style = 1;
    }
    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;
    }
    // NOTE: Start div out-rand()
    if (!$person) {
        echo "<div id=\"out-", Uuid::uuid4(), "\" class=\"person_boxNN\" style=\"width: ", $bwidth, "px; height: ", $bheight, "px; overflow: hidden;\">";
        echo '<br>';
        echo '</div>';
        return;
    }
    $pid = $person->getXref();
    if ($count == 0) {
        $count = rand();
    }
    $lbwidth = $bwidth * 0.75;
    if ($lbwidth < 150) {
        $lbwidth = 150;
    }
    $tmp = array('M' => '', 'F' => 'F', 'U' => 'NN');
    $isF = $tmp[$person->getSex()];
    $personlinks = '';
    $icons = '';
    $genderImage = '';
    $BirthDeath = '';
    $birthplace = '';
    $outBoxAdd = '';
    $showid = '';
    $iconsStyleAdd = 'float:right;';
    if ($TEXT_DIRECTION == 'rtl') {
        $iconsStyleAdd = 'float:left;';
    }
    $boxID = $pid . '.' . $personcount . '.' . $count . '.' . Uuid::uuid4();
    $mouseAction4 = " onclick=\"expandbox('" . $boxID . "', {$style}); return false;\"";
    if ($person->canShowName()) {
        if (empty($SEARCH_SPIDER)) {
            //-- draw a box for the family popup
            // NOTE: Start div I.$pid.$personcount.$count.links
            $personlinks .= '<ul class="person_box' . $isF . '">';
            $personlinks .= '<li><a href="pedigree.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;talloffset=' . $talloffset . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Pedigree') . '</b></a></li>';
            if (array_key_exists('googlemap', WT_Module::getActiveModules())) {
                $personlinks .= '<li><a href="module.php?mod=googlemap&amp;mod_action=pedigree_map&amp;rootid=' . $pid . '&amp;ged=' . WT_GEDURL . '"><b>' . WT_I18N::translate('Pedigree map') . '</b></a></li>';
            }
            if (WT_USER_GEDCOM_ID && WT_USER_GEDCOM_ID != $pid) {
                $personlinks .= '<li><a href="relationship.php?show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;pid1=' . WT_USER_GEDCOM_ID . '&amp;pid2=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;pretty=2&amp;followspouse=1&amp;ged=' . WT_GEDURL . '"><b>' . WT_I18N::translate('Relationship to me') . '</b></a></li>';
            }
            $personlinks .= '<li><a href="descendancy.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;generations=' . $generations . '&amp;box_width=' . $box_width . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Descendants') . '</b></a></li>';
            $personlinks .= '<li><a href="ancestry.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;chart_style=' . $chart_style . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;box_width=' . $box_width . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Ancestors') . '</b></a></li>';
            $personlinks .= '<li><a href="compact.php?rootid=' . $pid . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Compact tree') . '</b></a></li>';
            if (function_exists("imagettftext")) {
                $personlinks .= '<li><a href="fanchart.php?rootid=' . $pid . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Fan chart') . '</b></a></li>';
            }
            $personlinks .= '<li><a href="hourglass.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;chart_style=' . $chart_style . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;box_width=' . $box_width . '&amp;ged=' . rawurlencode($GEDCOM) . '&amp;show_spouse=' . $show_spouse . '"><b>' . WT_I18N::translate('Hourglass chart') . '</b></a></li>';
            if (array_key_exists('tree', WT_Module::getActiveModules())) {
                $personlinks .= '<li><a href="module.php?mod=tree&amp;mod_action=treeview&amp;ged=' . WT_GEDURL . '&amp;rootid=' . $pid . '"><b>' . WT_I18N::translate('Interactive tree') . '</b></a></li>';
            }
            foreach ($person->getSpouseFamilies() as $family) {
                $spouse = $family->getSpouse($person);
                if ($spouse) {
                    $personlinks .= '<li>';
                    $personlinks .= '<a href="' . $family->getHtmlUrl() . '"><b>' . WT_I18N::translate('Family with spouse') . '</b></a><br>';
                    $personlinks .= '<a href="' . $spouse->getHtmlUrl() . '">' . $spouse->getFullName() . '</a>';
                    $personlinks .= '</li>';
                    $personlinks .= '<li><ul>';
                }
                foreach ($family->getChildren() as $child) {
                    $personlinks .= '<li><a href="' . $child->getHtmlUrl() . '">';
                    $personlinks .= $child->getFullName();
                    $personlinks .= '</a></li>';
                }
                $personlinks .= '</ul></li>';
            }
            $personlinks .= '</ul>';
            // NOTE: Start div out-$pid.$personcount.$count
            if ($style == 1) {
                $outBoxAdd .= " class=\"person_box{$isF} person_box_template style1\" style=\"width: " . $bwidth . "px; height: " . $bheight . "px; z-index:-1;\"";
            } else {
                $outBoxAdd .= " class=\"person_box{$isF} person_box_template style0\"";
            }
            // NOTE: Zoom
            if (!$show_full) {
                $outBoxAdd .= $mouseAction4;
            } else {
                $icons .= "<a href=\"#\"" . $mouseAction4 . " id=\"iconz-{$boxID}\" class=\"icon-zoomin\" title=\"" . WT_I18N::translate('Zoom in/out on this box.') . "\"></a>";
                $icons .= '<div class="itr"><a href="#" class="icon-pedigree"></a><div class="popup">' . $personlinks . '</div></div>';
            }
        } else {
            if ($style == 1) {
                $outBoxAdd .= "class=\"person_box{$isF}\" style=\"width: " . $bwidth . "px; height: " . $bheight . "px; overflow: hidden;\"";
            } else {
                $outBoxAdd .= "class=\"person_box{$isF}\" style=\"overflow: hidden;\"";
            }
            // NOTE: Zoom
            if (!$SEARCH_SPIDER) {
                $outBoxAdd .= $mouseAction4;
            }
        }
    } else {
        if ($style == 1) {
            $outBoxAdd .= "class=\"person_box{$isF} person_box_template style1\" style=\"width: " . $bwidth . "px; height: " . $bheight . "px;\"";
        } else {
            $outBoxAdd .= "class=\"person_box{$isF} person_box_template style0\"";
        }
    }
    //-- find the name
    $name = $person->getFullName();
    $shortname = $person->getShortName();
    if ($SHOW_HIGHLIGHT_IMAGES) {
        $thumbnail = $person->displayImage();
    } else {
        $thumbnail = '';
    }
    //-- find additional name, e.g. Hebrew
    $addname = $person->getAddName();
    if ($PEDIGREE_SHOW_GENDER && $show_full) {
        $genderImage = " " . $person->getSexImage('small', "box-{$boxID}-gender");
    }
    // Here for alternate name2
    if ($addname) {
        $addname = "<br><span id=\"addnamedef-{$boxID}\" class=\"name1\"> " . $addname . "</span>";
    }
    if ($SHOW_LDS_AT_GLANCE && $show_full) {
        $addname = ' <span class="details$style">' . get_lds_glance($person) . '</span>' . $addname;
    }
    if ($show_full && $person->canShow()) {
        $opt_tags = preg_split('/\\W/', $CHART_BOX_TAGS, 0, PREG_SPLIT_NO_EMPTY);
        // Show BIRT or equivalent event
        foreach (explode('|', WT_EVENTS_BIRT) as $birttag) {
            if (!in_array($birttag, $opt_tags)) {
                $event = $person->getFirstFact($birttag);
                if ($event) {
                    $BirthDeath .= $event->summary();
                    break;
                }
            }
        }
        // Show optional events (before death)
        foreach ($opt_tags as $key => $tag) {
            if (!preg_match('/^(' . WT_EVENTS_DEAT . ')$/', $tag)) {
                $event = $person->getFirstFact($tag);
                if (!is_null($event)) {
                    $BirthDeath .= $event->summary();
                    unset($opt_tags[$key]);
                }
            }
        }
        // Show DEAT or equivalent event
        foreach (explode('|', WT_EVENTS_DEAT) as $deattag) {
            $event = $person->getFirstFact($deattag);
            if ($event) {
                $BirthDeath .= $event->summary();
                if (in_array($deattag, $opt_tags)) {
                    unset($opt_tags[array_search($deattag, $opt_tags)]);
                }
                break;
            }
        }
        // Show remaining optional events (after death)
        foreach ($opt_tags as $tag) {
            $event = $person->getFirstFact($tag);
            if ($event) {
                $BirthDeath .= $event->summary();
            }
        }
    }
    // Output to template
    $classfacts = '';
    if ($show_full) {
        require WT_THEME_DIR . 'templates/personbox_template.php';
    } else {
        require WT_THEME_DIR . 'templates/compactbox_template.php';
    }
}
Exemple #5
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;
 }
Exemple #6
0
/**
 * Get relationship between two individuals in the gedcom
 *
 * @param WT_Individual $person1 the person to compute the relationship from
 * @param WT_Individual $person2 the person to compute the relatiohip to
 * @param bool          $followspouse whether to add spouses to the path
 * @param int           $maxlength    the maximum length of path
 * @param int           $path_to_find which path in the relationship to find, 0 is the shortest path, 1 is the next shortest path, etc
 *
 * @return array|bool An array of nodes on the relationship path, or false if no path found
 */
function get_relationship(WT_Individual $person1, WT_Individual $person2, $followspouse = true, $maxlength = 0, $path_to_find = 0)
{
    if ($person1 === $person2) {
        return false;
    }
    //-- current path nodes
    $p1nodes = array();
    //-- ids visited
    $visited = array();
    //-- set up first node for person1
    $node1 = array('path' => array($person1), 'length' => 0, 'indi' => $person1, 'relations' => array('self'));
    $p1nodes[] = $node1;
    $visited[$person1->getXref()] = true;
    $found = false;
    while (!$found) {
        //-- search the node list for the shortest path length
        $shortest = -1;
        foreach ($p1nodes as $index => $node) {
            if ($shortest == -1) {
                $shortest = $index;
            } else {
                $node1 = $p1nodes[$shortest];
                if ($node1['length'] > $node['length']) {
                    $shortest = $index;
                }
            }
        }
        if ($shortest == -1) {
            return false;
        }
        $node = $p1nodes[$shortest];
        if ($maxlength == 0 || count($node['path']) <= $maxlength) {
            $indi = $node['indi'];
            //-- check all parents and siblings of this node
            foreach ($indi->getChildFamilies(WT_PRIV_HIDE) as $family) {
                $visited[$family->getXref()] = true;
                foreach ($family->getSpouses(WT_PRIV_HIDE) as $spouse) {
                    if (!isset($visited[$spouse->getXref()])) {
                        $node1 = $node;
                        $node1['length']++;
                        $node1['path'][] = $spouse;
                        $node1['indi'] = $spouse;
                        $node1['relations'][] = 'parent';
                        $p1nodes[] = $node1;
                        if ($spouse === $person2) {
                            if ($path_to_find > 0) {
                                $path_to_find--;
                            } else {
                                $found = true;
                                $resnode = $node1;
                            }
                        } else {
                            $visited[$spouse->getXref()] = true;
                        }
                    }
                }
                foreach ($family->getChildren(WT_PRIV_HIDE) as $child) {
                    if (!isset($visited[$child->getXref()])) {
                        $node1 = $node;
                        $node1['length']++;
                        $node1['path'][] = $child;
                        $node1['indi'] = $child;
                        $node1['relations'][] = 'sibling';
                        $p1nodes[] = $node1;
                        if ($child === $person2) {
                            if ($path_to_find > 0) {
                                $path_to_find--;
                            } else {
                                $found = true;
                                $resnode = $node1;
                            }
                        } else {
                            $visited[$child->getXref()] = true;
                        }
                    }
                }
            }
            //-- check all spouses and children of this node
            foreach ($indi->getSpouseFamilies(WT_PRIV_HIDE) as $family) {
                $visited[$family->getXref()] = true;
                if ($followspouse) {
                    foreach ($family->getSpouses(WT_PRIV_HIDE) as $spouse) {
                        if (!in_array($spouse->getXref(), $node1) || !isset($visited[$spouse->getXref()])) {
                            $node1 = $node;
                            $node1['length']++;
                            $node1['path'][] = $spouse;
                            $node1['indi'] = $spouse;
                            $node1['relations'][] = 'spouse';
                            $p1nodes[] = $node1;
                            if ($spouse === $person2) {
                                if ($path_to_find > 0) {
                                    $path_to_find--;
                                } else {
                                    $found = true;
                                    $resnode = $node1;
                                }
                            } else {
                                $visited[$spouse->getXref()] = true;
                            }
                        }
                    }
                }
                foreach ($family->getChildren(WT_PRIV_HIDE) as $child) {
                    if (!isset($visited[$child->getXref()])) {
                        $node1 = $node;
                        $node1['length']++;
                        $node1['path'][] = $child;
                        $node1['indi'] = $child;
                        $node1['relations'][] = 'child';
                        $p1nodes[] = $node1;
                        if ($child === $person2) {
                            if ($path_to_find > 0) {
                                $path_to_find--;
                            } else {
                                $found = true;
                                $resnode = $node1;
                            }
                        } else {
                            $visited[$child->getXref()] = true;
                        }
                    }
                }
            }
        }
        unset($p1nodes[$shortest]);
    }
    // Convert generic relationships into sex-specific ones.
    foreach ($resnode['path'] as $n => $indi) {
        switch ($resnode['relations'][$n]) {
            case 'parent':
                switch ($indi->getSex()) {
                    case 'M':
                        $resnode['relations'][$n] = 'father';
                        break;
                    case 'F':
                        $resnode['relations'][$n] = 'mother';
                        break;
                }
                break;
            case 'child':
                switch ($indi->getSex()) {
                    case 'M':
                        $resnode['relations'][$n] = 'son';
                        break;
                    case 'F':
                        $resnode['relations'][$n] = 'daughter';
                        break;
                }
                break;
            case 'spouse':
                switch ($indi->getSex()) {
                    case 'M':
                        $resnode['relations'][$n] = 'husband';
                        break;
                    case 'F':
                        $resnode['relations'][$n] = 'wife';
                        break;
                }
                break;
            case 'sibling':
                switch ($indi->getSex()) {
                    case 'M':
                        $resnode['relations'][$n] = 'brother';
                        break;
                    case 'F':
                        $resnode['relations'][$n] = 'sister';
                        break;
                }
                break;
        }
    }
    return $resnode;
}
function print_indi_form($nextaction, WT_Individual $person = null, WT_Family $family = null, WT_Fact $name_fact = null, $famtag = 'CHIL', $gender = 'U')
{
    global $WORD_WRAPPED_NOTES, $NPFX_accept, $SHOW_GEDCOM_RECORD, $bdm, $STANDARD_NAME_FACTS, $ADVANCED_NAME_FACTS;
    global $QUICK_REQUIRED_FACTS, $QUICK_REQUIRED_FAMFACTS, $controller;
    $SURNAME_TRADITION = get_gedcom_setting(WT_GED_ID, 'SURNAME_TRADITION');
    if ($person) {
        $xref = $person->getXref();
    } elseif ($family) {
        $xref = $family->getXref();
    } else {
        $xref = 'new';
    }
    $name_fields = array();
    if ($name_fact) {
        $name_fact_id = $name_fact->getFactId();
        $name_type = $name_fact->getAttribute('TYPE');
        $namerec = $name_fact->getGedcom();
        // Populate the standard NAME field and subfields
        foreach ($STANDARD_NAME_FACTS as $tag) {
            if ($tag == 'NAME') {
                $name_fields[$tag] = $name_fact->getValue();
            } else {
                $name_fields[$tag] = $name_fact->getAttribute($tag);
            }
        }
    } else {
        $name_fact_id = null;
        $name_type = null;
        $namerec = null;
        // Populate the standard NAME field and subfields
        foreach ($STANDARD_NAME_FACTS as $tag) {
            $name_fields[$tag] = '';
        }
    }
    $bdm = '';
    // used to copy '1 SOUR' to '2 SOUR' for BIRT DEAT MARR
    echo '<div id="edit_interface-page">';
    echo '<h4>', $controller->getPageTitle(), '</h4>';
    init_calendar_popup();
    echo '<form method="post" name="addchildform" onsubmit="return checkform();">';
    echo '<input type="hidden" name="ged" value="', WT_Filter::escapeHtml(WT_GEDCOM), '">';
    echo '<input type="hidden" name="action" value="', $nextaction, '">';
    echo '<input type="hidden" name="fact_id" value="', $name_fact_id, '">';
    echo '<input type="hidden" name="xref" value="', $xref, '">';
    echo '<input type="hidden" name="famtag" value="', $famtag, '">';
    echo '<input type="hidden" name="gender" value="', $gender, '">';
    echo '<input type="hidden" name="goto" value="">';
    // set by javascript
    echo WT_Filter::getCsrf();
    echo '<table class="facts_table">';
    switch ($nextaction) {
        case 'add_child_to_family_action':
        case 'add_child_to_individual_action':
            // When adding a new child, specify the pedigree
            add_simple_tag('0 PEDI');
            break;
        case 'update':
            // When adding/editing a name, specify the type
            add_simple_tag('0 TYPE ' . $name_type, '', '', null, $person);
            break;
    }
    $new_marnm = '';
    // Inherit surname from parents, spouse or child
    if (!$namerec) {
        // We’ll need the parent’s name to set the child’s surname
        if ($family) {
            $father = $family->getHusband();
            if ($father && $father->getFirstFact('NAME')) {
                $father_name = $father->getFirstFact('NAME')->getValue();
            } else {
                $father_name = '';
            }
            $mother = $family->getWife();
            if ($mother && $mother->getFirstFact('NAME')) {
                $mother_name = $mother->getFirstFact('NAME')->getValue();
            } else {
                $mother_name = '';
            }
        } else {
            $father_name = '';
            $mother_name = '';
        }
        // We’ll need the spouse/child’s name to set the spouse/parent’s surname
        if ($person && $person->getFirstFact('NAME')) {
            $indi_name = $person->getFirstFact('NAME')->getValue();
        } else {
            $indi_name = '';
        }
        // Different cultures do surnames differently
        switch ($SURNAME_TRADITION) {
            case 'spanish':
                //Mother: Maria /AAAA BBBB/
                //Father: Jose  /CCCC DDDD/
                //Child:  Pablo /CCCC AAAA/
                switch ($nextaction) {
                    case 'add_child_to_family_action':
                        if (preg_match('/\\/(\\S+) \\S+\\//', $mother_name, $matchm) && preg_match('/\\/(\\S+) \\S+\\//', $father_name, $matchf)) {
                            $name_fields['SURN'] = $matchf[1] . ' ' . $matchm[1];
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        break;
                    case 'add_parent_to_individual_action':
                        if ($famtag == 'HUSB' && preg_match('/\\/(\\S+) \\S+\\//', $indi_name, $match)) {
                            $name_fields['SURN'] = $match[1];
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        if ($famtag == 'WIFE' && preg_match('/\\/\\S+ (\\S+)\\//', $indi_name, $match)) {
                            $name_fields['SURN'] = $match[1];
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        break;
                    case 'add_child_to_individual_action':
                    case 'add_spouse_to_individual_action':
                    case 'add_spouse_to_family_action':
                        break;
                }
                break;
            case 'portuguese':
                //Mother: Maria /AAAA BBBB/
                //Father: Jose  /CCCC DDDD/
                //Child:  Pablo /BBBB DDDD/
                switch ($nextaction) {
                    case 'add_child_to_family_action':
                        if (preg_match('/\\/\\S+\\s+(\\S+)\\//', $mother_name, $matchm) && preg_match('/\\/\\S+\\s+(\\S+)\\//', $father_name, $matchf)) {
                            $name_fields['SURN'] = $matchf[1] . ' ' . $matchm[1];
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        break;
                    case 'add_parent_to_individual_action':
                        if ($famtag == 'HUSB' && preg_match('/\\/\\S+\\s+(\\S+)\\//', $indi_name, $match)) {
                            $name_fields['SURN'] = $match[1];
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        if ($famtag == 'WIFE' && preg_match('/\\/(\\S+)\\s+\\S+\\//', $indi_name, $match)) {
                            $name_fields['SURN'] = $match[1];
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        break;
                    case 'add_child_to_individual_action':
                    case 'add_spouse_to_individual_action':
                    case 'add_spouse_to_family_action':
                        break;
                }
                break;
            case 'icelandic':
                // Sons get their father’s given name plus “sson”
                // Daughters get their father’s given name plus “sdottir”
                switch ($nextaction) {
                    case 'add_child_to_family_action':
                        if ($gender == 'M' && preg_match('/(\\S+)\\s+\\/.*\\//', $father_name, $match)) {
                            $name_fields['SURN'] = preg_replace('/s$/', '', $match[1]) . 'sson';
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        if ($gender == 'F' && preg_match('/(\\S+)\\s+\\/.*\\//', $father_name, $match)) {
                            $name_fields['SURN'] = preg_replace('/s$/', '', $match[1]) . 'sdottir';
                            $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/';
                        }
                        break;
                    case 'add_parent_to_individual_action':
                        if ($famtag == 'HUSB' && preg_match('/(\\S+)sson\\s+\\/.*\\//i', $indi_name, $match)) {
                            $name_fields['GIVN'] = $match[1];
                            $name_fields['NAME'] = $name_fields['GIVN'] . ' //';
                        }
                        if ($famtag == 'WIFE' && preg_match('/(\\S+)sdottir\\s+\\/.*\\//i', $indi_name, $match)) {
                            $name_fields['GIVN'] = $match[1];
                            $name_fields['NAME'] = $name_fields['GIVN'] . ' //';
                        }
                        break;
                    case 'add_child_to_individual_action':
                    case 'add_spouse_to_individual_action':
                    case 'add_spouse_to_family_action':
                        break;
                }
                break;
            case 'patrilineal':
                // Father gives his surname to his children
                switch ($nextaction) {
                    case 'add_child_to_family_action':
                        if (preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $father_name, $match)) {
                            $name_fields['SURN'] = $match[2];
                            $name_fields['SPFX'] = trim($match[1]);
                            $name_fields['NAME'] = "/{$match[1]}{$match[2]}/";
                        }
                        break;
                    case 'add_parent_to_individual_action':
                        if ($famtag == 'HUSB' && preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $indi_name, $match)) {
                            $name_fields['SURN'] = $match[2];
                            $name_fields['SPFX'] = trim($match[1]);
                            $name_fields['NAME'] = "/{$match[1]}{$match[2]}/";
                        }
                        break;
                    case 'add_child_to_individual_action':
                    case 'add_spouse_to_individual_action':
                    case 'add_spouse_to_family_action':
                        break;
                }
                break;
            case 'matrilineal':
                // Mother gives her surname to her children
                switch ($nextaction) {
                    case 'add_child_to_family_action':
                        if (preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $mother, $match)) {
                            $name_fields['SURN'] = $match[2];
                            $name_fields['SPFX'] = trim($match[1]);
                            $name_fields['NAME'] = "/{$match[1]}{$match[2]}/";
                        }
                        break;
                    case 'add_parent_to_individual_action':
                        if ($famtag == 'WIFE' && preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $indi_name, $match)) {
                            $name_fields['SURN'] = $match[2];
                            $name_fields['SPFX'] = trim($match[1]);
                            $name_fields['NAME'] = "/{$match[1]}{$match[2]}/";
                        }
                        break;
                    case 'add_child_to_individual_action':
                    case 'add_spouse_to_individual_action':
                    case 'add_spouse_to_family_action':
                        break;
                }
                break;
            case 'paternal':
            case 'polish':
            case 'lithuanian':
                // Father gives his surname to his wife and children
                switch ($nextaction) {
                    case 'add_spouse_to_individual_action':
                        if ($famtag == 'WIFE' && preg_match('/\\/(.*)\\//', $indi_name, $match)) {
                            if ($SURNAME_TRADITION == 'polish') {
                                $match[1] = preg_replace(array('/ski$/', '/cki$/', '/dzki$/', '/żki$/'), array('ska', 'cka', 'dzka', 'żka'), $match[1]);
                            } elseif ($SURNAME_TRADITION == 'lithuanian') {
                                $match[1] = preg_replace(array('/as$/', '/is$/', '/ys$/', '/us$/'), array('ienė', 'ienė', 'ienė', 'ienė'), $match[1]);
                            }
                            $new_marnm = $match[1];
                        }
                        break;
                    case 'add_child_to_family_action':
                        if (preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $father_name, $match)) {
                            $name_fields['SURN'] = $match[2];
                            if ($SURNAME_TRADITION == 'polish' && $gender == 'F') {
                                $match[2] = preg_replace(array('/ski$/', '/cki$/', '/dzki$/', '/żki$/'), array('ska', 'cka', 'dzka', 'żka'), $match[2]);
                            } elseif ($SURNAME_TRADITION == 'lithuanian' && $gender == 'F') {
                                $match[2] = preg_replace(array('/as$/', '/a$/', '/is$/', '/ys$/', '/ius$/', '/us$/'), array('aitė', 'aitė', 'ytė', 'ytė', 'iūtė', 'utė'), $match[2]);
                            }
                            $name_fields['SPFX'] = trim($match[1]);
                            $name_fields['NAME'] = "/{$match[1]}{$match[2]}/";
                        }
                        break;
                    case 'add_child_to_individual_action':
                        if ($person->getSex() == 'M' && preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $indi_name, $match)) {
                            $name_fields['SURN'] = $match[2];
                            if ($SURNAME_TRADITION == 'polish' && $gender == 'F') {
                                $match[2] = preg_replace(array('/ski$/', '/cki$/', '/dzki$/', '/żki$/'), array('ska', 'cka', 'dzka', 'żka'), $match[2]);
                            } elseif ($SURNAME_TRADITION == 'lithuanian' && $gender == 'F') {
                                $match[2] = preg_replace(array('/as$/', '/a$/', '/is$/', '/ys$/', '/ius$/', '/us$/'), array('aitė', 'aitė', 'ytė', 'ytė', 'iūtė', 'utė'), $match[2]);
                            }
                            $name_fields['SPFX'] = trim($match[1]);
                            $name_fields['NAME'] = "/{$match[1]}{$match[2]}/";
                        }
                        break;
                    case 'add_parent_to_individual_action':
                        if ($famtag == 'HUSB' && preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $indi_name, $match)) {
                            if ($SURNAME_TRADITION == 'polish' && $gender == 'M') {
                                $match[2] = preg_replace(array('/ska$/', '/cka$/', '/dzka$/', '/żka$/'), array('ski', 'cki', 'dzki', 'żki'), $match[2]);
                            } elseif ($SURNAME_TRADITION == 'lithuanian') {
                                // not a complete list as the rules are somewhat complicated but will do 95% correctly
                                $match[2] = preg_replace(array('/aitė$/', '/ytė$/', '/iūtė$/', '/utė$/'), array('as', 'is', 'ius', 'us'), $match[2]);
                            }
                            $name_fields['SPFX'] = trim($match[1]);
                            $name_fields['SURN'] = $match[2];
                            $name_fields['NAME'] = "/{$match[1]}{$match[2]}/";
                        }
                        if ($famtag == 'WIFE' && preg_match('/\\/((?:[a-z]{2,3} )*)(.*)\\//i', $indi_name, $match)) {
                            if ($SURNAME_TRADITION == 'lithuanian') {
                                $match[2] = preg_replace(array('/as$/', '/is$/', '/ys$/', '/us$/'), array('ienė', 'ienė', 'ienė', 'ienė'), $match[2]);
                                $match[2] = preg_replace(array('/aitė$/', '/ytė$/', '/iūtė$/', '/utė$/'), array('ienė', 'ienė', 'ienė', 'ienė'), $match[2]);
                            }
                            $new_marnm = $match[2];
                        }
                        break;
                    case 'add_spouse_to_family_action':
                        break;
                }
                break;
        }
    }
    // Initialise an empty name field
    if (empty($name_fields['NAME'])) {
        $name_fields['NAME'] = '//';
    }
    // Populate any missing 2 XXXX fields from the 1 NAME field
    $npfx_accept = implode('|', $NPFX_accept);
    if (preg_match("/((({$npfx_accept})\\.? +)*)([^\n\\/\"]*)(\"(.*)\")? *\\/(([a-z]{2,3} +)*)(.*)\\/ *(.*)/i", $name_fields['NAME'], $name_bits)) {
        if (empty($name_fields['NPFX'])) {
            $name_fields['NPFX'] = $name_bits[1];
        }
        if (empty($name_fields['SPFX']) && empty($name_fields['SURN'])) {
            $name_fields['SPFX'] = trim($name_bits[7]);
            // For names with two surnames, there will be four slashes.
            // Turn them into a list
            $name_fields['SURN'] = preg_replace('~/[^/]*/~', ',', $name_bits[9]);
        }
        if (empty($name_fields['GIVN'])) {
            $name_fields['GIVN'] = $name_bits[4];
        }
        // Don’t automatically create an empty NICK - it is an “advanced” field.
        if (empty($name_fields['NICK']) && !empty($name_bits[6]) && !preg_match('/^2 NICK/m', $namerec)) {
            $name_fields['NICK'] = $name_bits[6];
        }
    }
    // Edit the standard name fields
    foreach ($name_fields as $tag => $value) {
        add_simple_tag("0 {$tag} {$value}");
    }
    // Get the advanced name fields
    $adv_name_fields = array();
    if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $ADVANCED_NAME_FACTS, $match)) {
        foreach ($match[1] as $tag) {
            $adv_name_fields[$tag] = '';
        }
    }
    // This is a custom tag, but webtrees uses it extensively.
    if ($SURNAME_TRADITION == 'paternal' || $SURNAME_TRADITION == 'polish' || $SURNAME_TRADITION == 'lithuanian' || strpos($namerec, '2 _MARNM') !== false) {
        $adv_name_fields['_MARNM'] = '';
    }
    if (isset($adv_name_fields['TYPE'])) {
        unset($adv_name_fields['TYPE']);
    }
    foreach ($adv_name_fields as $tag => $dummy) {
        // Edit existing tags
        if (preg_match_all("/2 {$tag} (.+)/", $namerec, $match)) {
            foreach ($match[1] as $value) {
                if ($tag == '_MARNM') {
                    $mnsct = preg_match('/\\/(.+)\\//', $value, $match2);
                    $marnm_surn = '';
                    if ($mnsct > 0) {
                        $marnm_surn = $match2[1];
                    }
                    add_simple_tag("2 _MARNM " . $value);
                    add_simple_tag("2 _MARNM_SURN " . $marnm_surn);
                } else {
                    add_simple_tag("2 {$tag} {$value}", '', WT_Gedcom_Tag::getLabel("NAME:{$tag}", $person));
                }
            }
        }
        // Allow a new row to be entered if there was no row provided
        if (count($match[1]) == 0 && empty($name_fields[$tag]) || $tag != '_HEB' && $tag != 'NICK') {
            if ($tag == '_MARNM') {
                if (strstr($ADVANCED_NAME_FACTS, '_MARNM') == false) {
                    add_simple_tag("0 _MARNM");
                    add_simple_tag("0 _MARNM_SURN {$new_marnm}");
                }
            } else {
                add_simple_tag("0 {$tag}", '', WT_Gedcom_Tag::getLabel("NAME:{$tag}", $person));
            }
        }
    }
    // Handle any other NAME subfields that aren’t included above (SOUR, NOTE, _CUSTOM, etc)
    if ($namerec) {
        $gedlines = explode("\n", $namerec);
        // -- find the number of lines in the record
        $fields = explode(' ', $gedlines[0]);
        $glevel = $fields[0];
        $level = $glevel;
        $type = trim($fields[1]);
        $tags = array();
        $i = 0;
        do {
            if ($type != 'TYPE' && !isset($name_fields[$type]) && !isset($adv_name_fields[$type])) {
                $text = '';
                for ($j = 2; $j < count($fields); $j++) {
                    if ($j > 2) {
                        $text .= ' ';
                    }
                    $text .= $fields[$j];
                }
                while ($i + 1 < count($gedlines) && preg_match("/" . ($level + 1) . " (CON[CT]) ?(.*)/", $gedlines[$i + 1], $cmatch) > 0) {
                    if ($cmatch[1] == "CONT") {
                        $text .= "\n";
                    }
                    if ($WORD_WRAPPED_NOTES) {
                        $text .= ' ';
                    }
                    $text .= $cmatch[2];
                    $i++;
                }
                add_simple_tag($level . ' ' . $type . ' ' . $text);
            }
            $tags[] = $type;
            $i++;
            if (isset($gedlines[$i])) {
                $fields = explode(' ', $gedlines[$i]);
                $level = $fields[0];
                if (isset($fields[1])) {
                    $type = $fields[1];
                }
            }
        } while ($level > $glevel && $i < count($gedlines));
    }
    // If we are adding a new individual, add the basic details
    if ($nextaction != 'update') {
        echo '</table><br><table class="facts_table">';
        // 1 SEX
        if ($famtag == "HUSB" || $gender == "M") {
            add_simple_tag("0 SEX M");
        } elseif ($famtag == "WIFE" || $gender == "F") {
            add_simple_tag("0 SEX F");
        } else {
            add_simple_tag("0 SEX");
        }
        $bdm = "BD";
        if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $QUICK_REQUIRED_FACTS, $matches)) {
            foreach ($matches[1] as $match) {
                if (!in_array($match, explode('|', WT_EVENTS_DEAT))) {
                    addSimpleTags($match);
                }
            }
        }
        //-- if adding a spouse add the option to add a marriage fact to the new family
        if ($nextaction == 'add_spouse_to_individual_action' || $nextaction == 'add_spouse_to_family_action') {
            $bdm .= "M";
            if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $QUICK_REQUIRED_FAMFACTS, $matches)) {
                foreach ($matches[1] as $match) {
                    addSimpleTags($match);
                }
            }
        }
        if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $QUICK_REQUIRED_FACTS, $matches)) {
            foreach ($matches[1] as $match) {
                if (in_array($match, explode('|', WT_EVENTS_DEAT))) {
                    addSimpleTags($match);
                }
            }
        }
    }
    echo keep_chan($person);
    echo "</table>";
    if ($nextaction == 'update') {
        // GEDCOM 5.5.1 spec says NAME doesn’t get a OBJE
        print_add_layer('SOUR');
        print_add_layer('NOTE');
        print_add_layer('SHARED_NOTE');
    } else {
        print_add_layer('SOUR', 1);
        print_add_layer('OBJE', 1);
        print_add_layer('NOTE', 1);
        print_add_layer('SHARED_NOTE', 1);
    }
    // If we are editing an existing name, allow raw GEDCOM editing
    if ($name_fact && (Auth::isAdmin() || $SHOW_GEDCOM_RECORD)) {
        echo '<br><br><a href="edit_interface.php?action=editrawfact&amp;xref=', $xref, '&amp;fact_id=', $name_fact->getFactId(), '&amp;ged=', WT_GEDURL, '">', WT_I18N::translate('Edit raw GEDCOM'), '</a>';
    }
    echo '<p id="save-cancel">';
    echo '<input type="submit" class="save" value="', WT_I18N::translate('save'), '">';
    if (preg_match('/^add_(child|spouse|parent|unlinked_indi)/', $nextaction)) {
        echo '<input type="submit" class="save" value="', WT_I18N::translate('go to new individual'), '" onclick="document.addchildform.goto.value=\'new\';">';
    }
    echo '<input type="button" class="cancel" value="', WT_I18N::translate('close'), '" onclick="window.close();">';
    echo '</p>';
    echo '</form>';
    $controller->addInlineJavascript('
	SURNAME_TRADITION="' . $SURNAME_TRADITION . '";
	gender="' . $gender . '";
	famtag="' . $famtag . '";
	function trim(str) {
		str=str.replace(/\\s\\s+/g, " ");
		return str.replace(/(^\\s+)|(\\s+$)/g, "");
	}

	function lang_class(str) {
		if (str.match(/[\\u0370-\\u03FF]/)) return "greek";
		if (str.match(/[\\u0400-\\u04FF]/)) return "cyrillic";
		if (str.match(/[\\u0590-\\u05FF]/)) return "hebrew";
		if (str.match(/[\\u0600-\\u06FF]/)) return "arabic";
		return "latin"; // No matched text implies latin :-)
	}

	// Generate a full name from the name components
	function generate_name() {
		var frm =document.forms[0];
		var npfx=frm.NPFX.value;
		var givn=frm.GIVN.value;
		var spfx=frm.SPFX.value;
		var surn=frm.SURN.value;
		var nsfx=frm.NSFX.value;
		if (SURNAME_TRADITION=="polish" && (gender=="F" || famtag=="WIFE")) {
			surn=surn.replace(/ski$/, "ska");
			surn=surn.replace(/cki$/, "cka");
			surn=surn.replace(/dzki$/, "dzka");
			surn=surn.replace(/żki$/, "żka");
		}
		// Commas are used in the GIVN and SURN field to separate lists of surnames.
		// For example, to differentiate the two Spanish surnames from an English
		// double-barred name.
		// Commas *may* be used in other fields, and will form part of the NAME.
		if (WT_LOCALE=="vi" || WT_LOCALE=="hu") {
			// Default format: /SURN/ GIVN
			return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+givn.replace(/ *, */g, " ")+" "+nsfx);
		} else if (WT_LOCALE=="zh") {
			// Default format: /SURN/GIVN
			return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/"+givn.replace(/ *, */g, " ")+" "+nsfx);
		} else {
			// Default format: GIVN /SURN/
			return trim(npfx+" "+givn.replace(/ *, */g, " ")+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+nsfx);
		}
	}

	// Update the NAME and _MARNM fields from the name components
	// and also display the value in read-only "gedcom" format.
	function updatewholename() {
		// don’t update the name if the user manually changed it
		if (manualChange) return;
		// Update NAME field from components and display it
		var frm =document.forms[0];
		var npfx=frm.NPFX.value;
		var givn=frm.GIVN.value;
		var spfx=frm.SPFX.value;
		var surn=frm.SURN.value;
		var nsfx=frm.NSFX.value;
		document.getElementById("NAME").value=generate_name();
		document.getElementById("NAME_display").innerText=frm.NAME.value;
		// Married names inherit some NSFX values, but not these
		nsfx=nsfx.replace(/^(I|II|III|IV|V|VI|Junior|Jr\\.?|Senior|Sr\\.?)$/i, "");
		// Update _MARNM field from _MARNM_SURN field and display it
		// Be careful of mixing latin/hebrew/etc. character sets.
		var ip=document.getElementsByTagName("input");
		var marnm_id="";
		var romn="";
		var heb="";
		for (var i=0; i<ip.length; i++) {
			var val=ip[i].value;
			if (ip[i].id.indexOf("_HEB")==0)
				heb=val;
			if (ip[i].id.indexOf("ROMN")==0)
				romn=val;
			if (ip[i].id.indexOf("_MARNM")==0) {
				if (ip[i].id.indexOf("_MARNM_SURN")==0) {
					var msurn="";
					if (val!="") {
						var lc=lang_class(document.getElementById(ip[i].id).value);
						if (lang_class(frm.NAME.value)==lc)
							msurn=trim(npfx+" "+givn+" /"+val+"/ "+nsfx);
						else if (lc=="hebrew")
							msurn=heb.replace(/\\/.*\\//, "/"+val+"/");
						else if (lang_class(romn)==lc)
							msurn=romn.replace(/\\/.*\\//, "/"+val+"/");
					}
					document.getElementById(marnm_id).value=msurn;
					document.getElementById(marnm_id+"_display").innerHTML=msurn;
				} else {
					marnm_id=ip[i].id;
				}
			}
		}
	}

	// Toggle the name editor fields between
	// <input type="hidden"> <span style="display:inline">
	// <input type="text">   <span style="display:hidden">
	var oldName = "";
	var manualChange = false;
	function convertHidden(eid) {
		var input1 = jQuery("#" + eid);
		var input2 = jQuery("#" + eid + "_display");
		// Note that IE does not allow us to change the type of an input, so we must create a new one.
		if (input1.attr("type")=="hidden") {
			input1.replaceWith(input1.clone().attr("type", "text"));
			input2.hide();
		} else {
			input1.replaceWith(input1.clone().attr("type", "hidden"));
			input2.show();
		}
	}

	/**
	 * if the user manually changed the NAME field, then update the textual
	 * HTML representation of it
	 * If the value changed set manualChange to true so that changing
	 * the other fields doesn’t change the NAME line
	 */
	function updateTextName(eid) {
		var element = document.getElementById(eid);
		if (element) {
			if (element.value!=oldName) manualChange = true;
			var delement = document.getElementById(eid+"_display");
			if (delement) {
				delement.innerHTML = element.value;
			}
		}
	}

	function checkform() {
		var ip=document.getElementsByTagName("input");
		for (var i=0; i<ip.length; i++) {
			// ADD slashes to _HEB and _AKA names
			if (ip[i].id.indexOf("_AKA")==0 || ip[i].id.indexOf("_HEB")==0 || ip[i].id.indexOf("ROMN")==0)
				if (ip[i].value.indexOf("/")<0 && ip[i].value!="")
					ip[i].value=ip[i].value.replace(/([^\\s]+)\\s*$/, "/$1/");
			// Blank out temporary _MARNM_SURN
			if (ip[i].id.indexOf("_MARNM_SURN")==0)
					ip[i].value="";
			// Convert "xxx yyy" and "xxx y yyy" surnames to "xxx,yyy"
			if ((SURNAME_TRADITION=="spanish" || "SURNAME_TRADITION"=="portuguese") && ip[i].id.indexOf("SURN")==0) {
				ip[i].value=document.forms[0].SURN.value.replace(/^\\s*([^\\s,]{2,})\\s+([iIyY] +)?([^\\s,]{2,})\\s*$/, "$1,$3");
			}
		}
		return true;
	}

	// If the name isn’t initially formed from the components in a standard way,
	// then don’t automatically update it.
	if (document.getElementById("NAME").value!=generate_name() && document.getElementById("NAME").value!="//") {
		convertHidden("NAME");
	}
	');
    echo '</div>';
}