Exemplo n.º 1
0
 /**
  * print information for a name record
  *
  * @param WT_Fact $event the event object
  */
 function print_name_record(WT_Fact $event)
 {
     global $WT_TREE;
     $factrec = $event->getGedcom();
     // Create a dummy record, so we can extract the formatted NAME value from the event.
     $dummy = new WT_Individual('xref', "0 @xref@ INDI\n1 DEAT Y\n" . $factrec, null, WT_GED_ID);
     $all_names = $dummy->getAllNames();
     $primary_name = $all_names[0];
     $this->name_count++;
     if ($this->name_count > 1) {
         echo '<h3 class="name_two">', $dummy->getFullName(), '</h3>';
     }
     //Other names accordion element
     echo '<div class="indi_name_details';
     if ($event->isOld()) {
         echo ' old';
     }
     if ($event->isNew()) {
         echo ' new';
     }
     echo '">';
     echo '<div class="name1">';
     echo '<dl><dt class="label">', WT_I18N::translate('Name'), '</dt>';
     $dummy->setPrimaryName(0);
     echo '<dd class="field">', $dummy->getFullName();
     if ($this->name_count == 1) {
         if (Auth::isAdmin()) {
             $user = User::findByGenealogyRecord($WT_TREE, $this->record);
             if ($user) {
                 echo '<span> - <a class="warning" href="admin_users.php?filter=' . WT_Filter::escapeHtml($user->getUserName()) . '">' . WT_Filter::escapeHtml($user->getUserName()) . '</a></span>';
             }
         }
     }
     if ($this->record->canEdit() && !$event->isOld()) {
         echo "<div class=\"deletelink\"><a class=\"deleteicon\" href=\"#\" onclick=\"return delete_fact('" . WT_I18N::translate('Are you sure you want to delete this fact?') . "', '" . $this->record->getXref() . "', '" . $event->getFactId() . "');\" title=\"" . WT_I18N::translate('Delete this name') . "\"><span class=\"link_text\">" . WT_I18N::translate('Delete this name') . "</span></a></div>";
         echo "<div class=\"editlink\"><a href=\"#\" class=\"editicon\" onclick=\"edit_name('" . $this->record->getXref() . "', '" . $event->getFactId() . "'); return false;\" title=\"" . WT_I18N::translate('Edit name') . "\"><span class=\"link_text\">" . WT_I18N::translate('Edit name') . "</span></a></div>";
     }
     echo '</dd>';
     echo '</dl>';
     echo '</div>';
     $ct = preg_match_all('/\\n2 (\\w+) (.*)/', $factrec, $nmatch, PREG_SET_ORDER);
     for ($i = 0; $i < $ct; $i++) {
         echo '<div>';
         $fact = $nmatch[$i][1];
         if ($fact != 'SOUR' && $fact != 'NOTE' && $fact != 'SPFX') {
             echo '<dl><dt class="label">', WT_Gedcom_Tag::getLabel($fact, $this->record), '</dt>';
             echo '<dd class="field">';
             // Before using dir="auto" on this field, note that Gecko treats this as an inline element but WebKit treats it as a block element
             if (isset($nmatch[$i][2])) {
                 $name = WT_Filter::escapeHtml($nmatch[$i][2]);
                 $name = str_replace('/', '', $name);
                 $name = preg_replace('/(\\S*)\\*/', '<span class="starredname">\\1</span>', $name);
                 switch ($fact) {
                     case 'TYPE':
                         echo WT_Gedcom_Code_Name::getValue($name, $this->record);
                         break;
                     case 'SURN':
                         // The SURN field is not necessarily the surname.
                         // Where it is not a substring of the real surname, show it after the real surname.
                         $surname = WT_Filter::escapeHtml($primary_name['surname']);
                         if (strpos($primary_name['surname'], str_replace(',', ' ', $nmatch[$i][2])) !== false) {
                             echo $surname;
                         } else {
                             echo WT_I18N::translate('%1$s (%2$s)', $surname, $name);
                         }
                         break;
                     default:
                         echo $name;
                         break;
                 }
             }
             echo '</dd>';
             echo '</dl>';
         }
         echo '</div>';
     }
     if (preg_match("/\n2 SOUR/", $factrec)) {
         echo '<div id="indi_sour" class="clearfloat">', print_fact_sources($factrec, 2), '</div>';
     }
     if (preg_match("/\n2 NOTE/", $factrec)) {
         echo '<div id="indi_note" class="clearfloat">', print_fact_notes($factrec, 2), '</div>';
     }
     echo '</div>';
 }
Exemplo n.º 2
0
function print_main_media(WT_Fact $fact, $level)
{
    $factrec = $fact->getGedcom();
    $parent = $fact->getParent();
    if ($fact->isNew()) {
        $styleadd = 'new';
        $can_edit = $level == 1 && $fact->canEdit();
    } elseif ($fact->isOld()) {
        $styleadd = 'old';
        $can_edit = false;
    } else {
        $styleadd = '';
        $can_edit = $level == 1 && $fact->canEdit();
    }
    // -- find source for each fact
    preg_match_all('/(?:^|\\n)' . $level . ' OBJE @(.*)@/', $factrec, $matches);
    foreach ($matches[1] as $xref) {
        $media = WT_Media::getInstance($xref);
        // Allow access to "1 OBJE @non_existent_source@", so it can be corrected/deleted
        if (!$media || $media->canShow()) {
            if ($level > 1) {
                echo '<tr class="row_obje2">';
            } else {
                echo '<tr>';
            }
            echo '<td class="descriptionbox';
            if ($level > 1) {
                echo ' rela';
            }
            echo ' ', $styleadd, ' width20">';
            preg_match("/^\\d (\\w*)/", $factrec, $factname);
            $factlines = explode("\n", $factrec);
            // 1 BIRT Y\n2 SOUR ...
            $factwords = explode(" ", $factlines[0]);
            // 1 BIRT Y
            $factname = $factwords[1];
            // BIRT
            if ($factname == 'EVEN' || $factname == 'FACT') {
                // Add ' EVEN' to provide sensible output for an event with an empty TYPE record
                $ct = preg_match("/2 TYPE (.*)/", $factrec, $ematch);
                if ($ct > 0) {
                    $factname = $ematch[1];
                    echo $factname;
                } else {
                    echo WT_Gedcom_Tag::getLabel($factname, $parent);
                }
            } else {
                if ($can_edit) {
                    echo '<a onclick="window.open(\'addmedia.php?action=editmedia&amp;pid=', $media->getXref(), '\', \'_blank\', edit_window_specs); return false;" href="#" title="', WT_I18N::translate('Edit'), '">';
                    echo WT_Gedcom_Tag::getLabel($factname, $parent), '</a>';
                    echo '<div class="editfacts">';
                    echo '<div class="editlink"><a class="editicon" onclick="window.open(\'addmedia.php?action=editmedia&amp;pid=', $media->getXref(), '\', \'_blank\', edit_window_specs); return false;" href="#" title="', WT_I18N::translate('Edit'), '"><span class="link_text">', WT_I18N::translate('Edit'), '</span></a></div>';
                    echo '<div class="copylink"><a class="copyicon" href="#" onclick="jQuery.post(\'action.php\',{action:\'copy-fact\', type:\'\', factgedcom:\'' . rawurlencode($factrec) . '\'},function(){location.reload();})" title="' . WT_I18N::translate('Copy') . '"><span class="link_text">' . WT_I18N::translate('Copy') . '</span></a></div>';
                    echo '<div class="deletelink"><a class="deleteicon" onclick="return delete_fact(\'', WT_I18N::translate('Are you sure you want to delete this fact?'), '\', \'', $parent->getXref(), '\', \'', $fact->getFactId(), '\');" href="#" title="', WT_I18N::translate('Delete'), '"><span class="link_text">', WT_I18N::translate('Delete'), '</span></a></div>';
                    echo '</div>';
                } else {
                    echo WT_Gedcom_Tag::getLabel($factname, $parent);
                }
            }
            echo '</td>';
            echo '<td class="optionbox ', $styleadd, ' wrap">';
            if ($media) {
                echo '<span class="field">';
                echo $media->displayImage();
                if (empty($SEARCH_SPIDER)) {
                    echo '<a href="' . $media->getHtmlUrl() . '">';
                }
                echo '<em>';
                foreach ($media->getAllNames() as $name) {
                    if ($name['type'] != 'TITL') {
                        echo '<br>';
                    }
                    echo $name['full'];
                }
                echo '</em>';
                if (empty($SEARCH_SPIDER)) {
                    echo '</a>';
                }
                echo '</span>';
                echo WT_Gedcom_Tag::getLabelValue('FORM', $media->mimeType());
                $imgsize = $media->getImageAttributes('main');
                if (!empty($imgsize['WxH'])) {
                    echo WT_Gedcom_Tag::getLabelValue('__IMAGE_SIZE__', $imgsize['WxH']);
                }
                if ($media->getFilesizeraw() > 0) {
                    echo WT_Gedcom_Tag::getLabelValue('__FILE_SIZE__', $media->getFilesize());
                }
                $mediatype = $media->getMediaType();
                if ($mediatype) {
                    echo WT_Gedcom_Tag::getLabelValue('TYPE', WT_Gedcom_Tag::getFileFormTypeValue($mediatype));
                }
                switch ($media->isPrimary()) {
                    case 'Y':
                        echo WT_Gedcom_Tag::getLabelValue('_PRIM', WT_I18N::translate('yes'));
                        break;
                    case 'N':
                        echo WT_Gedcom_Tag::getLabelValue('_PRIM', WT_I18N::translate('no'));
                        break;
                }
                echo print_fact_notes($media->getGedcom(), 1);
                echo print_fact_sources($media->getGedcom(), 1);
            } else {
                echo $xref;
            }
            echo '</td></tr>';
        }
    }
}
Exemplo n.º 3
0
function create_edit_form(WT_GedcomRecord $record, WT_Fact $fact)
{
    global $ADVANCED_PLAC_FACTS, $date_and_time, $FULL_SOURCES, $tags;
    $pid = $record->getXref();
    $tags = array();
    $gedlines = explode("\n", $fact->getGedcom());
    $linenum = 0;
    $fields = explode(' ', $gedlines[$linenum]);
    $glevel = $fields[0];
    $level = $glevel;
    $type = $fact->getTag();
    $parent = $fact->getParent();
    $level0type = $parent::RECORD_TYPE;
    $level1type = $type;
    $i = $linenum;
    $inSource = false;
    $levelSource = 0;
    $add_date = true;
    // List of tags we would expect at the next level
    // NB add_missing_subtags() already takes care of the simple cases
    // where a level 1 tag is missing a level 2 tag.  Here we only need to
    // handle the more complicated cases.
    $expected_subtags = array('SOUR' => array('PAGE', 'DATA'), 'DATA' => array('TEXT'), 'PLAC' => array('MAP'), 'MAP' => array('LATI', 'LONG'));
    if ($FULL_SOURCES) {
        $expected_subtags['SOUR'][] = 'QUAY';
        $expected_subtags['DATA'][] = 'DATE';
    }
    if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $ADVANCED_PLAC_FACTS, $match)) {
        $expected_subtags['PLAC'] = array_merge($match[1], $expected_subtags['PLAC']);
    }
    $stack = array(0 => $level0type);
    // Loop on existing tags :
    while (true) {
        // Keep track of our hierarchy, e.g. 1=>BIRT, 2=>PLAC, 3=>FONE
        $stack[(int) $level] = $type;
        // Merge them together, e.g. BIRT:PLAC:FONE
        $label = implode(':', array_slice($stack, 1, $level));
        $text = '';
        for ($j = 2; $j < count($fields); $j++) {
            if ($j > 2) {
                $text .= ' ';
            }
            $text .= $fields[$j];
        }
        $text = rtrim($text);
        while ($i + 1 < count($gedlines) && preg_match("/" . ($level + 1) . " CONT ?(.*)/", $gedlines[$i + 1], $cmatch) > 0) {
            $text .= "\n" . $cmatch[1];
            $i++;
        }
        if ($type == "SOUR") {
            $inSource = true;
            $levelSource = $level;
        } elseif ($levelSource >= $level) {
            $inSource = false;
        }
        if ($type != "DATA" && $type != "CONT") {
            $tags[] = $type;
            $person = WT_Individual::getInstance($pid);
            $subrecord = $level . ' ' . $type . ' ' . $text;
            if ($inSource && $type == "DATE") {
                add_simple_tag($subrecord, '', WT_Gedcom_Tag::getLabel($label, $person));
            } elseif (!$inSource && $type == "DATE") {
                add_simple_tag($subrecord, $level1type, WT_Gedcom_Tag::getLabel($label, $person));
                $add_date = false;
            } elseif ($type == 'STAT') {
                add_simple_tag($subrecord, $level1type, WT_Gedcom_Tag::getLabel($label, $person));
            } elseif ($level0type == 'REPO') {
                $repo = WT_Repository::getInstance($pid);
                add_simple_tag($subrecord, $level0type, WT_Gedcom_Tag::getLabel($label, $repo));
            } else {
                add_simple_tag($subrecord, $level0type, WT_Gedcom_Tag::getLabel($label, $person));
            }
        }
        // Get a list of tags present at the next level
        $subtags = array();
        for ($ii = $i + 1; isset($gedlines[$ii]) && preg_match('/^\\s*(\\d+)\\s+(\\S+)/', $gedlines[$ii], $mm) && $mm[1] > $level; ++$ii) {
            if ($mm[1] == $level + 1) {
                $subtags[] = $mm[2];
            }
        }
        // Insert missing tags
        if (!empty($expected_subtags[$type])) {
            foreach ($expected_subtags[$type] as $subtag) {
                if (!in_array($subtag, $subtags)) {
                    if (!$inSource || $subtag != "DATA") {
                        add_simple_tag($level + 1 . ' ' . $subtag, '', WT_Gedcom_Tag::getLabel("{$label}:{$subtag}"));
                    }
                    if (!empty($expected_subtags[$subtag])) {
                        foreach ($expected_subtags[$subtag] as $subsubtag) {
                            add_simple_tag($level + 2 . ' ' . $subsubtag, '', WT_Gedcom_Tag::getLabel("{$label}:{$subtag}:{$subsubtag}"));
                        }
                    }
                }
            }
        }
        // Awkward special cases
        if ($level == 2 && $type == 'DATE' && in_array($level1type, $date_and_time) && !in_array('TIME', $subtags)) {
            add_simple_tag("3 TIME");
            // TIME is NOT a valid 5.5.1 tag
        }
        if ($level == 2 && $type == 'STAT' && WT_Gedcom_Code_Temp::isTagLDS($level1type) && !in_array('DATE', $subtags)) {
            add_simple_tag("3 DATE", '', WT_Gedcom_Tag::getLabel('STAT:DATE'));
        }
        $i++;
        if (isset($gedlines[$i])) {
            $fields = explode(' ', $gedlines[$i]);
            $level = $fields[0];
            if (isset($fields[1])) {
                $type = trim($fields[1]);
            } else {
                $level = 0;
            }
        } else {
            $level = 0;
        }
        if ($level <= $glevel) {
            break;
        }
    }
    if ($level1type != '_PRIM') {
        insert_missing_subtags($level1type, $add_date);
    }
    return $level1type;
}
Exemplo n.º 4
0
/**
 * print fact PLACe TEMPle STATus
 *
 * @param WT_Fact $event       gedcom fact record
 * @param bool    $anchor      to print a link to placelist
 * @param bool    $sub_records to print place subrecords
 * @param bool    $lds         to print LDS TEMPle and STATus
 *
 * @return string HTML
 */
function format_fact_place(WT_Fact $event, $anchor = false, $sub_records = false, $lds = false)
{
    global $SEARCH_SPIDER;
    if ($anchor) {
        // Show the full place name, for facts/events tab
        if ($SEARCH_SPIDER) {
            $html = $event->getPlace()->getFullName();
        } else {
            $html = '<a href="' . $event->getPlace()->getURL() . '">' . $event->getPlace()->getFullName() . '</a>';
        }
    } else {
        // Abbreviate the place name, for chart boxes
        return ' - ' . $event->getPlace()->getShortName();
    }
    if ($sub_records) {
        $placerec = get_sub_record(2, '2 PLAC', $event->getGedcom());
        if (!empty($placerec)) {
            if (preg_match_all('/\\n3 (?:_HEB|ROMN) (.+)/', $placerec, $matches)) {
                foreach ($matches[1] as $match) {
                    $wt_place = new WT_Place($match, WT_GED_ID);
                    $html .= ' - ' . $wt_place->getFullName();
                }
            }
            $map_lati = "";
            $cts = preg_match('/\\d LATI (.*)/', $placerec, $match);
            if ($cts > 0) {
                $map_lati = $match[1];
                $html .= '<br><span class="label">' . WT_Gedcom_Tag::getLabel('LATI') . ': </span>' . $map_lati;
            }
            $map_long = '';
            $cts = preg_match('/\\d LONG (.*)/', $placerec, $match);
            if ($cts > 0) {
                $map_long = $match[1];
                $html .= ' <span class="label">' . WT_Gedcom_Tag::getLabel('LONG') . ': </span>' . $map_long;
            }
            if ($map_lati && $map_long) {
                $map_lati = trim(strtr($map_lati, "NSEW,�", " - -. "));
                // S5,6789 ==> -5.6789
                $map_long = trim(strtr($map_long, "NSEW,�", " - -. "));
                // E3.456� ==> 3.456
                $html .= ' <a rel="nofollow" href="https://maps.google.com/maps?q=' . $map_lati . ',' . $map_long . '" class="icon-googlemaps" title="' . WT_I18N::translate('Google Maps™') . '"></a>';
                $html .= ' <a rel="nofollow" href="https://www.bing.com/maps/?lvl=15&cp=' . $map_lati . '~' . $map_long . '" class="icon-bing" title="' . WT_I18N::translate('Bing Maps™') . '"></a>';
                $html .= ' <a rel="nofollow" href="https://www.openstreetmap.org/#map=15/' . $map_lati . '/' . $map_long . '" class="icon-osm" title="' . WT_I18N::translate('OpenStreetMap™') . '"></a>';
            }
            if (preg_match('/\\d NOTE (.*)/', $placerec, $match)) {
                $html .= '<br>' . print_fact_notes($placerec, 3);
            }
        }
    }
    if ($lds) {
        if (preg_match('/2 TEMP (.*)/', $event->getGedcom(), $match)) {
            $html .= '<br>' . WT_I18N::translate('LDS temple') . ': ' . WT_Gedcom_Code_Temp::templeName($match[1]);
        }
        if (preg_match('/2 STAT (.*)/', $event->getGedcom(), $match)) {
            $html .= '<br>' . WT_I18N::translate('Status') . ': ' . WT_Gedcom_Code_Stat::statusName($match[1]);
            if (preg_match('/3 DATE (.*)/', $event->getGedcom(), $match)) {
                $date = new WT_Date($match[1]);
                $html .= ', ' . WT_Gedcom_Tag::getLabel('STAT:DATE') . ': ' . $date->Display(false);
            }
        }
    }
    return $html;
}
Exemplo n.º 5
0
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>';
}