getParent();
// Some facts don't get printed here ...
switch ($fact->getTag()) {
case 'NOTE':
print_main_notes($fact, 1);
return;
case 'SOUR':
print_main_sources($fact, 1);
return;
case 'OBJE':
print_main_media($fact, 1);
return;
case 'FAMC':
case 'FAMS':
case 'CHIL':
case 'HUSB':
case 'WIFE':
// These are internal links, not facts
return;
case '_WT_OBJE_SORT':
// These links are used internally to record the sort order.
return;
default:
// Hide unrecognised/custom tags?
if ($HIDE_GEDCOM_ERRORS && !WT_Gedcom_Tag::isTag($fact->getTag())) {
return;
}
break;
}
// Who is this fact about? Need it to translate fact label correctly
if ($parent instanceof WT_Family && $record instanceof WT_Individual) {
// Family event
$label_person = $fact->getParent()->getSpouse($record);
} else {
// Individual event
$label_person=$parent;
}
// New or deleted facts need different styling
$styleadd='';
if ($fact->isNew()) {
$styleadd = 'new';
}
if ($fact->isOld()) {
$styleadd = 'old';
}
// Event of close relative
if (preg_match('/^_[A-Z_]{3,5}_[A-Z0-9]{4}$/', $fact->getTag())) {
$styleadd = trim($styleadd . ' rela');
}
// Event of close associates
if ($fact->getFactId()=='asso') {
$styleadd = trim($styleadd . ' rela');
}
// historical facts
if ($fact->getFactId()=='histo') {
$styleadd = trim($styleadd . ' histo');
}
// Does this fact have a type?
if (preg_match('/\n2 TYPE (.+)/', $fact->getGedcom(), $match)) {
$type=$match[1];
} else {
$type='';
}
switch ($fact->getTag()) {
case 'EVEN':
case 'FACT':
if (WT_Gedcom_Tag::isTag($type)) {
// Some users (just Meliza?) use "1 EVEN/2 TYPE BIRT". Translate the TYPE.
$label=WT_Gedcom_Tag::getLabel($type, $label_person);
$type=''; // Do not print this again
} elseif ($type) {
// We don't have a translation for $type - but a custom translation might exist.
$label=WT_I18N::translate(htmlspecialchars($type));
$type=''; // Do not print this again
} else {
// An unspecified fact/event
$label=WT_Gedcom_Tag::getLabel($fact->getTag(), $label_person);
}
break;
case 'MARR':
// This is a hack for a proprietory extension. Is it still used/needed?
$utype = strtoupper($type);
if ($utype=='CIVIL' || $utype=='PARTNERS' || $utype=='RELIGIOUS') {
$label=WT_Gedcom_Tag::getLabel('MARR_'.$utype, $label_person);
$type=''; // Do not print this again
} else {
$label=WT_Gedcom_Tag::getLabel($fact->getTag(), $label_person);
}
break;
default:
// Normal fact/event
$label=WT_Gedcom_Tag::getLabel($fact->getTag(), $label_person);
break;
}
echo '
';
echo '';
if ($SHOW_FACT_ICONS) {
echo $fact->Icon(), ' ';
}
if ($fact->getFactId()!='histo' && $fact->canEdit()) {
?>
getTag()) {
case '_BIRT_CHIL':
echo ' ', WT_I18N::translate('#%d', ++$n_chil);
break;
case '_BIRT_GCHI':
case '_BIRT_GCH1':
case '_BIRT_GCH2':
echo ' ', WT_I18N::translate('#%d', ++$n_gchi);
break;
}
echo ' | ';
// Print the spouse and family of this fact/event
if ($parent instanceof WT_Family && $record instanceof WT_Individual) {
foreach ($parent->getSpouses() as $spouse) {
if (!$record === $spouse) {
echo '', $spouse->getFullName(), ' - ';
}
}
// Family events on an individual page
echo '', WT_I18N::translate('View Family'), ' ';
}
// Print the value of this fact/event
switch ($fact->getTag()) {
case 'ADDR':
echo $fact->getValue();
break;
case 'AFN':
echo '';
break;
case 'ASSO':
// we handle this later, in print_asso_rela_record()
break;
case 'EMAIL':
case 'EMAI':
case '_EMAIL':
echo '';
break;
case 'FILE':
if (WT_USER_CAN_EDIT || WT_USER_CAN_ACCEPT) {
echo '', htmlspecialchars($fact->getValue()), ' ';
}
break;
case 'RESN':
echo '';
switch ($fact->getValue()) {
case 'none':
// Note: "1 RESN none" is not valid gedcom.
// However, webtrees privacy rules will interpret it as "show an otherwise private record to public".
echo ' ', WT_I18N::translate('Show to visitors');
break;
case 'privacy':
echo ' ', WT_I18N::translate('Show to members');
break;
case 'confidential':
echo ' ', WT_I18N::translate('Show to managers');
break;
case 'locked':
echo ' ', WT_I18N::translate('Only managers can edit');
break;
default:
echo htmlspecialchars($fact->getValue());
break;
}
echo ' ';
break;
case 'PUBL': // Publication details might contain URLs.
echo '', expand_urls(htmlspecialchars($fact->getValue())), ' ';
break;
case 'REPO':
if (preg_match('/^@('.WT_REGEX_XREF.')@$/', $fact->getValue(), $match)) {
print_repository_record($match[1]);
} else {
echo '', htmlspecialchars($fact->getValue()), ' ';
}
break;
case 'URL':
case 'WWW':
echo '';
break;
case 'TEXT': // 0 SOUR / 1 TEXT
echo '', nl2br(htmlspecialchars($fact->getValue()), false), ' ';
break;
default:
// Display the value for all other facts/events
switch ($fact->getValue()) {
case '':
// Nothing to display
break;
case 'N':
// Not valid GEDCOM
echo '', WT_I18N::translate('No'), ' ';
break;
case 'Y':
// Do not display "Yes".
break;
default:
if (preg_match('/^@('.WT_REGEX_XREF.')@$/', $fact->getValue(), $match)) {
$target=WT_GedcomRecord::getInstance($match[1]);
if ($target) {
echo '';
} else {
echo '', htmlspecialchars($fact->getValue()), ' ';
}
} else {
echo '', htmlspecialchars($fact->getValue()), ' ';
}
break;
}
break;
}
// Print the type of this fact/event
if ($type) {
// We don't have a translation for $type - but a custom translation might exist.
echo WT_Gedcom_Tag::getLabelValue('TYPE', WT_I18N::translate(htmlspecialchars($type)));
}
// Print the date of this fact/event
echo format_fact_date($fact, $record, true, true);
// Print the place of this fact/event
echo '', format_fact_place($fact, true, true, true), ' ';
// A blank line between the primary attributes (value, date, place) and the secondary ones
echo ' ';
$addr = $fact->getAttribute('ADDR');
if ($addr) {
echo WT_Gedcom_Tag::getLabelValue('ADDR', $addr);
}
// Print the associates of this fact/event
print_asso_rela_record($fact, $record);
// Print any other "2 XXXX" attributes, in the order in which they appear.
preg_match_all('/\n2 ('.WT_REGEX_TAG.') (.+)/', $fact->getGedcom(), $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
switch ($match[1]) {
case 'DATE':
case 'TIME':
case 'AGE':
case 'PLAC':
case 'ADDR':
case 'ALIA':
case 'ASSO':
case '_ASSO':
case 'DESC':
case 'RELA':
case 'STAT':
case 'TEMP':
case 'TYPE':
case 'FAMS':
case 'CONT':
// These were already shown at the beginning
break;
case 'NOTE':
case 'OBJE':
case 'SOUR':
// These will be shown at the end
break;
case 'EVEN': // 0 SOUR / 1 DATA / 2 EVEN / 3 DATE / 3 PLAC
$events=array();
foreach (preg_split('/ *, */', $match[2]) as $event) {
$events[]=WT_Gedcom_Tag::getLabel($event);
}
if (count($events)==1) echo WT_Gedcom_Tag::getLabelValue('EVEN', $event);
else echo WT_Gedcom_Tag::getLabelValue('EVEN', implode(WT_I18N::$list_separator, $events));
if (preg_match('/\n3 DATE (.+)/', $fact->getGedcom(), $date_match)) {
$date=new WT_Date($date_match[1]);
echo WT_Gedcom_Tag::getLabelValue('DATE', $date->Display());
}
if (preg_match('/\n3 PLAC (.+)/', $fact->getGedcom(), $plac_match)) {
echo WT_Gedcom_Tag::getLabelValue('PLAC', $plac_match[1]);
}
break;
case 'FAMC': // 0 INDI / 1 ADOP / 2 FAMC / 3 ADOP
$family=WT_Family::getInstance(str_replace('@', '', $match[2]));
if ($family) { // May be a pointer to a non-existant record
echo WT_Gedcom_Tag::getLabelValue('FAM', ''.$family->getFullName().'');
if (preg_match('/\n3 ADOP (HUSB|WIFE|BOTH)/', $fact->getGedcom(), $match)) {
echo WT_Gedcom_Tag::getLabelValue('ADOP', WT_Gedcom_Code_Adop::getValue($match[1], $label_person));
}
} else {
echo WT_Gedcom_Tag::getLabelValue('FAM', ''.$match[2].'');
}
break;
case '_WT_USER':
$fullname=getUserFullname(get_user_id($match[2])); // may not exist
if ($fullname) {
echo WT_Gedcom_Tag::getLabelValue('_WT_USER', $fullname);
} else {
echo WT_Gedcom_Tag::getLabelValue('_WT_USER', htmlspecialchars($match[2]));
}
break;
case 'RESN':
switch ($match[2]) {
case 'none':
// Note: "2 RESN none" is not valid gedcom.
// However, webtrees privacy rules will interpret it as "show an otherwise private fact to public".
echo WT_Gedcom_Tag::getLabelValue('RESN', ' '.WT_I18N::translate('Show to visitors'));
break;
case 'privacy':
echo WT_Gedcom_Tag::getLabelValue('RESN', ' '.WT_I18N::translate('Show to members'));
break;
case 'confidential':
echo WT_Gedcom_Tag::getLabelValue('RESN', ' '.WT_I18N::translate('Show to managers'));
break;
case 'locked':
echo WT_Gedcom_Tag::getLabelValue('RESN', ' '.WT_I18N::translate('Only managers can edit'));
break;
default:
echo WT_Gedcom_Tag::getLabelValue('RESN', htmlspecialchars($match[2]));
break;
}
break;
case 'CALN':
echo WT_Gedcom_Tag::getLabelValue('CALN', expand_urls($match[2]));
break;
case 'FORM': // 0 OBJE / 1 FILE / 2 FORM / 3 TYPE
echo WT_Gedcom_Tag::getLabelValue('FORM', $match[2]);
if (preg_match('/\n3 TYPE (.+)/', $fact->getGedcom(), $type_match)) {
echo WT_Gedcom_Tag::getLabelValue('TYPE', WT_Gedcom_Tag::getFileFormTypeValue($type_match[1]));
}
break;
default:
if (!$HIDE_GEDCOM_ERRORS || WT_Gedcom_Tag::isTag($match[1])) {
if (preg_match('/^@(' . WT_REGEX_XREF . ')@$/', $match[2], $xmatch)) {
// Links
$linked_record = WT_GedcomRecord::getInstance($xmatch[1]);
if ($linked_record) {
$link = '' . $linked_record->getFullName() . '';
echo WT_Gedcom_Tag::getLabelValue($fact->getTag().':'.$match[1], $link);
} else {
echo WT_Gedcom_Tag::getLabelValue($fact->getTag().':'.$match[1], htmlspecialchars($match[2]));
}
} else {
// Non links
echo WT_Gedcom_Tag::getLabelValue($fact->getTag().':'.$match[1], htmlspecialchars($match[2]));
}
}
break;
}
}
// -- find source for each fact
print_fact_sources($fact->getGedcom(), 2);
// -- find notes for each fact
print_fact_notes($fact->getGedcom(), 2);
//-- find media objects
print_media_links($fact->getGedcom(), 2, $parent->getXref());
echo ' |
';
}
//------------------- end print fact function
/**
* print a repository record
*
* find and print repository information attached to a source
* @param string $sid the Gedcom Xref ID of the repository to print
*/
function print_repository_record($xref) {
$repository=WT_Repository::getInstance($xref);
if ($repository && $repository->canShow()) {
echo '';
echo '';
$temp = 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 = trim($ematch[1]);
echo $factname;
} else {
echo WT_Gedcom_Tag::getLabel($factname, $parent);
}
} else
if ($can_edit) {
echo "';
if ($SHOW_FACT_ICONS) {
if ($level==1) echo ' ';
}
echo WT_Gedcom_Tag::getLabel($factname, $parent), '';
echo '';
echo " ";
echo ' ';
echo " ";
echo ' ';
} else {
echo WT_Gedcom_Tag::getLabel($factname, $parent);
}
echo ' | ';
echo '';
if ($source) {
echo '', $source->getFullName(), '';
// PUBL
$publ = $source->getFirstFact('PUBL');
if ($publ) {
echo WT_Gedcom_Tag::getLabelValue('PUBL', $publ->getValue());
}
// 2 RESN tags. Note, there can be more than one, such as "privacy" and "locked"
if (preg_match_all("/\n2 RESN (.+)/", $factrec, $rmatches)) {
foreach ($rmatches[1] as $rmatch) {
echo ' ', WT_Gedcom_Tag::getLabel('RESN'), ': ';
switch ($rmatch) {
case 'none':
// Note: "2 RESN none" is not valid gedcom, and the GUI will not let you add it.
// However, webtrees privacy rules will interpret it as "show an otherwise private fact to public".
echo ' ', WT_I18N::translate('Show to visitors');
break;
case 'privacy':
echo ' ', WT_I18N::translate('Show to members');
break;
case 'confidential':
echo ' ', WT_I18N::translate('Show to managers');
break;
case 'locked':
echo ' ', WT_I18N::translate('Only managers can edit');
break;
default:
echo $rmatch;
break;
}
echo '';
}
}
$cs = preg_match("/$nlevel EVEN (.*)/", $srec, $cmatch);
if ($cs>0) {
echo ' ', WT_Gedcom_Tag::getLabel('EVEN'), ' ', $cmatch[1], '';
$cs = preg_match("/".($nlevel+1)." ROLE (.*)/", $srec, $cmatch);
if ($cs>0) echo ' ', WT_Gedcom_Tag::getLabel('ROLE'), ' ', $cmatch[1], '';
}
echo printSourceStructure(getSourceStructure($srec));
echo '';
print_media_links($srec, $nlevel);
if ($nlevel==2) {
print_media_links($source->getGedcom(), 1);
}
print_fact_notes($srec, $nlevel);
if ($nlevel==2) {
print_fact_notes($source->getGedcom(), 1);
}
echo ' ';
} else {
echo $sid;
}
echo ' |
';
}
}
}
/**
* Print SOUR structure
*
* This function prints the input array of SOUR sub-records built by the
* getSourceStructure() function.
*/
function printSourceStructure($textSOUR) {
$html='';
if ($textSOUR['PAGE']) {
$html.='getGedcom();
$fact_id = $fact->getFactId();
$parent = $fact->getParent();
$pid = $parent->getXref();
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();
}
$ct = preg_match_all("/$level NOTE(.*)/", $factrec, $match, PREG_SET_ORDER);
for ($j=0; $j<$ct; $j++) {
if ($level>=2) echo '';
else echo '
';
echo '';
if ($can_edit) {
echo '';
if ($level<2) {
if ($SHOW_FACT_ICONS) {
echo ' ';
}
if (strstr($factrec, "1 NOTE @" )) {
echo WT_Gedcom_Tag::getLabel('SHARED_NOTE');
} else {
echo WT_Gedcom_Tag::getLabel('NOTE');
}
echo '';
echo '';
echo " ";
echo ' ';
echo " ";
echo ' ';
}
} else {
if ($level<2) {
if ($SHOW_FACT_ICONS) {
echo ' ';
}
if (strstr($factrec, "1 NOTE @" )) {
echo WT_Gedcom_Tag::getLabel('SHARED_NOTE');
} else {
echo WT_Gedcom_Tag::getLabel('NOTE');
}
}
$factlines = explode("\n", $factrec); // 1 BIRT Y\n2 NOTE ...
$factwords = explode(" ", $factlines[0]); // 1 BIRT Y
$factname = $factwords[1]; // BIRT
$parent=WT_GedcomRecord::getInstance($pid);
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 = trim($ematch[1]);
echo $factname;
} else {
echo WT_Gedcom_Tag::getLabel($factname, $parent);
}
} else if ($factname != 'NOTE') {
// Note is already printed
echo WT_Gedcom_Tag::getLabel($factname, $parent);
}
}
echo ' | ';
$nrec = get_sub_record($level, "$level NOTE", $factrec, $j+1);
if (preg_match("/$level NOTE @(.*)@/", $match[$j][0], $nmatch)) {
//-- print linked/shared note records
$nid = $nmatch[1];
$note=WT_Note::getInstance($nid);
if ($note) {
$text = $note->getNote();
// If Census assistant installed,
if ($fact->getTag()=='CENS' && array_key_exists('GEDFact_assistant', WT_Module::getActiveModules())) {
$centitl = str_replace('~~', '', $line1);
$centitl = str_replace('
', '', $centitl);
$centitl = "" . $centitl . '';
require WT_ROOT.WT_MODULES_DIR.'GEDFact_assistant/_CENS/census_note_decode.php';
} else {
$text = expand_urls($text);
}
} else {
$text = '' . htmlspecialchars($nid) . '';
}
} else {
//-- print embedded note records
$text = $match[$j][1] . get_cont($level+1, $nrec);
$text = expand_urls($text);
}
echo '';
echo ' ', $text, ' ';
if (!empty($noterec)) print_fact_sources($noterec, 1);
// 2 RESN tags. Note, there can be more than one, such as "privacy" and "locked"
if (preg_match_all("/\n2 RESN (.+)/", $factrec, $matches)) {
foreach ($matches[1] as $match) {
echo ' ', WT_Gedcom_Tag::getLabel('RESN'), ': ';
switch ($match) {
case 'none':
// Note: "2 RESN none" is not valid gedcom, and the GUI will not let you add it.
// However, webtrees privacy rules will interpret it as "show an otherwise private fact to public".
echo ' ', WT_I18N::translate('Show to visitors');
break;
case 'privacy':
echo ' ', WT_I18N::translate('Show to members');
break;
case 'confidential':
echo ' ', WT_I18N::translate('Show to managers');
break;
case 'locked':
echo ' ', WT_I18N::translate('Only managers can edit');
break;
default:
echo $match;
break;
}
echo '';
}
}
echo ' ';
print_fact_sources($nrec, $level+1);
echo ' |
';
}
}
// Print a row for the media tab on the individual page
function print_main_media(WT_Fact $fact, $level) {
$factrec = $fact->getGedcom();
$fact_id = $fact->getFactId();
$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 '';
} else {
echo '
';
}
echo '';
$temp = 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 '';
echo WT_Gedcom_Tag::getLabel($factname, $parent), '';
echo '';
echo ' ';
echo ' ';
echo ' ';
echo ' ';
} else {
echo WT_Gedcom_Tag::getLabel($factname, $parent);
}
echo ' | ';
echo '';
if ($media) {
echo '';
echo $media->displayImage();
if (empty($SEARCH_SPIDER)) {
echo '';
}
echo '';
foreach ($media->getAllNames() as $name) {
if ($name['type']!='TITL') echo ' ';
echo $name['full'];
}
echo '';
if (empty($SEARCH_SPIDER)) {
echo '';
}
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));
}
echo '';
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;
}
print_fact_notes($media->getGedcom(), 1);
print_fact_sources($media->getGedcom(), 1);
} else {
echo $xref;
}
echo ' |
';
}
}
}