/** * 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>'; }
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&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&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>'; } } }
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; }
/** * 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; }
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&xref=', $xref, '&fact_id=', $name_fact->getFactId(), '&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>'; }