function add_family_descendancy($famid, $level = "") { global $cart; if (!$famid) { return; } $famrec = find_family_record($famid); if ($famrec) { $parents = find_parents_in_record($famrec); if (!empty($parents["HUSB"])) { $clipping = array(); $clipping['type'] = "indi"; $clipping['id'] = $parents["HUSB"]; $this->add_clipping($clipping); } if (!empty($parents["WIFE"])) { $clipping = array(); $clipping['type'] = "indi"; $clipping['id'] = $parents["WIFE"]; $this->add_clipping($clipping); } $num = preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $famrec, $smatch, PREG_SET_ORDER); for ($i = 0; $i < $num; $i++) { $cfamids = find_sfamily_ids($smatch[$i][1]); if (count($cfamids) > 0) { foreach ($cfamids as $indexval => $cfamid) { if (!id_in_cart($cfamid)) { $clipping = array(); $clipping['type'] = "fam"; $clipping['id'] = $cfamid; $ret = $this->add_clipping($clipping); // add the childs family if ($level == "" || $level > 0) { if ($level != "") { $level--; } $this->add_family_descendancy($cfamid, $level); // recurse on the childs family } } } } else { $clipping = array(); $clipping['type'] = "indi"; $clipping['id'] = $smatch[$i][1]; $this->add_clipping($clipping); } } } }
/** * print ASSO RELA information * * Ex1: * <code>1 ASSO @I1@ * 2 RELA Twin</code> * * Ex2: * <code>1 CHR * 2 ASSO @I1@ * 3 RELA Godfather * 2 ASSO @I2@ * 3 RELA Godmother</code> * * @param string $pid person or family ID * @param string $factrec the raw gedcom record to print * @param string $linebr optional linebreak */ function print_asso_rela_record($pid, $factrec, $linebr = false) { global $GEDCOM, $SHOW_ID_NUMBERS, $TEXT_DIRECTION, $pgv_lang, $factarray, $PGV_IMAGE_DIR, $PGV_IMAGES, $view; // get ASSOciate(s) ID(s) $ct = preg_match_all("/\\d ASSO @(.*)@/", $factrec, $match, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { $level = substr($match[$i][0], 0, 1); $pid2 = $match[$i][1]; // get RELAtionship field $assorec = get_sub_record($level, "{$level} ASSO ", $factrec, $i + 1); // if (substr($_SERVER["SCRIPT_NAME"],1) == "pedigree.php") { $rct = preg_match("/\\d RELA (.*)/", $assorec, $rmatch); if ($rct > 0) { // RELAtionship name in user language $key = strtolower(trim($rmatch[1])); $cr = preg_match_all("/sosa_(.*)/", $key, $relamatch, PREG_SET_ORDER); if ($cr > 0) { $rela = get_sosa_name($relamatch[0][1]); } else { if (isset($pgv_lang["{$key}"])) { $rela = $pgv_lang[$key]; } else { $rela = $rmatch[1]; } } $p = strpos($rela, "(="); if ($p > 0) { $rela = trim(substr($rela, 0, $p)); } if ($pid2 == $pid) { print "<span class=\"details_label\">"; } print $rela . ": "; if ($pid2 == $pid) { print "</span>"; } } else { $rela = $factarray["RELA"]; } // default // } // ASSOciate ID link $gedrec = find_gedcom_record($pid2); if (strstr($gedrec, "@ INDI") !== false or strstr($gedrec, "@ SUBM") !== false) { // ID name if (DisplayDetailsByID($pid2) || showLivingNameByID($pid2)) { $name = get_person_name($pid2); $addname = get_add_person_name($pid2); } else { $name = $pgv_lang["private"]; $addname = ""; } print "<a href=\"individual.php?pid={$pid2}&ged={$GEDCOM}\">" . PrintReady($name); // if (!empty($addname)) print "<br />" . PrintReady($addname); if (!empty($addname)) { print " - " . PrintReady($addname); } if ($SHOW_ID_NUMBERS) { print " "; if ($TEXT_DIRECTION == "rtl") { print "‏"; } print "(" . $pid2 . ")"; if ($TEXT_DIRECTION == "rtl") { print "‏"; } } print "</a>"; // ID age if (!strstr($factrec, "_BIRT_")) { $dct = preg_match("/2 DATE (.*)/", $factrec, $dmatch); if ($dct > 0) { print " <span class=\"age\">" . get_age($gedrec, $dmatch[1]) . "</span>"; } } // RELAtionship calculation : for a family print relationship to both spouses if ($view != "preview") { $famrec = find_family_record($pid); if ($famrec) { $parents = find_parents_in_record($famrec); $pid1 = $parents["HUSB"]; if ($pid1 and $pid1 != $pid2) { print " - <a href=\"relationship.php?pid1={$pid1}&pid2={$pid2}&followspouse=1&ged={$GEDCOM}\">[" . $pgv_lang["relationship_chart"] . "<img src=\"{$PGV_IMAGE_DIR}/" . $PGV_IMAGES["sex"]["small"] . "\" title=\"" . $pgv_lang["husband"] . "\" alt=\"" . $pgv_lang["husband"] . "\" class=\"sex_image\" />]</a>"; } $pid1 = $parents["WIFE"]; if ($pid1 and $pid1 != $pid2) { print " - <a href=\"relationship.php?pid1={$pid1}&pid2={$pid2}&followspouse=1&ged={$GEDCOM}\">[" . $pgv_lang["relationship_chart"] . "<img src=\"{$PGV_IMAGE_DIR}/" . $PGV_IMAGES["sexf"]["small"] . "\" title=\"" . $pgv_lang["wife"] . "\" alt=\"" . $pgv_lang["wife"] . "\" class=\"sex_image\" />]</a>"; } } else { if ($pid != $pid2) { print " - <a href=\"relationship.php?pid1={$pid}&pid2={$pid2}&followspouse=1&ged={$GEDCOM}\">[" . $pgv_lang["relationship_chart"] . "]</a>"; } } } } else { if (strstr($gedrec, "@ FAM") !== false) { print "<a href=\"family.php?famid={$pid2}\">"; if ($TEXT_DIRECTION == "ltr") { print " ‎"; } else { print " ‏"; } print "[" . $pgv_lang["view_family"]; if ($SHOW_ID_NUMBERS) { print " ‎({$pid2})‎"; } if ($TEXT_DIRECTION == "ltr") { print "‎]</a>\n"; } else { print "‏]</a>\n"; } } else { print $pgv_lang["unknown"]; if ($SHOW_ID_NUMBERS) { print " "; if ($TEXT_DIRECTION == "rtl") { print "‏"; } print "(" . $pid2 . ")"; if ($TEXT_DIRECTION == "rtl") { print "‏"; } } } } if ($linebr) { print "<br />\n"; } print_fact_notes($assorec, $level + 1); if (substr($_SERVER["SCRIPT_NAME"], 1) == "pedigree.php") { print "<br />"; if (function_exists('print_fact_sources')) { print_fact_sources($assorec, $level + 1); } } } }
/** * prints a form to add an individual or edit an individual's name * * @param string $nextaction the next action the edit_interface.php file should take after the form is submitted * @param string $famid the family that the new person should be added to * @param string $namerec the name subrecord when editing a name * @param string $famtag how the new person is added to the family */ function print_indi_form($nextaction, $famid, $linenum = "", $namerec = "", $famtag = "CHIL", $sextag = "") { global $pgv_lang, $factarray, $pid, $PGV_IMAGE_DIR, $PGV_IMAGES, $WORD_WRAPPED_NOTES; global $NPFX_accept, $SPFX_accept, $NSFX_accept, $FILE_FORM_accept, $GEDCOM, $NAME_REVERSE; global $bdm, $TEXT_DIRECTION, $STANDARD_NAME_FACTS, $REVERSED_NAME_FACTS, $ADVANCED_NAME_FACTS, $ADVANCED_PLAC_FACTS, $SURNAME_TRADITION; global $QUICK_REQUIRED_FACTS, $QUICK_REQUIRED_FAMFACTS; $bdm = ""; // used to copy '1 SOUR' to '2 SOUR' for BIRT DEAT MARR init_calendar_popup(); echo "<form method=\"post\" name=\"addchildform\" onsubmit=\"return checkform();\">\n"; echo "<input type=\"hidden\" name=\"action\" value=\"{$nextaction}\" />\n"; echo "<input type=\"hidden\" name=\"linenum\" value=\"{$linenum}\" />\n"; echo "<input type=\"hidden\" name=\"famid\" value=\"{$famid}\" />\n"; echo "<input type=\"hidden\" name=\"pid\" value=\"{$pid}\" />\n"; echo "<input type=\"hidden\" name=\"famtag\" value=\"{$famtag}\" />\n"; echo "<input type=\"submit\" value=\"" . $pgv_lang["save"] . "\" />\n"; echo "<input type=\"hidden\" name=\"goto\" value=\"\" />\n"; if (preg_match('/^add(child|spouse|newparent|newrepository)/', $nextaction)) { echo "<input type=\"submit\" value=\"{$pgv_lang['saveandgo']}\" onclick=\"document.addchildform.goto.value='new';\"/>\n"; } echo "<table class=\"facts_table\">"; // When adding a new child, specify the pedigree if ($nextaction == 'addchildaction') { add_simple_tag("0 PEDI"); } // Populate the standard NAME field and subfields $name_fields = array(); if (!$NAME_REVERSE) { foreach ($STANDARD_NAME_FACTS as $tag) { $name_fields[$tag] = get_gedcom_value($tag, 0, $namerec); } } else { foreach ($REVERSED_NAME_FACTS as $tag) { $name_fields[$tag] = get_gedcom_value($tag, 0, $namerec); } } $new_marnm = ''; // Inherit surname from parents, spouse or child if (empty($namerec)) { // We'll need the parent's name to set the child's surname if (isset($pgv_changes[$famid . "_" . $GEDCOM])) { $famrec = find_updated_record($famid); } else { $famrec = find_family_record($famid); } $parents = find_parents_in_record($famrec); $father_name = get_gedcom_value('NAME', 0, find_person_record($parents['HUSB'])); $mother_name = get_gedcom_value('NAME', 0, find_person_record($parents['WIFE'])); // We'll need the spouse/child's name to set the spouse/parent's surname if (isset($pgv_changes[$pid . "_" . $GEDCOM])) { $prec = find_updated_record($pid); } else { $prec = find_person_record($pid); } $indi_name = get_gedcom_value('NAME', 0, $prec); // 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 'addchildaction': 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 'addnewparentaction': 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; } break; case 'portuguese': //Mother: Maria /AAAA BBBB/ //Father: Jose /CCCC DDDD/ //Child: Pablo /BBBB DDDD/ switch ($nextaction) { case 'addchildaction': 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 'addnewparentaction': 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; } break; case 'icelandic': // Sons get their father's given name plus "sson" // Daughters get their father's given name plus "sdottir" switch ($nextaction) { case 'addchildaction': if ($sextag == 'M' && preg_match('/(\\S+)\\s+\\/.*\\//', $father_name, $match)) { $name_fields['SURN'] = preg_replace('/s$/', '', $match[1]) . 'sson'; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } if ($sextag == '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 'addnewparentaction': 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; } break; case 'paternal': case 'polish': // Father gives his surname to his wife and children switch ($nextaction) { case 'addspouseaction': if ($famtag == 'WIFE' && preg_match('/\\/(.*)\\//', $indi_name, $match)) { if ($SURNAME_TRADITION == 'polish') { $match[1] = preg_replace(array('/ski$/', '/cki$/', '/dzki$/'), array('ska', 'cka', 'dzka'), $match[1]); } $new_marnm = $match[1]; } break; case 'addchildaction': if (preg_match('/\\/((?:[a-z]{2,3}\\s+)*)(.*)\\//i', $father_name, $match)) { if ($SURNAME_TRADITION == 'polish' && $sextag == 'F') { $match[2] = preg_replace(array('/ski$/', '/cki$/', '/dzki$/'), array('ska', 'cka', 'dzka'), $match[2]); } $name_fields['SPFX'] = trim($match[1]); $name_fields['SURN'] = $match[2]; $name_fields['NAME'] = "/{$match[1]}{$match[2]}/"; } break; case 'addnewparentaction': if ($famtag == 'HUSB' && preg_match('/\\/((?:[a-z]{2,3}\\s+)*)(.*)\\//i', $indi_name, $match)) { if ($SURNAME_TRADITION == 'polish' && $sextag == 'M') { $match[2] = preg_replace(array('/ska$/', '/cka$/', '/dzka$/'), array('ski', 'cki', 'dzki'), $match[2]); } $name_fields['SPFX'] = trim($match[1]); $name_fields['SURN'] = $match[2]; $name_fields['NAME'] = "/{$match[1]}{$match[2]}/"; } break; } break; } } // Make sure there are two slashes in the name if (!preg_match('/\\//', $name_fields['NAME'])) { $name_fields['NAME'] .= ' /'; } if (!preg_match('/\\/.*\\//', $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 (!$NAME_REVERSE && empty($name_fields['GIVN'])) { $name_fields['GIVN'] = $name_bits[4]; } if (empty($name_fields['SPFX']) && empty($name_fields['SURN'])) { $name_fields['SPFX'] = trim($name_bits[7]); $name_fields['SURN'] = $name_bits[9]; } if (empty($name_fields['NSFX'])) { $name_fields['NSFX'] = $name_bits[10]; } if ($NAME_REVERSE && 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('/(' . PGV_REGEX_TAG . ')/', $ADVANCED_NAME_FACTS, $match)) { foreach ($match[1] as $tag) { $adv_name_fields[$tag] = ''; } } // This is a custom tag, but PGV uses it extensively. if ($SURNAME_TRADITION == 'paternal' || $SURNAME_TRADITION == 'polish' || preg_match('/2 _MARNM/', $namerec)) { $adv_name_fields['_MARNM'] = ''; } 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}", "", fact_label("NAME:{$tag}")); } } } // 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') { add_simple_tag("0 _MARNM"); add_simple_tag("0 _MARNM_SURN {$new_marnm}"); } else { add_simple_tag("0 {$tag}", "", fact_label("NAME:{$tag}")); } } } // Handle any other NAME subfields that aren't included above (SOUR, NOTE, _CUSTOM, etc) if ($namerec != "" && $namerec != "NEW") { $gedlines = split("\n", $namerec); // -- find the number of lines in the record $fields = explode(' ', $gedlines[0]); $glevel = $fields[0]; $level = $glevel; $type = trim($fields[1]); $level1type = $type; $tags = array(); $i = 0; do { if (!isset($name_fields[$type]) && !isset($adv_name_fields[$type])) { $text = ""; for ($j = 2; $j < count($fields); $j++) { if ($j > 2) { $text .= " "; } $text .= $fields[$j]; } $iscont = false; while ($i + 1 < count($gedlines) && preg_match("/" . ($level + 1) . " (CON[CT])\\s?(.*)/", $gedlines[$i + 1], $cmatch) > 0) { $iscont = true; 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" || $sextag == "M") { add_simple_tag("0 SEX M"); } elseif ($famtag == "WIFE" || $sextag == "F") { add_simple_tag("0 SEX F"); } else { add_simple_tag("0 SEX"); } $bdm = "BD"; if (preg_match_all('/(' . PGV_REGEX_TAG . ')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (!in_array($match, explode('|', PGV_EVENTS_DEAT))) { addSimpleTags($match); } } } //-- if adding a spouse add the option to add a marriage fact to the new family if ($nextaction == 'addspouseaction' || $nextaction == 'addnewparentaction' && $famid != 'new') { $bdm .= "M"; if (preg_match_all('/(' . PGV_REGEX_TAG . ')/', $QUICK_REQUIRED_FAMFACTS, $matches)) { foreach ($matches[1] as $match) { addSimpleTags($match); } } } if (preg_match_all('/(' . PGV_REGEX_TAG . ')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (in_array($match, explode('|', PGV_EVENTS_DEAT))) { addSimpleTags($match); } } } } if (PGV_USER_IS_ADMIN) { echo "<tr><td class=\"descriptionbox " . $TEXT_DIRECTION . " wrap width25\">"; print_help_link("no_update_CHAN_help", "qm"); echo $pgv_lang["admin_override"] . "</td><td class=\"optionbox wrap\">\n"; echo "<input type=\"checkbox\" name=\"preserve_last_changed\" />\n"; echo $pgv_lang["no_update_CHAN"] . "<br />\n"; if (isset($famrec)) { $event = new Event(get_sub_record(1, "1 CHAN", $famrec)); echo format_fact_date($event, false, true); } echo "</td></tr>\n"; } echo "</table>\n"; 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('NOTE', 1); print_add_layer('SHARED_NOTE', 1); print_add_layer('OBJE', 1); } echo "<input type=\"submit\" value=\"" . $pgv_lang["save"] . "\" />\n"; if (preg_match('/^add(child|spouse|newparent|source)/', $nextaction)) { echo "<input type=\"submit\" value=\"{$pgv_lang['saveandgo']}\" onclick=\"document.addchildform.goto.value='new';\"/>\n"; } echo "</form>\n"; ?> <script type="text/javascript"> <!-- function trim(str) { // 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 the NAME field, and will form part of the displayed // name. This is not encouraged, as it may confuse some logic that assumes // "list" format names are always "surn, givn". str=str.replace(/,/g," "); 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; return trim(npfx+" "+givn+" /"+trim(spfx+" "+surn.replace(/ *, */, " "))+"/ "+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').innerHTML=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; } } } } /** * convert a hidden field to a text box */ var oldName = ""; var manualChange = false; function convertHidden(eid) { var element = document.getElementById(eid); if (element) { if (element.type=="hidden") { // IE doesn't allow changing the "type" of an input field so we'll cludge it ( silly :P) if (IE) { var newInput = document.createElement('input'); newInput.setAttribute("type", "text"); newInput.setAttribute("name", element.Name); newInput.setAttribute("id", element.id); newInput.setAttribute("value", element.value); newInput.setAttribute("onchange", element.onchange); var parent = element.parentNode; parent.replaceChild(newInput, element); element = newInput; } else { element.type="text"; } element.size="40"; oldName = element.value; manualChange = true; var delement = document.getElementById(eid+"_display"); if (delement) { delement.style.display='none'; // force FF ui to update the display if (delement.innerHTML != oldName) { oldName = delement.innerHTML; element.value = oldName; } } } else { manualChange = false; // IE doesn't allow changing the "type" of an input field so we'll cludge it ( silly :P) if (IE) { var newInput = document.createElement('input'); newInput.setAttribute("type", "hidden"); newInput.setAttribute("name", element.Name); newInput.setAttribute("id", element.id); newInput.setAttribute("value", element.value); newInput.setAttribute("onchange", element.onchange); var parent = element.parentNode; parent.replaceChild(newInput, element); element = newInput; } else { element.type="hidden"; } var delement = document.getElementById(eid+"_display"); if (delement) { delement.style.display='inline'; } } } } /** * 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 and empty name fields if (ip[i].id.indexOf("_MARNM_SURN")==0 || ip[i].value=='//') ip[i].value=''; // Convert "xxx yyy" and "xxx y yyy" surnames to "xxx,yyy" if ('<?php echo $SURNAME_TRADITION; ?> '=='spanish' || '<?php echo $SURNAME_TRADITION; ?> '=='portuguese') if (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"); //--> </script> <?php }
// TODO: this should be a parameter to a function, not a global $show_cousins = $controller->show_cousins; // Booklet // first page : show indi facts print_pedigree_person($controller->rootid, 2, false, 1); // expand the layer echo PGV_JS_START, 'expandbox("', $controller->rootid, '.1", 2);', PGV_JS_END; // process the tree $treeid = ancestry_array($controller->rootid, $PEDIGREE_GENERATIONS - 1); foreach ($treeid as $i => $pid) { if ($pid) { $person = Person::getInstance($pid); if (!is_null($person)) { $famids = $person->getChildFamilies(); foreach ($famids as $famid => $family) { $parents = find_parents_in_record($family->getGedcomRecord()); if ($parents) { print_sosa_family($famid, $pid, $i); } elseif ($i == 1) { // show empty family only if it is the first and only one print_sosa_family('', $pid, $i); } } } } } break; case 2: // Individual list $treeid = ancestry_array($controller->rootid, $PEDIGREE_GENERATIONS); echo '<div class="center">';
function print_descendency($pid, $count) { global $show_spouse, $dgenerations, $bwidth, $bheight, $bhalfheight; global $TEXT_DIRECTION, $PGV_IMAGE_DIR, $PGV_IMAGES, $generations, $box_width, $view, $show_full, $pgv_lang; if ($count >= $dgenerations) { return 0; } print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n"; print "<tr>"; print "<td width=\"" . ($bwidth - 2) . "\">\n"; $numkids = 0; $famids = find_sfamily_ids($pid); if (count($famids) > 0) { $firstkids = 0; foreach ($famids as $indexval => $famid) { $famrec = find_family_record($famid, PGV_GED_ID); $ct = preg_match_all("/1 CHIL @(.*)@/", $famrec, $match, PREG_SET_ORDER); if ($ct > 0) { print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n"; for ($i = 0; $i < $ct; $i++) { $rowspan = 2; if ($i > 0 && $i < $ct - 1) { $rowspan = 1; } $chil = trim($match[$i][1]); print "<tr><td rowspan=\"{$rowspan}\" width=\"{$bwidth}\" style=\"padding-top: 2px;\">\n"; if ($count < $dgenerations - 1) { $kids = print_descendency($chil, $count + 1); if ($i == 0) { $firstkids = $kids; } $numkids += $kids; } else { print_pedigree_person($chil); $numkids++; } print "</td>\n"; $twidth = 7; if ($ct == 1) { $twidth += 3; } print "<td rowspan=\"{$rowspan}\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" width=\"{$twidth}\" height=\"3\" alt=\"\" /></td>\n"; if ($ct > 1) { if ($i == 0) { print "<td height=\"" . ($bhalfheight + 3) . "\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" width=\"3\" alt=\"\" /></td></tr>\n"; print "<tr><td height=\"" . ($bhalfheight + 3) . "\" style=\"background: url('" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["vline"]["other"] . "');\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" width=\"3\" alt=\"\" /></td>\n"; } else { if ($i == $ct - 1) { print "<td height=\"" . ($bhalfheight + 4) . "\" style=\"background: url('" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["vline"]["other"] . "');\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" width=\"3\" alt=\"\" /></td></tr>\n"; print "<tr><td height=\"" . ($bhalfheight + 4) . "\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" width=\"3\" alt=\"\" /></td>\n"; } else { print "<td style=\"background: url('" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["vline"]["other"] . "');\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" width=\"3\" alt=\"\" /></td>\n"; } } } print "</tr>\n"; } print "</table>\n"; } } print "</td>\n"; print "<td width=\"{$bwidth}\">\n"; } // NOTE: If statement OK if ($numkids == 0) { $numkids = 1; $tbwidth = $bwidth + 16; for ($j = $count; $j < $dgenerations; $j++) { print "</td>\n<td width=\"{$bwidth}\">\n"; } } //-- add offset divs to make things line up better if ($show_spouse) { foreach ($famids as $indexval => $famid) { $famrec = find_family_record($famid, PGV_GED_ID); if (!empty($famrec)) { $marrec = get_sub_record(1, "1 MARR", $famrec); if (!empty($marrec)) { print "<br />"; } print "<div style=\"height: " . $bheight . "px; width: " . $bwidth . "px;\"><br /></div>\n"; } } } print_pedigree_person($pid); // NOTE: If statement OK if ($show_spouse) { foreach ($famids as $indexval => $famid) { $famrec = find_family_record($famid, PGV_GED_ID); if (!empty($famrec)) { $parents = find_parents_in_record($famrec); $marrec = get_sub_record(1, "1 MARR", $famrec); if (!empty($marrec)) { print "<br />"; $marriage = new Event($marrec); $marriage->print_simple_fact(); } if ($parents["HUSB"] != $pid) { print_pedigree_person($parents["HUSB"]); } else { print_pedigree_person($parents["WIFE"]); } } } } // NOTE: If statement OK if ($count == 0) { $indirec = find_person_record($pid, PGV_GED_ID); // NOTE: If statement OK if (displayDetailsById($pid, 'INDI') || showLivingNameById($pid)) { // -- print left arrow for decendants so that we can move down the tree $famids = find_sfamily_ids($pid); //-- make sure there is more than 1 child in the family with parents $cfamids = find_family_ids($pid); $num = 0; // NOTE: For statement OK for ($f = 0; $f < count($cfamids); $f++) { $famrec = find_family_record($cfamids[$f], PGV_GED_ID); if ($famrec) { $num += preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $famrec, $smatch, PREG_SET_ORDER); } } // NOTE: If statement OK if ($famids || $num > 1) { print "\n\t\t<div class=\"center\" id=\"childarrow.{$pid}\" dir=\"" . $TEXT_DIRECTION . "\""; print " style=\"position:absolute; width:" . $bwidth . "px; \">"; if ($view != "preview") { print "<a href=\"javascript: " . $pgv_lang["show"] . "\" onclick=\"return togglechildrenbox('{$pid}');\" onmouseover=\"swap_image('larrow.{$pid}',3);\" onmouseout=\"swap_image('larrow.{$pid}',3);\">"; print "<img id=\"larrow.{$pid}\" src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["darrow"]["other"] . "\" border=\"0\" alt=\"\" />"; print "</a>"; } print "\n\t\t<div id=\"childbox.{$pid}\" dir=\"" . $TEXT_DIRECTION . "\" style=\"width:" . $bwidth . "px; height:" . $bheight . "px; visibility: hidden;\">"; print "\n\t\t\t<table class=\"person_box\"><tr><td>"; for ($f = 0; $f < count($famids); $f++) { $famrec = find_family_record(trim($famids[$f]), PGV_GED_ID); if ($famrec) { $parents = find_parents($famids[$f]); if ($parents) { if ($pid != $parents["HUSB"]) { $spid = $parents["HUSB"]; } else { $spid = $parents["WIFE"]; } $spouse = Person::getInstance($spid); if ($spouse) { $name = $spouse->getFullName(); print "\n\t\t\t\t<a href=\"" . encode_url("familybook.php?pid={$spid}&show_spouse={$show_spouse}&show_full={$show_full}&generations={$generations}&box_width={$box_width}") . "\"><span class=\""; if (hasRTLText($name)) { print "name2"; } else { print "name1"; } print "\">"; print PrintReady($name); print "<br /></span></a>"; } } $num = preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $famrec, $smatch, PREG_SET_ORDER); for ($i = 0; $i < $num; $i++) { //-- add the following line to stop a bad PHP bug if ($i >= $num) { break; } $cid = $smatch[$i][1]; $child = Person::getInstance($cid); $name = $child->getFullName(); print "\n\t\t\t\t <a href=\"" . encode_url("familybook.php?pid={$cid}&show_spouse={$show_spouse}&show_full={$show_full}&generations={$generations}&box_width={$box_width}") . "\"><span class=\""; if (hasRTLText($name)) { print "name2"; } else { print "name1"; } print "\">< "; print PrintReady($name); print "<br /></span></a>"; } } } //-- print the siblings for ($f = 0; $f < count($cfamids); $f++) { $famrec = find_family_record($cfamids[$f], PGV_GED_ID); if ($famrec) { $parents = find_parents($cfamids[$f]); if ($parents) { print "<span class=\"name1\"><br />" . $pgv_lang["parents"] . "<br /></span>"; if (!empty($parents["HUSB"])) { $spid = $parents["HUSB"]; $spouse = Person::getInstance($spid); $name = $spouse->getFullName(); print "\n\t\t\t\t <a href=\"" . encode_url("familybook.php?pid={$spid}&show_spouse={$show_spouse}&show_full={$show_full}&generations={$generations}&box_width={$box_width}") . "\"><span class=\""; if (hasRTLText($name)) { print "name2"; } else { print "name1"; } print "\">"; print PrintReady($name); print "<br /></span></a>"; } if (!empty($parents["WIFE"])) { $spid = $parents["WIFE"]; $spouse = Person::getInstance($spid); $name = $spouse->getFullName(); print "\n\t\t\t\t <a href=\"" . encode_url("familybook.php?pid={$spid}&show_spouse={$show_spouse}&show_full={$show_full}&generations={$generations}&box_width={$box_width}") . "\"><span class=\""; if (hasRTLText($name)) { print "name2"; } else { print "name1"; } print "\">"; print PrintReady($name); print "<br /></span></a>"; } } $num = preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $famrec, $smatch, PREG_SET_ORDER); if ($num > 2) { print "<span class=\"name1\"><br />" . $pgv_lang["siblings"] . "<br /></span>"; } if ($num == 2) { print "<span class=\"name1\"><br />" . $pgv_lang["sibling"] . "<br /></span>"; } for ($i = 0; $i < $num; $i++) { //-- add the following line to stop a bad PHP bug if ($i >= $num) { break; } $cid = $smatch[$i][1]; if ($cid != $pid) { $child = Person::getInstance($cid); $name = $child->getFullName(); print "\n\t\t\t\t <a href=\"familybook.php?pid={$cid}&show_spouse={$show_spouse}&show_full={$show_full}&generations={$generations}&box_width={$box_width}\"><span class=\""; if (hasRTLText($name)) { print "name2"; } else { print "name1"; } print "\"> "; print PrintReady($name); print "<br /></span></a>"; } } } } print "\n\t\t\t</td></tr></table>"; print "\n\t\t</div>"; print "\n\t\t</div>"; } } } print "</td></tr>\n"; print "</table>\n"; return $numkids; }
/** * Get relationship between two individuals in the gedcom * * function to calculate the relationship between two people it uses hueristics based on the * individuals birthdate to try and calculate the shortest path between the two individuals * it uses a node cache to help speed up calculations when using relationship privacy * this cache is indexed using the string "$pid1-$pid2" * @param string $pid1 the ID of the first person to compute the relationship from * @param string $pid2 the ID of the second person to compute the relatiohip to * @param bool $followspouse whether to add spouses to the path * @param int $maxlenght the maximim length of path * @param bool $ignore_cache enable or disable the relationship cache * @param int $path_to_find which path in the relationship to find, 0 is the shortest path, 1 is the next shortest path, etc */ function get_relationship($pid1, $pid2, $followspouse = true, $maxlength = 0, $ignore_cache = false, $path_to_find = 0) { global $TIME_LIMIT, $start_time, $pgv_lang, $NODE_CACHE, $NODE_CACHE_LENGTH, $USE_RELATIONSHIP_PRIVACY, $pgv_changes, $GEDCOM; $pid1 = strtoupper($pid1); $pid2 = strtoupper($pid2); if (isset($pgv_changes[$pid2 . "_" . $GEDCOM]) && PGV_USER_CAN_EDIT) { $indirec = find_updated_record($pid2); } else { $indirec = find_person_record($pid2); } //-- check the cache if ($USE_RELATIONSHIP_PRIVACY && !$ignore_cache) { if (isset($NODE_CACHE["{$pid1}-{$pid2}"])) { if ($NODE_CACHE["{$pid1}-{$pid2}"] == "NOT FOUND") { return false; } if ($maxlength == 0 || count($NODE_CACHE["{$pid1}-{$pid2}"]["path"]) - 1 <= $maxlength) { return $NODE_CACHE["{$pid1}-{$pid2}"]; } else { return false; } } //-- check the cache for person 2's children $famids = array(); $ct = preg_match_all("/1\\sFAMS\\s@(.*)@/", $indirec, $match, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { $famids[$i] = $match[$i][1]; } foreach ($famids as $indexval => $fam) { if (isset($pgv_changes[$fam . "_" . $GEDCOM]) && PGV_USER_CAN_EDIT) { $famrec = find_updated_record($fam); } else { $famrec = find_family_record($fam); } $ct = preg_match_all("/1 CHIL @(.*)@/", $famrec, $match, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { $child = $match[$i][1]; if (!empty($child)) { if (isset($NODE_CACHE["{$pid1}-{$child}"])) { if ($maxlength == 0 || count($NODE_CACHE["{$pid1}-{$child}"]["path"]) + 1 <= $maxlength) { $node1 = $NODE_CACHE["{$pid1}-{$child}"]; if ($node1 != "NOT FOUND") { $node1["path"][] = $pid2; $node1["pid"] = $pid2; $ct = preg_match("/1 SEX F/", $indirec, $match); if ($ct > 0) { $node1["relations"][] = "mother"; } else { $node1["relations"][] = "father"; } } $NODE_CACHE["{$pid1}-{$pid2}"] = $node1; if ($node1 == "NOT FOUND") { return false; } return $node1; } else { return false; } } } } } if (!empty($NODE_CACHE_LENGTH) && $maxlength > 0) { if ($NODE_CACHE_LENGTH >= $maxlength) { return false; } } } //-- end cache checking //-- get the birth year of p2 for calculating heuristics $birthrec = get_sub_record(1, "1 BIRT", $indirec); $byear2 = -1; if ($birthrec !== false) { $dct = preg_match("/2 DATE .*(\\d\\d\\d\\d)/", $birthrec, $match); if ($dct > 0) { $byear2 = $match[1]; } } if ($byear2 == -1) { $numfams = preg_match_all("/1\\s*FAMS\\s*@(.*)@/", $indirec, $fmatch, PREG_SET_ORDER); for ($j = 0; $j < $numfams; $j++) { // Get the family record if (isset($pgv_changes[$fmatch[$j][1] . "_" . $GEDCOM]) && PGV_USER_CAN_EDIT) { $famrec = find_updated_record($fmatch[$j][1]); } else { $famrec = find_family_record($fmatch[$j][1]); } // Get the set of children $ct = preg_match_all("/1 CHIL @(.*)@/", $famrec, $cmatch, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { // Get each child's record if (isset($pgv_changes[$cmatch[$i][1] . "_" . $GEDCOM]) && PGV_USER_CAN_EDIT) { $childrec = find_updated_record($cmatch[$i][1]); } else { $childrec = find_person_record($cmatch[$i][1]); } $birthrec = get_sub_record(1, "1 BIRT", $childrec); if ($birthrec !== false) { $dct = preg_match("/2 DATE .*(\\d\\d\\d\\d)/", $birthrec, $bmatch); if ($dct > 0) { $byear2 = $bmatch[1] - 25; } if ($byear2 > 2100) { $byear2 -= 3760; } // Crude conversion from jewish to gregorian } } } } //-- end of approximating birth year //-- current path nodes $p1nodes = array(); //-- ids visited $visited = array(); //-- set up first node for person1 $node1 = array(); $node1["path"] = array(); $node1["path"][] = $pid1; $node1["length"] = 0; $node1["pid"] = $pid1; $node1["relations"] = array(); $node1["relations"][] = "self"; $p1nodes[] = $node1; $visited[$pid1] = true; $found = false; $count = 0; while (!$found) { //-- the following 2 lines ensure that the user can abort a long relationship calculation //-- refer to http://www.php.net/manual/en/features.connection-handling.php for more //-- information about why these lines are included if (headers_sent()) { print " "; if ($count % 100 == 0) { flush(); } } $count++; $end_time = microtime(true); $exectime = $end_time - $start_time; if ($TIME_LIMIT > 1 && $exectime > $TIME_LIMIT - 1) { print "<span class=\"error\">" . $pgv_lang["timeout_error"] . "</span>\n"; return false; } if (count($p1nodes) == 0) { if ($maxlength != 0) { if (!isset($NODE_CACHE_LENGTH)) { $NODE_CACHE_LENGTH = $maxlength; } else { if ($NODE_CACHE_LENGTH < $maxlength) { $NODE_CACHE_LENGTH = $maxlength; } } } if (headers_sent()) { print "\n<!-- Relationship {$pid1}-{$pid2} NOT FOUND | Visited " . count($visited) . " nodes | Required {$count} iterations.<br />\n"; print_execution_stats(); print "-->\n"; } $NODE_CACHE["{$pid1}-{$pid2}"] = "NOT FOUND"; return false; } //-- search the node list for the shortest path length $shortest = -1; foreach ($p1nodes as $index => $node) { if ($shortest == -1) { $shortest = $index; } else { $node1 = $p1nodes[$shortest]; if ($node1["length"] > $node["length"]) { $shortest = $index; } } } if ($shortest == -1) { return false; } $node = $p1nodes[$shortest]; if ($maxlength == 0 || count($node["path"]) <= $maxlength) { if ($node["pid"] == $pid2) { } else { //-- hueristic values $fatherh = 1; $motherh = 1; $siblingh = 2; $spouseh = 2; $childh = 3; //-- generate heuristic values based of the birthdates of the current node and p2 if (isset($pgv_changes[$node["pid"] . "_" . $GEDCOM]) && PGV_USER_CAN_EDIT) { $indirec = find_updated_record($node["pid"]); } else { $indirec = find_person_record($node["pid"]); } $byear1 = -1; $birthrec = get_sub_record(1, "1 BIRT", $indirec); if ($birthrec !== false) { $dct = preg_match("/2 DATE .*(\\d\\d\\d\\d)/", $birthrec, $match); if ($dct > 0) { $byear1 = $match[1]; } if ($byear1 > 2100) { $byear1 -= 3760; } // Crude conversion from jewish to gregorian } if ($byear1 != -1 && $byear2 != -1) { $yeardiff = $byear1 - $byear2; if ($yeardiff < -140) { $fatherh = 20; $motherh = 20; $siblingh = 15; $spouseh = 15; $childh = 1; } else { if ($yeardiff < -100) { $fatherh = 15; $motherh = 15; $siblingh = 10; $spouseh = 10; $childh = 1; } else { if ($yeardiff < -60) { $fatherh = 10; $motherh = 10; $siblingh = 5; $spouseh = 5; $childh = 1; } else { if ($yeardiff < -20) { $fatherh = 5; $motherh = 5; $siblingh = 3; $spouseh = 3; $childh = 1; } else { if ($yeardiff < 20) { $fatherh = 3; $motherh = 3; $siblingh = 1; $spouseh = 1; $childh = 5; } else { if ($yeardiff < 60) { $fatherh = 1; $motherh = 1; $siblingh = 5; $spouseh = 2; $childh = 10; } else { if ($yeardiff < 100) { $fatherh = 1; $motherh = 1; $siblingh = 10; $spouseh = 3; $childh = 15; } else { $fatherh = 1; $motherh = 1; $siblingh = 15; $spouseh = 4; $childh = 20; } } } } } } } } //-- check all parents and siblings of this node $famids = array(); $ct = preg_match_all("/1\\sFAMC\\s@(.*)@/", $indirec, $match, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { if (!isset($visited[$match[$i][1]])) { $famids[$i] = $match[$i][1]; } } foreach ($famids as $indexval => $fam) { $visited[$fam] = true; if (isset($pgv_changes[$fam . "_" . $GEDCOM]) && PGV_USER_CAN_EDIT) { $famrec = find_updated_record($fam); } else { $famrec = find_family_record($fam); } $parents = find_parents_in_record($famrec); if (!empty($parents["HUSB"]) && !isset($visited[$parents["HUSB"]])) { $node1 = $node; $node1["length"] += $fatherh; $node1["path"][] = $parents["HUSB"]; $node1["pid"] = $parents["HUSB"]; $node1["relations"][] = "father"; $p1nodes[] = $node1; if ($node1["pid"] == $pid2) { if ($path_to_find > 0) { $path_to_find--; } else { $found = true; $resnode = $node1; } } else { $visited[$parents["HUSB"]] = true; } if ($USE_RELATIONSHIP_PRIVACY) { $NODE_CACHE["{$pid1}-" . $node1["pid"]] = $node1; } } if (!empty($parents["WIFE"]) && !isset($visited[$parents["WIFE"]])) { $node1 = $node; $node1["length"] += $motherh; $node1["path"][] = $parents["WIFE"]; $node1["pid"] = $parents["WIFE"]; $node1["relations"][] = "mother"; $p1nodes[] = $node1; if ($node1["pid"] == $pid2) { if ($path_to_find > 0) { $path_to_find--; } else { $found = true; $resnode = $node1; } } else { $visited[$parents["WIFE"]] = true; } if ($USE_RELATIONSHIP_PRIVACY) { $NODE_CACHE["{$pid1}-" . $node1["pid"]] = $node1; } } $ct = preg_match_all("/1 CHIL @(.*)@/", $famrec, $match, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { $child = $match[$i][1]; if (!empty($child) && !isset($visited[$child])) { $node1 = $node; $node1["length"] += $siblingh; $node1["path"][] = $child; $node1["pid"] = $child; $node1["relations"][] = "sibling"; $p1nodes[] = $node1; if ($node1["pid"] == $pid2) { if ($path_to_find > 0) { $path_to_find--; } else { $found = true; $resnode = $node1; } } else { $visited[$child] = true; } if ($USE_RELATIONSHIP_PRIVACY) { $NODE_CACHE["{$pid1}-" . $node1["pid"]] = $node1; } } } } //-- check all spouses and children of this node $famids = array(); $ct = preg_match_all("/1\\sFAMS\\s@(.*)@/", $indirec, $match, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { $famids[$i] = $match[$i][1]; } foreach ($famids as $indexval => $fam) { $visited[$fam] = true; if (isset($pgv_changes[$fam . "_" . $GEDCOM]) && PGV_USER_CAN_EDIT) { $famrec = find_updated_record($fam); } else { $famrec = find_family_record($fam); } if ($followspouse) { $parents = find_parents_in_record($famrec); if (!empty($parents["HUSB"]) && (!in_arrayr($parents["HUSB"], $node1) || !isset($visited[$parents["HUSB"]]))) { $node1 = $node; $node1["length"] += $spouseh; $node1["path"][] = $parents["HUSB"]; $node1["pid"] = $parents["HUSB"]; $node1["relations"][] = "spouse"; $p1nodes[] = $node1; if ($node1["pid"] == $pid2) { if ($path_to_find > 0) { $path_to_find--; } else { $found = true; $resnode = $node1; } } else { $visited[$parents["HUSB"]] = true; } if ($USE_RELATIONSHIP_PRIVACY) { $NODE_CACHE["{$pid1}-" . $node1["pid"]] = $node1; } } if (!empty($parents["WIFE"]) && (!in_arrayr($parents["WIFE"], $node1) || !isset($visited[$parents["WIFE"]]))) { $node1 = $node; $node1["length"] += $spouseh; $node1["path"][] = $parents["WIFE"]; $node1["pid"] = $parents["WIFE"]; $node1["relations"][] = "spouse"; $p1nodes[] = $node1; if ($node1["pid"] == $pid2) { if ($path_to_find > 0) { $path_to_find--; } else { $found = true; $resnode = $node1; } } else { $visited[$parents["WIFE"]] = true; } if ($USE_RELATIONSHIP_PRIVACY) { $NODE_CACHE["{$pid1}-" . $node1["pid"]] = $node1; } } } $ct = preg_match_all("/1 CHIL @(.*)@/", $famrec, $match, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { $child = $match[$i][1]; if (!empty($child) && !isset($visited[$child])) { $node1 = $node; $node1["length"] += $childh; $node1["path"][] = $child; $node1["pid"] = $child; $node1["relations"][] = "child"; $p1nodes[] = $node1; if ($node1["pid"] == $pid2) { if ($path_to_find > 0) { $path_to_find--; } else { $found = true; $resnode = $node1; } } else { $visited[$child] = true; } if ($USE_RELATIONSHIP_PRIVACY) { $NODE_CACHE["{$pid1}-" . $node1["pid"]] = $node1; } } } } } } unset($p1nodes[$shortest]); } //-- end while loop if (headers_sent()) { print "\n<!-- Relationship {$pid1}-{$pid2} | Visited " . count($visited) . " nodes | Required {$count} iterations.<br />\n"; print_execution_stats(); print "-->\n"; } return $resnode; }
/** * print the parents table for a family * * @param string $famid family gedcom ID * @param int $sosa optional child sosa number * @param string $label optional indi label (descendancy booklet) * @param string $parid optional parent ID (descendancy booklet) * @param string $gparid optional gd-parent ID (descendancy booklet) */ function print_family_parents($famid, $sosa = 0, $label = "", $parid = "", $gparid = "", $personcount = "1") { global $pgv_lang, $view, $show_full, $show_famlink; global $TEXT_DIRECTION, $SHOW_EMPTY_BOXES, $SHOW_ID_NUMBERS, $LANGUAGE; global $pbwidth, $pbheight; global $PGV_IMAGE_DIR, $PGV_IMAGES; global $show_changes, $pgv_changes, $GEDCOM; $family = Family::getInstance($famid); if (is_null($family)) { return; } $husb = $family->getHusband(); if (is_null($husb)) { $husb = new Person(''); } $wife = $family->getWife(); if (is_null($wife)) { $wife = new Person(''); } if (!is_null($husb)) { $tempID = $husb->getXref(); if (!empty($tempID)) { print "<a name=\"{$tempID}\"></a>\r\n"; } } if (!is_null($wife)) { $tempID = $wife->getXref(); if (!empty($tempID)) { print "<a name=\"{$tempID}\"></a>\r\n"; } } print_family_header($famid); // -- get the new record and parents if in editing show changes mode if (PGV_USER_CAN_EDIT && isset($pgv_changes[$famid . "_" . $GEDCOM])) { $newrec = find_updated_record($famid); $newparents = find_parents_in_record($newrec); } /** * husband side */ print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr><td rowspan=\"2\">"; print "<span class=\"subheaders\">" . get_sosa_name($sosa * 2) . "</span>"; print "\n\t<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>"; if ($parid) { if ($husb->getXref() == $parid) { print_sosa_number($label); } else { print_sosa_number($label, "", "blank"); } } else { if ($sosa > 0) { print_sosa_number($sosa * 2); } } if (isset($newparents) && $husb->getXref() != $newparents["HUSB"]) { print "\n\t<td valign=\"top\" class=\"facts_valueblue\">"; print_pedigree_person($newparents['HUSB'], 1, $show_famlink, 2, $personcount); } else { print "\n\t<td valign=\"top\">"; print_pedigree_person($husb->getXref(), 1, $show_famlink, 2, $personcount); } print "</td></tr></table>"; print "</td>\n"; // husband's parents $hfams = $husb->getChildFamilies(); $hparents = false; $upfamid = ""; if (count($hfams) > 0 or $sosa != 0 and $SHOW_EMPTY_BOXES) { print "<td rowspan=\"2\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" alt=\"\" /></td><td rowspan=\"2\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["vline"]["other"] . "\" width=\"3\" height=\"" . $pbheight . "\" alt=\"\" /></td>"; print "<td><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" alt=\"\" /></td><td>"; $hparents = false; foreach ($hfams as $hfamid => $hfamily) { if (!is_null($hfamily)) { $hparents = find_parents_in_record($hfamily->getGedcomRecord()); $upfamid = $hfamid; break; } } if ($hparents or $sosa != 0 and $SHOW_EMPTY_BOXES) { // husband's father print "\n\t<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>"; if ($sosa > 0) { print_sosa_number($sosa * 4, $hparents['HUSB'], "down"); } if (!empty($gparid) and $hparents['HUSB'] == $gparid) { print_sosa_number(trim(substr($label, 0, -3), ".") . "."); } print "\n\t<td valign=\"top\">"; print_pedigree_person($hparents['HUSB'], 1, $show_famlink, 4, $personcount); print "</td></tr></table>"; } print "</td>"; } if (!empty($upfamid) and $sosa != -1 and $view != "preview") { print "<td valign=\"middle\" rowspan=\"2\">"; print_url_arrow($upfamid, $sosa == 0 ? "?famid={$upfamid}&show_full={$show_full}" : "#{$upfamid}", "{$upfamid}", 1); print "</td>\n"; } if ($hparents or $sosa != 0 and $SHOW_EMPTY_BOXES) { // husband's mother print "</tr><tr><td><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" alt=\"\" /></td><td>"; print "\n\t<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\" border=\"0\"><tr>"; if ($sosa > 0) { print_sosa_number($sosa * 4 + 1, $hparents['WIFE'], "down"); } if (!empty($gparid) and $hparents['WIFE'] == $gparid) { print_sosa_number(trim(substr($label, 0, -3), ".") . "."); } print "\n\t<td valign=\"top\">"; print_pedigree_person($hparents['WIFE'], 1, $show_famlink, 5, $personcount); print "</td></tr></table>"; print "</td>\n"; } print "</tr></table>\n\n"; if ($sosa != 0) { print "<a href=\"family.php?famid={$famid}\" class=\"details1\">"; if ($SHOW_ID_NUMBERS) { print getLRM() . "({$famid})" . getLRM() . " "; } else { print str_repeat(" ", 10); } $marriage = $family->getMarriage(); if ($marriage->canShow()) { $marriage->print_simple_fact(); } else { print $pgv_lang["private"]; } print "</a>"; } else { print "<br />\n"; } /** * wife side */ print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr><td rowspan=\"2\">"; print "<span class=\"subheaders\">" . get_sosa_name($sosa * 2 + 1) . "</span>"; print "\n\t<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\"><tr>"; if ($parid) { if ($wife->getXref() == $parid) { print_sosa_number($label); } else { print_sosa_number($label, "", "blank"); } } else { if ($sosa > 0) { print_sosa_number($sosa * 2 + 1); } } if (isset($newparents) && $wife->getXref() != $newparents["WIFE"]) { print "\n\t<td valign=\"top\" class=\"facts_valueblue\">"; print_pedigree_person($newparents['WIFE'], 1, $show_famlink, 3, $personcount); } else { print "\n\t<td valign=\"top\">"; print_pedigree_person($wife->getXref(), 1, $show_famlink, 3, $personcount); } print "</td></tr></table>"; print "</td>\n"; // wife's parents $hfams = $wife->getChildFamilies(); $hparents = false; $upfamid = ""; if (count($hfams) > 0 or $sosa != 0 and $SHOW_EMPTY_BOXES) { print "<td rowspan=\"2\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" alt=\"\" /></td><td rowspan=\"2\"><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["vline"]["other"] . "\" width=\"3\" height=\"" . $pbheight . "\" alt=\"\" /></td>"; print "<td><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" alt=\"\" /></td><td>"; $j = 0; foreach ($hfams as $hfamid => $hfamily) { if (!is_null($hfamily)) { $hparents = find_parents_in_record($hfamily->getGedcomRecord()); $upfamid = $hfamid; break; } } if ($hparents or $sosa != 0 and $SHOW_EMPTY_BOXES) { // wife's father print "\n\t<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\"><tr>"; if ($sosa > 0) { print_sosa_number($sosa * 4 + 2, $hparents['HUSB'], "down"); } if (!empty($gparid) and $hparents['HUSB'] == $gparid) { print_sosa_number(trim(substr($label, 0, -3), ".") . "."); } print "\n\t<td valign=\"top\">"; print_pedigree_person($hparents['HUSB'], 1, $show_famlink, 6, $personcount); print "</td></tr></table>"; } print "</td>\n"; } if (!empty($upfamid) and $sosa != -1 and $view != "preview") { print "<td valign=\"middle\" rowspan=\"2\">"; print_url_arrow($upfamid, $sosa == 0 ? "?famid={$upfamid}&show_full={$show_full}" : "#{$upfamid}", "{$upfamid}", 1); print "</td>\n"; } if ($hparents or $sosa != 0 and $SHOW_EMPTY_BOXES) { // wife's mother print "</tr><tr><td><img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" alt=\"\" /></td><td>"; print "\n\t<table style=\"width: " . $pbwidth . "px; height: " . $pbheight . "px;\"><tr>"; if ($sosa > 0) { print_sosa_number($sosa * 4 + 3, $hparents['WIFE'], "down"); } if (!empty($gparid) and $hparents['WIFE'] == $gparid) { print_sosa_number(trim(substr($label, 0, -3), ".") . "."); } print "\n\t<td valign=\"top\">"; print_pedigree_person($hparents['WIFE'], 1, $show_famlink, 7, $personcount); print "</td></tr></table>\n"; print "</td>\n"; } print "</tr></table>\n\n"; }
<table class="<?php echo $TEXT_DIRECTION; ?> width80"> <tr><td class="topbottombar" colspan="4"> <?php $famreqdfacts = preg_split("/[,; ]/", $QUICK_REQUIRED_FAMFACTS); $famid = $sfams[$i - 1]; $family = Family::getInstance($famid); $famrec = $family->getGedcomRecord(); if (isset($pgv_changes[$famid . "_" . PGV_GEDCOM])) { $famrec = find_updated_record($famid, PGV_GED_ID); $family = new Family($famrec); } echo $pgv_lang["family_with"], " "; $parents = find_parents_in_record($famrec); $spid = ""; if ($parents) { if ($pid != $parents["HUSB"]) { $spid = $parents["HUSB"]; } else { $spid = $parents["WIFE"]; } } $person = Person::getInstance($spid); if ($person) { echo "<a href=\"#\" onclick=\"return quickEdit('", $person->getXref(), "', '', '", PGV_GEDCOM, "');\">"; $name = PrintReady(stripLRMRLM($person->getFullName())); if ($SHOW_ID_NUMBERS) { $name .= PrintReady(" (" . $person->getXref() . ")"); }
/** * print a child ascendancy * * @param string $pid individual Gedcom Id * @param int $sosa child sosa number * @param int $depth the ascendancy depth to show */ function print_child_ascendancy($pid, $sosa, $depth) { global $pgv_lang, $TEXT_DIRECTION, $OLD_PGENS; global $PGV_IMAGE_DIR, $PGV_IMAGES, $Dindent; global $SHOW_EMPTY_BOXES, $pidarr, $box_width; $person = Person::getInstance($pid); // child print "\r\n<li>"; print "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr><td><a name=\"sosa" . $sosa . "\"></a>"; $new = ($pid == "" or !isset($pidarr["{$pid}"])); if ($sosa == 1) { print "<img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" height=\"3\" width=\"{$Dindent}\" border=\"0\" alt=\"\" /></td><td>\n"; } else { print "<img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" height=\"3\" width=\"2\" border=\"0\" alt=\"\" />"; print "<img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["hline"]["other"] . "\" height=\"3\" width=\"" . ($Dindent - 2) . "\" border=\"0\" alt=\"\" /></td><td>\n"; } print_pedigree_person($pid, 1, $this->view != "preview"); print "</td>"; print "<td>"; if ($TEXT_DIRECTION == "ltr") { $label = $pgv_lang["ancestry_chart"] . ": " . $pid; } else { $label = $pid . " :" . $pgv_lang["ancestry_chart"]; } if ($sosa > 1) { print_url_arrow($pid, encode_url("?rootid={$pid}&PEDIGREE_GENERATIONS={$OLD_PGENS}&show_full={$this->show_full}&box_width={$box_width}&chart_style={$this->chart_style}"), $label, 3); } print "</td>"; print "<td class=\"details1\"> <span dir=\"ltr\" class=\"person_box" . ($sosa == 1 ? "NN" : ($sosa % 2 ? "F" : "")) . "\"> {$sosa} </span> "; print "</td><td class=\"details1\">"; $relation = ""; if (!$new) { $relation = "<br />[=<a href=\"#sosa" . $pidarr["{$pid}"] . "\">" . $pidarr["{$pid}"] . "</a> - " . get_sosa_name($pidarr["{$pid}"]) . "]"; } else { $pidarr["{$pid}"] = $sosa; } print get_sosa_name($sosa) . $relation; print "</td>"; print "</tr></table>"; if (is_null($person)) { print "</li>"; return; } // parents $famids = $person->getChildFamilies(); $parents = false; $famrec = ""; $famid = ""; foreach ($famids as $famid => $family) { if (!is_null($family)) { $famrec = $family->getGedcomRecord(); $parents = find_parents_in_record($famrec); if ($parents) { break; } } } if (($parents || $SHOW_EMPTY_BOXES) && $new && $depth > 0) { // print marriage info print "<span class=\"details1\" style=\"white-space: nowrap;\" >"; print "<img src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["spacer"]["other"] . "\" height=\"2\" width=\"{$Dindent}\" border=\"0\" align=\"middle\" alt=\"\" /><a href=\"javascript: " . $pgv_lang["view_family"] . "\" onclick=\"expand_layer('sosa_" . $sosa . "'); return false;\" class=\"top\"><img id=\"sosa_" . $sosa . "_img\" src=\"" . $PGV_IMAGE_DIR . "/" . $PGV_IMAGES["minus"]["other"] . "\" align=\"middle\" hspace=\"0\" vspace=\"3\" border=\"0\" alt=\"" . $pgv_lang["view_family"] . "\" /></a> "; print " <span class=\"person_box\"> " . $sosa * 2 . " </span> " . $pgv_lang["and"]; print " <span class=\"person_boxF\"> " . ($sosa * 2 + 1) . " </span> "; if (!empty($family)) { $marriage = $family->getMarriage(); if ($marriage->canShow()) { $marriage->print_simple_fact(); } else { print $pgv_lang["private"]; } } print "</span>"; // display parents recursively print "\r\n<ul style=\"list-style: none; display: block;\" id=\"sosa_{$sosa}\">"; $this->print_child_ascendancy($parents["HUSB"], $sosa * 2, $depth - 1); $this->print_child_ascendancy($parents["WIFE"], $sosa * 2 + 1, $depth - 1); print "</ul>\r\n"; } print "</li>\r\n"; }
/** * Check if the given gedcom record has any RESN editing restrictions * This is used to prevent raw editing and deletion of records that are locked * @param string $gedrec * @return boolean */ function checkFactEdit($gedrec) { if (PGV_USER_GEDCOM_ADMIN) { return true; } $ct = preg_match("/2 RESN ((privacy)|(locked))/i", $gedrec, $match); if ($ct > 0) { $match[1] = strtolower(trim($match[1])); $gt = preg_match("/0 @(.+)@ (.+)/", $gedrec, $gmatch); if ($gt > 0) { $gid = trim($gmatch[1]); $type = trim($gmatch[2]); if (PGV_USER_GEDCOM_ID == $gid) { return true; } if ($type == 'FAM') { $parents = find_parents_in_record($gedrec); if (PGV_USER_GEDCOM_ID == $parents["HUSB"] || PGV_USER_GEDCOM_ID == $parents["WIFE"]) { return true; } } } return false; } return true; }
/** * add events where pid is an ASSOciate * * @return records added to indifacts array * */ function add_asso_facts() { global $factarray, $pgv_lang; $associates = array_merge(fetch_linked_indi($this->getXref(), 'ASSO', $this->ged_id), fetch_linked_fam($this->getXref(), 'ASSO', $this->ged_id)); foreach ($associates as $associate) { foreach ($associate->getFacts() as $event) { $srec = $event->getGedcomRecord(); $arec = get_sub_record(2, "2 ASSO @" . $this->getXref() . "@", $srec); if ($arec) { $fact = $event->getTag(); $label = $event->getLabel(); $sdate = get_sub_record(2, "2 DATE", $srec); // relationship ? $rrec = get_sub_record(3, "3 RELA", $arec); $rela = trim(substr($rrec, 7)); if (empty($rela)) { $rela = "ASSO"; } // add an event record $factrec = "1 EVEN\n2 TYPE " . $label . "<br/>[ <span class=\"details_label\">"; if (isset($pgv_lang[strtolower($rela)])) { $factrec .= $pgv_lang[strtolower($rela)] . "</span> ]"; } else { if (isset($factarray[$rela])) { $factrec .= $factarray[$rela] . "</span> ]"; } } $factrec .= "\n" . $sdate . "\n" . get_sub_record(2, '2 PLAC', $srec); if (!$event->canShow()) { $factrec .= "\n2 RESN privacy"; } if ($associate->getType() == 'FAM') { $famrec = find_family_record($associate->getXref()); if ($famrec) { $parents = find_parents_in_record($famrec); if ($parents["HUSB"]) { $factrec .= "\n2 ASSO @" . $parents["HUSB"] . "@"; } //\n3 RELA ".$factarray[$fact]; if ($parents["WIFE"]) { $factrec .= "\n2 ASSO @" . $parents["WIFE"] . "@"; } //\n3 RELA ".$factarray[$fact]; } } else { if ($fact == 'BIRT') { $sex = $associate->getSex(); if ($sex == "M") { $rela_b = "twin_brother"; } else { if ($sex == "F") { $rela_b = "twin_sister"; } else { $rela_b = "twin"; } } $factrec .= "\n2 ASSO @" . $associate->getXref() . "@\n3 RELA " . $rela_b; } else { if ($fact == 'CHR') { $sex = $associate->getSex(); if ($sex == "M") { $rela_chr = "godson"; } else { if ($sex == "F") { $rela_chr = "goddaughter"; } else { $rela_chr = "godchild"; } } $factrec .= "\n2 ASSO @" . $associate->getXref() . "@\n3 RELA " . $rela_chr; } else { $factrec .= "\n2 ASSO @" . $associate->getXref() . "@\n3 RELA " . $fact; } } } //$factrec .= "\n3 NOTE ".$rela; $factrec .= "\n2 ASSO @" . $this->getXref() . "@\n3 RELA *" . $rela; // check if this fact already exists in the list $found = false; if ($sdate) { foreach ($this->indifacts as $k => $v) { if (strpos($v->getGedcomRecord(), $sdate) && strpos($v->getGedcomRecord(), "2 ASSO @" . $this->getXref() . "@")) { $found = true; break; } } } if (!$found) { $this->indifacts[] = new Event($factrec, 0); } } } } }