/**
* add a new tag input field
*
* called for each fact to be edited on a form.
* Fact level=0 means a new empty form : data are POSTed by name
* else data are POSTed using arrays :
* glevels[] : tag level
* islink[] : tag is a link
* tag[] : tag name
* text[] : tag value
*
* @param string $tag fact record to edit (eg 2 DATE xxxxx)
* @param string $upperlevel optional upper level tag (eg BIRT)
* @param string $label An optional label to echo instead of the default
* @param string $extra optional text to display after the input field
* @param Individual $person For male/female translations
*
* @return string
*/
public static function addSimpleTag($tag, $upperlevel = '', $label = '', $extra = null, Individual $person = null)
{
global $tags, $main_fact, $xref, $bdm, $action, $WT_TREE;
// Keep track of SOUR fields, so we can reference them in subsequent PAGE fields.
static $source_element_id;
$subnamefacts = array('NPFX', 'GIVN', 'SPFX', 'SURN', 'NSFX', '_MARNM_SURN');
preg_match('/^(?:(\\d+) (' . WT_REGEX_TAG . ') ?(.*))/', $tag, $match);
list(, $level, $fact, $value) = $match;
$level = (int) $level;
// element name : used to POST data
if ($level === 0) {
if ($upperlevel) {
$element_name = $upperlevel . '_' . $fact;
} else {
$element_name = $fact;
}
} else {
$element_name = 'text[]';
}
if ($level === 1) {
$main_fact = $fact;
}
// element id : used by javascript functions
if ($level === 0) {
$element_id = $fact;
} else {
$element_id = $fact . Uuid::uuid4();
}
if ($upperlevel) {
$element_id = $upperlevel . '_' . $fact . Uuid::uuid4();
}
// field value
$islink = substr($value, 0, 1) === '@' && substr($value, 0, 2) !== '@#';
if ($islink) {
$value = trim(substr($tag, strlen($fact) + 3), ' @\\r');
} else {
$value = (string) substr($tag, strlen($fact) + 3);
}
if ($fact === 'REPO' || $fact === 'SOUR' || $fact === 'OBJE' || $fact === 'FAMC') {
$islink = true;
}
if ($fact === 'SHARED_NOTE_EDIT' || $fact === 'SHARED_NOTE') {
$islink = true;
$fact = 'NOTE';
}
// label
echo '<tr id="', $element_id, '_tr"';
if ($fact === 'MAP' || ($fact === 'LATI' || $fact === 'LONG') && $value === '') {
echo ' style="display:none;"';
}
echo '>';
if (in_array($fact, $subnamefacts) || $fact === 'LATI' || $fact === 'LONG') {
echo '<td class="optionbox wrap width25">';
} else {
echo '<td class="descriptionbox wrap width25">';
}
// tag name
if ($label) {
echo $label;
} elseif ($upperlevel) {
echo GedcomTag::getLabel($upperlevel . ':' . $fact);
} else {
echo GedcomTag::getLabel($fact);
}
// If using GEDFact-assistant window
if ($action === 'addnewnote_assisted') {
// Do not print on GEDFact Assistant window
} else {
// Not all facts have help text.
switch ($fact) {
case 'NAME':
if ($upperlevel !== 'REPO' && $upperlevel !== 'UNKNOWN') {
echo FunctionsPrint::helpLink($fact);
}
break;
case 'DATE':
case 'PLAC':
case 'RESN':
case 'ROMN':
case 'SURN':
case '_HEB':
echo FunctionsPrint::helpLink($fact);
break;
}
}
// tag level
if ($level > 0) {
if ($fact === 'TEXT' && $level > 1) {
echo '<input type="hidden" name="glevels[]" value="', $level - 1, '">';
echo '<input type="hidden" name="islink[]" value="0">';
echo '<input type="hidden" name="tag[]" value="DATA">';
// leave data text[] value empty because the following TEXT line will cause the DATA to be added
echo '<input type="hidden" name="text[]" value="">';
}
echo '<input type="hidden" name="glevels[]" value="', $level, '">';
echo '<input type="hidden" name="islink[]" value="', $islink, '">';
echo '<input type="hidden" name="tag[]" value="', $fact, '">';
}
echo '</td>';
// value
echo '<td class="optionbox wrap">';
// retrieve linked NOTE
if ($fact === 'NOTE' && $islink) {
$note1 = Note::getInstance($value, $WT_TREE);
if ($note1) {
$noterec = $note1->getGedcom();
preg_match('/' . $value . '/i', $noterec, $notematch);
$value = $notematch[0];
}
}
// Show names for spouses in MARR/HUSB/AGE and MARR/WIFE/AGE
if ($fact === 'HUSB' || $fact === 'WIFE') {
$family = Family::getInstance($xref, $WT_TREE);
if ($family) {
$spouse_link = $family->getFirstFact($fact);
if ($spouse_link) {
$spouse = $spouse_link->getTarget();
if ($spouse) {
echo $spouse->getFullName();
}
}
}
}
if (in_array($fact, Config::emptyFacts()) && ($value === '' || $value === 'Y' || $value === 'y')) {
echo '<input type="hidden" id="', $element_id, '" name="', $element_name, '" value="', $value, '">';
if ($level <= 1) {
echo '<input type="checkbox" ';
if ($value) {
echo 'checked';
}
echo ' onclick="document.getElementById(\'' . $element_id . '\').value = (this.checked) ? \'Y\' : \'\';">';
echo I18N::translate('yes');
}
if ($fact === 'CENS' && $value === 'Y') {
echo self::censusDateSelector(WT_LOCALE, $xref);
if (Module::getModuleByName('GEDFact_assistant') && GedcomRecord::getInstance($xref, $WT_TREE) instanceof Individual) {
echo '<div></div><a href="#" style="display: none;" id="assistant-link" onclick="return activateCensusAssistant();">' . I18N::translate('Create a new shared note using assistant') . '</a></div>';
}
}
} elseif ($fact === 'TEMP') {
echo self::selectEditControl($element_name, GedcomCodeTemp::templeNames(), I18N::translate('No temple - living ordinance'), $value);
} elseif ($fact === 'ADOP') {
echo self::editFieldAdoption($element_name, $value, '', $person);
} elseif ($fact === 'PEDI') {
echo self::editFieldPedigree($element_name, $value, '', $person);
} elseif ($fact === 'STAT') {
echo self::selectEditControl($element_name, GedcomCodeStat::statusNames($upperlevel), '', $value);
} elseif ($fact === 'RELA') {
echo self::editFieldRelationship($element_name, strtolower($value));
} elseif ($fact === 'QUAY') {
echo self::selectEditControl($element_name, GedcomCodeQuay::getValues(), '', $value);
} elseif ($fact === '_WT_USER') {
echo self::editFieldUsername($element_name, $value);
} elseif ($fact === 'RESN') {
echo self::editFieldRestriction($element_name, $value);
} elseif ($fact === '_PRIM') {
echo '<select id="', $element_id, '" name="', $element_name, '" >';
echo '<option value=""></option>';
echo '<option value="Y" ';
if ($value === 'Y') {
echo ' selected';
}
echo '>', I18N::translate('always'), '</option>';
echo '<option value="N" ';
if ($value === 'N') {
echo 'selected';
}
echo '>', I18N::translate('never'), '</option>';
echo '</select>';
echo '<p class="small text-muted">', I18N::translate('Use this image for charts and on the individual’s page.'), '</p>';
} elseif ($fact === 'SEX') {
echo '<select id="', $element_id, '" name="', $element_name, '"><option value="M" ';
if ($value === 'M') {
echo 'selected';
}
echo '>', I18N::translate('Male'), '</option><option value="F" ';
if ($value === 'F') {
echo 'selected';
}
echo '>', I18N::translate('Female'), '</option><option value="U" ';
if ($value === 'U' || empty($value)) {
echo 'selected';
}
echo '>', I18N::translateContext('unknown gender', 'Unknown'), '</option></select>';
} elseif ($fact === 'TYPE' && $level === 3) {
//-- Build the selector for the Media 'TYPE' Fact
echo '<select name="text[]"><option selected value="" ></option>';
$selectedValue = strtolower($value);
if (!array_key_exists($selectedValue, GedcomTag::getFileFormTypes())) {
echo '<option selected value="', Filter::escapeHtml($value), '" >', Filter::escapeHtml($value), '</option>';
}
foreach (GedcomTag::getFileFormTypes() as $typeName => $typeValue) {
echo '<option value="', $typeName, '" ';
if ($selectedValue === $typeName) {
echo 'selected';
}
echo '>', $typeValue, '</option>';
}
echo '</select>';
} elseif ($fact === 'NAME' && $upperlevel !== 'REPO' && $upperlevel !== 'UNKNOWN' || $fact === '_MARNM') {
// Populated in javascript from sub-tags
echo '<input type="hidden" id="', $element_id, '" name="', $element_name, '" onchange="updateTextName(\'', $element_id, '\');" value="', Filter::escapeHtml($value), '" class="', $fact, '">';
echo '<span id="', $element_id, '_display" dir="auto">', Filter::escapeHtml($value), '</span>';
echo ' <a href="#edit_name" onclick="convertHidden(\'', $element_id, '\'); return false;" class="icon-edit_indi" title="' . I18N::translate('Edit name') . '"></a>';
} else {
// textarea
if ($fact === 'TEXT' || $fact === 'ADDR' || $fact === 'NOTE' && !$islink) {
echo '<textarea id="', $element_id, '" name="', $element_name, '" dir="auto">', Filter::escapeHtml($value), '</textarea><br>';
} else {
// text
// If using GEDFact-assistant window
if ($action === 'addnewnote_assisted') {
echo '<input type="text" id="', $element_id, '" name="', $element_name, '" value="', Filter::escapeHtml($value), '" style="width:4.1em;" dir="ltr"';
} else {
echo '<input type="text" id="', $element_id, '" name="', $element_name, '" value="', Filter::escapeHtml($value), '" dir="ltr"';
}
echo ' class="', $fact, '"';
if (in_array($fact, $subnamefacts)) {
echo ' onblur="updatewholename();" onkeyup="updatewholename();"';
}
// Extra markup for specific fact types
switch ($fact) {
case 'ALIA':
case 'ASSO':
case '_ASSO':
echo ' data-autocomplete-type="ASSO" data-autocomplete-extra="input.DATE"';
break;
case 'DATE':
echo ' onblur="valid_date(this);" onmouseout="valid_date(this);"';
break;
case 'GIVN':
echo ' autofocus data-autocomplete-type="GIVN"';
break;
case 'LATI':
echo ' onblur="valid_lati_long(this, \'N\', \'S\');" onmouseout="valid_lati_long(this, \'N\', \'S\');"';
break;
case 'LONG':
echo ' onblur="valid_lati_long(this, \'E\', \'W\');" onmouseout="valid_lati_long(this, \'E\', \'W\');"';
break;
case 'NOTE':
// Shared notes. Inline notes are handled elsewhere.
echo ' data-autocomplete-type="NOTE"';
break;
case 'OBJE':
echo ' data-autocomplete-type="OBJE"';
break;
case 'PAGE':
echo ' data-autocomplete-type="PAGE" data-autocomplete-extra="#' . $source_element_id . '"';
break;
case 'PLAC':
echo ' data-autocomplete-type="PLAC"';
break;
case 'REPO':
echo ' data-autocomplete-type="REPO"';
break;
case 'SOUR':
$source_element_id = $element_id;
echo ' data-autocomplete-type="SOUR"';
break;
case 'SURN':
case '_MARNM_SURN':
echo ' data-autocomplete-type="SURN"';
break;
case 'TIME':
echo ' pattern="([0-1][0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?" dir="ltr" placeholder="' . I18N::translate('hh:mm or hh:mm:ss') . '"';
break;
}
echo '>';
}
$tmp_array = array('TYPE', 'TIME', 'NOTE', 'SOUR', 'REPO', 'OBJE', 'ASSO', '_ASSO', 'AGE');
// split PLAC
if ($fact === 'PLAC') {
echo '<div id="', $element_id, '_pop" style="display: inline;">';
echo FunctionsPrint::printSpecialCharacterLink($element_id), ' ', FunctionsPrint::printFindPlaceLink($element_id);
echo '<span onclick="jQuery(\'tr[id^=', $upperlevel, '_LATI],tr[id^=', $upperlevel, '_LONG],tr[id^=LATI],tr[id^=LONG]\').toggle(\'fast\'); return false;" class="icon-target" title="', GedcomTag::getLabel('LATI'), ' / ', GedcomTag::getLabel('LONG'), '"></span>';
echo '</div>';
if (Module::getModuleByName('places_assistant')) {
\PlacesAssistantModule::setup_place_subfields($element_id);
\PlacesAssistantModule::print_place_subfields($element_id);
}
} elseif (!in_array($fact, $tmp_array)) {
echo FunctionsPrint::printSpecialCharacterLink($element_id);
}
}
// MARRiage TYPE : hide text field and show a selection list
if ($fact === 'TYPE' && $level === 2 && $tags[0] === 'MARR') {
echo '<script>';
echo 'document.getElementById(\'', $element_id, '\').style.display=\'none\'';
echo '</script>';
echo '<select id="', $element_id, '_sel" onchange="document.getElementById(\'', $element_id, '\').value=this.value;" >';
foreach (array('Unknown', 'Civil', 'Religious', 'Partners') as $key) {
if ($key === 'Unknown') {
echo '<option value="" ';
} else {
echo '<option value="', $key, '" ';
}
$a = strtolower($key);
$b = strtolower($value);
if ($b !== '' && strpos($a, $b) !== false || strpos($b, $a) !== false) {
echo 'selected';
}
echo '>', GedcomTag::getLabel('MARR_' . strtoupper($key)), '</option>';
}
echo '</select>';
} elseif ($fact === 'TYPE' && $level === 0) {
// NAME TYPE : hide text field and show a selection list
$onchange = 'onchange="document.getElementById(\'' . $element_id . '\').value=this.value;"';
echo self::editFieldNameType($element_name, $value, $onchange, $person);
echo '<script>document.getElementById("', $element_id, '").style.display="none";</script>';
}
// popup links
switch ($fact) {
case 'DATE':
echo self::printCalendarPopup($element_id);
break;
case 'FAMC':
case 'FAMS':
echo FunctionsPrint::printFindFamilyLink($element_id);
break;
case 'ALIA':
case 'ASSO':
case '_ASSO':
echo FunctionsPrint::printFindIndividualLink($element_id, $element_id . '_description');
break;
case 'FILE':
FunctionsPrint::printFindMediaLink($element_id, '0file');
break;
case 'SOUR':
echo FunctionsPrint::printFindSourceLink($element_id, $element_id . '_description'), ' ', self::printAddNewSourceLink($element_id);
//-- checkboxes to apply '1 SOUR' to BIRT/MARR/DEAT as '2 SOUR'
if ($level === 1) {
echo '<br>';
switch ($WT_TREE->getPreference('PREFER_LEVEL2_SOURCES')) {
case '2':
// records
$level1_checked = 'checked';
$level2_checked = '';
break;
case '1':
// facts
$level1_checked = '';
$level2_checked = 'checked';
break;
case '0':
// none
// none
default:
$level1_checked = '';
$level2_checked = '';
break;
}
if (strpos($bdm, 'B') !== false) {
echo ' <label><input type="checkbox" name="SOUR_INDI" ', $level1_checked, ' value="1">', I18N::translate('Individual'), '</label>';
if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
foreach ($matches[1] as $match) {
if (!in_array($match, explode('|', WT_EVENTS_DEAT))) {
echo ' <label><input type="checkbox" name="SOUR_', $match, '" ', $level2_checked, ' value="1">', GedcomTag::getLabel($match), '</label>';
}
}
}
}
if (strpos($bdm, 'D') !== false) {
if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
foreach ($matches[1] as $match) {
if (in_array($match, explode('|', WT_EVENTS_DEAT))) {
echo ' <label><input type="checkbox" name="SOUR_', $match, '"', $level2_checked, ' value="1">', GedcomTag::getLabel($match), '</label>';
}
}
}
}
if (strpos($bdm, 'M') !== false) {
echo ' <label><input type="checkbox" name="SOUR_FAM" ', $level1_checked, ' value="1">', I18N::translate('Family'), '</label>';
if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) {
foreach ($matches[1] as $match) {
echo ' <label><input type="checkbox" name="SOUR_', $match, '"', $level2_checked, ' value="1">', GedcomTag::getLabel($match), '</label>';
}
}
}
}
break;
case 'REPO':
echo FunctionsPrint::printFindRepositoryLink($element_id), ' ', self::printAddNewRepositoryLink($element_id);
break;
case 'NOTE':
// Shared Notes Icons ========================================
if ($islink) {
// Print regular Shared Note icons ---------------------------
echo ' ', FunctionsPrint::printFindNoteLink($element_id, $element_id . '_description'), ' ', self::printAddNewNoteLink($element_id);
if ($value) {
echo ' ', self::printEditNoteLink($value);
}
}
break;
case 'OBJE':
echo FunctionsPrint::printFindMediaLink($element_id, '1media');
if (!$value) {
echo ' ', self::printAddNewMediaLink($element_id);
$value = 'new';
}
break;
}
echo '<div id="' . $element_id . '_description">';
// current value
if ($fact === 'DATE') {
$date = new Date($value);
echo $date->display();
}
if (($fact === 'ASSO' || $fact === '_ASSO') && $value === '') {
if ($level === 1) {
echo '<p class="small text-muted">' . I18N::translate('An associate is another individual who was involved with this individual, such as a friend or an employer.') . '</p>';
} else {
echo '<p class="small text-muted">' . I18N::translate('An associate is another individual who was involved with this fact or event, such as a witness or a priest.') . '</p>';
}
}
if ($value && $value !== 'new' && $islink) {
switch ($fact) {
case 'ALIA':
case 'ASSO':
case '_ASSO':
$tmp = Individual::getInstance($value, $WT_TREE);
if ($tmp) {
echo ' ', $tmp->getFullName();
}
break;
case 'SOUR':
$tmp = Source::getInstance($value, $WT_TREE);
if ($tmp) {
echo ' ', $tmp->getFullName();
}
break;
case 'NOTE':
$tmp = Note::getInstance($value, $WT_TREE);
if ($tmp) {
echo ' ', $tmp->getFullName();
}
break;
case 'OBJE':
$tmp = Media::getInstance($value, $WT_TREE);
if ($tmp) {
echo ' ', $tmp->getFullName();
}
break;
case 'REPO':
$tmp = Repository::getInstance($value, $WT_TREE);
if ($tmp) {
echo ' ', $tmp->getFullName();
}
break;
}
}
// pastable values
if ($fact === 'FORM' && $upperlevel === 'OBJE') {
FunctionsPrint::printAutoPasteLink($element_id, Config::fileFormats());
}
echo '</div>', $extra, '</td></tr>';
return $element_id;
}